2015-08-18 19:03:09 +00:00
/******************************************************************************
*
* Copyright ( c ) 2007 - 2012 Realtek Corporation . All rights reserved .
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License along with
* this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 , USA
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define _USB_OPS_LINUX_C_
# include <drv_types.h>
# include <hal_data.h>
# include <rtw_sreset.h>
int usbctrl_vendorreq ( struct intf_hdl * pintfhdl , u8 request , u16 value , u16 index , void * pdata , u16 len , u8 requesttype )
{
_adapter * padapter = pintfhdl - > padapter ;
struct dvobj_priv * pdvobjpriv = adapter_to_dvobj ( padapter ) ;
struct pwrctrl_priv * pwrctl = dvobj_to_pwrctl ( pdvobjpriv ) ;
struct usb_device * udev = pdvobjpriv - > pusbdev ;
unsigned int pipe ;
int status = 0 ;
u32 tmp_buflen = 0 ;
u8 reqtype ;
u8 * pIo_buf ;
int vendorreq_times = 0 ;
# ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE
u8 * tmp_buf ;
# else // use stack memory
u8 tmp_buf [ MAX_USB_IO_CTL_SIZE ] ;
# endif
# ifdef CONFIG_CONCURRENT_MODE
if ( padapter - > adapter_type > PRIMARY_ADAPTER )
{
padapter = padapter - > pbuddy_adapter ;
pdvobjpriv = adapter_to_dvobj ( padapter ) ;
udev = pdvobjpriv - > pusbdev ;
}
# endif
//DBG_871X("%s %s:%d\n",__FUNCTION__, current->comm, current->pid);
if ( RTW_CANNOT_IO ( padapter ) ) {
RT_TRACE ( _module_hci_ops_os_c_ , _drv_err_ , ( " usbctrl_vendorreq:(RTW_CANNOT_IO)!!! \n " ) ) ;
status = - EPERM ;
goto exit ;
}
if ( len > MAX_VENDOR_REQ_CMD_SIZE ) {
DBG_8192C ( " [%s] Buffer len error ,vendor request failed \n " , __FUNCTION__ ) ;
status = - EINVAL ;
goto exit ;
}
# ifdef CONFIG_USB_VENDOR_REQ_MUTEX
_enter_critical_mutex ( & pdvobjpriv - > usb_vendor_req_mutex , NULL ) ;
# endif
// Acquire IO memory for vendorreq
# ifdef CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC
pIo_buf = pdvobjpriv - > usb_vendor_req_buf ;
# else
# ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE
tmp_buf = rtw_malloc ( ( u32 ) len + ALIGNMENT_UNIT ) ;
tmp_buflen = ( u32 ) len + ALIGNMENT_UNIT ;
# else // use stack memory
tmp_buflen = MAX_USB_IO_CTL_SIZE ;
# endif
// Added by Albert 2010/02/09
// For mstar platform, mstar suggests the address for USB IO should be 16 bytes alignment.
// Trying to fix it here.
pIo_buf = ( tmp_buf = = NULL ) ? NULL : tmp_buf + ALIGNMENT_UNIT - ( ( SIZE_PTR ) ( tmp_buf ) & 0x0f ) ;
# endif
if ( pIo_buf = = NULL ) {
DBG_8192C ( " [%s] pIo_buf == NULL \n " , __FUNCTION__ ) ;
status = - ENOMEM ;
goto release_mutex ;
}
while ( + + vendorreq_times < = MAX_USBCTRL_VENDORREQ_TIMES )
{
_rtw_memset ( pIo_buf , 0 , len ) ;
if ( requesttype = = 0x01 )
{
pipe = usb_rcvctrlpipe ( udev , 0 ) ; //read_in
reqtype = REALTEK_USB_VENQT_READ ;
}
else
{
pipe = usb_sndctrlpipe ( udev , 0 ) ; //write_out
reqtype = REALTEK_USB_VENQT_WRITE ;
_rtw_memcpy ( pIo_buf , pdata , len ) ;
}
status = rtw_usb_control_msg ( udev , pipe , request , reqtype , value , index , pIo_buf , len , RTW_USB_CONTROL_MSG_TIMEOUT ) ;
if ( status = = len ) // Success this control transfer.
{
rtw_reset_continual_io_error ( pdvobjpriv ) ;
if ( requesttype = = 0x01 )
{ // For Control read transfer, we have to copy the read data from pIo_buf to pdata.
_rtw_memcpy ( pdata , pIo_buf , len ) ;
}
}
else { // error cases
DBG_8192C ( " reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d \n "
, value , ( requesttype = = 0x01 ) ? " read " : " write " , len , status , * ( u32 * ) pdata , vendorreq_times ) ;
if ( status < 0 ) {
if ( status = = ( - ESHUTDOWN ) | | status = = - ENODEV )
{
padapter - > bSurpriseRemoved = _TRUE ;
} else {
# ifdef DBG_CONFIG_ERROR_DETECT
{
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
pHalData - > srestpriv . Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL ;
}
# endif
}
}
else // status != len && status >= 0
{
if ( status > 0 ) {
if ( requesttype = = 0x01 )
{ // For Control read transfer, we have to copy the read data from pIo_buf to pdata.
_rtw_memcpy ( pdata , pIo_buf , len ) ;
}
}
}
if ( rtw_inc_and_chk_continual_io_error ( pdvobjpriv ) = = _TRUE ) {
padapter - > bSurpriseRemoved = _TRUE ;
break ;
}
}
// firmware download is checksumed, don't retry
if ( ( value > = FW_START_ADDRESS ) | | status = = len )
break ;
}
// release IO memory used by vendorreq
# ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE
rtw_mfree ( tmp_buf , tmp_buflen ) ;
# endif
release_mutex :
# ifdef CONFIG_USB_VENDOR_REQ_MUTEX
_exit_critical_mutex ( & pdvobjpriv - > usb_vendor_req_mutex , NULL ) ;
# endif
exit :
return status ;
}
# ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ
static void _usbctrl_vendorreq_async_callback ( struct urb * urb , struct pt_regs * regs )
{
if ( urb ) {
if ( urb - > context ) {
rtw_mfree ( urb - > context ) ;
}
usb_free_urb ( urb ) ;
}
}
static int _usbctrl_vendorreq_async_write ( struct usb_device * udev , u8 request ,
u16 value , u16 index , void * pdata , u16 len , u8 requesttype )
{
int rc ;
unsigned int pipe ;
u8 reqtype ;
struct usb_ctrlrequest * dr ;
struct urb * urb ;
struct rtl819x_async_write_data {
u8 data [ VENDOR_CMD_MAX_DATA_LEN ] ;
struct usb_ctrlrequest dr ;
} * buf ;
if ( requesttype = = VENDOR_READ ) {
pipe = usb_rcvctrlpipe ( udev , 0 ) ; //read_in
reqtype = REALTEK_USB_VENQT_READ ;
}
else {
pipe = usb_sndctrlpipe ( udev , 0 ) ; //write_out
reqtype = REALTEK_USB_VENQT_WRITE ;
}
buf = ( struct rtl819x_async_write_data * ) rtw_zmalloc ( sizeof ( * buf ) ) ;
if ( ! buf ) {
rc = - ENOMEM ;
goto exit ;
}
urb = usb_alloc_urb ( 0 , GFP_ATOMIC ) ;
if ( ! urb ) {
rtw_mfree ( ( u8 * ) buf , sizeof ( * buf ) ) ;
rc = - ENOMEM ;
goto exit ;
}
dr = & buf - > dr ;
dr - > bRequestType = reqtype ;
dr - > bRequest = request ;
dr - > wValue = cpu_to_le16 ( value ) ;
dr - > wIndex = cpu_to_le16 ( index ) ;
dr - > wLength = cpu_to_le16 ( len ) ;
_rtw_memcpy ( buf , pdata , len ) ;
usb_fill_control_urb ( urb , udev , pipe , ( unsigned char * ) dr , buf , len ,
_usbctrl_vendorreq_async_callback , buf ) ;
rc = usb_submit_urb ( urb , GFP_ATOMIC ) ;
if ( rc < 0 ) {
rtw_mfree ( ( u8 * ) buf , sizeof ( * buf ) ) ;
usb_free_urb ( urb ) ;
}
exit :
return rc ;
}
int usb_write_async ( struct usb_device * udev , u32 addr , void * pdata , u16 len )
{
u8 request ;
u8 requesttype ;
u16 wvalue ;
u16 index ;
int ret ;
requesttype = VENDOR_WRITE ; //write_out
request = REALTEK_USB_VENQT_CMD_REQ ;
index = REALTEK_USB_VENQT_CMD_IDX ; //n/a
wvalue = ( u16 ) ( addr & 0x0000ffff ) ;
ret = _usbctrl_vendorreq_async_write ( udev , request , wvalue , index , pdata , len , requesttype ) ;
return ret ;
}
int usb_async_write8 ( struct intf_hdl * pintfhdl , u32 addr , u8 val )
{
u8 data ;
int ret ;
struct dvobj_priv * pdvobjpriv = ( struct dvobj_priv * ) pintfhdl - > pintf_dev ;
struct usb_device * udev = pdvobjpriv - > pusbdev ;
_func_enter_ ;
data = val ;
ret = usb_write_async ( udev , addr , & data , 1 ) ;
_func_exit_ ;
return ret ;
}
int usb_async_write16 ( struct intf_hdl * pintfhdl , u32 addr , u16 val )
{
u16 data ;
int ret ;
struct dvobj_priv * pdvobjpriv = ( struct dvobj_priv * ) pintfhdl - > pintf_dev ;
struct usb_device * udev = pdvobjpriv - > pusbdev ;
_func_enter_ ;
data = val ;
ret = usb_write_async ( udev , addr , & data , 2 ) ;
_func_exit_ ;
return ret ;
}
int usb_async_write32 ( struct intf_hdl * pintfhdl , u32 addr , u32 val )
{
u32 data ;
int ret ;
struct dvobj_priv * pdvobjpriv = ( struct dvobj_priv * ) pintfhdl - > pintf_dev ;
struct usb_device * udev = pdvobjpriv - > pusbdev ;
_func_enter_ ;
data = val ;
ret = usb_write_async ( udev , addr , & data , 4 ) ;
_func_exit_ ;
return ret ;
}
# endif /* CONFIG_USB_SUPPORT_ASYNC_VDN_REQ */
unsigned int ffaddr2pipehdl ( struct dvobj_priv * pdvobj , u32 addr )
{
unsigned int pipe = 0 , ep_num = 0 ;
struct usb_device * pusbd = pdvobj - > pusbdev ;
if ( addr = = RECV_BULK_IN_ADDR ) {
pipe = usb_rcvbulkpipe ( pusbd , pdvobj - > RtInPipe [ 0 ] ) ;
} else if ( addr = = RECV_INT_IN_ADDR ) {
pipe = usb_rcvintpipe ( pusbd , pdvobj - > RtInPipe [ 1 ] ) ;
} else if ( addr < HW_QUEUE_ENTRY ) {
ep_num = pdvobj - > Queue2Pipe [ addr ] ;
pipe = usb_sndbulkpipe ( pusbd , ep_num ) ;
}
return pipe ;
}
struct zero_bulkout_context {
void * pbuf ;
void * purb ;
void * pirp ;
void * padapter ;
} ;
static void usb_bulkout_zero_complete ( struct urb * purb , struct pt_regs * regs )
{
struct zero_bulkout_context * pcontext = ( struct zero_bulkout_context * ) purb - > context ;
//DBG_8192C("+usb_bulkout_zero_complete\n");
if ( pcontext )
{
if ( pcontext - > pbuf )
{
rtw_mfree ( pcontext - > pbuf , sizeof ( int ) ) ;
}
if ( pcontext - > purb & & ( pcontext - > purb = = purb ) )
{
usb_free_urb ( pcontext - > purb ) ;
}
rtw_mfree ( ( u8 * ) pcontext , sizeof ( struct zero_bulkout_context ) ) ;
}
}
static u32 usb_bulkout_zero ( struct intf_hdl * pintfhdl , u32 addr )
{
int pipe , status , len ;
u32 ret ;
unsigned char * pbuf ;
struct zero_bulkout_context * pcontext ;
PURB purb = NULL ;
_adapter * padapter = ( _adapter * ) pintfhdl - > padapter ;
struct dvobj_priv * pdvobj = adapter_to_dvobj ( padapter ) ;
struct pwrctrl_priv * pwrctl = dvobj_to_pwrctl ( pdvobj ) ;
struct usb_device * pusbd = pdvobj - > pusbdev ;
//DBG_871X("%s\n", __func__);
if ( RTW_CANNOT_TX ( padapter ) )
{
return _FAIL ;
}
pcontext = ( struct zero_bulkout_context * ) rtw_zmalloc ( sizeof ( struct zero_bulkout_context ) ) ;
if ( pcontext = = NULL ) {
return _FAIL ;
}
pbuf = ( unsigned char * ) rtw_zmalloc ( sizeof ( int ) ) ;
purb = usb_alloc_urb ( 0 , GFP_ATOMIC ) ;
//translate DMA FIFO addr to pipehandle
pipe = ffaddr2pipehdl ( pdvobj , addr ) ;
len = 0 ;
pcontext - > pbuf = pbuf ;
pcontext - > purb = purb ;
pcontext - > pirp = NULL ;
pcontext - > padapter = padapter ;
//translate DMA FIFO addr to pipehandle
//pipe = ffaddr2pipehdl(pdvobj, addr);
usb_fill_bulk_urb ( purb , pusbd , pipe ,
pbuf ,
len ,
usb_bulkout_zero_complete ,
pcontext ) ; //context is pcontext
status = usb_submit_urb ( purb , GFP_ATOMIC ) ;
if ( ! status )
{
ret = _SUCCESS ;
}
else
{
ret = _FAIL ;
}
return _SUCCESS ;
}
void usb_read_mem ( struct intf_hdl * pintfhdl , u32 addr , u32 cnt , u8 * rmem )
{
}
void usb_write_mem ( struct intf_hdl * pintfhdl , u32 addr , u32 cnt , u8 * wmem )
{
}
void usb_read_port_cancel ( struct intf_hdl * pintfhdl )
{
int i ;
struct recv_buf * precvbuf ;
_adapter * padapter = pintfhdl - > padapter ;
precvbuf = ( struct recv_buf * ) padapter - > recvpriv . precv_buf ;
DBG_871X ( " %s \n " , __func__ ) ;
for ( i = 0 ; i < NR_RECVBUFF ; i + + ) {
precvbuf - > reuse = _TRUE ;
if ( precvbuf - > purb ) {
//DBG_8192C("usb_read_port_cancel : usb_kill_urb \n");
usb_kill_urb ( precvbuf - > purb ) ;
}
precvbuf + + ;
}
# ifdef CONFIG_USB_INTERRUPT_IN_PIPE
usb_kill_urb ( padapter - > recvpriv . int_in_urb ) ;
# endif
}
static void usb_write_port_complete ( struct urb * purb , struct pt_regs * regs )
{
_irqL irqL ;
int i ;
struct xmit_buf * pxmitbuf = ( struct xmit_buf * ) purb - > context ;
//struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
//_adapter *padapter = pxmitframe->padapter;
_adapter * padapter = pxmitbuf - > padapter ;
struct xmit_priv * pxmitpriv = & padapter - > xmitpriv ;
//struct pkt_attrib *pattrib = &pxmitframe->attrib;
_func_enter_ ;
switch ( pxmitbuf - > flags )
{
case VO_QUEUE_INX :
pxmitpriv - > voq_cnt - - ;
break ;
case VI_QUEUE_INX :
pxmitpriv - > viq_cnt - - ;
break ;
case BE_QUEUE_INX :
pxmitpriv - > beq_cnt - - ;
break ;
case BK_QUEUE_INX :
pxmitpriv - > bkq_cnt - - ;
break ;
default :
break ;
}
/*
_enter_critical ( & pxmitpriv - > lock , & irqL ) ;
pxmitpriv - > txirp_cnt - - ;
switch ( pattrib - > priority )
{
case 1 :
case 2 :
pxmitpriv - > bkq_cnt - - ;
//DBG_8192C("pxmitpriv->bkq_cnt=%d\n", pxmitpriv->bkq_cnt);
break ;
case 4 :
case 5 :
pxmitpriv - > viq_cnt - - ;
//DBG_8192C("pxmitpriv->viq_cnt=%d\n", pxmitpriv->viq_cnt);
break ;
case 6 :
case 7 :
pxmitpriv - > voq_cnt - - ;
//DBG_8192C("pxmitpriv->voq_cnt=%d\n", pxmitpriv->voq_cnt);
break ;
case 0 :
case 3 :
default :
pxmitpriv - > beq_cnt - - ;
//DBG_8192C("pxmitpriv->beq_cnt=%d\n", pxmitpriv->beq_cnt);
break ;
}
_exit_critical ( & pxmitpriv - > lock , & irqL ) ;
if ( pxmitpriv - > txirp_cnt = = 0 )
{
RT_TRACE ( _module_hci_ops_os_c_ , _drv_err_ , ( " usb_write_port_complete: txirp_cnt== 0, set allrxreturnevt! \n " ) ) ;
_rtw_up_sema ( & ( pxmitpriv - > tx_retevt ) ) ;
}
*/
//rtw_free_xmitframe(pxmitpriv, pxmitframe);
if ( RTW_CANNOT_TX ( padapter ) )
{
RT_TRACE ( _module_hci_ops_os_c_ , _drv_err_ , ( " usb_write_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d) " , padapter - > bDriverStopped , padapter - > bSurpriseRemoved ) ) ;
DBG_8192C ( " %s(): TX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) pxmitbuf->buf_tag(%x) \n " ,
__FUNCTION__ , padapter - > bDriverStopped , padapter - > bSurpriseRemoved , pxmitbuf - > buf_tag ) ;
goto check_completion ;
}
if ( purb - > status = = 0 ) {
} else {
RT_TRACE ( _module_hci_ops_os_c_ , _drv_err_ , ( " usb_write_port_complete : purb->status(%d) != 0 \n " , purb - > status ) ) ;
DBG_871X ( " ###=> urb_write_port_complete status(%d) \n " , purb - > status ) ;
if ( ( purb - > status = = - EPIPE ) | | ( purb - > status = = - EPROTO ) )
{
//usb_clear_halt(pusbdev, purb->pipe);
//msleep(10);
sreset_set_wifi_error_status ( padapter , USB_WRITE_PORT_FAIL ) ;
} else if ( purb - > status = = - EINPROGRESS ) {
RT_TRACE ( _module_hci_ops_os_c_ , _drv_err_ , ( " usb_write_port_complete: EINPROGESS \n " ) ) ;
goto check_completion ;
} else if ( purb - > status = = - ENOENT ) {
DBG_871X ( " %s: -ENOENT \n " , __func__ ) ;
goto check_completion ;
} else if ( purb - > status = = - ECONNRESET ) {
DBG_871X ( " %s: -ECONNRESET \n " , __func__ ) ;
goto check_completion ;
} else if ( purb - > status = = - ESHUTDOWN ) {
RT_TRACE ( _module_hci_ops_os_c_ , _drv_err_ , ( " usb_write_port_complete: ESHUTDOWN \n " ) ) ;
padapter - > bDriverStopped = _TRUE ;
RT_TRACE ( _module_hci_ops_os_c_ , _drv_err_ , ( " usb_write_port_complete:bDriverStopped=TRUE \n " ) ) ;
goto check_completion ;
}
else
{
padapter - > bSurpriseRemoved = _TRUE ;
DBG_8192C ( " bSurpriseRemoved=TRUE \n " ) ;
//rtl8192cu_trigger_gpio_0(padapter);
RT_TRACE ( _module_hci_ops_os_c_ , _drv_err_ , ( " usb_write_port_complete:bSurpriseRemoved=TRUE \n " ) ) ;
goto check_completion ;
}
}
# ifdef DBG_CONFIG_ERROR_DETECT
{
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
pHalData - > srestpriv . last_tx_complete_time = rtw_get_current_time ( ) ;
}
# endif
check_completion :
_enter_critical ( & pxmitpriv - > lock_sctx , & irqL ) ;
rtw_sctx_done_err ( & pxmitbuf - > sctx ,
2017-05-11 18:35:20 +00:00
purb - > status ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS ) ;
2015-08-18 19:03:09 +00:00
_exit_critical ( & pxmitpriv - > lock_sctx , & irqL ) ;
rtw_free_xmitbuf ( pxmitpriv , pxmitbuf ) ;
//if(rtw_txframes_pending(padapter))
{
tasklet_hi_schedule ( & pxmitpriv - > xmit_tasklet ) ;
}
_func_exit_ ;
}
u32 usb_write_port ( struct intf_hdl * pintfhdl , u32 addr , u32 cnt , u8 * wmem )
{
_irqL irqL ;
unsigned int pipe ;
int status ;
u32 ret = _FAIL , bwritezero = _FALSE ;
PURB purb = NULL ;
_adapter * padapter = ( _adapter * ) pintfhdl - > padapter ;
struct dvobj_priv * pdvobj = adapter_to_dvobj ( padapter ) ;
struct pwrctrl_priv * pwrctl = dvobj_to_pwrctl ( pdvobj ) ;
struct xmit_priv * pxmitpriv = & padapter - > xmitpriv ;
struct xmit_buf * pxmitbuf = ( struct xmit_buf * ) wmem ;
struct xmit_frame * pxmitframe = ( struct xmit_frame * ) pxmitbuf - > priv_data ;
struct usb_device * pusbd = pdvobj - > pusbdev ;
struct pkt_attrib * pattrib = & pxmitframe - > attrib ;
_func_enter_ ;
RT_TRACE ( _module_hci_ops_os_c_ , _drv_err_ , ( " +usb_write_port \n " ) ) ;
if ( RTW_CANNOT_TX ( padapter ) ) {
# ifdef DBG_TX
DBG_871X ( " DBG_TX %s:%d bDriverStopped%d, bSurpriseRemoved:%d \n " , __FUNCTION__ , __LINE__
, padapter - > bDriverStopped , padapter - > bSurpriseRemoved ) ;
# endif
RT_TRACE ( _module_hci_ops_os_c_ , _drv_err_ , ( " usb_write_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved )!!! \n " ) ) ;
rtw_sctx_done_err ( & pxmitbuf - > sctx , RTW_SCTX_DONE_TX_DENY ) ;
goto exit ;
}
_enter_critical ( & pxmitpriv - > lock , & irqL ) ;
switch ( addr )
{
case VO_QUEUE_INX :
pxmitpriv - > voq_cnt + + ;
pxmitbuf - > flags = VO_QUEUE_INX ;
break ;
case VI_QUEUE_INX :
pxmitpriv - > viq_cnt + + ;
pxmitbuf - > flags = VI_QUEUE_INX ;
break ;
case BE_QUEUE_INX :
pxmitpriv - > beq_cnt + + ;
pxmitbuf - > flags = BE_QUEUE_INX ;
break ;
case BK_QUEUE_INX :
pxmitpriv - > bkq_cnt + + ;
pxmitbuf - > flags = BK_QUEUE_INX ;
break ;
case HIGH_QUEUE_INX :
pxmitbuf - > flags = HIGH_QUEUE_INX ;
break ;
default :
pxmitbuf - > flags = MGT_QUEUE_INX ;
break ;
}
_exit_critical ( & pxmitpriv - > lock , & irqL ) ;
purb = pxmitbuf - > pxmit_urb [ 0 ] ;
//translate DMA FIFO addr to pipehandle
pipe = ffaddr2pipehdl ( pdvobj , addr ) ;
# ifdef CONFIG_REDUCE_USB_TX_INT
if ( ( pxmitpriv - > free_xmitbuf_cnt % NR_XMITBUFF = = 0 )
| | ( pxmitbuf - > buf_tag > XMITBUF_DATA ) )
{
purb - > transfer_flags & = ( ~ URB_NO_INTERRUPT ) ;
} else {
purb - > transfer_flags | = URB_NO_INTERRUPT ;
//DBG_8192C("URB_NO_INTERRUPT ");
}
# endif
usb_fill_bulk_urb ( purb , pusbd , pipe ,
pxmitframe - > buf_addr , //= pxmitbuf->pbuf
cnt ,
usb_write_port_complete ,
pxmitbuf ) ; //context is pxmitbuf
# ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX
purb - > transfer_dma = pxmitbuf - > dma_transfer_addr ;
purb - > transfer_flags | = URB_NO_TRANSFER_DMA_MAP ;
purb - > transfer_flags | = URB_ZERO_PACKET ;
# endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
# ifdef USB_PACKET_OFFSET_SZ
# if (USB_PACKET_OFFSET_SZ == 0)
purb - > transfer_flags | = URB_ZERO_PACKET ;
# endif
# endif
#if 0
if ( bwritezero )
{
purb - > transfer_flags | = URB_ZERO_PACKET ;
}
# endif
status = usb_submit_urb ( purb , GFP_ATOMIC ) ;
if ( ! status ) {
# ifdef DBG_CONFIG_ERROR_DETECT
{
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
pHalData - > srestpriv . last_tx_time = rtw_get_current_time ( ) ;
}
# endif
} else {
rtw_sctx_done_err ( & pxmitbuf - > sctx , RTW_SCTX_DONE_WRITE_PORT_ERR ) ;
DBG_871X ( " usb_write_port, status=%d \n " , status ) ;
RT_TRACE ( _module_hci_ops_os_c_ , _drv_err_ , ( " usb_write_port(): usb_submit_urb, status=%x \n " , status ) ) ;
switch ( status ) {
case - ENODEV :
padapter - > bDriverStopped = _TRUE ;
break ;
default :
break ;
}
goto exit ;
}
ret = _SUCCESS ;
// Commented by Albert 2009/10/13
// We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically.
/*
if ( bwritezero = = _TRUE )
{
usb_bulkout_zero ( pintfhdl , addr ) ;
}
*/
RT_TRACE ( _module_hci_ops_os_c_ , _drv_err_ , ( " -usb_write_port \n " ) ) ;
exit :
if ( ret ! = _SUCCESS )
rtw_free_xmitbuf ( pxmitpriv , pxmitbuf ) ;
_func_exit_ ;
return ret ;
}
void usb_write_port_cancel ( struct intf_hdl * pintfhdl )
{
int i , j ;
_adapter * padapter = pintfhdl - > padapter ;
struct xmit_buf * pxmitbuf = ( struct xmit_buf * ) padapter - > xmitpriv . pxmitbuf ;
DBG_871X ( " %s \n " , __func__ ) ;
for ( i = 0 ; i < NR_XMITBUFF ; i + + ) {
for ( j = 0 ; j < 8 ; j + + ) {
if ( pxmitbuf - > pxmit_urb [ j ] ) {
usb_kill_urb ( pxmitbuf - > pxmit_urb [ j ] ) ;
}
}
pxmitbuf + + ;
}
pxmitbuf = ( struct xmit_buf * ) padapter - > xmitpriv . pxmit_extbuf ;
2017-05-11 18:35:20 +00:00
for ( i = 0 ; i < NR_XMIT_EXTBUFF ; i + + ) {
2015-08-18 19:03:09 +00:00
for ( j = 0 ; j < 8 ; j + + ) {
if ( pxmitbuf - > pxmit_urb [ j ] ) {
usb_kill_urb ( pxmitbuf - > pxmit_urb [ j ] ) ;
}
}
pxmitbuf + + ;
}
}