?? 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.
*
* 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_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
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 + -