diff options
Diffstat (limited to 'drivers/staging/rtl8712/usb_ops_linux.c')
-rw-r--r-- | drivers/staging/rtl8712/usb_ops_linux.c | 92 |
1 files changed, 40 insertions, 52 deletions
diff --git a/drivers/staging/rtl8712/usb_ops_linux.c b/drivers/staging/rtl8712/usb_ops_linux.c index 6f12345709c2..fc6bb0be2a28 100644 --- a/drivers/staging/rtl8712/usb_ops_linux.c +++ b/drivers/staging/rtl8712/usb_ops_linux.c @@ -50,7 +50,7 @@ uint r8712_usb_init_intf_priv(struct intf_priv *pintfpriv) pintfpriv->piorw_urb = usb_alloc_urb(0, GFP_ATOMIC); if (!pintfpriv->piorw_urb) return _FAIL; - sema_init(&(pintfpriv->io_retevt), 0); + init_completion(&pintfpriv->io_retevt_comp); return _SUCCESS; } @@ -163,7 +163,7 @@ static void usb_write_mem_complete(struct urb *purb) else padapter->bSurpriseRemoved = true; } - up(&pintfpriv->io_retevt); + complete(&pintfpriv->io_retevt_comp); } void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) @@ -187,7 +187,7 @@ void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) wmem, cnt, usb_write_mem_complete, pio_queue); usb_submit_urb(piorw_urb, GFP_ATOMIC); - _down_sema(&pintfpriv->io_retevt); + wait_for_completion_interruptible(&pintfpriv->io_retevt_comp); } static void r8712_usb_read_port_complete(struct urb *purb) @@ -202,26 +202,23 @@ static void r8712_usb_read_port_complete(struct urb *purb) if (purb->status == 0) { /* SUCCESS */ if ((purb->actual_length > (MAX_RECVBUF_SZ)) || (purb->actual_length < RXDESC_SIZE)) { - precvbuf->reuse = true; r8712_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); } else { + _pkt *pskb = precvbuf->pskb; + precvbuf->transfer_len = purb->actual_length; pbuf = (uint *)precvbuf->pbuf; isevt = le32_to_cpu(*(pbuf + 1)) & 0x1ff; if ((isevt & 0x1ff) == 0x1ff) { r8712_rxcmd_event_hdl(padapter, pbuf); - precvbuf->reuse = true; + skb_queue_tail(&precvpriv->rx_skb_queue, pskb); r8712_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); } else { - _pkt *pskb = precvbuf->pskb; - skb_put(pskb, purb->actual_length); skb_queue_tail(&precvpriv->rx_skb_queue, pskb); tasklet_hi_schedule(&precvpriv->recv_tasklet); - precvbuf->pskb = NULL; - precvbuf->reuse = false; r8712_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); } @@ -241,7 +238,6 @@ static void r8712_usb_read_port_complete(struct urb *purb) } /* Fall through. */ case -EPROTO: - precvbuf->reuse = true; r8712_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); break; @@ -270,51 +266,43 @@ u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) struct usb_device *pusbd = pdvobj->pusbdev; if (adapter->bDriverStopped || adapter->bSurpriseRemoved || - adapter->pwrctrlpriv.pnp_bstop_trx) + adapter->pwrctrlpriv.pnp_bstop_trx || !precvbuf) return _FAIL; - if (precvbuf->reuse || !precvbuf->pskb) { - precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue); - if (precvbuf->pskb != NULL) - precvbuf->reuse = true; + r8712_init_recvbuf(adapter, precvbuf); + /* Try to use skb from the free queue */ + precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue); + + if (!precvbuf->pskb) { + precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, + MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); + if (!precvbuf->pskb) + return _FAIL; + tmpaddr = (addr_t)precvbuf->pskb->data; + alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); + skb_reserve(precvbuf->pskb, + (RECVBUFF_ALIGN_SZ - alignment)); + precvbuf->phead = precvbuf->pskb->head; + precvbuf->pdata = precvbuf->pskb->data; + precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); + precvbuf->pend = skb_end_pointer(precvbuf->pskb); + precvbuf->pbuf = precvbuf->pskb->data; + } else { /* skb is reused */ + precvbuf->phead = precvbuf->pskb->head; + precvbuf->pdata = precvbuf->pskb->data; + precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); + precvbuf->pend = skb_end_pointer(precvbuf->pskb); + precvbuf->pbuf = precvbuf->pskb->data; } - if (precvbuf != NULL) { - r8712_init_recvbuf(adapter, precvbuf); - /* re-assign for linux based on skb */ - if (!precvbuf->reuse || !precvbuf->pskb) { - precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, - MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); - if (!precvbuf->pskb) - return _FAIL; - tmpaddr = (addr_t)precvbuf->pskb->data; - alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); - skb_reserve(precvbuf->pskb, - (RECVBUFF_ALIGN_SZ - alignment)); - precvbuf->phead = precvbuf->pskb->head; - precvbuf->pdata = precvbuf->pskb->data; - precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); - precvbuf->pend = skb_end_pointer(precvbuf->pskb); - precvbuf->pbuf = precvbuf->pskb->data; - } else { /* reuse skb */ - precvbuf->phead = precvbuf->pskb->head; - precvbuf->pdata = precvbuf->pskb->data; - precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); - precvbuf->pend = skb_end_pointer(precvbuf->pskb); - precvbuf->pbuf = precvbuf->pskb->data; - precvbuf->reuse = false; - } - purb = precvbuf->purb; - /* translate DMA FIFO addr to pipehandle */ - pipe = ffaddr2pipehdl(pdvobj, addr); - usb_fill_bulk_urb(purb, pusbd, pipe, - precvbuf->pbuf, MAX_RECVBUF_SZ, - r8712_usb_read_port_complete, - precvbuf); - err = usb_submit_urb(purb, GFP_ATOMIC); - if ((err) && (err != (-EPERM))) - ret = _FAIL; - } else { + purb = precvbuf->purb; + /* translate DMA FIFO addr to pipehandle */ + pipe = ffaddr2pipehdl(pdvobj, addr); + usb_fill_bulk_urb(purb, pusbd, pipe, + precvbuf->pbuf, MAX_RECVBUF_SZ, + r8712_usb_read_port_complete, + precvbuf); + err = usb_submit_urb(purb, GFP_ATOMIC); + if ((err) && (err != (-EPERM))) ret = _FAIL; - } return ret; } |