Staging: rt2870: add fRTUSB_BULK_OUT_DATA_NORMAL_5 quirk
[linux-2.6/linux-2.6-openrd.git] / drivers / staging / rt2870 / common / rtusb_bulk.c
bloba4244b516440f8461f1a85ebc006a2151a1b72ee
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
27 Module Name:
28 rtusb_bulk.c
30 Abstract:
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 Paul Lin 06-25-2004 created
40 #include "../rt_config.h"
41 // Match total 6 bulkout endpoint to corresponding queue.
42 UCHAR EpToQueue[6]={FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT};
44 //static BOOLEAN SingleBulkOut = FALSE;
46 void RTUSB_FILL_BULK_URB (struct urb *pUrb,
47 struct usb_device *pUsb_Dev,
48 unsigned int bulkpipe,
49 void *pTransferBuf,
50 int BufSize,
51 usb_complete_t Complete,
52 void *pContext)
55 usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, (usb_complete_t)Complete, pContext);
59 VOID RTUSBInitTxDesc(
60 IN PRTMP_ADAPTER pAd,
61 IN PTX_CONTEXT pTxContext,
62 IN UCHAR BulkOutPipeId,
63 IN usb_complete_t Func)
65 PURB pUrb;
66 PUCHAR pSrc = NULL;
67 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
69 pUrb = pTxContext->pUrb;
70 ASSERT(pUrb);
72 // Store BulkOut PipeId
73 pTxContext->BulkOutPipeId = BulkOutPipeId;
75 if (pTxContext->bAggregatible)
77 pSrc = &pTxContext->TransferBuffer->Aggregation[2];
79 else
81 pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket;
85 //Initialize a tx bulk urb
86 RTUSB_FILL_BULK_URB(pUrb,
87 pObj->pUsb_Dev,
88 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
89 pSrc,
90 pTxContext->BulkOutSize,
91 Func,
92 pTxContext);
94 if (pTxContext->bAggregatible)
95 pUrb->transfer_dma = (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
96 else
97 pUrb->transfer_dma = pTxContext->data_dma;
99 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
103 VOID RTUSBInitHTTxDesc(
104 IN PRTMP_ADAPTER pAd,
105 IN PHT_TX_CONTEXT pTxContext,
106 IN UCHAR BulkOutPipeId,
107 IN ULONG BulkOutSize,
108 IN usb_complete_t Func)
110 PURB pUrb;
111 PUCHAR pSrc = NULL;
112 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
114 pUrb = pTxContext->pUrb;
115 ASSERT(pUrb);
117 // Store BulkOut PipeId
118 pTxContext->BulkOutPipeId = BulkOutPipeId;
120 pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
123 //Initialize a tx bulk urb
124 RTUSB_FILL_BULK_URB(pUrb,
125 pObj->pUsb_Dev,
126 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
127 pSrc,
128 BulkOutSize,
129 Func,
130 pTxContext);
132 pUrb->transfer_dma = (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
133 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
137 VOID RTUSBInitRxDesc(
138 IN PRTMP_ADAPTER pAd,
139 IN PRX_CONTEXT pRxContext)
141 PURB pUrb;
142 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
143 ULONG RX_bulk_size;
146 pUrb = pRxContext->pUrb;
147 ASSERT(pUrb);
149 if ( pAd->BulkInMaxPacketSize == 64)
150 RX_bulk_size = 4096;
151 else
152 RX_bulk_size = MAX_RXBULK_SIZE;
154 //Initialize a rx bulk urb
155 RTUSB_FILL_BULK_URB(pUrb,
156 pObj->pUsb_Dev,
157 usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
158 &(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]),
159 RX_bulk_size - (pAd->NextRxBulkInPosition),
160 (usb_complete_t)RTUSBBulkRxComplete,
161 (void *)pRxContext);
163 pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition;
164 pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
170 ========================================================================
172 Routine Description:
174 Arguments:
176 Return Value:
178 Note:
180 ========================================================================
183 #define BULK_OUT_LOCK(pLock, IrqFlags) \
184 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
185 RTMP_IRQ_LOCK((pLock), IrqFlags);
187 #define BULK_OUT_UNLOCK(pLock, IrqFlags) \
188 if(1 /*!(in_interrupt() & 0xffff0000)*/) \
189 RTMP_IRQ_UNLOCK((pLock), IrqFlags);
192 VOID RTUSBBulkOutDataPacket(
193 IN PRTMP_ADAPTER pAd,
194 IN UCHAR BulkOutPipeId,
195 IN UCHAR Index)
198 PHT_TX_CONTEXT pHTTXContext;
199 PURB pUrb;
200 int ret = 0;
201 PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL;
202 PTXWI_STRUC pTxWI;
203 ULONG TmpBulkEndPos, ThisBulkSize;
204 unsigned long IrqFlags = 0, IrqFlags2 = 0;
205 PUCHAR pWirelessPkt, pAppendant;
206 BOOLEAN bTxQLastRound = FALSE;
207 UCHAR allzero[4]= {0x0,0x0,0x0,0x0};
209 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
210 if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
212 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
213 return;
215 pAd->BulkOutPending[BulkOutPipeId] = TRUE;
217 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
220 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
221 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
222 return;
224 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
227 pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
229 BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
230 if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)
231 || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
233 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
235 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
236 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
238 // Clear Data flag
239 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
240 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
242 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
243 return;
246 // Clear Data flag
247 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
248 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
250 //DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(),
251 // pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition,
252 // pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
253 pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
254 ThisBulkSize = 0;
255 TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
256 pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
258 if ((pHTTXContext->bCopySavePad == TRUE))
260 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
262 DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n",
263 pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
264 ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
266 NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8);
267 pHTTXContext->bCopySavePad = FALSE;
268 if (pAd->bForcePrintTX == TRUE)
269 DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition));
274 pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos];
275 pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
277 if (pAd->bForcePrintTX == TRUE)
278 DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU));
280 // add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items
281 //if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0))
282 if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK))
284 if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
286 // Limit BulkOut size to about 4k bytes.
287 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
288 break;
290 else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
292 // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
293 // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
294 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
295 break;
298 // end Iverson
299 else
301 if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
302 { // Limit BulkOut size to about 24k bytes.
303 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
304 break;
306 else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
307 { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
308 // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
309 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
310 break;
314 if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
316 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
317 break;
320 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
321 if (pTxInfo->QSEL != FIFO_EDCA)
323 printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL);
324 printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad);
325 hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
328 if (pTxInfo->USBDMATxPktLen <= 8)
330 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
331 DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
332 pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
334 DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n",
335 pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
336 ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
338 pAd->bForcePrintTX = TRUE;
339 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
340 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
341 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
342 //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
343 return;
346 // Increase Total transmit byte counter
347 pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount;
348 pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount;
350 pLastTxInfo = pTxInfo;
352 // Make sure we use EDCA QUEUE.
353 pTxInfo->QSEL = FIFO_EDCA; //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
354 ThisBulkSize += (pTxInfo->USBDMATxPktLen+4);
355 TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4);
357 if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
358 pTxInfo->USBDMANextVLD = 1;
360 if (pTxInfo->SwUseLastRound == 1)
362 if (pHTTXContext->CurWritePosition == 8)
363 pTxInfo->USBDMANextVLD = 0;
364 pTxInfo->SwUseLastRound = 0;
366 bTxQLastRound = TRUE;
367 pHTTXContext->ENextBulkOutPosition = 8;
369 break;
371 }while (TRUE);
373 // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
374 if (pLastTxInfo)
376 pLastTxInfo->USBDMANextVLD = 0;
380 We need to copy SavedPad when following condition matched!
381 1. Not the last round of the TxQueue and
382 2. any match of following cases:
383 (1). The End Position of this bulk out is reach to the Currenct Write position and
384 the TxInfo and related header already write to the CurWritePosition.
385 =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
387 (2). The EndPosition of the bulk out is not reach to the Current Write Position.
388 =>(ENextBulkOutPosition != CurWritePosition)
390 if ((bTxQLastRound == FALSE) &&
391 (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
392 (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
395 NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
396 pHTTXContext->bCopySavePad = TRUE;
397 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
399 PUCHAR pBuf = &pHTTXContext->SavedPad[0];
400 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",
401 pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
402 pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
404 pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
405 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]));
407 //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
410 if (pAd->bForcePrintTX == TRUE)
411 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));
412 //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));
414 // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
415 pAppendant = &pWirelessPkt[TmpBulkEndPos];
416 NdisZeroMemory(pAppendant, 8);
417 ThisBulkSize += 4;
418 pHTTXContext->LastOne = TRUE;
419 if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
420 ThisBulkSize += 4;
421 pHTTXContext->BulkOutSize = ThisBulkSize;
423 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
424 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
426 // Init Tx context descriptor
427 RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
429 pUrb = pHTTXContext->pUrb;
430 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
432 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
434 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
435 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
436 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
437 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
439 return;
442 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
443 pHTTXContext->IRPPending = TRUE;
444 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
445 pAd->BulkOutReq++;
450 VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
452 PHT_TX_CONTEXT pHTTXContext;
453 PRTMP_ADAPTER pAd;
454 POS_COOKIE pObj;
455 UCHAR BulkOutPipeId;
458 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
459 pAd = pHTTXContext->pAd;
460 pObj = (POS_COOKIE) pAd->OS_Cookie;
462 // Store BulkOut PipeId
463 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
464 pAd->BulkOutDataOneSecCount++;
466 switch (BulkOutPipeId)
468 case 0:
469 pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
470 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
471 break;
472 case 1:
473 pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
474 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
475 break;
476 case 2:
477 pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
478 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
479 break;
480 case 3:
481 pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
482 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
483 break;
484 case 4:
485 pObj->hcca_dma_done_task.data = (unsigned long)pUrb;
486 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
487 break;
493 ========================================================================
495 Routine Description:
497 Arguments:
499 Return Value:
501 Note: NULL frame use BulkOutPipeId = 0
503 ========================================================================
505 VOID RTUSBBulkOutNullFrame(
506 IN PRTMP_ADAPTER pAd)
508 PTX_CONTEXT pNullContext = &(pAd->NullContext);
509 PURB pUrb;
510 int ret = 0;
511 unsigned long IrqFlags;
513 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
514 if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
516 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
517 return;
519 pAd->BulkOutPending[0] = TRUE;
520 pAd->watchDogTxPendingCnt[0] = 1;
521 pNullContext->IRPPending = TRUE;
522 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
524 // Increase Total transmit byte counter
525 pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
528 // Clear Null frame bulk flag
529 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
531 // Init Tx context descriptor
532 RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);
534 pUrb = pNullContext->pUrb;
535 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
537 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
538 pAd->BulkOutPending[0] = FALSE;
539 pAd->watchDogTxPendingCnt[0] = 0;
540 pNullContext->IRPPending = FALSE;
541 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
543 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
544 return;
549 // NULL frame use BulkOutPipeId = 0
550 VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
552 PRTMP_ADAPTER pAd;
553 PTX_CONTEXT pNullContext;
554 NTSTATUS Status;
555 POS_COOKIE pObj;
558 pNullContext = (PTX_CONTEXT)pUrb->context;
559 pAd = pNullContext->pAd;
560 Status = pUrb->status;
562 pObj = (POS_COOKIE) pAd->OS_Cookie;
563 pObj->null_frame_complete_task.data = (unsigned long)pUrb;
564 tasklet_hi_schedule(&pObj->null_frame_complete_task);
568 ========================================================================
570 Routine Description:
572 Arguments:
574 Return Value:
576 Note: MLME use BulkOutPipeId = 0
578 ========================================================================
580 VOID RTUSBBulkOutMLMEPacket(
581 IN PRTMP_ADAPTER pAd,
582 IN UCHAR Index)
584 PTX_CONTEXT pMLMEContext;
585 PURB pUrb;
586 int ret = 0;
587 unsigned long IrqFlags;
589 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
590 pUrb = pMLMEContext->pUrb;
592 if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
593 (pMLMEContext->InUse == FALSE) ||
594 (pMLMEContext->bWaitingBulkOut == FALSE))
598 // Clear MLME bulk flag
599 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
601 return;
605 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
606 if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
608 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
609 return;
612 pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
613 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
614 pMLMEContext->IRPPending = TRUE;
615 pMLMEContext->bWaitingBulkOut = FALSE;
616 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
618 // Increase Total transmit byte counter
619 pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
621 // Clear MLME bulk flag
622 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
624 // Init Tx context descriptor
625 RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);
627 //For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
628 pUrb->transfer_dma = 0;
629 pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
631 pUrb = pMLMEContext->pUrb;
632 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
634 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
635 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
636 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
637 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
638 pMLMEContext->IRPPending = FALSE;
639 pMLMEContext->bWaitingBulkOut = TRUE;
640 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
642 return;
645 //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
646 // printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
650 VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
652 PTX_CONTEXT pMLMEContext;
653 PRTMP_ADAPTER pAd;
654 NTSTATUS Status;
655 POS_COOKIE pObj;
656 int index;
658 //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
659 pMLMEContext = (PTX_CONTEXT)pUrb->context;
660 pAd = pMLMEContext->pAd;
661 pObj = (POS_COOKIE)pAd->OS_Cookie;
662 Status = pUrb->status;
663 index = pMLMEContext->SelfIdx;
665 pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
666 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
671 ========================================================================
673 Routine Description:
675 Arguments:
677 Return Value:
679 Note: PsPoll use BulkOutPipeId = 0
681 ========================================================================
683 VOID RTUSBBulkOutPsPoll(
684 IN PRTMP_ADAPTER pAd)
686 PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
687 PURB pUrb;
688 int ret = 0;
689 unsigned long IrqFlags;
691 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
692 if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
694 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
695 return;
697 pAd->BulkOutPending[0] = TRUE;
698 pAd->watchDogTxPendingCnt[0] = 1;
699 pPsPollContext->IRPPending = TRUE;
700 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
703 // Clear PS-Poll bulk flag
704 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
706 // Init Tx context descriptor
707 RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);
709 pUrb = pPsPollContext->pUrb;
710 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
712 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
713 pAd->BulkOutPending[0] = FALSE;
714 pAd->watchDogTxPendingCnt[0] = 0;
715 pPsPollContext->IRPPending = FALSE;
716 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
718 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
719 return;
724 // PS-Poll frame use BulkOutPipeId = 0
725 VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
727 PRTMP_ADAPTER pAd;
728 PTX_CONTEXT pPsPollContext;
729 NTSTATUS Status;
730 POS_COOKIE pObj;
733 pPsPollContext= (PTX_CONTEXT)pUrb->context;
734 pAd = pPsPollContext->pAd;
735 Status = pUrb->status;
737 pObj = (POS_COOKIE) pAd->OS_Cookie;
738 pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
739 tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
742 VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
744 PRX_CONTEXT pRxContext;
745 PURB pUrb;
746 int ret = 0;
747 unsigned long IrqFlags;
749 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
750 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
751 if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
753 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
754 return;
756 pRxContext->InUse = TRUE;
757 pRxContext->IRPPending = TRUE;
758 pAd->PendingRx++;
759 pAd->BulkInReq++;
760 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
762 // Init Rx context descriptor
763 NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
764 RTUSBInitRxDesc(pAd, pRxContext);
766 pUrb = pRxContext->pUrb;
767 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
768 { // fail
770 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
771 pRxContext->InUse = FALSE;
772 pRxContext->IRPPending = FALSE;
773 pAd->PendingRx--;
774 pAd->BulkInReq--;
775 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
776 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
778 else
779 { // success
780 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
781 //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
787 ========================================================================
789 Routine Description:
790 USB_RxPacket initializes a URB and uses the Rx IRP to submit it
791 to USB. It checks if an Rx Descriptor is available and passes the
792 the coresponding buffer to be filled. If no descriptor is available
793 fails the request. When setting the completion routine we pass our
794 Adapter Object as Context.
796 Arguments:
798 Return Value:
799 TRUE found matched tuple cache
800 FALSE no matched found
802 Note:
804 ========================================================================
806 #define fRTMP_ADAPTER_NEED_STOP_RX \
807 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
808 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
809 fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
811 #define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \
812 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
813 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
814 fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
816 VOID RTUSBBulkReceive(
817 IN PRTMP_ADAPTER pAd)
819 PRX_CONTEXT pRxContext;
820 unsigned long IrqFlags;
823 /* sanity check */
824 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
825 return;
827 while(1)
830 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
831 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
832 if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) &&
833 (pRxContext->bRxHandling == FALSE))
835 pRxContext->bRxHandling = TRUE;
836 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
838 // read RxContext, Since not
839 STARxDoneInterruptHandle(pAd, TRUE);
841 // Finish to handle this bulkIn buffer.
842 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
843 pRxContext->BulkInOffset = 0;
844 pRxContext->Readable = FALSE;
845 pRxContext->bRxHandling = FALSE;
846 pAd->ReadPosition = 0;
847 pAd->TransferBufferLength = 0;
848 INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE);
849 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
852 else
854 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
855 break;
859 if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
860 DoBulkIn(pAd);
866 ========================================================================
868 Routine Description:
869 This routine process Rx Irp and call rx complete function.
871 Arguments:
872 DeviceObject Pointer to the device object for next lower
873 device. DeviceObject passed in here belongs to
874 the next lower driver in the stack because we
875 were invoked via IoCallDriver in USB_RxPacket
876 AND it is not OUR device object
877 Irp Ptr to completed IRP
878 Context Ptr to our Adapter object (context specified
879 in IoSetCompletionRoutine
881 Return Value:
882 Always returns STATUS_MORE_PROCESSING_REQUIRED
884 Note:
885 Always returns STATUS_MORE_PROCESSING_REQUIRED
886 ========================================================================
888 VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
890 // use a receive tasklet to handle received packets;
891 // or sometimes hardware IRQ will be disabled here, so we can not
892 // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
893 PRX_CONTEXT pRxContext;
894 PRTMP_ADAPTER pAd;
895 POS_COOKIE pObj;
898 pRxContext = (PRX_CONTEXT)pUrb->context;
899 pAd = pRxContext->pAd;
900 pObj = (POS_COOKIE) pAd->OS_Cookie;
902 pObj->rx_done_task.data = (unsigned long)pUrb;
903 tasklet_hi_schedule(&pObj->rx_done_task);
910 ========================================================================
912 Routine Description:
914 Arguments:
916 Return Value:
918 Note:
920 ========================================================================
922 VOID RTUSBKickBulkOut(
923 IN PRTMP_ADAPTER pAd)
925 // BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
926 if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
929 // 2. PS-Poll frame is next
930 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
932 RTUSBBulkOutPsPoll(pAd);
935 // 5. Mlme frame is next
936 else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) &&
937 (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
939 RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
942 // 6. Data frame normal is next
943 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
945 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
946 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
949 RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
952 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
954 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
955 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
958 RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
961 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
963 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
964 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
967 RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
970 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
972 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
973 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
976 RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
980 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
981 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_5))
983 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
984 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
990 // 7. Null frame is the last
991 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
993 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
995 RTUSBBulkOutNullFrame(pAd);
999 // 8. No data avaliable
1000 else
1008 ========================================================================
1010 Routine Description:
1011 Call from Reset action after BulkOut failed.
1012 Arguments:
1014 Return Value:
1016 Note:
1018 ========================================================================
1020 VOID RTUSBCleanUpDataBulkOutQueue(
1021 IN PRTMP_ADAPTER pAd)
1023 UCHAR Idx;
1024 PHT_TX_CONTEXT pTxContext;
1026 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
1028 for (Idx = 0; Idx < 4; Idx++)
1030 pTxContext = &pAd->TxContext[Idx];
1032 pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
1033 pTxContext->LastOne = FALSE;
1034 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1035 pAd->BulkOutPending[Idx] = FALSE;
1036 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1039 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
1043 ========================================================================
1045 Routine Description:
1047 Arguments:
1049 Return Value:
1051 Note:
1053 ========================================================================
1055 VOID RTUSBCleanUpMLMEBulkOutQueue(
1056 IN PRTMP_ADAPTER pAd)
1058 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
1059 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
1064 ========================================================================
1066 Routine Description:
1068 Arguments:
1070 Return Value:
1073 Note:
1075 ========================================================================
1077 VOID RTUSBCancelPendingIRPs(
1078 IN PRTMP_ADAPTER pAd)
1080 RTUSBCancelPendingBulkInIRP(pAd);
1081 RTUSBCancelPendingBulkOutIRP(pAd);
1085 ========================================================================
1087 Routine Description:
1089 Arguments:
1091 Return Value:
1093 Note:
1095 ========================================================================
1097 VOID RTUSBCancelPendingBulkInIRP(
1098 IN PRTMP_ADAPTER pAd)
1100 PRX_CONTEXT pRxContext;
1101 UINT i;
1103 DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
1104 for ( i = 0; i < (RX_RING_SIZE); i++)
1106 pRxContext = &(pAd->RxContext[i]);
1107 if(pRxContext->IRPPending == TRUE)
1109 RTUSB_UNLINK_URB(pRxContext->pUrb);
1110 pRxContext->IRPPending = FALSE;
1111 pRxContext->InUse = FALSE;
1112 //NdisInterlockedDecrement(&pAd->PendingRx);
1113 //pAd->PendingRx--;
1116 DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
1121 ========================================================================
1123 Routine Description:
1125 Arguments:
1127 Return Value:
1129 Note:
1131 ========================================================================
1133 VOID RTUSBCancelPendingBulkOutIRP(
1134 IN PRTMP_ADAPTER pAd)
1136 PHT_TX_CONTEXT pHTTXContext;
1137 PTX_CONTEXT pMLMEContext;
1138 PTX_CONTEXT pBeaconContext;
1139 PTX_CONTEXT pNullContext;
1140 PTX_CONTEXT pPsPollContext;
1141 PTX_CONTEXT pRTSContext;
1142 UINT i, Idx;
1143 // unsigned int IrqFlags;
1144 // NDIS_SPIN_LOCK *pLock;
1145 // BOOLEAN *pPending;
1148 // pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
1149 // pPending = &pAd->BulkOutPending[MGMTPIPEIDX];
1151 for (Idx = 0; Idx < 4; Idx++)
1153 pHTTXContext = &(pAd->TxContext[Idx]);
1155 if (pHTTXContext->IRPPending == TRUE)
1158 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1159 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1160 // when the last IRP on the list has been cancelled; that's how we exit this loop
1163 RTUSB_UNLINK_URB(pHTTXContext->pUrb);
1165 // Sleep 200 microseconds to give cancellation time to work
1166 RTMPusecDelay(200);
1169 pAd->BulkOutPending[Idx] = FALSE;
1172 //RTMP_IRQ_LOCK(pLock, IrqFlags);
1173 for (i = 0; i < MGMT_RING_SIZE; i++)
1175 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
1176 if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
1179 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1180 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1181 // when the last IRP on the list has been cancelled; that's how we exit this loop
1184 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
1185 pMLMEContext->IRPPending = FALSE;
1187 // Sleep 200 microsecs to give cancellation time to work
1188 RTMPusecDelay(200);
1191 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1192 //RTMP_IRQ_UNLOCK(pLock, IrqFlags);
1195 for (i = 0; i < BEACON_RING_SIZE; i++)
1197 pBeaconContext = &(pAd->BeaconContext[i]);
1199 if(pBeaconContext->IRPPending == TRUE)
1202 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1203 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1204 // when the last IRP on the list has been cancelled; that's how we exit this loop
1207 RTUSB_UNLINK_URB(pBeaconContext->pUrb);
1209 // Sleep 200 microsecs to give cancellation time to work
1210 RTMPusecDelay(200);
1214 pNullContext = &(pAd->NullContext);
1215 if (pNullContext->IRPPending == TRUE)
1216 RTUSB_UNLINK_URB(pNullContext->pUrb);
1218 pRTSContext = &(pAd->RTSContext);
1219 if (pRTSContext->IRPPending == TRUE)
1220 RTUSB_UNLINK_URB(pRTSContext->pUrb);
1222 pPsPollContext = &(pAd->PsPollContext);
1223 if (pPsPollContext->IRPPending == TRUE)
1224 RTUSB_UNLINK_URB(pPsPollContext->pUrb);
1226 for (Idx = 0; Idx < 4; Idx++)
1228 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1229 pAd->BulkOutPending[Idx] = FALSE;
1230 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);