aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/vt6656/usbpipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/vt6656/usbpipe.c')
-rw-r--r--drivers/staging/vt6656/usbpipe.c451
1 files changed, 197 insertions, 254 deletions
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
index 01cf09999b6d..c5838d99f89f 100644
--- a/drivers/staging/vt6656/usbpipe.c
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -105,6 +105,8 @@ int PIPEnsControlOutAsyn(struct vnt_private *pDevice, u8 byRequest,
int PIPEnsControlOut(struct vnt_private *pDevice, u8 byRequest, u16 wValue,
u16 wIndex, u16 wLength, u8 *pbyBuffer)
+ __releases(&pDevice->lock)
+ __acquires(&pDevice->lock)
{
int ntStatus = 0;
int ii;
@@ -167,6 +169,8 @@ int PIPEnsControlOut(struct vnt_private *pDevice, u8 byRequest, u16 wValue,
int PIPEnsControlIn(struct vnt_private *pDevice, u8 byRequest, u16 wValue,
u16 wIndex, u16 wLength, u8 *pbyBuffer)
+ __releases(&pDevice->lock)
+ __acquires(&pDevice->lock)
{
int ntStatus = 0;
int ii;
@@ -295,40 +299,38 @@ static void s_nsControlInUsbIoCompleteRead(struct urb *urb)
*
*/
-int PIPEnsInterruptRead(struct vnt_private *pDevice)
+int PIPEnsInterruptRead(struct vnt_private *priv)
{
- int ntStatus = STATUS_FAILURE;
+ int status = STATUS_FAILURE;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartInterruptUsbRead()\n");
+ 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,
+ 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,
- 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) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "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;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "<----s_nsStartInterruptUsbRead Return(%x)\n", status);
+
+ return status;
}
/*
@@ -348,67 +350,48 @@ usb_fill_bulk_urb(pDevice->pInterruptURB,
static void s_nsInterruptUsbIoCompleteRead(struct urb *urb)
{
- struct vnt_private *pDevice = (struct vnt_private *)urb->context;
- int ntStatus;
+ struct vnt_private *priv = urb->context;
+ int status;
- 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);
- }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "---->s_nsInterruptUsbIoCompleteRead\n");
+
+ switch (urb->status) {
+ case 0:
+ case -ETIMEDOUT:
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ priv->int_buf.in_use = false;
+ return;
+ default:
+ break;
+ }
- 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);
+ status = urb->status;
- 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 ;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "s_nsInterruptUsbIoCompleteRead Status %d\n", status);
+
+ if (status != STATUS_SUCCESS) {
+ priv->int_buf.in_use = false;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "IntUSBIoCompleteControl STATUS = %d\n", status);
+ } else {
+ INTnsProcessData(priv);
+ }
+
+ status = usb_submit_urb(priv->pInterruptURB, GFP_ATOMIC);
+ if (status) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Submit int URB failed %d\n", status);
+ } else {
+ priv->int_buf.in_use = true;
+ }
+
+ return;
}
/*
@@ -425,45 +408,41 @@ 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");
+ int status = 0;
+ struct urb *urb;
- if (pDevice->Flags & fMP_DISCONNECTED)
- return STATUS_FAILURE;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartBulkInUsbRead\n");
- pDevice->ulBulkInPosted++;
+ if (priv->Flags & fMP_DISCONNECTED)
+ return STATUS_FAILURE;
- 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;
- }
+ urb = rcb->pUrb;
+ if (rcb->skb == NULL) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"rcb->skb is null\n");
+ return status;
+ }
- usb_fill_bulk_urb(pUrb,
- pDevice->usb,
- usb_rcvbulkpipe(pDevice->usb, 2),
- (void *) (pRCB->skb->data),
+ 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) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "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;
}
/*
@@ -483,51 +462,47 @@ 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;
+ int re_alloc_skb = false;
- 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);
-//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;
- }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkInUsbIoCompleteRead\n");
- 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);
- }
+ switch (urb->status) {
+ case 0:
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ case -ETIMEDOUT:
+ default:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "BULK In failed %d\n", urb->status);
+ break;
+ }
+
+ if (urb->actual_length) {
+ spin_lock(&priv->lock);
+
+ if (RXbBulkInProcessData(priv, rcb, urb->actual_length) == true)
+ re_alloc_skb = true;
+
+ spin_unlock(&priv->lock);
+ }
+
+ rcb->Ref--;
+ if (rcb->Ref == 0) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeNormal %d\n",
+ priv->NumRecvFreeList);
+ spin_lock(&priv->lock);
+
+ RXvFreeRCB(rcb, re_alloc_skb);
- return;
+ spin_unlock(&priv->lock);
+ }
+
+ return;
}
/*
@@ -544,53 +519,40 @@ 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;
- }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_nsSendBulkOut\n");
+
+ if (!(MP_IS_READY(priv) && priv->Flags & fMP_POST_WRITES)) {
+ context->bBoolInUse = false;
+ return STATUS_RESOURCES;
+ }
+
+ urb = context->pUrb;
+
+ usb_fill_bulk_urb(urb,
+ priv->usb,
+ usb_sndbulkpipe(priv->usb, 3),
+ context->Data,
+ context->uBufLen,
+ s_nsBulkOutIoCompleteWrite,
+ context);
+
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status != 0) {
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Submit Tx URB failed %d\n", status);
+ context->bBoolInUse = false;
+ return STATUS_FAILURE;
+ }
+
+ return STATUS_PENDING;
}
/*
@@ -623,68 +585,49 @@ 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;
+ struct vnt_usb_send_context *context = urb->context;
+ struct vnt_private *priv = context->pDevice;
+ u8 context_type = context->type;
- //
- // Perform various IRP, URB, and buffer 'sanity checks'
- //
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkOutIoCompleteWrite\n");
- status = urb->status;
-
- if(status == STATUS_SUCCESS) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Write %d bytes\n",(int)ulBufLen);
- pDevice->ulBulkOutBytesWrite += ulBufLen;
- pDevice->ulBulkOutContCRCError = 0;
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK Out failed %d\n", status);
- pDevice->ulBulkOutError++;
- }
+ switch (urb->status) {
+ case 0:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "Write %d bytes\n", context->uBufLen);
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ context->bBoolInUse = false;
+ return;
+ case -ETIMEDOUT:
+ default:
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "BULK Out failed %d\n", urb->status);
+ break;
+ }
-// pDevice->ulCheckForHangCount = 0;
-// pDevice->pPendingBulkOutContext = NULL;
+ if (!netif_device_present(priv->dev))
+ return;
- 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);
- }
+ if (CONTEXT_DATA_PACKET == context_type) {
+ if (context->pPacket != NULL) {
+ dev_kfree_skb_irq(context->pPacket);
+ context->pPacket = NULL;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "tx %d bytes\n", context->uBufLen);
+ }
- pDevice->dev->trans_start = jiffies;
+ priv->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 (priv->bLinkPass == true) {
+ if (netif_queue_stopped(priv->dev))
+ netif_wake_queue(priv->dev);
+ }
- }
- if (pDevice->bLinkPass == true) {
- if (netif_queue_stopped(pDevice->dev))
- netif_wake_queue(pDevice->dev);
- }
- pContext->bBoolInUse = false;
+ context->bBoolInUse = false;
- return;
+ return;
}