📄 rtusb_bulk.c
字号:
/*************************************************************************** * RT2x00 SourceForge Project - http://rt2x00.sourceforge.net * * * * 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. * * * * Licensed under the GNU GPL * * Original code supplied under license from RaLink Inc, 2004. * ***************************************************************************//*************************************************************************** * Module Name: rtusb_bulk.c * * Abstract: * * Revision History: * Who When What * -------- ---------- ------------------------------- * Name Date Modification logs * Jan Lee 2005-06-01 Release * RobinC 02-06-2005 usb_kill_urb fixes for kernels =>2.6.7 ***************************************************************************/#include "rt_config.h"#ifndef URB_ASYNC_UNLINK#define URB_ASYNC_UNLINK 0#endif//typedef VOID (*STATE_MACHINE_FUNC)(VOID *Adaptor, MLME_QUEUE_ELEM *Elem);void RTusb_fill_bulk_urb (struct urb *pUrb, struct usb_device *usb, unsigned int bulkpipe, void *TransferBuf, int BufSize, usb_complete_t Complete, void *Context){#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)usb_fill_bulk_urb(pUrb, usb, bulkpipe, TransferBuf, BufSize, Complete, Context); #elseFILL_BULK_URB(pUrb, usb, bulkpipe, TransferBuf, BufSize, Complete, Context); #endif}/* ======================================================================== Routine Description: Arguments: Return Value: IRQL = Note: ========================================================================*/VOID RTUSBBulkOutDataPacket( IN PRT2570ADAPTER pAdapter, IN UCHAR Index){ PTX_CONTEXT pTxContext; PURB pUrb; int ret = 0; NdisAcquireSpinLock(&pAdapter->BulkOutLock); if (pAdapter->BulkOutPending == TRUE) { NdisReleaseSpinLock(&pAdapter->BulkOutLock); return; } pAdapter->BulkOutPending = TRUE; NdisReleaseSpinLock(&pAdapter->BulkOutLock); pTxContext = &(pAdapter->TxContext[Index]); // Increase Total transmit byte counter pAdapter->RalinkCounters.TransmittedByteCount += pTxContext->BulkOutSize; // Clear Data flag RTUSB_CLEAR_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_DATA_FRAG); //The Data Bulk out protection is to Test InUse flag, temporarily not CLEAR DATA_NORMAL flag to test //RTUSB_CLEAR_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_DATA_NORMAL); pUrb = pTxContext->pUrb; if (pTxContext->InUse != TRUE) { DBGPRINT(RT_DEBUG_ERROR, "RTUSBBulkOutDataPacket failed, pTxContext->InUse != TRUE, Index %d, NextBulkOutIndex %d\n", Index, pAdapter->NextBulkOutIndex); NdisAcquireSpinLock(&pAdapter->BulkOutLock); pAdapter->BulkOutPending = FALSE; NdisReleaseSpinLock(&pAdapter->BulkOutLock); return; } else if (pAdapter->MediaState == NdisMediaStateDisconnected && !( pAdapter->PortCfg.BssType == BSS_MONITOR && pAdapter->PortCfg.MallowRFMONTx == TRUE ) ) { // // Since there is no connection, so we need to empty the Tx Bulk out Ring. // while (atomic_read(&pAdapter->TxCount) > 0) { DBGPRINT(RT_DEBUG_ERROR, "RTUSBBulkOutDataPacket failed, snice NdisMediaStateDisconnected discard NextBulkOutIndex %d, NextIndex = %d\n", pAdapter->NextBulkOutIndex, pAdapter->NextTxIndex); FREE_TX_RING(pAdapter, pTxContext); pTxContext = &(pAdapter->TxContext[pAdapter->NextBulkOutIndex]); } NdisAcquireSpinLock(&pAdapter->BulkOutLock); pAdapter->BulkOutPending = FALSE; NdisReleaseSpinLock(&pAdapter->BulkOutLock); return; } pTxContext->IRPPending = TRUE; RTusb_fill_bulk_urb(pUrb, pAdapter->usb, usb_sndbulkpipe(pAdapter->usb, 1), pTxContext->TransferBuffer, pTxContext->BulkOutSize, RTUSBBulkOutDataPacketComplete, pTxContext); if((ret = rtusb_submit_urb(pUrb))!=0) { DBGPRINT(RT_DEBUG_ERROR,"Submit Tx URB failed %d\n", ret); return; } DBGPRINT(RT_DEBUG_INFO,"<==RTUSBBulkOutDataPacket BulkOutSize = %d\n", pTxContext->BulkOutSize); return;}/* ======================================================================== Routine Description: Arguments: Return Value: IRQL = Note: ========================================================================*/VOID RTUSBBulkOutNullFrame( IN PRT2570ADAPTER pAdapter){ PTX_CONTEXT pNullContext = &(pAdapter->NullContext); PURB pUrb; int ret = 0; NdisAcquireSpinLock(&pAdapter->BulkOutLock); if (pAdapter->BulkOutPending == TRUE) { NdisReleaseSpinLock(&pAdapter->BulkOutLock); return; } pAdapter->BulkOutPending = TRUE; NdisReleaseSpinLock(&pAdapter->BulkOutLock); // Increase Total transmit byte counter pAdapter->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize; DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutNullFrame \n"); pUrb = pNullContext->pUrb; RTusb_fill_bulk_urb(pUrb, pAdapter->usb, usb_sndbulkpipe(pAdapter->usb, 1), pNullContext->TransferBuffer, pNullContext->BulkOutSize, RTUSBBulkOutNullFrameComplete, pNullContext); if((ret = rtusb_submit_urb(pUrb))!=0) { DBGPRINT(RT_DEBUG_ERROR,"Submit Tx URB failed %d\n", ret); return; } DBGPRINT(RT_DEBUG_INFO,"<==RTUSBBulkOutDataPacket\n"); return;}/* ======================================================================== Routine Description: Arguments: Return Value: IRQL = Note: ========================================================================*/VOID RTUSBBulkOutMLMEPacket( IN PRT2570ADAPTER pAdapter, IN UCHAR Index){ PTX_CONTEXT pMLMEContext; PURB pUrb; int ret = 0; pMLMEContext = &pAdapter->MLMEContext[Index]; NdisAcquireSpinLock(&pAdapter->BulkOutLock); if (pAdapter->BulkOutPending == TRUE) { NdisReleaseSpinLock(&pAdapter->BulkOutLock); return; } pAdapter->BulkOutPending = TRUE; NdisReleaseSpinLock(&pAdapter->BulkOutLock); // Increase Total transmit byte counter pAdapter->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize; // Clear MLME bulk flag RTUSB_CLEAR_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_MLME); DBGPRINT(RT_DEBUG_INFO, "RTUSBBulkOutMLMEPacket::PrioRingFirstIndex = %d, PrioRingTxCnt = %d, PopMgmtIndex = %d, PushMgmtIndex = %d, NextMLMEIndex = %d\n", pAdapter->PrioRingFirstIndex, pAdapter->PrioRingTxCnt, pAdapter->PopMgmtIndex, pAdapter->PushMgmtIndex, pAdapter->NextMLMEIndex); pMLMEContext->IRPPending = TRUE; pUrb = pMLMEContext->pUrb; RTusb_fill_bulk_urb(pUrb, pAdapter->usb, usb_sndbulkpipe(pAdapter->usb, 1), pMLMEContext->TransferBuffer, pMLMEContext->BulkOutSize, RTUSBBulkOutMLMEPacketComplete, pMLMEContext); if((ret = rtusb_submit_urb(pUrb))!=0) { DBGPRINT(RT_DEBUG_ERROR,"Submit MLME URB failed %d\n", ret); return; } DBGPRINT(RT_DEBUG_INFO,"<==RTUSBBulkOutMLMEPacket\n"); return;}#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb,struct pt_regs *pt_regs){ PTX_CONTEXT pTxContext; PRT2570ADAPTER pAdapter; NTSTATUS status; DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutDataPacketComplete\n"); pTxContext= (PTX_CONTEXT)pUrb->context; pAdapter = pTxContext->pAdapter; status = pUrb->status; if (status == USB_ST_NOERROR) { if (pTxContext->LastOne == TRUE) { pAdapter->Counters.GoodTransmits++; FREE_TX_RING(pAdapter, pTxContext); if (!skb_queue_empty(&pAdapter->SendTxWaitQueue)) { RTUSBDeQueuePacket(pAdapter); } } else { if ((!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_REMOVE_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BULKOUT_RESET))) { FREE_TX_RING(pAdapter, pTxContext); // Indicate next one is frag data which has highest priority RTUSB_SET_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_DATA_FRAG); } else { while (pTxContext->LastOne != TRUE) { FREE_TX_RING(pAdapter, pTxContext); pTxContext = &(pAdapter->TxContext[pAdapter->NextBulkOutIndex]); } FREE_TX_RING(pAdapter, pTxContext); } } } NdisAcquireSpinLock(&pAdapter->BulkOutLock); pAdapter->BulkOutPending = FALSE; NdisReleaseSpinLock(&pAdapter->BulkOutLock); // Always call Bulk routine, even reset bulk. // The protectioon of rest bulk should be in BulkOut routine RTUSBKickBulkOut(pAdapter); }VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb,struct pt_regs *pt_regs){ PRT2570ADAPTER pAdapter; PTX_CONTEXT pNullContext; NTSTATUS status; pNullContext= (PTX_CONTEXT)pUrb->context; pAdapter = pNullContext->pAdapter; DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutNullFrameComplete\n"); // Reset Null frame context flags pNullContext->IRPPending = FALSE; pNullContext->InUse = FALSE; // Clear Null frame bulk flag RTUSB_CLEAR_BULK_FLAG(pAdapter, fRTUSB_BULK_OUT_DATA_NULL); status = pUrb->status; if (status == USB_ST_NOERROR) { // Don't worry about the queue is empty or not, this function will check itself RTUSBDeQueuePacket(pAdapter); } else { if ((!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_REMOVE_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BULKOUT_RESET))) { DBGPRINT_RAW(RT_DEBUG_ERROR, "Bulk Out Null Frame Failed\n"); RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BULKOUT_RESET); RTUSBEnqueueInternalCmd(pAdapter, RT_OID_USB_RESET_BULK_OUT); } } NdisAcquireSpinLock(&pAdapter->BulkOutLock); pAdapter->BulkOutPending = FALSE; NdisReleaseSpinLock(&pAdapter->BulkOutLock); // Always call Bulk routine, even reset bulk. // The protectioon of rest bulk should be in BulkOut routine RTUSBKickBulkOut(pAdapter); DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutNullFrameComplete\n");}VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb,struct pt_regs *pt_regs){ PTX_CONTEXT pMLMEContext; PRT2570ADAPTER pAdapter; NTSTATUS status; pMLMEContext= (PTX_CONTEXT)pUrb->context; pAdapter = pMLMEContext->pAdapter; status = pUrb->status; pAdapter->PrioRingTxCnt--; pAdapter->PrioRingFirstIndex++; if (pAdapter->PrioRingFirstIndex >= PRIO_RING_SIZE) { pAdapter->PrioRingFirstIndex = 0; } DBGPRINT(RT_DEBUG_TRACE, ":: = %d, = %d, = %d, = %d, = %d\n", pAdapter->PrioRingFirstIndex, pAdapter->PrioRingTxCnt, pAdapter->PopMgmtIndex, pAdapter->PushMgmtIndex, pAdapter->NextMLMEIndex); // Reset MLME context flags pMLMEContext->IRPPending = FALSE; pMLMEContext->InUse = FALSE; if (status == STATUS_SUCCESS) { // Don't worry about the queue is empty or not, this function will check itself RTUSBDequeueMLMEPacket(pAdapter); }#if 0 else if (status != STATUS_CANCELLED) { if ((!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_REMOVE_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BULKOUT_RESET))) { DBGPRINT_RAW(RT_DEBUG_ERROR, "Bulk Out MLME Failed\n"); RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BULKOUT_RESET); RTUSBEnqueueInternalCmd(pAdapter, RT_OID_USB_RESET_BULK_OUT); } }#endif NdisAcquireSpinLock(&pAdapter->BulkOutLock); pAdapter->BulkOutPending = FALSE; NdisReleaseSpinLock(&pAdapter->BulkOutLock); // Always call Bulk routine, even reset bulk. // The protectioon of rest bulk should be in BulkOut routine RTUSBKickBulkOut(pAdapter); DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutMLMEPacketComplete\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; PRT2570ADAPTER pAdapter; NTSTATUS status; pRxContext= (PRX_CONTEXT)pUrb->context; pAdapter = pRxContext->pAdapter; // // 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(&pAdapter->PendingRx);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -