rtusb_bulk.c

来自「ralink最新rt3070 usb wifi 无线网卡驱动程序」· C语言 代码 · 共 1,383 行 · 第 1/3 页

C
1,383
字号
				#ifdef RT_BIG_ENDIAN			RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);			RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);	#endif // RT_BIG_ENDIAN //				break;		}	#ifdef RT_BIG_ENDIAN		RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);		RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);#endif // RT_BIG_ENDIAN //	}while (TRUE);	// adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.	if (pLastTxInfo)	{#ifdef RT_BIG_ENDIAN		RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);#endif // RT_BIG_ENDIAN //		pLastTxInfo->USBDMANextVLD = 0;#ifdef RT_BIG_ENDIAN		RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);#endif // RT_BIG_ENDIAN //	}	/* 		We need to copy SavedPad when following condition matched!			1. Not the last round of the TxQueue and			2. any match of following cases:				(1). The End Position of this bulk out is reach to the Currenct Write position and 						the TxInfo and related header already write to the CurWritePosition.			   		=>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)						(2). The EndPosition of the bulk out is not reach to the Current Write Position.					=>(ENextBulkOutPosition != CurWritePosition)	*/	if ((bTxQLastRound == FALSE) &&		 (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||		  (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))		)	{		NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);		pHTTXContext->bCopySavePad = TRUE;		if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))		{				PUCHAR	pBuf = &pHTTXContext->SavedPad[0];			DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",				pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,				pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));						pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];			DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7]));		}		//DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));	}					if (pAd->bForcePrintTX == TRUE)		DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));	//DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound));			// USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.	pAppendant = &pWirelessPkt[TmpBulkEndPos];	NdisZeroMemory(pAppendant, 8);		ThisBulkSize += 4;		pHTTXContext->LastOne = TRUE;		if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)			ThisBulkSize += 4;	pHTTXContext->BulkOutSize = ThisBulkSize;		pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;	BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);		// Init Tx context descriptor	RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);		pUrb = pHTTXContext->pUrb;	if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)	{		DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));				BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);		pAd->BulkOutPending[BulkOutPipeId] = FALSE;		pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;		BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);		return;	}	BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);	pHTTXContext->IRPPending = TRUE;	BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);	pAd->BulkOutReq++;}VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs){	PHT_TX_CONTEXT	pHTTXContext;	PRTMP_ADAPTER	pAd;	POS_COOKIE 		pObj;	UCHAR			BulkOutPipeId;		pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;	pAd 			= pHTTXContext->pAd;	pObj 			= (POS_COOKIE) pAd->OS_Cookie;	// Store BulkOut PipeId	BulkOutPipeId	= pHTTXContext->BulkOutPipeId;	pAd->BulkOutDataOneSecCount++;	switch (BulkOutPipeId)	{		case 0:				pObj->ac0_dma_done_task.data = (unsigned long)pUrb;				tasklet_hi_schedule(&pObj->ac0_dma_done_task);				break;		case 1:				pObj->ac1_dma_done_task.data = (unsigned long)pUrb;				tasklet_hi_schedule(&pObj->ac1_dma_done_task);				break;		case 2:				pObj->ac2_dma_done_task.data = (unsigned long)pUrb;				tasklet_hi_schedule(&pObj->ac2_dma_done_task);				break;		case 3:				pObj->ac3_dma_done_task.data = (unsigned long)pUrb;				tasklet_hi_schedule(&pObj->ac3_dma_done_task);				break;		case 4:				pObj->hcca_dma_done_task.data = (unsigned long)pUrb;				tasklet_hi_schedule(&pObj->hcca_dma_done_task);				break;	}}/*	========================================================================		Routine Description:	Arguments:	Return Value:	Note: NULL frame use BulkOutPipeId = 0		========================================================================*/VOID	RTUSBBulkOutNullFrame(	IN	PRTMP_ADAPTER	pAd){	PTX_CONTEXT		pNullContext = &(pAd->NullContext);	PURB			pUrb;	int				ret = 0;	unsigned long	IrqFlags;		RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);	if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))	{		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);		return;	}	pAd->BulkOutPending[0] = TRUE;	pAd->watchDogTxPendingCnt[0] = 1;	pNullContext->IRPPending = TRUE;	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);	// Increase Total transmit byte counter	pAd->RalinkCounters.TransmittedByteCount +=  pNullContext->BulkOutSize;		// Clear Null frame bulk flag	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);#ifdef RT_BIG_ENDIAN	RTMPDescriptorEndianChange((PUCHAR)pNullContext->TransferBuffer, TYPE_TXINFO);#endif // RT_BIG_ENDIAN //	// Init Tx context descriptor	RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);	pUrb = pNullContext->pUrb;	if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)	{		RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);		pAd->BulkOutPending[0] = FALSE;		pAd->watchDogTxPendingCnt[0] = 0;		pNullContext->IRPPending = FALSE;		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);				DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));		return;	}		}// NULL frame use BulkOutPipeId = 0VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs){	PRTMP_ADAPTER		pAd;	PTX_CONTEXT			pNullContext;	NTSTATUS			Status;	POS_COOKIE			pObj;		pNullContext	= (PTX_CONTEXT)pUrb->context;	pAd 			= pNullContext->pAd;	Status 			= pUrb->status;		pObj = (POS_COOKIE) pAd->OS_Cookie;	pObj->null_frame_complete_task.data = (unsigned long)pUrb;	tasklet_hi_schedule(&pObj->null_frame_complete_task);}/*	========================================================================		Routine Description:	Arguments:	Return Value:	Note: MLME use BulkOutPipeId = 0		========================================================================*/VOID	RTUSBBulkOutMLMEPacket(	IN	PRTMP_ADAPTER	pAd,	IN	UCHAR			Index){	PTX_CONTEXT		pMLMEContext;	PURB			pUrb;	int				ret = 0;	unsigned long	IrqFlags;			pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;	pUrb = pMLMEContext->pUrb;	if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||		(pMLMEContext->InUse == FALSE) ||		(pMLMEContext->bWaitingBulkOut == FALSE))	{						// Clear MLME bulk flag		RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);				return;	} 	RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);	if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))	{		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);		return;	}	pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;	pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;	pMLMEContext->IRPPending = TRUE;	pMLMEContext->bWaitingBulkOut = FALSE;	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);		// Increase Total transmit byte counter	pAd->RalinkCounters.TransmittedByteCount +=  pMLMEContext->BulkOutSize;	// Clear MLME bulk flag	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);#ifdef RT_BIG_ENDIAN	RTMPDescriptorEndianChange((PUCHAR)pMLMEContext->TransferBuffer, TYPE_TXINFO);#endif // RT_BIG_ENDIAN //	// Init Tx context descriptor	RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)	//For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.	pUrb->transfer_dma	= 0;	pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);#endif	pUrb = pMLMEContext->pUrb;	if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)	{		DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));		RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);		pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;		pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;		pMLMEContext->IRPPending = FALSE;		pMLMEContext->bWaitingBulkOut = TRUE;		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);				return;	}	//DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));//	printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);}VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs){	PTX_CONTEXT			pMLMEContext;	PRTMP_ADAPTER		pAd;	NTSTATUS			Status;	POS_COOKIE 			pObj;	int					index;	//DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));	pMLMEContext	= (PTX_CONTEXT)pUrb->context;	pAd 			= pMLMEContext->pAd;	pObj 			= (POS_COOKIE)pAd->OS_Cookie;	Status			= pUrb->status;	index 			= pMLMEContext->SelfIdx;	pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;	tasklet_hi_schedule(&pObj->mgmt_dma_done_task);}/*	========================================================================		Routine Description:	Arguments:	Return Value:	Note: PsPoll use BulkOutPipeId = 0		========================================================================*/VOID	RTUSBBulkOutPsPoll(	IN	PRTMP_ADAPTER	pAd){	PTX_CONTEXT		pPsPollContext = &(pAd->PsPollContext);	PURB			pUrb;	int				ret = 0;	unsigned long	IrqFlags;		RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);	if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))	{		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);		return;	}	pAd->BulkOutPending[0] = TRUE;	pAd->watchDogTxPendingCnt[0] = 1;	pPsPollContext->IRPPending = TRUE;	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);		// Clear PS-Poll bulk flag	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);#ifdef RT_BIG_ENDIAN	RTMPDescriptorEndianChange((PUCHAR)pPsPollContext->TransferBuffer, TYPE_TXINFO);#endif // RT_BIG_ENDIAN //	// Init Tx context descriptor	RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);		pUrb = pPsPollContext->pUrb;	if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)	{		RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);		pAd->BulkOutPending[0] = FALSE;		pAd->watchDogTxPendingCnt[0] = 0;		pPsPollContext->IRPPending = FALSE;		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);				DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));		return;	}		}// PS-Poll frame use BulkOutPipeId = 0VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs){	PRTMP_ADAPTER		pAd;	PTX_CONTEXT			pPsPollContext;	NTSTATUS			Status;	POS_COOKIE			pObj;			pPsPollContext= (PTX_CONTEXT)pUrb->context;	pAd = pPsPollContext->pAd;	Status = pUrb->status;	pObj = (POS_COOKIE) pAd->OS_Cookie;	pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;	tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);}VOID DoBulkIn(IN RTMP_ADAPTER *pAd){		PRX_CONTEXT		pRxContext;	PURB			pUrb;	int				ret = 0;	unsigned long	IrqFlags;		RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);	pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);	if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))	{		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);		return;	}	pRxContext->InUse = TRUE;	pRxContext->IRPPending = TRUE;	pAd->PendingRx++;	pAd->BulkInReq++;	RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);	// Init Rx context descriptor	NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);	RTUSBInitRxDesc(pAd, pRxContext);	pUrb = pRxContext->pUrb;	if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)	{	// fail			RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);		pRxContext->InUse = FALSE;		pRxContext->IRPPending = FALSE;		pAd->PendingRx--;		pAd->BulkInReq--;		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);		DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));	}	else	{	// success		ASSERT((pRxContext->InUse == pRxContext->IRPPending));		//printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);	}}/*	========================================================================	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:

⌨️ 快捷键说明

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