diff options
Diffstat (limited to 'drivers/staging/vt6656/usbpipe.c')
| -rw-r--r-- | drivers/staging/vt6656/usbpipe.c | 702 |
1 files changed, 223 insertions, 479 deletions
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index 3a03f1d5b68..e4751b71e4d 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -26,10 +26,10 @@ * Date: Mar. 29, 2005 * * Functions: - * CONTROLnsRequestOut - Write variable length bytes to MEM/BB/MAC/EEPROM - * CONTROLnsRequestIn - Read variable length bytes from MEM/BB/MAC/EEPROM - * ControlvWriteByte - Write one byte to MEM/BB/MAC/EEPROM - * ControlvReadByte - Read one byte from MEM/BB/MAC/EEPROM + * vnt_control_out - Write variable length bytes to MEM/BB/MAC/EEPROM + * 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: @@ -41,9 +41,9 @@ #include "int.h" #include "rxtx.h" #include "dpc.h" -#include "control.h" #include "desc.h" #include "device.h" +#include "usbpipe.h" //endpoint def //endpoint 0: control @@ -51,9 +51,6 @@ //endpoint 2: read bulk //endpoint 3: write bulk -//static int msglevel =MSG_LEVEL_DEBUG; -static int msglevel =MSG_LEVEL_INFO; - #define USB_CTL_WAIT 500 //ms #ifndef URB_ASYNC_UNLINK @@ -63,191 +60,70 @@ static int msglevel =MSG_LEVEL_INFO; static void s_nsInterruptUsbIoCompleteRead(struct urb *urb); static void s_nsBulkInUsbIoCompleteRead(struct urb *urb); static void s_nsBulkOutIoCompleteWrite(struct urb *urb); -static void s_nsControlInUsbIoCompleteRead(struct urb *urb); -static void s_nsControlInUsbIoCompleteWrite(struct urb *urb); -int PIPEnsControlOutAsyn(struct vnt_private *pDevice, u8 byRequest, - u16 wValue, u16 wIndex, u16 wLength, u8 *pbyBuffer) +int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, + u16 index, u16 length, u8 *buffer) { - int ntStatus; - - if (pDevice->Flags & fMP_DISCONNECTED) - return STATUS_FAILURE; - - if (pDevice->Flags & fMP_CONTROL_WRITES) - return STATUS_FAILURE; - - if (in_interrupt()) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"in_interrupt return ..byRequest %x\n", byRequest); - return STATUS_FAILURE; - } - - ntStatus = usb_control_msg( - pDevice->usb, - usb_sndctrlpipe(pDevice->usb , 0), - byRequest, - 0x40, // RequestType - wValue, - wIndex, - (void *) pbyBuffer, - wLength, - HZ - ); - if (ntStatus >= 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"usb_sndctrlpipe ntStatus= %d\n", ntStatus); - ntStatus = 0; - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"usb_sndctrlpipe fail, ntStatus= %d\n", ntStatus); - } - - return ntStatus; -} + int status = 0; -int PIPEnsControlOut(struct vnt_private *pDevice, u8 byRequest, u16 wValue, - u16 wIndex, u16 wLength, u8 *pbyBuffer) -{ - int ntStatus = 0; - int ii; + if (priv->Flags & fMP_DISCONNECTED) + return STATUS_FAILURE; - if (pDevice->Flags & fMP_DISCONNECTED) - return STATUS_FAILURE; + mutex_lock(&priv->usb_lock); - if (pDevice->Flags & fMP_CONTROL_WRITES) - return STATUS_FAILURE; + status = usb_control_msg(priv->usb, + usb_sndctrlpipe(priv->usb, 0), request, 0x40, value, + index, buffer, length, USB_CTL_WAIT); - if (pDevice->Flags & fMP_CONTROL_READS) - return STATUS_FAILURE; + mutex_unlock(&priv->usb_lock); - MP_SET_FLAG(pDevice, fMP_CONTROL_WRITES); - - pDevice->sUsbCtlRequest.bRequestType = 0x40; - pDevice->sUsbCtlRequest.bRequest = byRequest; - pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue); - pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex); - pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength); - pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK; - pDevice->pControlURB->actual_length = 0; - // Notice, pbyBuffer limited point to variable buffer, can't be constant. - usb_fill_control_urb(pDevice->pControlURB, pDevice->usb, - usb_sndctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest, - pbyBuffer, wLength, s_nsControlInUsbIoCompleteWrite, pDevice); - - ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC); - if (ntStatus != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO - "control send request submission failed: %d\n", - ntStatus); - MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES); + if (status < (int)length) return STATUS_FAILURE; - } - - spin_unlock_irq(&pDevice->lock); - for (ii = 0; ii <= USB_CTL_WAIT; ii ++) { - - if (pDevice->Flags & fMP_CONTROL_WRITES) - mdelay(1); - else - break; - if (ii >= USB_CTL_WAIT) { - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "control send request submission timeout\n"); - spin_lock_irq(&pDevice->lock); - MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES); - return STATUS_FAILURE; - } - } - spin_lock_irq(&pDevice->lock); - - return STATUS_SUCCESS; + return STATUS_SUCCESS; } -int PIPEnsControlIn(struct vnt_private *pDevice, u8 byRequest, u16 wValue, - u16 wIndex, u16 wLength, u8 *pbyBuffer) +void vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 data) { - int ntStatus = 0; - int ii; - - if (pDevice->Flags & fMP_DISCONNECTED) - return STATUS_FAILURE; + vnt_control_out(priv, MESSAGE_TYPE_WRITE, + reg_off, reg, sizeof(u8), &data); +} - if (pDevice->Flags & fMP_CONTROL_READS) - return STATUS_FAILURE; +int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, + u16 index, u16 length, u8 *buffer) +{ + int status; - if (pDevice->Flags & fMP_CONTROL_WRITES) + if (priv->Flags & fMP_DISCONNECTED) return STATUS_FAILURE; - MP_SET_FLAG(pDevice, fMP_CONTROL_READS); - - pDevice->sUsbCtlRequest.bRequestType = 0xC0; - pDevice->sUsbCtlRequest.bRequest = byRequest; - pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue); - pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex); - pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength); - pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK; - pDevice->pControlURB->actual_length = 0; - usb_fill_control_urb(pDevice->pControlURB, pDevice->usb, - usb_rcvctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest, - pbyBuffer, wLength, s_nsControlInUsbIoCompleteRead, pDevice); - - ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC); - if (ntStatus != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO - "control request submission failed: %d\n", ntStatus); - MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS); - return STATUS_FAILURE; - } + mutex_lock(&priv->usb_lock); - spin_unlock_irq(&pDevice->lock); - for (ii = 0; ii <= USB_CTL_WAIT; ii ++) { + status = usb_control_msg(priv->usb, + usb_rcvctrlpipe(priv->usb, 0), request, 0xc0, value, + index, buffer, length, USB_CTL_WAIT); - if (pDevice->Flags & fMP_CONTROL_READS) - mdelay(1); - else - break; + mutex_unlock(&priv->usb_lock); - if (ii >= USB_CTL_WAIT) { - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "control rcv request submission timeout\n"); - spin_lock_irq(&pDevice->lock); - MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS); - return STATUS_FAILURE; - } - } - spin_lock_irq(&pDevice->lock); - - return ntStatus; + if (status < (int)length) + return STATUS_FAILURE; + + return STATUS_SUCCESS; } -static void s_nsControlInUsbIoCompleteWrite(struct urb *urb) +void vnt_control_in_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 *data) { - struct vnt_private *pDevice = (struct vnt_private *)urb->context; - - pDevice = urb->context; - switch (urb->status) { - case 0: - break; - case -EINPROGRESS: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status EINPROGRESS%d\n", urb->status); - break; - case -ENOENT: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status ENOENT %d\n", urb->status); - break; - default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status %d\n", urb->status); - } - - MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES); + vnt_control_in(priv, MESSAGE_TYPE_READ, + reg_off, reg, sizeof(u8), data); } /* * Description: - * Complete function of usb Control callback + * Allocates an usb interrupt in irp and calls USBD. * * Parameters: * In: * pDevice - Pointer to the adapter - * * Out: * none * @@ -255,74 +131,31 @@ static void s_nsControlInUsbIoCompleteWrite(struct urb *urb) * */ -static void s_nsControlInUsbIoCompleteRead(struct urb *urb) +int PIPEnsInterruptRead(struct vnt_private *priv) { - struct vnt_private *pDevice = (struct vnt_private *)urb->context; + int status = STATUS_FAILURE; - switch (urb->status) { - case 0: - break; - case -EINPROGRESS: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status EINPROGRESS%d\n", urb->status); - break; - case -ENOENT: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status = ENOENT %d\n", urb->status); - break; - default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status %d\n", urb->status); - } - - MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS); -} + if (priv->int_buf.in_use == true) + return STATUS_FAILURE; -/* - * 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 - * - */ + priv->int_buf.in_use = true; -int PIPEnsInterruptRead(struct vnt_private *pDevice) -{ - int ntStatus = STATUS_FAILURE; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartInterruptUsbRead()\n"); - - if(pDevice->intBuf.bInUse == true){ - return (STATUS_FAILURE); - } - pDevice->intBuf.bInUse = true; -// pDevice->bEventAvailable = false; - pDevice->ulIntInPosted++; - - // - // Now that we have created the urb, we will send a - // request to the USB device object. - // - pDevice->pInterruptURB->interval = pDevice->int_interval; - -usb_fill_bulk_urb(pDevice->pInterruptURB, - pDevice->usb, - usb_rcvbulkpipe(pDevice->usb, 1), - (void *) pDevice->intBuf.pDataBuf, + usb_fill_int_urb(priv->pInterruptURB, + priv->usb, + usb_rcvintpipe(priv->usb, 1), + priv->int_buf.data_buf, MAX_INTERRUPT_SIZE, s_nsInterruptUsbIoCompleteRead, - pDevice); + priv, + priv->int_interval); - ntStatus = usb_submit_urb(pDevice->pInterruptURB, GFP_ATOMIC); - if (ntStatus != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus); - } + 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; + } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----s_nsStartInterruptUsbRead Return(%x)\n",ntStatus); - return ntStatus; + return status; } /* @@ -342,69 +175,40 @@ usb_fill_bulk_urb(pDevice->pInterruptURB, static void s_nsInterruptUsbIoCompleteRead(struct urb *urb) { - struct vnt_private *pDevice = (struct vnt_private *)urb->context; - int ntStatus; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptUsbIoCompleteRead\n"); - // - // The context given to IoSetCompletionRoutine is the receive buffer object - // - - // - // We have a number of cases: - // 1) The USB read timed out and we received no data. - // 2) The USB read timed out and we received some data. - // 3) The USB read was successful and fully filled our irp buffer. - // 4) The irp was cancelled. - // 5) Some other failure from the USB device object. - // - ntStatus = urb->status; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_nsInterruptUsbIoCompleteRead Status %d\n", ntStatus); - - // if we were not successful, we need to free the int buffer for future use right here - // otherwise interrupt data handler will free int buffer after it handle it. - if (( ntStatus != STATUS_SUCCESS )) { - pDevice->ulBulkInError++; - pDevice->intBuf.bInUse = false; - -// if (ntStatus == USBD_STATUS_CRC) { -// pDevice->ulIntInContCRCError++; -// } - -// if (ntStatus == STATUS_NOT_CONNECTED ) -// { - pDevice->fKillEventPollingThread = true; -// } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"IntUSBIoCompleteControl STATUS = %d\n", ntStatus ); - } else { - pDevice->ulIntInBytesRead += (unsigned long) urb->actual_length; - pDevice->ulIntInContCRCError = 0; - pDevice->bEventAvailable = true; - INTnsProcessData(pDevice); - } - - STAvUpdateUSBCounter(&pDevice->scStatistic.USB_InterruptStat, ntStatus); - - if (pDevice->fKillEventPollingThread != true) { - usb_fill_bulk_urb(pDevice->pInterruptURB, - pDevice->usb, - usb_rcvbulkpipe(pDevice->usb, 1), - (void *) pDevice->intBuf.pDataBuf, - MAX_INTERRUPT_SIZE, - s_nsInterruptUsbIoCompleteRead, - pDevice); - - ntStatus = usb_submit_urb(pDevice->pInterruptURB, GFP_ATOMIC); - if (ntStatus != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus); - } - } - // - // We return STATUS_MORE_PROCESSING_REQUIRED so that the completion - // routine (IofCompleteRequest) will stop working on the irp. - // - return ; + struct vnt_private *priv = urb->context; + int status; + + switch (urb->status) { + case 0: + case -ETIMEDOUT: + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + priv->int_buf.in_use = false; + return; + default: + break; + } + + status = urb->status; + + if (status != STATUS_SUCCESS) { + priv->int_buf.in_use = false; + + dev_dbg(&priv->usb->dev, "%s status = %d\n", __func__, status); + } else { + INTnsProcessData(priv); + } + + status = usb_submit_urb(priv->pInterruptURB, GFP_ATOMIC); + if (status) { + dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", status); + } else { + priv->int_buf.in_use = true; + } + + return; } /* @@ -421,45 +225,38 @@ static void s_nsInterruptUsbIoCompleteRead(struct urb *urb) * */ -int PIPEnsBulkInUsbRead(struct vnt_private *pDevice, struct vnt_rcb *pRCB) +int PIPEnsBulkInUsbRead(struct vnt_private *priv, struct vnt_rcb *rcb) { - int ntStatus = 0; - struct urb *pUrb; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartBulkInUsbRead\n"); - - if (pDevice->Flags & fMP_DISCONNECTED) - return STATUS_FAILURE; - - pDevice->ulBulkInPosted++; - - pUrb = pRCB->pUrb; - // - // Now that we have created the urb, we will send a - // request to the USB device object. - // - if (pRCB->skb == NULL) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pRCB->skb is null \n"); - return ntStatus; - } - - usb_fill_bulk_urb(pUrb, - pDevice->usb, - usb_rcvbulkpipe(pDevice->usb, 2), - (void *) (pRCB->skb->data), + int status = 0; + struct urb *urb; + + if (priv->Flags & fMP_DISCONNECTED) + return STATUS_FAILURE; + + urb = rcb->pUrb; + if (rcb->skb == NULL) { + dev_dbg(&priv->usb->dev, "rcb->skb is null\n"); + return status; + } + + usb_fill_bulk_urb(urb, + priv->usb, + usb_rcvbulkpipe(priv->usb, 2), + (void *) (rcb->skb->data), MAX_TOTAL_SIZE_WITH_ALL_HEADERS, s_nsBulkInUsbIoCompleteRead, - pRCB); + rcb); - ntStatus = usb_submit_urb(pUrb, GFP_ATOMIC); - if (ntStatus != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Rx URB failed %d\n", ntStatus); + 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 ; } - pRCB->Ref = 1; - pRCB->bBoolInUse= true; - return ntStatus; + rcb->Ref = 1; + rcb->bBoolInUse = true; + + return status; } /* @@ -479,57 +276,46 @@ int PIPEnsBulkInUsbRead(struct vnt_private *pDevice, struct vnt_rcb *pRCB) static void s_nsBulkInUsbIoCompleteRead(struct urb *urb) { - struct vnt_rcb *pRCB = (struct vnt_rcb *)urb->context; - struct vnt_private *pDevice = pRCB->pDevice; - unsigned long bytesRead; - int bIndicateReceive = false; - int bReAllocSkb = false; - int status; + struct vnt_rcb *rcb = urb->context; + struct vnt_private *priv = rcb->pDevice; + unsigned long flags; + int re_alloc_skb = false; + + switch (urb->status) { + case 0: + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + return; + case -ETIMEDOUT: + default: + dev_dbg(&priv->usb->dev, "BULK In failed %d\n", urb->status); + break; + } + + if (urb->actual_length) { + spin_lock_irqsave(&priv->lock, flags); + + if (RXbBulkInProcessData(priv, rcb, urb->actual_length) == true) + re_alloc_skb = true; + + spin_unlock_irqrestore(&priv->lock, flags); + } + + rcb->Ref--; + if (rcb->Ref == 0) { + dev_dbg(&priv->usb->dev, + "RxvFreeNormal %d\n", priv->NumRecvFreeList); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkInUsbIoCompleteRead\n"); - status = urb->status; - bytesRead = urb->actual_length; - - if (status) { - pDevice->ulBulkInError++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK In failed %d\n", status); - - pDevice->scStatistic.RxFcsErrCnt ++; -//todo...xxxxxx -// if (status == USBD_STATUS_CRC) { -// pDevice->ulBulkInContCRCError++; -// } -// if (status == STATUS_DEVICE_NOT_CONNECTED ) -// { -// MP_SET_FLAG(pDevice, fMP_DISCONNECTED); -// } - } else { - if (bytesRead) - bIndicateReceive = true; - pDevice->ulBulkInContCRCError = 0; - pDevice->ulBulkInBytesRead += bytesRead; - - pDevice->scStatistic.RxOkCnt ++; - } - - STAvUpdateUSBCounter(&pDevice->scStatistic.USB_BulkInStat, status); - - if (bIndicateReceive) { - spin_lock(&pDevice->lock); - if (RXbBulkInProcessData(pDevice, pRCB, bytesRead) == true) - bReAllocSkb = true; - spin_unlock(&pDevice->lock); - } - pRCB->Ref--; - if (pRCB->Ref == 0) - { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeNormal %d \n",pDevice->NumRecvFreeList); - spin_lock(&pDevice->lock); - RXvFreeRCB(pRCB, bReAllocSkb); - spin_unlock(&pDevice->lock); - } - - return; + spin_lock_irqsave(&priv->lock, flags); + + RXvFreeRCB(rcb, re_alloc_skb); + + spin_unlock_irqrestore(&priv->lock, flags); + } + + return; } /* @@ -546,53 +332,38 @@ static void s_nsBulkInUsbIoCompleteRead(struct urb *urb) * */ -int PIPEnsSendBulkOut(struct vnt_private *pDevice, - struct vnt_usb_send_context *pContext) +int PIPEnsSendBulkOut(struct vnt_private *priv, + struct vnt_usb_send_context *context) { int status; - struct urb *pUrb; + struct urb *urb; - pDevice->bPWBitOn = false; + priv->bPWBitOn = false; -/* - if (pDevice->pPendingBulkOutContext != NULL) { - pDevice->NumContextsQueued++; - EnqueueContext(pDevice->FirstTxContextQueue, pDevice->LastTxContextQueue, pContext); - status = STATUS_PENDING; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send pending!\n"); - return status; - } -*/ - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_nsSendBulkOut\n"); - - if (MP_IS_READY(pDevice) && (pDevice->Flags & fMP_POST_WRITES)) { - - pUrb = pContext->pUrb; - pDevice->ulBulkOutPosted++; -// pDevice->pPendingBulkOutContext = pContext; - usb_fill_bulk_urb( - pUrb, - pDevice->usb, - usb_sndbulkpipe(pDevice->usb, 3), - (void *) &(pContext->Data[0]), - pContext->uBufLen, - s_nsBulkOutIoCompleteWrite, - pContext); - - status = usb_submit_urb(pUrb, GFP_ATOMIC); - if (status != 0) - { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Tx URB failed %d\n", status); - pContext->bBoolInUse = false; - return STATUS_FAILURE; - } - return STATUS_PENDING; - } - else { - pContext->bBoolInUse = false; - return STATUS_RESOURCES; - } + if (!(MP_IS_READY(priv) && priv->Flags & fMP_POST_WRITES)) { + context->in_use = false; + return STATUS_RESOURCES; + } + + urb = context->urb; + + usb_fill_bulk_urb(urb, + priv->usb, + usb_sndbulkpipe(priv->usb, 3), + context->data, + context->buf_len, + s_nsBulkOutIoCompleteWrite, + context); + + 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; } /* @@ -625,72 +396,45 @@ int PIPEnsSendBulkOut(struct vnt_private *pDevice, static void s_nsBulkOutIoCompleteWrite(struct urb *urb) { - struct vnt_private *pDevice; - int status; - CONTEXT_TYPE ContextType; - unsigned long ulBufLen; - struct vnt_usb_send_context *pContext; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkOutIoCompleteWrite\n"); - // - // The context given to IoSetCompletionRoutine is an USB_CONTEXT struct - // - pContext = (struct vnt_usb_send_context *)urb->context; - - pDevice = pContext->pDevice; - ContextType = pContext->Type; - ulBufLen = pContext->uBufLen; - - if (!netif_device_present(pDevice->dev)) - return; - - // - // Perform various IRP, URB, and buffer 'sanity checks' - // - - status = urb->status; - //we should have failed, succeeded, or cancelled, but NOT be pending - STAvUpdateUSBCounter(&pDevice->scStatistic.USB_BulkOutStat, status); - - if(status == STATUS_SUCCESS) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Write %d bytes\n",(int)ulBufLen); - pDevice->ulBulkOutBytesWrite += ulBufLen; - pDevice->ulBulkOutContCRCError = 0; - pDevice->nTxDataTimeCout = 0; - - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK Out failed %d\n", status); - pDevice->ulBulkOutError++; - } - -// pDevice->ulCheckForHangCount = 0; -// pDevice->pPendingBulkOutContext = NULL; - - if ( CONTEXT_DATA_PACKET == ContextType ) { - // Indicate to the protocol the status of the sent packet and return - // ownership of the packet. - if (pContext->pPacket != NULL) { - dev_kfree_skb_irq(pContext->pPacket); - pContext->pPacket = NULL; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"tx %d bytes\n",(int)ulBufLen); - } - - pDevice->dev->trans_start = jiffies; - - if (status == STATUS_SUCCESS) { - pDevice->packetsSent++; - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send USB error! [%08xh]\n", status); - pDevice->packetsSentDropped++; - } - - } - if (pDevice->bLinkPass == true) { - if (netif_queue_stopped(pDevice->dev)) - netif_wake_queue(pDevice->dev); - } - pContext->bBoolInUse = false; - - return; + struct vnt_usb_send_context *context = urb->context; + struct vnt_private *priv = context->priv; + u8 context_type = context->type; + + switch (urb->status) { + case 0: + dev_dbg(&priv->usb->dev, "Write %d bytes\n", context->buf_len); + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + context->in_use = false; + return; + case -ETIMEDOUT: + default: + dev_dbg(&priv->usb->dev, "BULK Out failed %d\n", urb->status); + break; + } + + if (!netif_device_present(priv->dev)) + return; + + 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); + } + + priv->dev->trans_start = jiffies; + } + + if (priv->bLinkPass == true) { + if (netif_queue_stopped(priv->dev)) + netif_wake_queue(priv->dev); + } + + context->in_use = false; + + return; } |
