diff options
Diffstat (limited to 'drivers/staging/vt6656/usbpipe.c')
-rw-r--r-- | drivers/staging/vt6656/usbpipe.c | 321 |
1 files changed, 95 insertions, 226 deletions
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index e4751b71e4d3..cba653292996 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -30,7 +30,6 @@ * vnt_control_in - Read variable length bytes from MEM/BB/MAC/EEPROM * vnt_control_out_u8 - Write one byte to MEM/BB/MAC/EEPROM * vnt_control_in_u8 - Read one byte from MEM/BB/MAC/EEPROM - * ControlvMaskByte - Read one byte from MEM/BB/MAC/EEPROM and clear/set some bits in the same address * * Revision History: * 04-05-2004 Jerry Chen: Initial release @@ -45,28 +44,14 @@ #include "device.h" #include "usbpipe.h" -//endpoint def -//endpoint 0: control -//endpoint 1: interrupt -//endpoint 2: read bulk -//endpoint 3: write bulk - -#define USB_CTL_WAIT 500 //ms - -#ifndef URB_ASYNC_UNLINK -#define URB_ASYNC_UNLINK 0 -#endif - -static void s_nsInterruptUsbIoCompleteRead(struct urb *urb); -static void s_nsBulkInUsbIoCompleteRead(struct urb *urb); -static void s_nsBulkOutIoCompleteWrite(struct urb *urb); +#define USB_CTL_WAIT 500 /* ms */ int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, u16 index, u16 length, u8 *buffer) { int status = 0; - if (priv->Flags & fMP_DISCONNECTED) + if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) return STATUS_FAILURE; mutex_lock(&priv->usb_lock); @@ -94,7 +79,7 @@ int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, { int status; - if (priv->Flags & fMP_DISCONNECTED) + if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) return STATUS_FAILURE; mutex_lock(&priv->usb_lock); @@ -117,63 +102,7 @@ void vnt_control_in_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 *data) reg_off, reg, sizeof(u8), data); } -/* - * Description: - * Allocates an usb interrupt in irp and calls USBD. - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * Out: - * none - * - * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver - * - */ - -int PIPEnsInterruptRead(struct vnt_private *priv) -{ - int status = STATUS_FAILURE; - - if (priv->int_buf.in_use == true) - return STATUS_FAILURE; - - priv->int_buf.in_use = true; - - usb_fill_int_urb(priv->pInterruptURB, - priv->usb, - usb_rcvintpipe(priv->usb, 1), - priv->int_buf.data_buf, - MAX_INTERRUPT_SIZE, - s_nsInterruptUsbIoCompleteRead, - priv, - priv->int_interval); - - status = usb_submit_urb(priv->pInterruptURB, GFP_ATOMIC); - if (status) { - dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", status); - priv->int_buf.in_use = false; - } - - return status; -} - -/* - * Description: - * Complete function of usb interrupt in irp. - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * - * Out: - * none - * - * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver - * - */ - -static void s_nsInterruptUsbIoCompleteRead(struct urb *urb) +static void vnt_start_interrupt_urb_complete(struct urb *urb) { struct vnt_private *priv = urb->context; int status; @@ -198,88 +127,49 @@ static void s_nsInterruptUsbIoCompleteRead(struct urb *urb) dev_dbg(&priv->usb->dev, "%s status = %d\n", __func__, status); } else { - INTnsProcessData(priv); + vnt_int_process_data(priv); } - status = usb_submit_urb(priv->pInterruptURB, GFP_ATOMIC); + status = usb_submit_urb(priv->interrupt_urb, GFP_ATOMIC); if (status) { dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", status); } else { priv->int_buf.in_use = true; } - - return; } -/* - * Description: - * Allocates an usb BulkIn irp and calls USBD. - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * Out: - * none - * - * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver - * - */ - -int PIPEnsBulkInUsbRead(struct vnt_private *priv, struct vnt_rcb *rcb) +int vnt_start_interrupt_urb(struct vnt_private *priv) { - int status = 0; - struct urb *urb; + int status = STATUS_FAILURE; - if (priv->Flags & fMP_DISCONNECTED) + if (priv->int_buf.in_use == true) return STATUS_FAILURE; - urb = rcb->pUrb; - if (rcb->skb == NULL) { - dev_dbg(&priv->usb->dev, "rcb->skb is null\n"); - return status; - } + priv->int_buf.in_use = true; - usb_fill_bulk_urb(urb, - priv->usb, - usb_rcvbulkpipe(priv->usb, 2), - (void *) (rcb->skb->data), - MAX_TOTAL_SIZE_WITH_ALL_HEADERS, - s_nsBulkInUsbIoCompleteRead, - rcb); + usb_fill_int_urb(priv->interrupt_urb, + priv->usb, + usb_rcvintpipe(priv->usb, 1), + priv->int_buf.data_buf, + MAX_INTERRUPT_SIZE, + vnt_start_interrupt_urb_complete, + priv, + priv->int_interval); - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status != 0) { - dev_dbg(&priv->usb->dev, "Submit Rx URB failed %d\n", status); - return STATUS_FAILURE ; + status = usb_submit_urb(priv->interrupt_urb, GFP_ATOMIC); + if (status) { + dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", status); + priv->int_buf.in_use = false; } - rcb->Ref = 1; - rcb->bBoolInUse = true; - return status; } -/* - * Description: - * Complete function of usb BulkIn irp. - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * - * Out: - * none - * - * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver - * - */ - -static void s_nsBulkInUsbIoCompleteRead(struct urb *urb) +static void vnt_submit_rx_urb_complete(struct urb *urb) { struct vnt_rcb *rcb = urb->context; - struct vnt_private *priv = rcb->pDevice; + struct vnt_private *priv = rcb->priv; unsigned long flags; - int re_alloc_skb = false; switch (urb->status) { case 0: @@ -297,108 +187,68 @@ static void s_nsBulkInUsbIoCompleteRead(struct urb *urb) if (urb->actual_length) { spin_lock_irqsave(&priv->lock, flags); - if (RXbBulkInProcessData(priv, rcb, urb->actual_length) == true) - re_alloc_skb = true; + if (vnt_rx_data(priv, rcb, urb->actual_length)) { + rcb->skb = dev_alloc_skb(priv->rx_buf_sz); + if (!rcb->skb) { + dev_dbg(&priv->usb->dev, + "Failed to re-alloc rx skb\n"); + + rcb->in_use = false; + spin_unlock_irqrestore(&priv->lock, flags); + return; + } + } else { + skb_push(rcb->skb, skb_headroom(rcb->skb)); + skb_trim(rcb->skb, 0); + } + + urb->transfer_buffer = skb_put(rcb->skb, + skb_tailroom(rcb->skb)); spin_unlock_irqrestore(&priv->lock, flags); } - rcb->Ref--; - if (rcb->Ref == 0) { - dev_dbg(&priv->usb->dev, - "RxvFreeNormal %d\n", priv->NumRecvFreeList); + if (usb_submit_urb(urb, GFP_ATOMIC)) { + dev_dbg(&priv->usb->dev, "Failed to re submit rx skb\n"); - spin_lock_irqsave(&priv->lock, flags); - - RXvFreeRCB(rcb, re_alloc_skb); - - spin_unlock_irqrestore(&priv->lock, flags); + rcb->in_use = false; } - - return; } -/* - * Description: - * Allocates an usb BulkOut irp and calls USBD. - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * Out: - * none - * - * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver - * - */ - -int PIPEnsSendBulkOut(struct vnt_private *priv, - struct vnt_usb_send_context *context) +int vnt_submit_rx_urb(struct vnt_private *priv, struct vnt_rcb *rcb) { - int status; + int status = 0; struct urb *urb; - priv->bPWBitOn = false; - - if (!(MP_IS_READY(priv) && priv->Flags & fMP_POST_WRITES)) { - context->in_use = false; - return STATUS_RESOURCES; + urb = rcb->urb; + if (rcb->skb == NULL) { + dev_dbg(&priv->usb->dev, "rcb->skb is null\n"); + return status; } - urb = context->urb; - usb_fill_bulk_urb(urb, - priv->usb, - usb_sndbulkpipe(priv->usb, 3), - context->data, - context->buf_len, - s_nsBulkOutIoCompleteWrite, - context); + priv->usb, + usb_rcvbulkpipe(priv->usb, 2), + skb_put(rcb->skb, skb_tailroom(rcb->skb)), + MAX_TOTAL_SIZE_WITH_ALL_HEADERS, + vnt_submit_rx_urb_complete, + rcb); status = usb_submit_urb(urb, GFP_ATOMIC); if (status != 0) { - dev_dbg(&priv->usb->dev, "Submit Tx URB failed %d\n", status); - - context->in_use = false; + dev_dbg(&priv->usb->dev, "Submit Rx URB failed %d\n", status); return STATUS_FAILURE; } - return STATUS_PENDING; -} + rcb->in_use = true; -/* - * Description: s_nsBulkOutIoCompleteWrite - * 1a) Indicate to the protocol the status of the write. - * 1b) Return ownership of the packet to the protocol. - * - * 2) If any more packets are queue for sending, send another packet - * to USBD. - * If the attempt to send the packet to the driver fails, - * return ownership of the packet to the protocol and - * try another packet (until one succeeds). - * - * Parameters: - * In: - * pdoUsbDevObj - pointer to the USB device object which - * completed the irp - * pIrp - the irp which was completed by the - * device object - * pContext - the context given to IoSetCompletionRoutine - * before calling IoCallDriver on the irp - * The pContext is a pointer to the USB device object. - * Out: - * none - * - * Return Value: STATUS_MORE_PROCESSING_REQUIRED - allows the completion routine - * (IofCompleteRequest) to stop working on the irp. - * - */ + return status; +} -static void s_nsBulkOutIoCompleteWrite(struct urb *urb) +static void vnt_tx_context_complete(struct urb *urb) { struct vnt_usb_send_context *context = urb->context; struct vnt_private *priv = context->priv; - u8 context_type = context->type; switch (urb->status) { case 0: @@ -415,26 +265,45 @@ static void s_nsBulkOutIoCompleteWrite(struct urb *urb) break; } - if (!netif_device_present(priv->dev)) - return; + if (context->type == CONTEXT_DATA_PACKET) + ieee80211_wake_queues(priv->hw); - if (CONTEXT_DATA_PACKET == context_type) { - if (context->skb != NULL) { - dev_kfree_skb_irq(context->skb); - context->skb = NULL; - dev_dbg(&priv->usb->dev, - "tx %d bytes\n", context->buf_len); - } + if (urb->status || context->type == CONTEXT_BEACON_PACKET) { + if (context->skb) + ieee80211_free_txskb(priv->hw, context->skb); - priv->dev->trans_start = jiffies; + context->in_use = false; } +} + +int vnt_tx_context(struct vnt_private *priv, + struct vnt_usb_send_context *context) +{ + int status; + struct urb *urb; - if (priv->bLinkPass == true) { - if (netif_queue_stopped(priv->dev)) - netif_wake_queue(priv->dev); + if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) { + context->in_use = false; + return STATUS_RESOURCES; } - context->in_use = false; + urb = context->urb; + + usb_fill_bulk_urb(urb, + priv->usb, + usb_sndbulkpipe(priv->usb, 3), + context->data, + context->buf_len, + vnt_tx_context_complete, + context); - return; + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status != 0) { + dev_dbg(&priv->usb->dev, "Submit Tx URB failed %d\n", status); + + context->in_use = false; + return STATUS_FAILURE; + } + + return STATUS_PENDING; } |