📄 rtusb_bulk.c
字号:
{
DBGPRINT(RT_DEBUG_ERROR,"Submit Tx URB failed %d\n", ret);
return;
}
DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutPsPoll \n");
return;
}
/*
========================================================================
Routine Description:
USB_RxPacket initializes a URB and uses the Rx IRP to submit it
to USB. It checks if an Rx Descriptor is available and passes the
the coresponding buffer to be filled. If no descriptor is available
fails the request. When setting the completion routine we pass our
Adapter Object as Context.
Arguments:
Return Value:
TRUE found matched tuple cache
FALSE no matched found
Note:
========================================================================
*/
VOID RTUSBBulkReceive(
IN PRTMP_ADAPTER pAd)
{
PRX_CONTEXT pRxContext;
PURB pUrb;
int ret = 0;
if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_PIPE_IN_PROGRESS)))
{
return;
}
DBGPRINT(RT_DEBUG_INFO,"RTUSBBulkReceive:: pAd->NextRxBulkInIndex = %d\n",pAd->NextRxBulkInIndex);
pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
pRxContext->InUse = TRUE;
pAd->NextRxBulkInIndex = (pAd->NextRxBulkInIndex + 1) % RX_RING_SIZE;
atomic_set(&pRxContext->IrpLock, IRPLOCK_CANCELABLE);
atomic_inc(&pAd->PendingRx);
// Init Rx context descriptor
NdisZeroMemory(pRxContext->TransferBuffer, BUFFER_SIZE);
RTUSBInitRxDesc(pAd, pRxContext);
pUrb = pRxContext->pUrb;
if((ret = rtusb_submit_urb(pUrb))!=0)
{
DBGPRINT(RT_DEBUG_ERROR,"Submit Rx URB failed %d\n", ret);
return;
}
return;
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note:
========================================================================
*/
VOID RTUSBKickBulkOut(
IN PRTMP_ADAPTER pAd)
{
DBGPRINT_RAW(RT_DEBUG_INFO, "--->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_RAW(RT_DEBUG_INFO, "<---RTUSBKickBulkOut\n");
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note:
========================================================================
*/
VOID RTUSBCleanUpDataBulkOutQueue(
IN PRTMP_ADAPTER pAd)
{
UCHAR Idx;
PTX_CONTEXT pTxContext;
ULONG IrqFlags;
DBGPRINT(RT_DEBUG_TRACE, "--->CleanUpDataBulkOutQueue\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], IrqFlags);
pAd->BulkOutPending[Idx] = FALSE;
NdisReleaseSpinLock(&pAd->BulkOutLock[Idx], IrqFlags);
}
DBGPRINT(RT_DEBUG_TRACE, "<---CleanUpDataBulkOutQueue\n");
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note:
========================================================================
*/
VOID RTUSBCleanUpMLMEBulkOutQueue(
IN PRTMP_ADAPTER pAd)
{
ULONG IrqFlags;
DBGPRINT(RT_DEBUG_TRACE, "--->CleanUpMLMEBulkOutQueue\n");
NdisAcquireSpinLock(&pAd->MLMEQLock, IrqFlags);
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, IrqFlags);
DBGPRINT(RT_DEBUG_TRACE, "<---CleanUpMLMEBulkOutQueue\n");
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note:
========================================================================
*/
VOID RTUSBCancelPendingBulkInIRP(
IN PRTMP_ADAPTER pAd)
{
PRX_CONTEXT pRxContext;
UINT i;
DBGPRINT_RAW(RT_DEBUG_TRACE,"--->RTUSBCancelPendingBulkInIRP\n");
for ( i = 0; i < RX_RING_SIZE; i++)
{
pRxContext = &(pAd->RxContext[i]);
if(atomic_read(&pRxContext->IrpLock) == IRPLOCK_CANCELABLE)
{
RTUSB_UNLINK_URB(pRxContext->pUrb);
}
atomic_set(&pRxContext->IrpLock, IRPLOCK_CANCE_START);
}
DBGPRINT_RAW(RT_DEBUG_TRACE,"<---RTUSBCancelPendingBulkInIRP\n");
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
Note:
========================================================================
*/
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;
ULONG IrqFlags;
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], IrqFlags);
pAd->BulkOutPending[Idx] = FALSE;
NdisReleaseSpinLock(&pAd->BulkOutLock[Idx], IrqFlags);
}
}
/*
========================================================================
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 + -