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

📄 rtusb_bulk.c

📁 经过修改的在uClinux2.6上正常运行的ralink rt2571芯片组的设备驱动程序.
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 ***************************************************************************
 * Ralink Tech Inc.
 * 4F, No. 2 Technology 5th Rd.
 * Science-based Industrial Park
 * Hsin-chu, Taiwan, R.O.C.
 *
 * (c) Copyright 2002-2006, Ralink Technology, Inc.
 *
 * This program is free software; you can redistribute it and/or modify  * 
 * it under the terms of the GNU General Public License as published by  * 
 * the Free Software Foundation; either version 2 of the License, or     * 
 * (at your option) any later version.                                   * 
 *                                                                       * 
 * This program is distributed in the hope that it will be useful,       * 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of        * 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         * 
 * GNU General Public License for more details.                          * 
 *                                                                       * 
 * You should have received a copy of the GNU General Public License     * 
 * along with this program; if not, write to the                         * 
 * Free Software Foundation, Inc.,                                       * 
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             * 
 *                                                                       * 
 ************************************************************************

	Module Name:
	rtusb_bulk.c

	Abstract:

	Revision History:
	Who			When		What
	--------	----------	----------------------------------------------
	Name		Date		Modification logs
	Paul Lin	06-25-2004	created
	
*/

#include	"rt_config.h"


void RTusb_fill_bulk_urb (struct urb *pUrb,
	struct usb_device *pUsb_Dev,
	unsigned int bulkpipe,
	void *pTransferBuf,
	int BufSize,
	usb_complete_t Complete,
	void *pContext)
{

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
	usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, Complete, pContext);	
#else
	FILL_BULK_URB(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, Complete, pContext);
#endif

}

// ************************ Completion Func ************************ //
VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
{
	PTX_CONTEXT 	pTxContext;
	PRTMP_ADAPTER	pAd;
	NTSTATUS		status;
	UCHAR			BulkOutPipeId;
	ULONG			IrqFlags;

	DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutDataPacketComplete\n");
	pTxContext= (PTX_CONTEXT)pUrb->context;
	pAd = pTxContext->pAd;
	status = pUrb->status;

	// Store BulkOut PipeId
	BulkOutPipeId = pTxContext->BulkOutPipeId;
	pAd->BulkOutDataOneSecCount++;
	
	if (status == USB_ST_NOERROR)
	{	
		DBGPRINT_RAW(RT_DEBUG_INFO, "BulkOutDataPacketComplete %d (STATUS_SUCCESS)\n", BulkOutPipeId);

		if (pTxContext->LastOne == TRUE)
		{
			pAd->Counters.GoodTransmits++;
			FREE_TX_RING(pAd, BulkOutPipeId, pTxContext);
            pAd->TxRingTotalNumber[BulkOutPipeId]--;    // sync. to TxCount

			if (pAd->SendTxWaitQueue[BulkOutPipeId].Number > 0)
			{
				RTMPDeQueuePacket(pAd, BulkOutPipeId);
			}
		}
		else
		{
			if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
				(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
				(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
				(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
			{
				FREE_TX_RING(pAd, BulkOutPipeId, pTxContext);
				pAd->TxRingTotalNumber[BulkOutPipeId]--;    // sync. to TxCount
				// Indicate next one is frag data which has highest priority
				RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
			}
			else
			{
				while (pTxContext->LastOne != TRUE)
				{
					FREE_TX_RING(pAd, BulkOutPipeId, pTxContext);
					pAd->TxRingTotalNumber[BulkOutPipeId]--;    // sync. to TxCount
					pTxContext = &(pAd->TxContext[BulkOutPipeId][pAd->NextBulkOutIndex[BulkOutPipeId]]);
				}
				
				FREE_TX_RING(pAd, BulkOutPipeId, pTxContext);
				pAd->TxRingTotalNumber[BulkOutPipeId]--;    // sync. to TxCount
			}
		}
	}
#if 1	// STATUS_OTHER
	else
	{
		DBGPRINT_RAW(RT_DEBUG_ERROR, "BulkOutDataPacketComplete %d (STATUS_OTHER)\n", BulkOutPipeId);

		while (pTxContext->LastOne != TRUE)
		{
			FREE_TX_RING(pAd, BulkOutPipeId, pTxContext);
			pAd->TxRingTotalNumber[BulkOutPipeId]--;    // sync. to TxCount
			pTxContext = &(pAd->TxContext[BulkOutPipeId][pAd->NextBulkOutIndex[BulkOutPipeId]]);
		}
		FREE_TX_RING(pAd, BulkOutPipeId, pTxContext);
		pAd->TxRingTotalNumber[BulkOutPipeId]--;    // sync. to TxCount

		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
		{
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);

			RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT);
		}

	}
#endif


	pTxContext = &(pAd->TxContext[BulkOutPipeId][pAd->NextBulkOutIndex[BulkOutPipeId]]);
	//
	// bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
	// bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out. 
	//
	if ((pTxContext->bWaitingBulkOut == TRUE) && !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
	{
		// Indicate There is data avaliable
		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
	}


	NdisAcquireSpinLock(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
	pAd->BulkOutPending[BulkOutPipeId] = FALSE;
	NdisReleaseSpinLock(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
	// Always call Bulk routine, even reset bulk.
	// The protectioon of rest bulk should be in BulkOut routine
	RTUSBKickBulkOut(pAd);
}

// NULL frame use BulkOutPipeId = 0
VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
{
	PRTMP_ADAPTER	pAd;
	PTX_CONTEXT		pNullContext;
	NTSTATUS		status;
	ULONG			IrqFlags;
	
	pNullContext= (PTX_CONTEXT)pUrb->context;
	pAd = pNullContext->pAd;

	DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutNullFrameComplete\n");

	// Reset Null frame context flags
	pNullContext->IRPPending = FALSE;
	pNullContext->InUse = FALSE;
	
	status = pUrb->status;
	
	if (status == USB_ST_NOERROR)
	{
		// Don't worry about the queue is empty or not, this function will check itself
		RTMPDeQueuePacket(pAd, 0);
	}
#if 1	// STATUS_OTHER
	else
	{
		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
		{
			DBGPRINT_RAW(RT_DEBUG_ERROR, "Bulk Out Null Frame Failed\n");
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
			RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT);
		}
	}
#endif

	NdisAcquireSpinLock(&pAd->BulkOutLock[0], IrqFlags);
	pAd->BulkOutPending[0] = FALSE;
	NdisReleaseSpinLock(&pAd->BulkOutLock[0], IrqFlags);

	// Always call Bulk routine, even reset bulk.
	// The protectioon of rest bulk should be in BulkOut routine
	RTUSBKickBulkOut(pAd);

	DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutNullFrameComplete\n");

}

// RTS frame use BulkOutPipeId = PipeID
VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
{
	PRTMP_ADAPTER	pAd;
	PTX_CONTEXT		pRTSContext;
	NTSTATUS		status;
	ULONG			IrqFlags;
	
	pRTSContext= (PTX_CONTEXT)pUrb->context;
	pAd = pRTSContext->pAd;
	
	
	DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutRTSFrameComplete\n");

	// Reset RTS frame context flags
	pRTSContext->IRPPending = FALSE;
	pRTSContext->InUse = FALSE;
		
	status = pUrb->status;
	
	if (status == USB_ST_NOERROR)
	{
		// Don't worry about the queue is empty or not, this function will check itself
		RTMPDeQueuePacket(pAd, pRTSContext->BulkOutPipeId);
	}
#if 1	// STATUS_OTHER
	else
	{
		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
		{
			DBGPRINT_RAW(RT_DEBUG_ERROR, "Bulk Out RTS Frame Failed\n");
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
			RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT);
		}
	}
#endif

	NdisAcquireSpinLock(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId], IrqFlags);
	pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
	NdisReleaseSpinLock(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId], IrqFlags);

	// Always call Bulk routine, even reset bulk.
	// The protectioon of rest bulk should be in BulkOut routine
	RTUSBKickBulkOut(pAd);

	DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutRTSFrameComplete\n");
	
}

// MLME use BulkOutPipeId = 0
VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
{
	PTX_CONTEXT			pMLMEContext;
	PRTMP_ADAPTER		pAd;
	NTSTATUS			status;
	ULONG				IrqFlags;
	
	pMLMEContext= (PTX_CONTEXT)pUrb->context;
	pAd = pMLMEContext->pAd;
	status = pUrb->status;

	pAd->PrioRingTxCnt--;
	if (pAd->PrioRingTxCnt < 0)
		pAd->PrioRingTxCnt = 0;

	pAd->PrioRingFirstIndex++;
	if (pAd->PrioRingFirstIndex >= PRIO_RING_SIZE)
	{
		pAd->PrioRingFirstIndex = 0;
	}	

	DBGPRINT(RT_DEBUG_INFO, "RTUSBBulkOutMLMEPacketComplete::PrioRingFirstIndex = %d, PrioRingTxCnt = %d, PopMgmtIndex = %d, PushMgmtIndex = %d, NextMLMEIndex = %d\n", 
			pAd->PrioRingFirstIndex, 
			pAd->PrioRingTxCnt, pAd->PopMgmtIndex, pAd->PushMgmtIndex, pAd->NextMLMEIndex);

	DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutMLMEPacketComplete\n");
	
	// Reset MLME context flags
	pMLMEContext->IRPPending	= FALSE;
	pMLMEContext->InUse 		= FALSE;
	
	if (status == USB_ST_NOERROR)
	{
		// Don't worry about the queue is empty or not, this function will check itself
		RTUSBDequeueMLMEPacket(pAd);
	}
#if 1	// STATUS_OTHER
	else
	{
		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
		{
			DBGPRINT_RAW(RT_DEBUG_ERROR, "Bulk Out MLME Failed\n");
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
			RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT);
		}
	}
#endif

	NdisAcquireSpinLock(&pAd->BulkOutLock[0], IrqFlags);
	pAd->BulkOutPending[0] = FALSE;
	NdisReleaseSpinLock(&pAd->BulkOutLock[0], IrqFlags);

	// Always call Bulk routine, even reset bulk.
	// The protectioon of rest bulk should be in BulkOut routine
	RTUSBKickBulkOut(pAd);

	DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutMLMEPacketComplete\n");

}

// PS-Poll frame use BulkOutPipeId = 0
VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
{
	PRTMP_ADAPTER	pAd;
	PTX_CONTEXT		pPsPollContext;
	NTSTATUS		status;
	ULONG			IrqFlags;

	pPsPollContext= (PTX_CONTEXT)pUrb->context;
	pAd = pPsPollContext->pAd;

	DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutPsPollComplete\n");
		
	// Reset PsPoll context flags
	pPsPollContext->IRPPending	= FALSE;
	pPsPollContext->InUse		= FALSE;
	
	status = pUrb->status;
	if (status == USB_ST_NOERROR)
	{
		// Don't worry about the queue is empty or not, this function will check itself
		RTMPDeQueuePacket(pAd, 0);
	}
#if 1	// STATUS_OTHER
	else
	{
		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
		{
			DBGPRINT_RAW(RT_DEBUG_ERROR, "Bulk Out PSPoll Failed\n");
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
			RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT);
		}
	}
#endif

	NdisAcquireSpinLock(&pAd->BulkOutLock[0], IrqFlags);
	pAd->BulkOutPending[0] = FALSE;
	NdisReleaseSpinLock(&pAd->BulkOutLock[0], IrqFlags);

	// Always call Bulk routine, even reset bulk.
	// The protectioon of rest bulk should be in BulkOut routine
	RTUSBKickBulkOut(pAd);

	DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutPsPollComplete\n");

}

/*
	========================================================================

	Routine Description:
		This routine process Rx Irp and call rx complete function.
		
	Arguments:
		DeviceObject	Pointer to the device object for next lower
						device. DeviceObject passed in here belongs to
						the next lower driver in the stack because we
						were invoked via IoCallDriver in USB_RxPacket
						AND it is not OUR device object
	  Irp				Ptr to completed IRP
	  Context			Ptr to our Adapter object (context specified
						in IoSetCompletionRoutine
		
	Return Value:
		Always returns STATUS_MORE_PROCESSING_REQUIRED

	Note:
		Always returns STATUS_MORE_PROCESSING_REQUIRED
	========================================================================
*/
VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
{
	PRX_CONTEXT 	pRxContext;
	PRTMP_ADAPTER	pAd;
	NTSTATUS		status;
	
	pRxContext= (PRX_CONTEXT)pUrb->context;
	pAd = pRxContext->pAd;

	//
	// We have a number of cases:
	//		1) The USB read timed out and we received no data.
	//		2) The USB read timed out and we received some data.
	//		3) The USB read was successful and fully filled our irp buffer.
	//		4) The irp was cancelled.
	//		5) Some other failure from the USB device object.
	//
	
	//
	// Free the IRP  and its mdl because they were	alloced by us
	//
#if 0
	if ( (atomread = (atomic_read(&pRxContext->IrpLock))) == IRPLOCK_CANCE_START)
	{
		atomic_dec(&pAd->PendingRx);
		atomic_set(&pRxContext->IrpLock, IRPLOCK_CANCE_COMPLETE);	
	}
#endif

⌨️ 快捷键说明

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