⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtusb_bulk.c

📁 r73模块的无线网卡在Linux下的驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*	========================================================================	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 + -