+static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter)
+{
+ phw_data_t pHwData = &adapter->sHwData;
+ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct urb * pUrb = (struct urb *)pWb35Tx->Tx2Urb;
+ u32 * pltmp = (u32 *)pWb35Tx->EP2_buf;
+ int retv;
+
+ if (pHwData->SurpriseRemove || pHwData->HwStop)
+ goto error;
+
+ if (pWb35Tx->tx_halt)
+ goto error;
+
+ //
+ // Issuing URB
+ //
+ usb_fill_int_urb( pUrb, pHwData->WbUsb.udev, usb_rcvintpipe(pHwData->WbUsb.udev,2),
+ pltmp, MAX_INTERRUPT_LENGTH, Wb35Tx_EP2VM_complete, adapter, 32);
+
+ pWb35Tx->EP2vm_state = VM_RUNNING;
+ retv = usb_submit_urb(pUrb, GFP_ATOMIC);
+
+ if (retv < 0) {
+ #ifdef _PE_TX_DUMP_
+ WBDEBUG(("EP2 Tx Irp sending error\n"));
+ #endif
+ goto error;
+ }
+
+ return;
+error:
+ pWb35Tx->EP2vm_state = VM_STOP;
+ atomic_dec(&pWb35Tx->TxResultCount);
+}
+
+void Wb35Tx_EP2VM_start(struct wbsoft_priv *adapter)
+{
+ phw_data_t pHwData = &adapter->sHwData;
+ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+
+ // Allow only one thread to run into function
+ if (atomic_inc_return(&pWb35Tx->TxResultCount) == 1) {
+ pWb35Tx->EP2vm_state = VM_RUNNING;
+ Wb35Tx_EP2VM(adapter);
+ }
+ else
+ atomic_dec(&pWb35Tx->TxResultCount);
+}