📄 rtusb_bulk.c
字号:
/* *************************************************************************** * 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. * * All rights reserved. Ralink's source code is an unpublished work and the * use of a copyright notice does not imply otherwise. This source code * contains confidential trade secret material of Ralink Tech. Any attemp * or participation in deciphering, decoding, reverse engineering or in any * way altering the source code is stricitly prohibited, unless the prior * written consent of Ralink Technology, Inc. is obtained. *************************************************************************** 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; unsigned long 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 = 0VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs){ PRTMP_ADAPTER pAd; PTX_CONTEXT pNullContext; NTSTATUS status; unsigned long 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 = PipeIDVOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs){ PRTMP_ADAPTER pAd; PTX_CONTEXT pRTSContext; NTSTATUS status; unsigned long 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 = 0VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs){ PTX_CONTEXT pMLMEContext; PRTMP_ADAPTER pAd; NTSTATUS status; unsigned long 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; pMLMEContext->bWaitingBulkOut =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 pMLMEContext = &pAd->MLMEContext[pAd->PrioRingFirstIndex]; if ( (pAd->PrioRingTxCnt >= 1) && (pMLMEContext->bWaitingBulkOut == TRUE)) RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); 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 = 0VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs){ PRTMP_ADAPTER pAd; PTX_CONTEXT pPsPollContext; NTSTATUS status; unsigned long 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 status = pUrb->status; atomic_set(&pRxContext->IrpLock, IRPLOCK_COMPLETED); if( atomic_read(&pAd->PendingRx) > 0) atomic_dec(&pAd->PendingRx); switch (status) { case 0: break; case -ECONNRESET: // async unlink case -ESHUTDOWN: // hardware gone = -108 //pUrb = NULL; DBGPRINT(RT_DEBUG_ERROR, "==> RTUSBBulkRxComplete Error code = %d\n", status); break; default: DBGPRINT(RT_DEBUG_ERROR, "==> RTUSBBulkRxComplete UnKnown Error code = %d\n", status); break; } if (atomic_read(&pRxContext->IrpLock) != IRPLOCK_CANCE_START) { pAd->rx_bh.data = (unsigned long)pUrb; if(!RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_HALT_IN_PROGRESS)) //Add by Zero:Jan09.2008 Fix IF down crash tasklet_schedule(&pAd->rx_bh);//iverson patch usb 1.1 or 2.0 2007 1109 if(pAd->BulkOutMaxPacketSize == 512) { DBGPRINT(RT_DEBUG_INFO, "In USB 2.0 Mode \n"); } else{ RTUSBBulkReceive(pAd); } } else DBGPRINT(RT_DEBUG_INFO, "==> RTUSBBulkRxComplete (IrpLock) = %d\n", atomic_read(&pRxContext->IrpLock));#if 0 if ((status == USB_ST_NOERROR) && (atomic_read(&pRxContext->IrpLock) != IRPLOCK_CANCE_START)) { RTUSBRxPacket(pUrb); //tasklet_schedule(&pAd->rx_bh); }// STATUS_SUCCESS else { DBGPRINT(RT_DEBUG_TEMP,"==> RTUSBBulkRxComplete Error code = %d\n", status); pRxContext->InUse = FALSE; if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { DBGPRINT_RAW(RT_DEBUG_ERROR, "Bulk In Failed\n"); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_IN); } }#endif}VOID RTUSBInitTxDesc( IN PRTMP_ADAPTER pAd, IN PTX_CONTEXT pTxContext, IN UCHAR BulkOutPipeId, IN usb_complete_t Func)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -