Staging: Add pristine upstream vt6656 driver sources to drivers/staging/vt6656.

Add pristine upstream vt6656 driver sources to drivers/staging/vt6656.  These
files were copied from the driver directory in the upstream source archive,
available here:

  http://www.viaarena.com/Driver/VT6656_Linux_src_v1.19_12_x86.zip

After copying, trailing whitespace was stripped.  This is GPL-licensed code.

Signed-off-by: Forest Bond <forest@alittletooquiet.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
new file mode 100644
index 0000000..625ffb6
--- /dev/null
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -0,0 +1,989 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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-1301 USA.
+ *
+ *
+ * File: usbpipe.c
+ *
+ * Purpose: Handle USB control endpoint
+ *
+ * Author: Warren Hsu
+ *
+ * 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
+ *      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
+ *      11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,ControlvMaskByte
+ *
+ */
+
+#if !defined(__UMEM_H__)
+#include "umem.h"
+#endif
+#if !defined(__INT_H__)
+#include "int.h"
+#endif
+#if !defined(__RXTX_H__)
+#include "rxtx.h"
+#endif
+#if !defined(__DPC_H__)
+#include "dpc.h"
+#endif
+#if !defined(__CONTROL_H__)
+#include "control.h"
+#endif
+#if !defined(__DESC_H__)
+#include "desc.h"
+#endif
+#if !defined(__DEVICE_H__)
+#include "device.h"
+#endif
+
+
+/*---------------------  Static Definitions -------------------------*/
+//endpoint def
+//endpoint 0: control
+//endpoint 1: interrupt
+//endpoint 2: read bulk
+//endpoint 3: write bulk
+
+//RequestType:
+//#define REQUEST_OUT       (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) // 0x40
+//#define REQUEST_IN        (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE )  //0xc0
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+
+#define USB_CTL_WAIT   500 //ms
+
+#ifndef URB_ASYNC_UNLINK
+#define URB_ASYNC_UNLINK    0
+#endif
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+//2007-0508-02<Add>by MikeLiu
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+
+static
+VOID
+s_nsInterruptUsbIoCompleteRead(
+    IN struct urb *urb,
+    IN struct pt_regs *regs
+    );
+
+
+static
+VOID
+s_nsBulkInUsbIoCompleteRead(
+    IN struct urb *urb,
+    IN struct pt_regs *regs
+    );
+
+
+static
+VOID
+s_nsBulkOutIoCompleteWrite(
+    IN struct urb *urb,
+    IN struct pt_regs *regs
+    );
+
+
+static
+VOID
+s_nsControlInUsbIoCompleteRead(
+    IN struct urb *urb,
+    IN struct pt_regs *regs
+    );
+
+static
+VOID
+s_nsControlInUsbIoCompleteWrite(
+    IN struct urb *urb,
+    IN struct pt_regs *regs
+    );
+
+#else
+
+static
+VOID
+s_nsInterruptUsbIoCompleteRead(
+    IN struct urb *urb
+    );
+
+
+static
+VOID
+s_nsBulkInUsbIoCompleteRead(
+    IN struct urb *urb
+    );
+
+
+static
+VOID
+s_nsBulkOutIoCompleteWrite(
+    IN struct urb *urb
+    );
+
+
+static
+VOID
+s_nsControlInUsbIoCompleteRead(
+    IN struct urb *urb
+    );
+
+static
+VOID
+s_nsControlInUsbIoCompleteWrite(
+    IN struct urb *urb
+    );
+
+#endif
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+NTSTATUS
+PIPEnsControlOutAsyn(
+    IN PSDevice     pDevice,
+    IN BYTE         byRequest,
+    IN WORD         wValue,
+    IN WORD         wIndex,
+    IN WORD         wLength,
+    IN PBYTE        pbyBuffer
+    )
+{
+    NTSTATUS                ntStatus;
+
+
+    if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
+        return STATUS_FAILURE;
+
+
+    if (MP_TEST_FLAG(pDevice, 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,
+                            (PVOID) 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;
+}
+
+
+
+
+
+NTSTATUS
+PIPEnsControlOut(
+    IN PSDevice     pDevice,
+    IN BYTE         byRequest,
+    IN WORD         wValue,
+    IN WORD         wIndex,
+    IN WORD         wLength,
+    IN PBYTE        pbyBuffer
+    )
+{
+    NTSTATUS            ntStatus = 0;
+    int ii;
+
+
+    if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
+        return STATUS_FAILURE;
+
+    if (MP_TEST_FLAG(pDevice, fMP_CONTROL_WRITES)) {
+        return STATUS_FAILURE;
+    }
+
+	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);
+
+	if ((ntStatus = vntwusb_submit_urb(pDevice->pControlURB) != 0)) {
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control send request submission failed: %d\n", ntStatus);
+		return STATUS_FAILURE;
+	}
+	else {
+	    MP_SET_FLAG(pDevice, fMP_CONTROL_WRITES);
+	}
+	spin_unlock_irq(&pDevice->lock);
+    for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
+        if (MP_TEST_FLAG(pDevice, 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;
+}
+
+
+
+
+NTSTATUS
+PIPEnsControlIn(
+    IN PSDevice     pDevice,
+    IN BYTE         byRequest,
+    IN WORD         wValue,
+    IN WORD         wIndex,
+    IN WORD         wLength,
+    IN OUT  PBYTE   pbyBuffer
+    )
+{
+    NTSTATUS            ntStatus = 0;
+    int ii;
+
+    if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
+        return STATUS_FAILURE;
+
+    if (MP_TEST_FLAG(pDevice, fMP_CONTROL_READS)) {
+        return STATUS_FAILURE;
+    }
+	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);
+
+	if ((ntStatus = vntwusb_submit_urb(pDevice->pControlURB) != 0)) {
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control request submission failed: %d\n", ntStatus);
+	}else {
+		MP_SET_FLAG(pDevice, fMP_CONTROL_READS);
+    }
+
+	spin_unlock_irq(&pDevice->lock);
+    for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
+        if (MP_TEST_FLAG(pDevice, fMP_CONTROL_READS))
+            mdelay(1);
+        else {
+            break;
+        }
+        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;
+}
+
+//2007-0508-03<Add>by MikeLiu
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+
+static
+VOID
+s_nsControlInUsbIoCompleteWrite(
+    IN struct urb *urb,
+    IN struct pt_regs *regs
+    )
+#else
+
+static
+VOID
+s_nsControlInUsbIoCompleteWrite(
+    IN struct urb *urb
+    )
+#endif
+{
+    PSDevice        pDevice;
+
+	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);
+}
+
+
+
+/*
+ * Description:
+ *      Complete function of usb Control callback
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to the adapter
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
+ *
+ */
+
+//2007-0508-04<Add>by MikeLiu
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+static
+VOID
+s_nsControlInUsbIoCompleteRead(
+    IN struct urb *urb,
+    IN struct pt_regs *regs
+    )
+#else
+
+static
+VOID
+s_nsControlInUsbIoCompleteRead(
+    IN struct urb *urb
+    )
+#endif
+{
+    PSDevice        pDevice;
+
+	pDevice = urb->context;
+	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);
+}
+
+
+
+
+/*
+ * 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
+ *
+ */
+NTSTATUS
+PIPEnsInterruptRead(
+    IN PSDevice pDevice
+    )
+{
+    NTSTATUS            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.
+    //
+#if 0            //reserve int URB submit
+	usb_fill_int_urb(pDevice->pInterruptURB,
+	                 pDevice->usb,
+	                 usb_rcvintpipe(pDevice->usb, 1),
+	                 (PVOID) pDevice->intBuf.pDataBuf,
+	                 MAX_INTERRUPT_SIZE,
+	                 s_nsInterruptUsbIoCompleteRead,
+	                 pDevice,
+	                 pDevice->int_interval
+	                 );
+#else            //replace int URB submit by bulk transfer
+#ifndef Safe_Close
+	usb_fill_int_urb(pDevice->pInterruptURB,
+	                 pDevice->usb,
+	                 usb_rcvintpipe(pDevice->usb, 1),
+	                 (PVOID) pDevice->intBuf.pDataBuf,
+	                 MAX_INTERRUPT_SIZE,
+	                 s_nsInterruptUsbIoCompleteRead,
+	                 pDevice,
+	                 pDevice->int_interval
+	                 );
+#else
+
+//2008-0526-01<Add>by MikeLiu
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+    pDevice->pInterruptURB->interval = pDevice->int_interval;
+#endif
+
+usb_fill_bulk_urb(pDevice->pInterruptURB,
+		pDevice->usb,
+		usb_rcvbulkpipe(pDevice->usb, 1),
+		(PVOID) pDevice->intBuf.pDataBuf,
+		MAX_INTERRUPT_SIZE,
+		s_nsInterruptUsbIoCompleteRead,
+		pDevice);
+#endif
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+	if ((ntStatus = vntwusb_submit_urb(pDevice->pInterruptURB)) != 0) {
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
+    }
+
+#else
+    if (pDevice->bEventAvailable == FALSE) {
+	    if ((ntStatus = vntwusb_submit_urb(pDevice->pInterruptURB)) != 0) {
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
+        }
+    }
+#endif
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----s_nsStartInterruptUsbRead Return(%x)\n",ntStatus);
+    return ntStatus;
+}
+
+
+/*
+ * 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
+ *
+ */
+//2007-0508-05<Add>by MikeLiu
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+static
+VOID
+s_nsInterruptUsbIoCompleteRead(
+    IN struct urb *urb,
+    IN struct pt_regs *regs
+    )
+#else
+
+static
+VOID
+s_nsInterruptUsbIoCompleteRead(
+    IN struct urb *urb
+    )
+
+#endif
+{
+    PSDevice        pDevice;
+    NTSTATUS        ntStatus;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptUsbIoCompleteRead\n");
+    //
+    // The context given to IoSetCompletionRoutine is the receive buffer object
+    //
+    pDevice = (PSDevice)urb->context;
+
+    //
+    // 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 += (ULONG)urb->actual_length;
+        pDevice->ulIntInContCRCError = 0;
+        pDevice->bEventAvailable = TRUE;
+        INTnsProcessData(pDevice);
+    }
+
+    STAvUpdateUSBCounter(&pDevice->scStatistic.USB_InterruptStat, ntStatus);
+
+
+    if (pDevice->fKillEventPollingThread != TRUE) {
+   #if 0               //reserve int URB submit
+    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+	if ((ntStatus = vntwusb_submit_urb(urb)) != 0) {
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Re-Submit int URB failed %d\n", ntStatus);
+    }
+
+    #else
+    if (pDevice->bEventAvailable == FALSE) {
+	    if ((ntStatus = vntwusb_submit_urb(urb)) != 0) {
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Re-Submit int URB failed %d\n", ntStatus);
+        }
+    }
+    #endif
+   #else                                                                                     //replace int URB submit by bulk transfer
+    #ifdef Safe_Close
+       usb_fill_bulk_urb(pDevice->pInterruptURB,
+		      pDevice->usb,
+		      usb_rcvbulkpipe(pDevice->usb, 1),
+		     (PVOID) pDevice->intBuf.pDataBuf,
+		     MAX_INTERRUPT_SIZE,
+		     s_nsInterruptUsbIoCompleteRead,
+		     pDevice);
+
+     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+	if ((ntStatus = vntwusb_submit_urb(pDevice->pInterruptURB)) != 0) {
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
+           }
+
+     #else
+         if (pDevice->bEventAvailable == FALSE) {
+	    if ((ntStatus = vntwusb_submit_urb(pDevice->pInterruptURB)) != 0) {
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
+               }
+           }
+      #endif
+    #else
+        tasklet_schedule(&pDevice->EventWorkItem);
+    #endif
+#endif
+    }
+    //
+    // We return STATUS_MORE_PROCESSING_REQUIRED so that the completion
+    // routine (IofCompleteRequest) will stop working on the irp.
+    //
+    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
+ *
+ */
+NTSTATUS
+PIPEnsBulkInUsbRead(
+    IN PSDevice pDevice,
+    IN PRCB     pRCB
+    )
+{
+    NTSTATUS            ntStatus= 0;
+    struct urb          *pUrb;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartBulkInUsbRead\n");
+
+    if (MP_TEST_FLAG(pDevice, 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),
+		(PVOID) (pRCB->skb->data),
+		MAX_TOTAL_SIZE_WITH_ALL_HEADERS,
+		s_nsBulkInUsbIoCompleteRead,
+		pRCB);
+
+	if((ntStatus = vntwusb_submit_urb(pUrb)!=0)){
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Rx URB failed %d\n", ntStatus);
+		return STATUS_FAILURE ;
+	}
+    pRCB->Ref = 1;
+    pRCB->bBoolInUse= TRUE;
+
+    return ntStatus;
+}
+
+
+
+
+/*
+ * 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
+ *
+ */
+//2007-0508-06<Add>by MikeLiu
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+static
+VOID
+s_nsBulkInUsbIoCompleteRead(
+    IN struct urb *urb,
+    IN struct pt_regs *regs
+    )
+#else
+
+static
+VOID
+s_nsBulkInUsbIoCompleteRead(
+    IN struct urb *urb
+    )
+
+#endif
+{
+    PRCB    pRCB = (PRCB)urb->context;
+    PSDevice pDevice = (PSDevice)pRCB->pDevice;
+    ULONG   bytesRead;
+    BOOLEAN bIndicateReceive = FALSE;
+    BOOL    bReAllocSkb = FALSE;
+    NTSTATUS    status;
+
+
+
+    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);
+
+     	#ifdef Calcu_LinkQual
+           pDevice->scStatistic.RxFcsErrCnt ++;
+	#endif
+//todo...xxxxxx
+//        if (status == USBD_STATUS_CRC) {
+//            pDevice->ulBulkInContCRCError++;
+//        }
+//        if (status == STATUS_DEVICE_NOT_CONNECTED )
+//        {
+//            MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
+//        }
+    } else {
+        bIndicateReceive = TRUE;
+        pDevice->ulBulkInContCRCError = 0;
+        pDevice->ulBulkInBytesRead += bytesRead;
+
+	#ifdef Calcu_LinkQual
+           pDevice->scStatistic.RxOkCnt ++;
+	#endif
+    }
+
+
+    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;
+}
+
+/*
+ * 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
+ *
+ */
+NDIS_STATUS
+PIPEnsSendBulkOut(
+    IN  PSDevice pDevice,
+    IN  PUSB_SEND_CONTEXT pContext
+    )
+{
+    NTSTATUS            status;
+    struct urb          *pUrb;
+
+
+
+    pDevice->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) && MP_TEST_FLAG(pDevice, fMP_POST_WRITES)) {
+
+        pUrb = pContext->pUrb;
+        pDevice->ulBulkOutPosted++;
+//        pDevice->pPendingBulkOutContext = pContext;
+        usb_fill_bulk_urb(
+        	    pUrb,
+        		pDevice->usb,
+        		usb_sndbulkpipe(pDevice->usb, 3),
+        		(PVOID) &(pContext->Data[0]),
+        		pContext->uBufLen,
+        		s_nsBulkOutIoCompleteWrite,
+        		pContext);
+
+    	if((status = vntwusb_submit_urb(pUrb))!=0)
+    	{
+    		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Tx URB failed %d\n", status);
+    		return STATUS_FAILURE;
+    	}
+        return STATUS_PENDING;
+    }
+    else {
+        pContext->bBoolInUse = FALSE;
+        return STATUS_RESOURCES;
+    }
+}
+
+/*
+ * 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.
+ *
+ */
+//2007-0508-07<Add>by MikeLiu
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+static
+VOID
+s_nsBulkOutIoCompleteWrite(
+    IN struct urb *urb,
+    IN struct pt_regs *regs
+    )
+#else
+
+static
+VOID
+s_nsBulkOutIoCompleteWrite(
+    IN struct urb *urb
+    )
+#endif
+{
+    PSDevice            pDevice;
+    NTSTATUS            status;
+    CONTEXT_TYPE        ContextType;
+    ULONG               ulBufLen;
+    PUSB_SEND_CONTEXT   pContext;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkOutIoCompleteWrite\n");
+    //
+    // The context given to IoSetCompletionRoutine is an USB_CONTEXT struct
+    //
+    pContext = (PUSB_SEND_CONTEXT) urb->context;
+    ASSERT( NULL != pContext );
+
+    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;
+	//2007-0115-06<Add>by MikeLiu
+           #ifdef TxInSleep
+             pDevice->nTxDataTimeCout = 0;
+           #endif
+
+    } 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;
+}