📄 rtusb_bulk.c
字号:
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)
{
int RoundOver = 0;
DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBKickBulkOut\n");
do
{
// greedy to bulk out. protection are in BulkOut function using InUse parameter
if (++RoundOver > 2)
break;
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_BULKOUT_RESET)) &&
!(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)) ||
(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
{
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)) ||
(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
{
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)) ||
(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
{
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)) ||
(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
{
RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
}
}
// 2. PS-Poll frame is next
if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
{
RTUSBBulkOutPsPoll(pAd);
}
if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_RTS))
{
RTUSBBulkOutRTSFrame(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
else 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)) ||
(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
{
RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
}
}
else 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)) ||
(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
{
RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
}
}
else 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)) ||
(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
{
RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
}
}
else 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)) ||
(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
{
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
{
}
}
} while (FALSE);
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], (unsigned long)IrqFlags);
pAd->BulkOutPending[Idx] = FALSE;
NdisReleaseSpinLock(&pAd->BulkOutLock[Idx], (unsigned long)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, (unsigned long)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, (unsigned long)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], (unsigned long)IrqFlags);
pAd->BulkOutPending[Idx] = FALSE;
NdisReleaseSpinLock(&pAd->BulkOutLock[Idx], (unsigned long)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 + -