📄 rtusb_bulk.c
字号:
/* ======================================================================== Routine Description: RTUSBBulkReceive cannot be called when in an interrupt as it raises a bug on ARM, so we schedule this function so that it calls RTUSBBulkReceive outside of interrupt context. Arguments: ulong data, memory address to pAd structure. Return Value: Note: ========================================================================*/VOID rtusb_bulkrx( IN unsigned long data){ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)data; RTUSBBulkReceive(pAd);}/* ======================================================================== Routine Description: Arguments: Return Value: Note: ========================================================================*/VOID RTUSBKickBulkOut( IN PRTMP_ADAPTER pAd){ DBGPRINT(RT_DEBUG_TRACE, "--->RTUSBKickBulkOut\n"); if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && !(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && !(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && !(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_PIPE_IN_PROGRESS)) && !(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))) { // 1. Data Fragment has highest priority if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG)) { if ((!LOCAL_TX_RING_EMPTY(pAd, 0)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) { RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]); } } if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_2)) { if ((!LOCAL_TX_RING_EMPTY(pAd, 1)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) { RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]); } } if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_3)) { if ((!LOCAL_TX_RING_EMPTY(pAd, 2)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) { RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]); } } if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_4)) { if ((!LOCAL_TX_RING_EMPTY(pAd, 3)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) { RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]); } } // 2. PS-Poll frame is next if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL)) { RTUSBBulkOutPsPoll(pAd); } // 5. Mlme frame is next else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) { RTUSBBulkOutMLMEPacket(pAd, pAd->PrioRingFirstIndex); } // 6. Data frame normal is next if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL)) { if ((!LOCAL_TX_RING_EMPTY(pAd, 0)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) { RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]); } } if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2)) { if ((!LOCAL_TX_RING_EMPTY(pAd, 1)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) { RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]); } } if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3)) { if ((!LOCAL_TX_RING_EMPTY(pAd, 2)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) { RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]); } } if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4)) { if ((!LOCAL_TX_RING_EMPTY(pAd, 3)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) { RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]); } } // 7. Null frame is the last else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL)) { if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { RTUSBBulkOutNullFrame(pAd); } } // 8. No data avaliable else { } } DBGPRINT(RT_DEBUG_TRACE, "<---RTUSBKickBulkOut\n");}/* ======================================================================== Routine Description: Arguments: Return Value: Note: ========================================================================*/VOID RTUSBCleanUpDataBulkInQueue( IN PRTMP_ADAPTER pAd){ int i = 0; DBGPRINT(RT_DEBUG_TRACE, "--> %s: %d PendingRx left\n", __FUNCTION__, atomic_read(&pAd->PendingRx)); do { PRX_CONTEXT pRxContext = &pAd->RxContext[i]; pRxContext->InUse = FALSE; atomic_set(&pRxContext->IrpLock, IRPLOCK_COMPLETED); pRxContext->IRPPending = FALSE; } while (++i < RX_RING_SIZE); DBGPRINT(RT_DEBUG_TRACE, "<-- RTUSBCleanUpDataBulkInQueue\n");} /* End RTUSBCleanUpDataBulkInQueue () *//* ======================================================================== Routine Description: Arguments: Return Value: Note: ========================================================================*/VOID RTUSBCleanUpDataBulkOutQueue( IN PRTMP_ADAPTER pAd){ UCHAR Idx; PTX_CONTEXT pTxContext; unsigned long flags; DBGPRINT(RT_DEBUG_TRACE, "--->RTUSBCleanUpDataBulkOutQueue\n"); for (Idx = 0; Idx < 4; Idx++) { while (!LOCAL_TX_RING_EMPTY(pAd, Idx)) { pTxContext = &(pAd->TxContext[Idx][pAd->NextBulkOutIndex[Idx]]); pTxContext->LastOne = FALSE; pTxContext->InUse = FALSE; pTxContext->bWaitingBulkOut = FALSE; pAd->NextBulkOutIndex[Idx] = (pAd->NextBulkOutIndex[Idx] + 1) % TX_RING_SIZE; } NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]); pAd->BulkOutPending[Idx] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]); } DBGPRINT(RT_DEBUG_TRACE, "<---RTUSBCleanUpDataBulkOutQueue\n");}/* ======================================================================== Routine Description: Arguments: Return Value: Note: ========================================================================*/VOID RTUSBCleanUpMLMEBulkOutQueue( IN PRTMP_ADAPTER pAd){ unsigned long flags; // For "Ndis" spin lock DBGPRINT(RT_DEBUG_TRACE, "--->%s\n", __FUNCTION__); NdisAcquireSpinLock(&pAd->MLMEQLock); while (pAd->PrioRingTxCnt > 0) { pAd->MLMEContext[pAd->PrioRingFirstIndex].InUse = FALSE; pAd->PrioRingFirstIndex++; if (pAd->PrioRingFirstIndex >= PRIO_RING_SIZE) { pAd->PrioRingFirstIndex = 0; } pAd->PrioRingTxCnt--; } NdisReleaseSpinLock(&pAd->MLMEQLock); DBGPRINT(RT_DEBUG_TRACE, "<---%s\n", __FUNCTION__);}VOID RTUSBwaitRxDone( IN PRTMP_ADAPTER pAd){ int i; for (i = 0; atomic_read(&pAd->PendingRx) > 0 && i < 25; i++) { msleep(UNLINK_TIMEOUT_MS); }} /* End RTUSBwaitRxDone () */VOID RTUSBwaitTxDone( IN PRTMP_ADAPTER pAd){ int i; for (i = 0; atomic_read(&pAd->PendingTx) > 0 && i < 25; i++) { msleep(UNLINK_TIMEOUT_MS); }} /* End RTUSBwaitTxDone () *//* ======================================================================== Routine Description: Arguments: Return Value: Note: Must be called in process context. ========================================================================*/VOID RTUSBCancelPendingBulkInIRP( IN PRTMP_ADAPTER pAd){ PRX_CONTEXT pRxContext; //UINT i; int i = pAd->CurRxBulkInIndex; DBGPRINT(RT_DEBUG_TRACE, "--> %s: %d PendingRx left\n", __FUNCTION__, atomic_read(&pAd->PendingRx));#if 0 for ( i = 0; i < RX_RING_SIZE; i++) { pRxContext = &(pAd->RxContext[i]); if(atomic_read(&pRxContext->IrpLock) == IRPLOCK_CANCELABLE) { RTUSB_UNLINK_URB(pRxContext->pUrb); } pRxContext->InUse = FALSE; atomic_set(&pRxContext->IrpLock, IRPLOCK_COMPLETED); }#else // Cancel till we've caught up with newly issued recieves - bb do { pRxContext = &pAd->RxContext[i]; if(atomic_read(&pRxContext->IrpLock) == IRPLOCK_CANCELABLE) { RTUSB_UNLINK_URB(pRxContext->pUrb); } if (++i >= RX_RING_SIZE) i = 0; } while (i != pAd->NextRxBulkInIndex);#endif // maybe wait for cancellations to finish. RTUSBwaitRxDone(pAd); pAd->CurRxBulkInIndex = pAd->NextRxBulkInIndex = 0; DBGPRINT(RT_DEBUG_TRACE, "<-- %s: %d PendingRx left\n", __FUNCTION__, atomic_read(&pAd->PendingRx));}/* ======================================================================== Routine Description: Arguments: Return Value: Note: Must be called in process context. ========================================================================*/VOID RTUSBCancelPendingBulkOutIRP( IN PRTMP_ADAPTER pAd){ PTX_CONTEXT pTxContext; PTX_CONTEXT pMLMEContext; PTX_CONTEXT pBeaconContext; PTX_CONTEXT pNullContext; PTX_CONTEXT pPsPollContext; PTX_CONTEXT pRTSContext; UINT i, Idx; unsigned long flags; DBGPRINT(RT_DEBUG_TRACE, "--> %s: %d PendingTx left\n", __FUNCTION__, atomic_read(&pAd->PendingTx)); for (Idx = 0; Idx < 4; Idx++) { for (i = 0; i < TX_RING_SIZE; i++) { pTxContext = &(pAd->TxContext[Idx][i]); if (pTxContext->IRPPending == TRUE) { // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself // remove it from the HeadPendingSendList and NULL out HeadPendingSendList // when the last IRP on the list has been cancelled; that's how we exit this loop // RTUSB_UNLINK_URB(pTxContext->pUrb); // Sleep 200 microseconds to give cancellation time to work RTMPusecDelay(200); } } } for (i = 0; i < PRIO_RING_SIZE; i++) { pMLMEContext = &(pAd->MLMEContext[i]); if(pMLMEContext->IRPPending == TRUE) { // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself // remove it from the HeadPendingSendList and NULL out HeadPendingSendList // when the last IRP on the list has been cancelled; that's how we exit this loop // RTUSB_UNLINK_URB(pMLMEContext->pUrb); // Sleep 200 microsecs to give cancellation time to work RTMPusecDelay(200); } } for (i = 0; i < BEACON_RING_SIZE; i++) { pBeaconContext = &(pAd->BeaconContext[i]); if(pBeaconContext->IRPPending == TRUE) { // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself // remove it from the HeadPendingSendList and NULL out HeadPendingSendList // when the last IRP on the list has been cancelled; that's how we exit this loop // RTUSB_UNLINK_URB(pBeaconContext->pUrb); // Sleep 200 microsecs to give cancellation time to work RTMPusecDelay(200); } } pNullContext = &(pAd->NullContext); if (pNullContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pNullContext->pUrb); pRTSContext = &(pAd->RTSContext); if (pRTSContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pRTSContext->pUrb); pPsPollContext = &(pAd->PsPollContext); if (pPsPollContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pPsPollContext->pUrb); for (Idx = 0; Idx < 4; Idx++) { NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]); pAd->BulkOutPending[Idx] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]); } // maybe wait for cancellations to finish. RTUSBwaitTxDone(pAd); DBGPRINT(RT_DEBUG_TRACE, "<-- %s: %d PendingTx left\n", __FUNCTION__, atomic_read(&pAd->PendingTx));}/* ======================================================================== Routine Description: Arguments: Return Value: Note: ========================================================================*/VOID RTUSBCancelPendingIRPs( IN PRTMP_ADAPTER pAd){ RTUSBCancelPendingBulkInIRP(pAd); RTUSBCancelPendingBulkOutIRP(pAd);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -