📄 rtusb_bulk.c
字号:
/*************************************************************************** * RT2x00 SourceForge Project - http://rt2x00.serialmonkey.com * * * * 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * * Licensed under the GNU GPL * * Original code supplied under license from RaLink Inc, 2004. * ***************************************************************************//*************************************************************************** * Module Name: rtusb_bulk.c * * Abstract: * * Revision History: * Who When What * -------- ---------- ----------------------------- * idamlaj 14-10-2006 RFMONTx (based on MarkW's code) * ***************************************************************************/#include "rt_config.h"void RTusb_fill_bulk_urb (struct urb *pUrb, struct usb_device *pUsb_Dev, unsigned int bulkpipe, void *pTransferBuf, int BufSize, usb_complete_t Complete, void *pContext){#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, Complete, pContext);#else FILL_BULK_URB(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, Complete, pContext);#endif}// ************************ Completion Func ************************ ///* ======================================================================== Routine Description: This routine processes data and RTS/CTS frame completions. If the current frame has transmitted OK and there are more fragments, then schedule the next frame fragment. If there's been an error, empty any remaining fragments for that queue from the tx ring. Arguments: pUrb Our URB pt_regs Historical Return Value: void Note: ALL (i.e. we've done a submit_urb) in-flight URBS are posted complete. ========================================================================*/VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs){ PTX_CONTEXT pTxContext; PRTMP_ADAPTER pAd; NTSTATUS status; UCHAR BulkOutPipeId; unsigned long flags; pTxContext= (PTX_CONTEXT)pUrb->context; pAd = pTxContext->pAd; status = pUrb->status; atomic_dec(&pAd->PendingTx); DBGPRINT(RT_DEBUG_TRACE, "--->%s status=%d PendingTx=%d\n", __FUNCTION__, status, atomic_read(&pAd->PendingTx)); // Store BulkOut PipeId BulkOutPipeId = pTxContext->BulkOutPipeId; pAd->BulkOutDataOneSecCount++; switch (status) { case 0: // OK if (pTxContext->LastOne == TRUE) { pAd->Counters.GoodTransmits++; FREE_TX_RING(pAd, BulkOutPipeId, pTxContext); pAd->TxRingTotalNumber[BulkOutPipeId]--;// sync. to PendingTx pTxContext = nextTxContext(pAd, BulkOutPipeId); if (pTxContext->bWaitingBulkOut == TRUE) { RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); } } else { if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { FREE_TX_RING(pAd, BulkOutPipeId, pTxContext); pAd->TxRingTotalNumber[BulkOutPipeId]--;// sync. to PendingTx // Indicate next one is frag data which has highest priority RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); } else { do { FREE_TX_RING(pAd, BulkOutPipeId, pTxContext); pAd->TxRingTotalNumber[BulkOutPipeId]--;// sync. to PendingTx pTxContext = nextTxContext(pAd, BulkOutPipeId); } while (pTxContext->InUse != FALSE); } } RTUSBMlmeUp(pAd); break; case -ECONNRESET: // async unlink via call to usb_unlink_urb() case -ENOENT: // stopped by call to usb_kill_urb case -ESHUTDOWN: // hardware gone = -108 case -EPROTO: // unplugged = -71 DBGPRINT(RT_DEBUG_ERROR,"=== %s: shutdown status=%d\n", __FUNCTION__, status); do { FREE_TX_RING(pAd, BulkOutPipeId, pTxContext); pAd->TxRingTotalNumber[BulkOutPipeId]--;// sync. to PendingTx pTxContext = nextTxContext(pAd, BulkOutPipeId); } while (pTxContext->InUse != FALSE); break; default:#if 1 // TODO: Think about if we really want to do this reset - bb do { FREE_TX_RING(pAd, BulkOutPipeId, pTxContext); pAd->TxRingTotalNumber[BulkOutPipeId]--;// sync. to PendingTx pTxContext = nextTxContext(pAd, BulkOutPipeId); } while (pTxContext->InUse != FALSE); if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { DBGPRINT(RT_DEBUG_ERROR, "Bulk Out Data Packet Failed\n"); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT); }#endif break; } NdisAcquireSpinLock(&pAd->BulkOutLock[BulkOutPipeId]); pAd->BulkOutPending[BulkOutPipeId] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[BulkOutPipeId]);}// NULL frame use BulkOutPipeId = 0VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs){ PRTMP_ADAPTER pAd; PTX_CONTEXT pNullContext; NTSTATUS status; unsigned long flags; pNullContext= (PTX_CONTEXT)pUrb->context; pAd = pNullContext->pAd; // Reset Null frame context flags pNullContext->IRPPending = FALSE; pNullContext->InUse = FALSE; status = pUrb->status; atomic_dec(&pAd->PendingTx); DBGPRINT(RT_DEBUG_TRACE, "--->%s status=%d PendingTx=%d\n", __FUNCTION__, status, atomic_read(&pAd->PendingTx)); switch (status) { case 0: // OK RTUSBMlmeUp(pAd); break; case -ECONNRESET: // async unlink via call to usb_unlink_urb() case -ENOENT: // stopped by call to usb_kill_urb case -ESHUTDOWN: // hardware gone = -108 case -EPROTO: // unplugged = -71 DBGPRINT(RT_DEBUG_ERROR,"=== %s: shutdown status=%d\n", __FUNCTION__, status); break; default:#if 1 // STATUS_OTHER if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { DBGPRINT(RT_DEBUG_ERROR, "Bulk Out Null Frame Failed\n"); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT); } break;#endif } NdisAcquireSpinLock(&pAd->BulkOutLock[0]); pAd->BulkOutPending[0] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[0]); DBGPRINT(RT_DEBUG_TRACE, "<---RTUSBBulkOutNullFrameComplete\n");}// RTS frame use BulkOutPipeId = PipeIDVOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs){ PRTMP_ADAPTER pAd; PTX_CONTEXT pRTSContext; NTSTATUS status; unsigned long flags; pRTSContext= (PTX_CONTEXT)pUrb->context; pAd = pRTSContext->pAd; // Reset RTS frame context flags pRTSContext->IRPPending = FALSE; pRTSContext->InUse = FALSE; status = pUrb->status; atomic_dec(&pAd->PendingTx); DBGPRINT(RT_DEBUG_TRACE, "--->%s status=%d PendingTx=%d\n", __FUNCTION__, status, atomic_read(&pAd->PendingTx)); switch (status) { case 0: // OK RTUSBMlmeUp(pAd); break; case -ECONNRESET: // async unlink via call to usb_unlink_urb() case -ENOENT: // stopped by call to usb_kill_urb case -ESHUTDOWN: // hardware gone = -108 case -EPROTO: // unplugged = -71 DBGPRINT(RT_DEBUG_ERROR,"=== %s: shutdown status=%d\n", __FUNCTION__, status); break; default:#if 1 // STATUS_OTHER if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { DBGPRINT(RT_DEBUG_ERROR, "Bulk Out RTS Frame Failed\n"); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT); } break;#endif } NdisAcquireSpinLock(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]); pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]); DBGPRINT(RT_DEBUG_TRACE, "<---RTUSBBulkOutRTSFrameComplete\n");}// MLME use BulkOutPipeId = 0VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs){ PTX_CONTEXT pMLMEContext; PRTMP_ADAPTER pAd; NTSTATUS status; unsigned long flags; pMLMEContext= (PTX_CONTEXT)pUrb->context; pAd = pMLMEContext->pAd; status = pUrb->status; atomic_dec(&pAd->PendingTx); DBGPRINT(RT_DEBUG_TRACE, "--->%s status=%d PendingTx=%d\n", __FUNCTION__, status, atomic_read(&pAd->PendingTx)); pAd->PrioRingTxCnt--; if (pAd->PrioRingTxCnt < 0) pAd->PrioRingTxCnt = 0; pAd->PrioRingFirstIndex++; if (pAd->PrioRingFirstIndex >= PRIO_RING_SIZE) { pAd->PrioRingFirstIndex = 0; }#if 0 DBGPRINT(RT_DEBUG_INFO, "RTUSBBulkOutMLMEPacketComplete::PrioRingFirstIndex = %d, PrioRingTxCnt = %d, PopMgmtIndex = %d, PushMgmtIndex = %d, NextMLMEIndex = %d\n", pAd->PrioRingFirstIndex, pAd->PrioRingTxCnt, pAd->PopMgmtIndex, pAd->PushMgmtIndex, pAd->NextMLMEIndex);#endif // Reset MLME context flags pMLMEContext->IRPPending = FALSE; pMLMEContext->InUse = FALSE; switch (status) { case 0: // OK if (pAd->PrioRingTxCnt > 0) { RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); } RTUSBMlmeUp(pAd); break; case -ECONNRESET: // async unlink via call to usb_unlink_urb() case -ENOENT: // stopped by call to usb_kill_urb case -ESHUTDOWN: // hardware gone = -108 case -EPROTO: // unplugged = -71 DBGPRINT(RT_DEBUG_ERROR,"=== %s: shutdown status=%d\n", __FUNCTION__, status); break; default:#if 1 // STATUS_OTHER if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { DBGPRINT(RT_DEBUG_ERROR, "Bulk Out MLME Failed\n"); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT); } break;#endif } NdisAcquireSpinLock(&pAd->BulkOutLock[0]); pAd->BulkOutPending[0] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[0]); DBGPRINT(RT_DEBUG_TRACE, "<---RTUSBBulkOutMLMEPacketComplete\n");}// PS-Poll frame use BulkOutPipeId = 0VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs){ PRTMP_ADAPTER pAd; PTX_CONTEXT pPsPollContext; NTSTATUS status; unsigned long flags; pPsPollContext= (PTX_CONTEXT)pUrb->context; pAd = pPsPollContext->pAd; // Reset PsPoll context flags pPsPollContext->IRPPending = FALSE; pPsPollContext->InUse = FALSE; status = pUrb->status; atomic_dec(&pAd->PendingTx); DBGPRINT(RT_DEBUG_TRACE, "--->%s status=%d PendingTx=%d\n", __FUNCTION__, status, atomic_read(&pAd->PendingTx)); switch (status) { case 0: // OK RTUSBMlmeUp(pAd); break; case -ECONNRESET: // async unlink via call to usb_unlink_urb() case -ENOENT: // stopped by call to usb_kill_urb case -ESHUTDOWN: // hardware gone = -108 case -EPROTO: // unplugged = -71 DBGPRINT(RT_DEBUG_ERROR,"=== %s: shutdown status=%d\n", __FUNCTION__, status); break; default:#if 1 // STATUS_OTHER if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { DBGPRINT(RT_DEBUG_ERROR, "Bulk Out PSPoll Failed\n"); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT); } break;#endif } NdisAcquireSpinLock(&pAd->BulkOutLock[0]); pAd->BulkOutPending[0] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[0]); DBGPRINT(RT_DEBUG_TRACE, "<---RTUSBBulkOutPsPollComplete\n");}/* ======================================================================== Routine Description: This routine process Rx Irp and call rx complete function. Arguments: DeviceObject Pointer to the device object for next lower device. DeviceObject passed in here belongs to the next lower driver in the stack because we were invoked via IoCallDriver in USB_RxPacket AND it is not OUR device object Irp Ptr to completed IRP Context Ptr to our Adapter object (context specified in IoSetCompletionRoutine Return Value: Always returns STATUS_MORE_PROCESSING_REQUIRED Note: Always returns STATUS_MORE_PROCESSING_REQUIRED ========================================================================*/VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs){ PRX_CONTEXT pRxContext; PRTMP_ADAPTER pAd; NTSTATUS status; pRxContext= (PRX_CONTEXT)pUrb->context; pAd = pRxContext->pAd; // // 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. // status = pUrb->status; atomic_set(&pRxContext->IrpLock, IRPLOCK_COMPLETED); atomic_dec(&pAd->PendingRx); DBGPRINT(RT_DEBUG_TRACE, "--->%s status=%d PendingRx=%d\n", __FUNCTION__, status, atomic_read(&pAd->PendingRx)); switch (status) { case 0: RTUSBMlmeUp(pAd); break; case -ECONNRESET: // async unlink via call to usb_unlink_urb() case -ENOENT: // stopped by call to usb_kill_urb case -ESHUTDOWN: // hardware gone = -108 case -EPROTO: // unplugged = -71 DBGPRINT(RT_DEBUG_ERROR,"=== %s: shutdown status=%d\n", __FUNCTION__, status); pRxContext->InUse = FALSE; default: break; }}VOID RTUSBInitTxDesc(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -