rtusb_bulk.c

来自「台湾RALink公司的 rt2570无线 802.11g 网卡的 驱动的源代码 」· C语言 代码 · 共 1,457 行 · 第 1/3 页

C
1,457
字号
		NdisReleaseSpinLock(&pAdapter->BulkOutLock);
		return;
	}
	pAdapter->BulkOutPending = TRUE;
	NdisReleaseSpinLock(&pAdapter->BulkOutLock);

	
	// Clear Beacon 0, 1 flag and set beacon 1 flag if required
	if (RTUSB_TEST_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_BEACON_0))
	{
		// Clear beacon 0 flag
		RTUSB_CLEAR_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_BEACON_0);
		// Set beacon 1 flag
		RTUSB_SET_BULK_FLAG (pAdapter, fRTUSB_BULK_OUT_BEACON_1);
	}
	else
	{
		// Clear beacon 1 flag
		RTUSB_CLEAR_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_BEACON_1);
	}
	
	pBeaconContext  = &pAdapter->BeaconContext[BeaconIndex];
	DBGPRINT_RAW(RT_DEBUG_TEMP, "--->RTUSBBulkOutBeacon BulkOutSize %d\n",pBeaconContext->BulkOutSize);
	pUrb = pBeaconContext->pUrb;
	RTusb_fill_bulk_urb(pUrb,
		pAdapter->usb,
		usb_sndbulkpipe(pAdapter->usb, 1),
		pBeaconContext->TransferBuffer,
		pBeaconContext->BulkOutSize,
		RTUSBBulkOutBeaconComplete,
		pBeaconContext);

	if((ret = rtusb_submit_urb(pUrb))!=0)
	{
		DBGPRINT(RT_DEBUG_ERROR,"Submit Tx URB failed %d\n", ret);
		return;
	}
	
	DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutBeacon \n");
}


/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:

	IRQL = 
	
	Note:
	
	========================================================================
*/
VOID	RTUSBBulkOutPsPoll(
	IN	PRT2570ADAPTER	pAdapter)
{
	PTX_CONTEXT	pPsPollContext = &(pAdapter->PsPollContext);
	PURB			pUrb;
	int ret = 0;

	NdisAcquireSpinLock(&pAdapter->BulkOutLock);
	if (pAdapter->BulkOutPending == TRUE)
	{
		NdisReleaseSpinLock(&pAdapter->BulkOutLock);
		return;
	}
	pAdapter->BulkOutPending = TRUE;
	NdisReleaseSpinLock(&pAdapter->BulkOutLock);

	// Clear PS-Poll bulk flag
	RTUSB_CLEAR_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_PSPOLL);

	DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutPsPollFrame \n");
	
	pUrb = pPsPollContext->pUrb;
	RTusb_fill_bulk_urb(pUrb,
		pAdapter->usb,
		usb_sndbulkpipe(pAdapter->usb, 1),
		pPsPollContext->TransferBuffer,
		pPsPollContext->BulkOutSize,
		RTUSBBulkOutPsPollComplete,
		pPsPollContext);

	if((ret = rtusb_submit_urb(pUrb))!=0)
	{
		DBGPRINT(RT_DEBUG_ERROR,"Submit Tx URB failed %d\n", ret);
		return;
	}
	DBGPRINT(RT_DEBUG_INFO,"<==RTUSBBulkOutPsPollPacket\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	PRT2570ADAPTER	pAdapter)
{
	
	PRX_CONTEXT pRxContext;
	PURB			pUrb;
	int ret = 0;

	if ((RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_REMOVE_IN_PROGRESS))||
		(RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))||
		(RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_PIPE_IN_PROGRESS)))
		{
	DBGPRINT(RT_DEBUG_TEMP,"==>RTUSBBulkReceive, pAdapter->NextRxBulkInIndex = %d\n",pAdapter->NextRxBulkInIndex);
		return;
		}
	//DBGPRINT(RT_DEBUG_TEMP,"==>RTUSBBulkReceive, pAdapter->NextRxBulkInIndex = %d\n",pAdapter->NextRxBulkInIndex);
	pRxContext = &(pAdapter->RxContext[pAdapter->NextRxBulkInIndex]);
	pRxContext->InUse = TRUE;
	pAdapter->NextRxBulkInIndex = (pAdapter->NextRxBulkInIndex + 1) % RX_RING_SIZE;

	pUrb = pRxContext->pUrb;
		
	atomic_set(&pRxContext->IrpLock, IRPLOCK_CANCELABLE);	
	atomic_add(1, &pAdapter->PendingRx);
	RTMPZeroMemory(pRxContext->TransferBuffer, BUFFER_SIZE);
	RTusb_fill_bulk_urb(pUrb,
		pAdapter->usb,
		usb_rcvbulkpipe(pAdapter->usb, 1),
		pRxContext->TransferBuffer,
		BUFFER_SIZE,
		RTUSBBulkRxComplete,
		pRxContext);
	
	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:

	IRQL = 
	
	Note:
	
	========================================================================
*/
VOID	RTUSBKickBulkOut(
	IN	PRT2570ADAPTER pAdapter)
{
	int	RoundOver = 0;
	do
	{
		// greedy to bulk out. protection are in BulkOut function using InUse parameter
		if (++RoundOver > 2)
			break;
		
		if (!(RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_REMOVE_IN_PROGRESS)) &&
			!(RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
			!(RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
			!(RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BULKOUT_RESET)) &&
			!(RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF)))
		{
			// Start aribritrating Bulk out candidates

			// 0. Check if no flags set, we will do a dequeue from MLME and Data
			//if (pAdapter->BulkFlags == 0x0)
			//{
			//	RTUSBDequeueMLMEPacket(pAdapter);
			//	RTUSBDeQueuePacket(pAdapter);
			//}
		
			// 1. Data Fragment has highest priority
			if (RTUSB_TEST_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_DATA_FRAG))
			{
				RTUSBBulkOutDataPacket(pAdapter, pAdapter->NextBulkOutIndex);
			}
			
			// 2. PS-Poll frame is next
			else if (RTUSB_TEST_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_PSPOLL))
			{
				RTUSBBulkOutPsPoll(pAdapter);
			}
			
			// 3. Beacon 0, guarding beacon frame is next
			else if (RTUSB_TEST_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_BEACON_0))
			{
				RTUSBBulkOutBeacon(pAdapter, 0);
			}

			// 4. Beacon 1, beacon frame body is next
			else if (RTUSB_TEST_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_BEACON_1))
			{
				RTUSBBulkOutBeacon(pAdapter, 1);
			}

			// 5. Mlme frame is next
			else if (RTUSB_TEST_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_MLME))
			{
				RTUSBBulkOutMLMEPacket(pAdapter, pAdapter->PrioRingFirstIndex);
			}

			// 6. Data frame normal is next
			else if (RTUSB_TEST_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_DATA_NORMAL))
			{
				if ((!LOCAL_TX_RING_EMPTY(pAdapter)) && 
					((!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) && 
					(pAdapter->MediaState == NdisMediaStateConnected)))
				{
					RTUSBBulkOutDataPacket(pAdapter, pAdapter->NextBulkOutIndex);
				}
			}

			// 7. Null frame is the last
			else if (RTUSB_TEST_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_DATA_NULL))
			{
				if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
				{
					RTUSBBulkOutNullFrame(pAdapter);
				}
			}
			
			// 8. No data avaliable
			else
			{
				// Do nothing, or dequeue MLME and Data
				//RTUSBDequeueMLMEPacket(pAdapter);
				//RTUSBDeQueuePacket(pAdapter);
			}
		}
	}while(TRUE);
	DBGPRINT_RAW(RT_DEBUG_INFO,"<---RTUSBKickBulkOut\n");
}

/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:

	IRQL = 
	
	Note:
	
	========================================================================
*/
VOID	RTUSBCleanUpDataBulkOutQueue(
	IN	PRT2570ADAPTER	pAdapter)
{
	PTX_CONTEXT pTxContext;			

	DBGPRINT(RT_DEBUG_TRACE, "--->CleanUpDataBulkOutQueue\n");
				
	while (!LOCAL_TX_RING_EMPTY(pAdapter))
	{			
		pTxContext 					= &(pAdapter->TxContext[pAdapter->NextBulkOutIndex]);
		pTxContext->LastOne 		= FALSE;
		pTxContext->InUse 			= FALSE;
		pAdapter->NextBulkOutIndex 	= (pAdapter->NextBulkOutIndex + 1) % TX_RING_SIZE;
	}
	
	NdisAcquireSpinLock(&pAdapter->BulkOutLock);
	pAdapter->BulkOutPending = FALSE;
	NdisReleaseSpinLock(&pAdapter->BulkOutLock);

	DBGPRINT(RT_DEBUG_TRACE, "<---CleanUpDataBulkOutQueue\n");
}

/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:

	IRQL = 
	
	Note:
	
	========================================================================
*/
VOID	RTUSBCleanUpMLMEBulkOutQueue(
	IN	PRT2570ADAPTER	pAdapter)
{
	DBGPRINT(RT_DEBUG_TRACE, "--->CleanUpMLMEBulkOutQueue\n");

	NdisAcquireSpinLock(&pAdapter->MLMEQLock);
	while (pAdapter->PrioRingTxCnt > 0)
	{
		pAdapter->MLMEContext[pAdapter->PrioRingFirstIndex].InUse = FALSE;
			
		pAdapter->PrioRingFirstIndex++;
		if (pAdapter->PrioRingFirstIndex >= PRIO_RING_SIZE)
		{
			pAdapter->PrioRingFirstIndex = 0;
		}

		pAdapter->PrioRingTxCnt--;
	}
	NdisReleaseSpinLock(&pAdapter->MLMEQLock);

	DBGPRINT(RT_DEBUG_TRACE, "<---CleanUpMLMEBulkOutQueue\n");
}

/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:

	IRQL = 
	
	Note:
	
	========================================================================
*/
VOID	RTUSBCancelPendingIRPs(
	IN	PRT2570ADAPTER	pAdapter)
{
	RTUSBCancelPendingBulkInIRP(pAdapter);
	RTUSBCancelPendingBulkOutIRP(pAdapter);
}

/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:

	IRQL = 
	
	Note:
	
	========================================================================
*/
VOID	RTUSBCancelPendingBulkInIRP(
	IN	PRT2570ADAPTER	pAdapter)
{
	PRX_CONTEXT	pRxContext;
	UINT		i;

	DBGPRINT_RAW(RT_DEBUG_TRACE,"--->RTUSBCancelPendingBulkInIRP\n");
	for ( i = 0; i < RX_RING_SIZE; i++)
	{
		pRxContext = &(pAdapter->RxContext[i]);
		if(atomic_read(&pRxContext->IrpLock) == IRPLOCK_CANCELABLE)
		{
			usb_unlink_urb(pRxContext->pUrb);
		}
		atomic_set(&pRxContext->IrpLock, IRPLOCK_CANCE_START);
	}
	DBGPRINT_RAW(RT_DEBUG_TRACE,"<---RTUSBCancelPendingBulkInIRP\n");
}

/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:

	IRQL = 
	
	Note:
	
	========================================================================
*/
VOID	RTUSBCancelPendingBulkOutIRP(
	IN	PRT2570ADAPTER	pAdapter)
{
	PTX_CONTEXT		pTxContext;
	PTX_CONTEXT		pMLMEContext;
	PTX_CONTEXT		pBeaconContext;
	PTX_CONTEXT		pNullContext;
	PTX_CONTEXT		pPsPollContext;
	UINT		i;
	
	DBGPRINT_RAW(RT_DEBUG_TRACE,"--->RTUSBCancelPendingBulkOutIRP\n");
	for ( i = 0; i < TX_RING_SIZE; i++)
	{
		pTxContext = &(pAdapter->TxContext[i]);
		if (pTxContext->IRPPending == TRUE)
		{
			usb_unlink_urb(pTxContext->pUrb);
		}
	}

	for (i = 0; i < PRIO_RING_SIZE; i++)
	{
		pMLMEContext = &(pAdapter->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
			//

			usb_unlink_urb(pMLMEContext->pUrb);

			// Sleep 200 microsecs to give cancellation time to work
			NdisMSleep(200);
		}
	}

	for (i = 0; i < BEACON_RING_SIZE; i++)
	{
		pBeaconContext = &(pAdapter->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
			//

			usb_unlink_urb(pBeaconContext->pUrb);

			// Sleep 200 microsecs to give cancellation time to work
			NdisMSleep(200);
		}
	}

	pNullContext = &(pAdapter->NullContext);
	if (pNullContext->IRPPending == TRUE)
	usb_unlink_urb(pNullContext->pUrb);

	pPsPollContext = &(pAdapter->PsPollContext);
	if (pPsPollContext->IRPPending == TRUE)
	usb_unlink_urb(pPsPollContext->pUrb);

	NdisAcquireSpinLock(&pAdapter->BulkOutLock);
	pAdapter->BulkOutPending = FALSE;
	NdisReleaseSpinLock(&pAdapter->BulkOutLock);
	
	DBGPRINT_RAW(RT_DEBUG_TRACE,"<---RTUSBCancelPendingBulkOutIRP\n");
	
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?