Merge branch 'master' into next
[pandora-kernel.git] / drivers / staging / rt2870 / common / rtusb_bulk.c
1  /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
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  *************************************************************************
26
27         Module Name:
28         rtusb_bulk.c
29
30         Abstract:
31
32         Revision History:
33         Who                     When            What
34         --------        ----------      ----------------------------------------------
35         Name            Date            Modification logs
36         Paul Lin        06-25-2004      created
37
38 */
39
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};
43
44 //static BOOLEAN SingleBulkOut = FALSE;
45
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)
53 {
54
55 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
56         usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, (usb_complete_t)Complete, pContext);
57 #else
58         FILL_BULK_URB(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, Complete, pContext);
59 #endif
60
61 }
62
63 VOID    RTUSBInitTxDesc(
64         IN      PRTMP_ADAPTER   pAd,
65         IN      PTX_CONTEXT             pTxContext,
66         IN      UCHAR                   BulkOutPipeId,
67         IN      usb_complete_t  Func)
68 {
69         PURB                            pUrb;
70         PUCHAR                          pSrc = NULL;
71         POS_COOKIE                      pObj = (POS_COOKIE) pAd->OS_Cookie;
72
73         pUrb = pTxContext->pUrb;
74         ASSERT(pUrb);
75
76         // Store BulkOut PipeId
77         pTxContext->BulkOutPipeId = BulkOutPipeId;
78
79         if (pTxContext->bAggregatible)
80         {
81                 pSrc = &pTxContext->TransferBuffer->Aggregation[2];
82         }
83         else
84         {
85                 pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket;
86         }
87
88
89         //Initialize a tx bulk urb
90         RTUSB_FILL_BULK_URB(pUrb,
91                                                 pObj->pUsb_Dev,
92                                                 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
93                                                 pSrc,
94                                                 pTxContext->BulkOutSize,
95                                                 Func,
96                                                 pTxContext);
97
98 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
99         if (pTxContext->bAggregatible)
100                 pUrb->transfer_dma      = (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
101         else
102                 pUrb->transfer_dma      = pTxContext->data_dma;
103
104         pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
105 #endif
106
107 }
108
109 VOID    RTUSBInitHTTxDesc(
110         IN      PRTMP_ADAPTER   pAd,
111         IN      PHT_TX_CONTEXT  pTxContext,
112         IN      UCHAR                   BulkOutPipeId,
113         IN      ULONG                   BulkOutSize,
114         IN      usb_complete_t  Func)
115 {
116         PURB                            pUrb;
117         PUCHAR                          pSrc = NULL;
118         POS_COOKIE                      pObj = (POS_COOKIE) pAd->OS_Cookie;
119
120         pUrb = pTxContext->pUrb;
121         ASSERT(pUrb);
122
123         // Store BulkOut PipeId
124         pTxContext->BulkOutPipeId = BulkOutPipeId;
125
126         pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
127
128
129         //Initialize a tx bulk urb
130         RTUSB_FILL_BULK_URB(pUrb,
131                                                 pObj->pUsb_Dev,
132                                                 usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
133                                                 pSrc,
134                                                 BulkOutSize,
135                                                 Func,
136                                                 pTxContext);
137
138 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
139         pUrb->transfer_dma      = (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
140         pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
141 #endif
142
143 }
144
145 VOID    RTUSBInitRxDesc(
146         IN      PRTMP_ADAPTER   pAd,
147         IN      PRX_CONTEXT             pRxContext)
148 {
149         PURB                            pUrb;
150         POS_COOKIE                      pObj = (POS_COOKIE) pAd->OS_Cookie;
151         ULONG                           RX_bulk_size;
152
153
154         pUrb = pRxContext->pUrb;
155         ASSERT(pUrb);
156
157         if ( pAd->BulkInMaxPacketSize == 64)
158                 RX_bulk_size = 4096;
159         else
160                 RX_bulk_size = MAX_RXBULK_SIZE;
161
162         //Initialize a rx bulk urb
163         RTUSB_FILL_BULK_URB(pUrb,
164                                                 pObj->pUsb_Dev,
165                                                 usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
166                                                 &(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]),
167                                                 RX_bulk_size - (pAd->NextRxBulkInPosition),
168                                                 (usb_complete_t)RTUSBBulkRxComplete,
169                                                 (void *)pRxContext);
170
171 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
172         pUrb->transfer_dma      = pRxContext->data_dma + pAd->NextRxBulkInPosition;
173         pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
174 #endif
175
176
177 }
178
179 /*
180         ========================================================================
181
182         Routine Description:
183
184         Arguments:
185
186         Return Value:
187
188         Note:
189
190         ========================================================================
191 */
192
193 #define BULK_OUT_LOCK(pLock, IrqFlags)  \
194                 if(1 /*!(in_interrupt() & 0xffff0000)*/)        \
195                         RTMP_IRQ_LOCK((pLock), IrqFlags);
196
197 #define BULK_OUT_UNLOCK(pLock, IrqFlags)        \
198                 if(1 /*!(in_interrupt() & 0xffff0000)*/)        \
199                         RTMP_IRQ_UNLOCK((pLock), IrqFlags);
200
201
202 VOID    RTUSBBulkOutDataPacket(
203         IN      PRTMP_ADAPTER   pAd,
204         IN      UCHAR                   BulkOutPipeId,
205         IN      UCHAR                   Index)
206 {
207
208         PHT_TX_CONTEXT  pHTTXContext;
209         PURB                    pUrb;
210         int                             ret = 0;
211         PTXINFO_STRUC   pTxInfo, pLastTxInfo = NULL;
212         PTXWI_STRUC             pTxWI;
213         ULONG                   TmpBulkEndPos, ThisBulkSize;
214         unsigned long   IrqFlags = 0, IrqFlags2 = 0;
215         PUCHAR                  pWirelessPkt, pAppendant;
216         BOOLEAN                 bTxQLastRound = FALSE;
217         UCHAR                   allzero[4]= {0x0,0x0,0x0,0x0};
218
219         BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
220         if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
221         {
222                 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
223                 return;
224         }
225         pAd->BulkOutPending[BulkOutPipeId] = TRUE;
226
227         if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
228                 )
229         {
230                 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
231                 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
232                 return;
233         }
234         BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
235
236
237         pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
238
239         BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
240         if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)
241                 || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
242         {
243                 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
244
245                 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
246                 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
247
248                 // Clear Data flag
249                 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
250                 RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
251
252                 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
253                 return;
254         }
255
256         // Clear Data flag
257         RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
258         RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
259
260         //DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(),
261         //                                                      pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition,
262         //                                                      pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
263         pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
264         ThisBulkSize = 0;
265         TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
266         pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
267
268         if ((pHTTXContext->bCopySavePad == TRUE))
269         {
270                 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
271                 {
272                         DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x  %x  %x  %x  %x  %x  %x  %x \n",
273                                 pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
274                                 ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
275                 }
276                 NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8);
277                 pHTTXContext->bCopySavePad = FALSE;
278                 if (pAd->bForcePrintTX == TRUE)
279                         DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld.   ENextBulk = %ld.\n",   pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition));
280         }
281
282         do
283         {
284                 pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos];
285                 pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
286
287                 if (pAd->bForcePrintTX == TRUE)
288                         DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n",   pTxWI->AMPDU));
289
290                 // add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items
291                 //if ((ThisBulkSize != 0)  && (pTxWI->AMPDU == 0))
292                 if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK))
293                 {
294                         if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
295                         {
296                                 // Limit BulkOut size to about 4k bytes.
297                                 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
298                                 break;
299                         }
300                         else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0))*/)
301                         {
302                                 // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
303                                 // 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.
304                                 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
305                                 break;
306                         }
307                 }
308                 // end Iverson
309                 else
310                 {
311                         if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
312                         {       // Limit BulkOut size to about 24k bytes.
313                                 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
314                                 break;
315                         }
316                         else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0))*/)
317                         {       // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
318                                 // 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.
319                                 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
320                                 break;
321                         }
322                 }
323
324                 if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
325                 {
326                         pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
327                         break;
328                 }
329
330                 if (pTxInfo->QSEL != FIFO_EDCA)
331                 {
332                         printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL);
333                         printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad);
334                         hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
335                 }
336
337                 if (pTxInfo->USBDMATxPktLen <= 8)
338                 {
339                         BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
340                         DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
341                                         pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
342                         {
343                                 DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x  %x  %x  %x  %x  %x  %x  %x \n",
344                                         pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
345                                         ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
346                         }
347                         pAd->bForcePrintTX = TRUE;
348                         BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
349                         pAd->BulkOutPending[BulkOutPipeId] = FALSE;
350                         BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
351                         //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
352                         return;
353                 }
354
355                         // Increase Total transmit byte counter
356                 pAd->RalinkCounters.OneSecTransmittedByteCount +=  pTxWI->MPDUtotalByteCount;
357                 pAd->RalinkCounters.TransmittedByteCount +=  pTxWI->MPDUtotalByteCount;
358
359                 pLastTxInfo = pTxInfo;
360
361                 // Make sure we use EDCA QUEUE.
362                 pTxInfo->QSEL = FIFO_EDCA;
363                 ThisBulkSize += (pTxInfo->USBDMATxPktLen+4);
364                 TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4);
365
366                 if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
367                         pTxInfo->USBDMANextVLD = 1;
368
369                 if (pTxInfo->SwUseLastRound == 1)
370                 {
371                         if (pHTTXContext->CurWritePosition == 8)
372                                 pTxInfo->USBDMANextVLD = 0;
373                         pTxInfo->SwUseLastRound = 0;
374
375                         bTxQLastRound = TRUE;
376                         pHTTXContext->ENextBulkOutPosition = 8;
377
378         #ifdef RT_BIG_ENDIAN
379                         RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
380                         RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
381         #endif // RT_BIG_ENDIAN //
382
383                         break;
384                 }
385
386 #ifdef RT_BIG_ENDIAN
387                 RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
388                 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
389 #endif // RT_BIG_ENDIAN //
390
391         }while (TRUE);
392
393         // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
394         if (pLastTxInfo)
395         {
396 #ifdef RT_BIG_ENDIAN
397                 RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
398 #endif // RT_BIG_ENDIAN //
399                 pLastTxInfo->USBDMANextVLD = 0;
400 #ifdef RT_BIG_ENDIAN
401                 RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
402 #endif // RT_BIG_ENDIAN //
403         }
404
405         /*
406                 We need to copy SavedPad when following condition matched!
407                         1. Not the last round of the TxQueue and
408                         2. any match of following cases:
409                                 (1). The End Position of this bulk out is reach to the Currenct Write position and
410                                                 the TxInfo and related header already write to the CurWritePosition.
411                                         =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
412
413                                 (2). The EndPosition of the bulk out is not reach to the Current Write Position.
414                                         =>(ENextBulkOutPosition != CurWritePosition)
415         */
416         if ((bTxQLastRound == FALSE) &&
417                  (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
418                   (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
419                 )
420         {
421                 NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
422                 pHTTXContext->bCopySavePad = TRUE;
423                 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
424                 {
425                         PUCHAR  pBuf = &pHTTXContext->SavedPad[0];
426                         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",
427                                 pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
428                                 pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
429
430                         pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
431                         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]));
432                 }
433                 //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
434         }
435
436         if (pAd->bForcePrintTX == TRUE)
437                 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));
438         //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));
439
440                 // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
441         pAppendant = &pWirelessPkt[TmpBulkEndPos];
442         NdisZeroMemory(pAppendant, 8);
443                 ThisBulkSize += 4;
444                 pHTTXContext->LastOne = TRUE;
445                 if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
446                         ThisBulkSize += 4;
447         pHTTXContext->BulkOutSize = ThisBulkSize;
448
449         pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
450         BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
451
452         // Init Tx context descriptor
453         RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
454
455         pUrb = pHTTXContext->pUrb;
456         if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
457         {
458                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
459
460                 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
461                 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
462                 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
463                 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
464
465                 return;
466         }
467
468         BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
469         pHTTXContext->IRPPending = TRUE;
470         BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
471         pAd->BulkOutReq++;
472
473 }
474
475
476 VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
477 {
478 #if 0 // sample, IRQ LOCK
479         PRTMP_ADAPTER           pAd;
480         POS_COOKIE                      pObj;
481         PHT_TX_CONTEXT          pHTTXContext;
482         UCHAR                           BulkOutPipeId;
483         NTSTATUS                        Status;
484         unsigned long           IrqFlags;
485
486         DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutDataPacketComplete\n"));
487
488         pHTTXContext    = (PHT_TX_CONTEXT)pUrb->context;
489         pAd                     = pHTTXContext->pAd;
490         pObj            = (POS_COOKIE) pAd->OS_Cookie;
491         Status          = pUrb->status;
492
493         // Store BulkOut PipeId
494         BulkOutPipeId = pHTTXContext->BulkOutPipeId;
495         pAd->BulkOutDataOneSecCount++;
496
497         //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
498         //              pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
499
500         RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
501         pAd->BulkOutPending[BulkOutPipeId] = FALSE;
502         pHTTXContext->IRPPending = FALSE;
503         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
504
505         if (Status == USB_ST_NOERROR)
506         {
507                 pAd->BulkOutComplete++;
508
509                 pAd->Counters8023.GoodTransmits++;
510                 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
511                 FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
512                 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
513
514
515         }
516         else    // STATUS_OTHER
517         {
518                 PUCHAR  pBuf;
519
520                 pAd->BulkOutCompleteOther++;
521
522                 pBuf = &pHTTXContext->TransferBuffer->WirelessPacket[pHTTXContext->NextBulkOutPosition];
523
524                 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
525                 DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
526                 DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
527                 //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
528
529                 if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
530                                                                         fRTMP_ADAPTER_HALT_IN_PROGRESS |
531                                                                         fRTMP_ADAPTER_NIC_NOT_EXIST |
532                                                                         fRTMP_ADAPTER_BULKOUT_RESET)))
533                 {
534                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
535                         pAd->bulkResetPipeid = BulkOutPipeId;
536                 }
537         }
538
539         //
540         // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
541         // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
542         //
543         //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
544         if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
545                 (pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
546                 !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
547         {
548                 // Indicate There is data avaliable
549                 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
550         }
551         //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
552
553         // Always call Bulk routine, even reset bulk.
554         // The protection of rest bulk should be in BulkOut routine
555         RTUSBKickBulkOut(pAd);
556
557
558         //DBGPRINT(RT_DEBUG_LOUD,("Done-A(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d\n", BulkOutPipeId, in_interrupt(),
559         //              pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
560
561         switch (BulkOutPipeId)
562         {
563                 case 0:
564                                 pObj->ac0_dma_done_task.data = (unsigned long)pAd;
565                                 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
566                                 break;
567                 case 1:
568                                 pObj->ac1_dma_done_task.data = (unsigned long)pAd;
569                                 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
570                                 break;
571                 case 2:
572                                 pObj->ac2_dma_done_task.data = (unsigned long)pAd;
573                                 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
574                                 break;
575                 case 3:
576                                 pObj->ac3_dma_done_task.data = (unsigned long)pAd;
577                                 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
578                                 break;
579                 case 4:
580                                 pObj->hcca_dma_done_task.data = (unsigned long)pAd;
581                                 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
582                                 break;
583         }
584 #else
585
586 {
587         PHT_TX_CONTEXT  pHTTXContext;
588         PRTMP_ADAPTER   pAd;
589         POS_COOKIE              pObj;
590         UCHAR                   BulkOutPipeId;
591
592
593         pHTTXContext    = (PHT_TX_CONTEXT)pUrb->context;
594         pAd                     = pHTTXContext->pAd;
595         pObj                    = (POS_COOKIE) pAd->OS_Cookie;
596
597         // Store BulkOut PipeId
598         BulkOutPipeId   = pHTTXContext->BulkOutPipeId;
599         pAd->BulkOutDataOneSecCount++;
600
601         switch (BulkOutPipeId)
602         {
603                 case 0:
604                                 pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
605                                 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
606                                 break;
607                 case 1:
608                                 pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
609                                 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
610                                 break;
611                 case 2:
612                                 pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
613                                 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
614                                 break;
615                 case 3:
616                                 pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
617                                 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
618                                 break;
619                 case 4:
620                                 pObj->hcca_dma_done_task.data = (unsigned long)pUrb;
621                                 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
622                                 break;
623         }
624 }
625 #endif
626
627
628 }
629
630
631 /*
632         ========================================================================
633
634         Routine Description:
635
636         Arguments:
637
638         Return Value:
639
640         Note: NULL frame use BulkOutPipeId = 0
641
642         ========================================================================
643 */
644 VOID    RTUSBBulkOutNullFrame(
645         IN      PRTMP_ADAPTER   pAd)
646 {
647         PTX_CONTEXT             pNullContext = &(pAd->NullContext);
648         PURB                    pUrb;
649         int                             ret = 0;
650         unsigned long   IrqFlags;
651
652         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
653         if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
654         {
655                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
656                 return;
657         }
658         pAd->BulkOutPending[0] = TRUE;
659         pAd->watchDogTxPendingCnt[0] = 1;
660         pNullContext->IRPPending = TRUE;
661         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
662
663         // Increase Total transmit byte counter
664         pAd->RalinkCounters.TransmittedByteCount +=  pNullContext->BulkOutSize;
665
666
667         // Clear Null frame bulk flag
668         RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
669
670 #ifdef RT_BIG_ENDIAN
671         RTMPDescriptorEndianChange((PUCHAR)pNullContext->TransferBuffer, TYPE_TXINFO);
672 #endif // RT_BIG_ENDIAN //
673
674         // Init Tx context descriptor
675         RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);
676
677         pUrb = pNullContext->pUrb;
678         if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
679         {
680                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
681                 pAd->BulkOutPending[0] = FALSE;
682                 pAd->watchDogTxPendingCnt[0] = 0;
683                 pNullContext->IRPPending = FALSE;
684                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
685
686                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
687                 return;
688         }
689
690 }
691
692 // NULL frame use BulkOutPipeId = 0
693 VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
694 {
695         PRTMP_ADAPTER           pAd;
696         PTX_CONTEXT                     pNullContext;
697         NTSTATUS                        Status;
698 #if 0 // sample, IRQ LOCK
699         unsigned long           IrqFlags;
700 #endif
701         POS_COOKIE                      pObj;
702
703
704         pNullContext    = (PTX_CONTEXT)pUrb->context;
705         pAd                     = pNullContext->pAd;
706         Status                  = pUrb->status;
707
708 #if 0 // sample, IRQ LOCK
709         // Reset Null frame context flags
710         pNullContext->IRPPending        = FALSE;
711         pNullContext->InUse             = FALSE;
712
713         if (Status == USB_ST_NOERROR)
714         {
715                 // Don't worry about the queue is empty or not, this function will check itself
716                 //RTMPUSBDeQueuePacket(pAd, 0);
717                 RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
718         }
719         else    // STATUS_OTHER
720         {
721                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
722                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
723                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
724                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
725                 {
726                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed\n"));
727                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
728                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
729                 }
730         }
731
732         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
733         pAd->BulkOutPending[0] = FALSE;
734         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
735
736         // Always call Bulk routine, even reset bulk.
737         // The protectioon of rest bulk should be in BulkOut routine
738         RTUSBKickBulkOut(pAd);
739 #else
740
741         pObj = (POS_COOKIE) pAd->OS_Cookie;
742         pObj->null_frame_complete_task.data = (unsigned long)pUrb;
743         tasklet_hi_schedule(&pObj->null_frame_complete_task);
744 #endif
745
746 }
747
748 #if 0   // For RT2870, RTS frame not used now, but maybe will use it latter.
749 /*
750         ========================================================================
751
752         Routine Description:
753
754         Arguments:
755
756         Return Value:
757
758         Note: RTS frame use BulkOutPipeId = 0
759
760         ========================================================================
761 */
762 VOID    RTUSBBulkOutRTSFrame(
763         IN      PRTMP_ADAPTER   pAd)
764 {
765         PTX_CONTEXT             pRTSContext = &(pAd->RTSContext);
766         PURB                    pUrb;
767         int                             ret = 0;
768         unsigned long   IrqFlags;
769         UCHAR                   PipeID=0;
770
771         if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
772                 PipeID= 3;
773         else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
774                 PipeID= 2;
775         else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
776                 PipeID= 1;
777         else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
778                 PipeID= 0;
779
780         RTMP_IRQ_LOCK(&pAd->BulkOutLock[PipeID], IrqFlags);
781         if ((pAd->BulkOutPending[PipeID] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
782         {
783                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[PipeID], IrqFlags);
784                 return;
785         }
786         pAd->BulkOutPending[PipeID] = TRUE;
787         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[PipeID], IrqFlags);
788
789         // Increase Total transmit byte counter
790         pAd->RalinkCounters.TransmittedByteCount +=  pRTSContext->BulkOutSize;
791
792         DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutRTSFrame \n"));
793
794         // Clear RTS frame bulk flag
795         RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_RTS);
796
797 #ifdef RT_BIG_ENDIAN
798         RTMPDescriptorEndianChange((PUCHAR)pRTSContext->TransferBuffer, TYPE_TXINFO);
799 #endif // RT_BIG_ENDIAN //
800
801         // Init Tx context descriptor
802         RTUSBInitTxDesc(pAd, pRTSContext, PipeID, (usb_complete_t)RTUSBBulkOutRTSFrameComplete);
803         pRTSContext->IRPPending = TRUE;
804
805         pUrb = pRTSContext->pUrb;
806         if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
807         {
808                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutRTSFrame: Submit Tx URB failed %d\n", ret));
809                 return;
810         }
811
812         DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutRTSFrame \n"));
813
814 }
815
816 // RTS frame use BulkOutPipeId = 0
817 VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
818 {
819         PRTMP_ADAPTER   pAd;
820         PTX_CONTEXT             pRTSContext;
821         NTSTATUS                Status;
822 #if 0 // sample, IRQ LOCK
823         unsigned long   IrqFlags;
824 #endif
825         POS_COOKIE              pObj;
826
827         DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutRTSFrameComplete\n"));
828
829         pRTSContext     = (PTX_CONTEXT)pUrb->context;
830         pAd                     = pRTSContext->pAd;
831         Status          = pUrb->status;
832
833 #if 0 // sample, IRQ LOCK
834         // Reset RTS frame context flags
835         pRTSContext->IRPPending = FALSE;
836         pRTSContext->InUse              = FALSE;
837
838         if (Status == USB_ST_NOERROR)
839         {
840                 // Don't worry about the queue is empty or not, this function will check itself
841                 //RTMPUSBDeQueuePacket(pAd, pRTSContext->BulkOutPipeId);
842                 RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
843         }
844         else    // STATUS_OTHER
845         {
846                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
847                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
848                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
849                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
850                 {
851                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
852                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
853                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
854                 }
855         }
856
857         RTMP_IRQ_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId], IrqFlags);
858         pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
859         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId], IrqFlags);
860
861         // Always call Bulk routine, even reset bulk.
862         // The protectioon of rest bulk should be in BulkOut routine
863         RTUSBKickBulkOut(pAd);
864 #else
865
866         pObj = (POS_COOKIE) pAd->OS_Cookie;
867         pObj->rts_frame_complete_task.data = (unsigned long)pUrb;
868         tasklet_hi_schedule(&pObj->rts_frame_complete_task);
869 #endif
870
871         DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutRTSFrameComplete\n"));
872
873 }
874 #endif
875
876 /*
877         ========================================================================
878
879         Routine Description:
880
881         Arguments:
882
883         Return Value:
884
885         Note: MLME use BulkOutPipeId = 0
886
887         ========================================================================
888 */
889 VOID    RTUSBBulkOutMLMEPacket(
890         IN      PRTMP_ADAPTER   pAd,
891         IN      UCHAR                   Index)
892 {
893         PTX_CONTEXT             pMLMEContext;
894         PURB                    pUrb;
895         int                             ret = 0;
896         unsigned long   IrqFlags;
897
898         pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
899         pUrb = pMLMEContext->pUrb;
900
901         if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
902                 (pMLMEContext->InUse == FALSE) ||
903                 (pMLMEContext->bWaitingBulkOut == FALSE))
904         {
905
906
907                 // Clear MLME bulk flag
908                 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
909
910                 return;
911         }
912
913
914         RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
915         if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
916         {
917                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
918                 return;
919         }
920
921         pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
922         pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
923         pMLMEContext->IRPPending = TRUE;
924         pMLMEContext->bWaitingBulkOut = FALSE;
925         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
926
927         // Increase Total transmit byte counter
928         pAd->RalinkCounters.TransmittedByteCount +=  pMLMEContext->BulkOutSize;
929
930         // Clear MLME bulk flag
931         RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
932
933
934         //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacket\n"));
935 #if 0 // for debug
936 {
937         printk("MLME-Out, C=%d!, D=%d, F=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
938
939         //TODO: Need to remove it when formal release
940         PTXINFO_STRUC pTxInfo;
941
942         pTxInfo = (PTXINFO_STRUC)pMLMEContext->TransferBuffer;
943         if (pTxInfo->QSEL != FIFO_EDCA)
944         {
945                         printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL);
946                         printk("\tMLME_Index=%d!\n", Index);
947                         hex_dump("Wrong QSel Pkt:", (PUCHAR)pMLMEContext->TransferBuffer, pTxInfo->USBDMATxPktLen);
948         }
949 }
950 #endif
951
952 #ifdef RT_BIG_ENDIAN
953         RTMPDescriptorEndianChange((PUCHAR)pMLMEContext->TransferBuffer, TYPE_TXINFO);
954 #endif // RT_BIG_ENDIAN //
955
956         // Init Tx context descriptor
957         RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);
958
959 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
960         //For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
961         pUrb->transfer_dma      = 0;
962         pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
963 #endif
964
965         pUrb = pMLMEContext->pUrb;
966         if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
967         {
968                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
969                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
970                 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
971                 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
972                 pMLMEContext->IRPPending = FALSE;
973                 pMLMEContext->bWaitingBulkOut = TRUE;
974                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
975
976                 return;
977         }
978
979         //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
980 //      printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
981 }
982
983
984 VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
985 {
986         PTX_CONTEXT                     pMLMEContext;
987         PRTMP_ADAPTER           pAd;
988         NTSTATUS                        Status;
989         POS_COOKIE                      pObj;
990         int                                     index;
991 #if 0 // sample, IRQ LOCK
992         unsigned long           IrqFlags;
993         PNDIS_PACKET            pPacket;
994 #endif
995
996
997         //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
998         pMLMEContext    = (PTX_CONTEXT)pUrb->context;
999         pAd                     = pMLMEContext->pAd;
1000         pObj                    = (POS_COOKIE)pAd->OS_Cookie;
1001         Status                  = pUrb->status;
1002         index                   = pMLMEContext->SelfIdx;
1003
1004
1005 #if 0 // sample, IRQ LOCK
1006         ASSERT((pAd->MgmtRing.TxDmaIdx == index));
1007         //printk("MLME-Done-B: C=%d, D=%d, F=%d, Self=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx, pMLMEContext->SelfIdx);
1008
1009         RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1010
1011
1012         if (Status != USB_ST_NOERROR)
1013         {
1014                 //Bulk-Out fail status handle
1015                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1016                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1017                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1018                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1019                 {
1020                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
1021                         // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
1022                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1023                         pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1024                 }
1025         }
1026         pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1027         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1028
1029         RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1030         // Reset MLME context flags
1031         pMLMEContext->IRPPending = FALSE;
1032         pMLMEContext->InUse = FALSE;
1033         pMLMEContext->bWaitingBulkOut = FALSE;
1034         pMLMEContext->BulkOutSize = 0;
1035
1036         pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
1037         pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
1038
1039         // Increase MgmtRing Index
1040         INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
1041         pAd->MgmtRing.TxSwFreeIdx++;
1042
1043         RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1044
1045         // No-matter success or fail, we free the mgmt packet.
1046         if (pPacket)
1047                 RTMPFreeNdisPacket(pAd, pPacket);
1048
1049 #if 0
1050         //Bulk-Out fail status handle
1051         if (Status != USB_ST_NOERROR)
1052         {
1053                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1054                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1055                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1056                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1057                 {
1058                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
1059                         // TODO: How to handle about the MLMEBulkOut failed issue. Need to reset the endpoint?
1060                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1061                         pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1062                 }
1063         }
1064 #endif
1065
1066         //printk("MLME-Done-A: C=%d, D=%d, F=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
1067
1068         pObj->mgmt_dma_done_task.data = (unsigned long)pAd;
1069         tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
1070
1071         //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacketComplete\n"));
1072 //      printk("<---RTUSBBulkOutMLMEPacketComplete, Cpu=%d, Dma=%d, SwIdx=%d!\n",
1073 //                              pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
1074
1075 #else
1076
1077         pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
1078         tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
1079 #endif
1080 }
1081
1082
1083 /*
1084         ========================================================================
1085
1086         Routine Description:
1087
1088         Arguments:
1089
1090         Return Value:
1091
1092         Note: PsPoll use BulkOutPipeId = 0
1093
1094         ========================================================================
1095 */
1096 VOID    RTUSBBulkOutPsPoll(
1097         IN      PRTMP_ADAPTER   pAd)
1098 {
1099         PTX_CONTEXT             pPsPollContext = &(pAd->PsPollContext);
1100         PURB                    pUrb;
1101         int                             ret = 0;
1102         unsigned long   IrqFlags;
1103
1104         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
1105         if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
1106         {
1107                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1108                 return;
1109         }
1110         pAd->BulkOutPending[0] = TRUE;
1111         pAd->watchDogTxPendingCnt[0] = 1;
1112         pPsPollContext->IRPPending = TRUE;
1113         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1114
1115
1116         // Clear PS-Poll bulk flag
1117         RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
1118
1119 #ifdef RT_BIG_ENDIAN
1120         RTMPDescriptorEndianChange((PUCHAR)pPsPollContext->TransferBuffer, TYPE_TXINFO);
1121 #endif // RT_BIG_ENDIAN //
1122
1123         // Init Tx context descriptor
1124         RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);
1125
1126         pUrb = pPsPollContext->pUrb;
1127         if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1128         {
1129                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
1130                 pAd->BulkOutPending[0] = FALSE;
1131                 pAd->watchDogTxPendingCnt[0] = 0;
1132                 pPsPollContext->IRPPending = FALSE;
1133                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1134
1135                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
1136                 return;
1137         }
1138
1139 }
1140
1141 // PS-Poll frame use BulkOutPipeId = 0
1142 VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
1143 {
1144         PRTMP_ADAPTER           pAd;
1145         PTX_CONTEXT                     pPsPollContext;
1146         NTSTATUS                        Status;
1147 #if 0 // sample, IRQ LOCK
1148         unsigned long           IrqFlags;
1149 #endif
1150         POS_COOKIE                      pObj;
1151
1152
1153         pPsPollContext= (PTX_CONTEXT)pUrb->context;
1154         pAd = pPsPollContext->pAd;
1155         Status = pUrb->status;
1156
1157 #if 0 // sample, IRQ LOCK
1158         // Reset PsPoll context flags
1159         pPsPollContext->IRPPending      = FALSE;
1160         pPsPollContext->InUse           = FALSE;
1161
1162         if (Status == USB_ST_NOERROR)
1163         {
1164                 // Don't worry about the queue is empty or not, this function will check itself
1165                 RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1166         }
1167         else // STATUS_OTHER
1168         {
1169                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1170                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1171                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1172                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1173                 {
1174                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
1175                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1176                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1177                 }
1178         }
1179
1180         RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
1181         pAd->BulkOutPending[0] = FALSE;
1182         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1183
1184         // Always call Bulk routine, even reset bulk.
1185         // The protectioon of rest bulk should be in BulkOut routine
1186         RTUSBKickBulkOut(pAd);
1187 #else
1188
1189         pObj = (POS_COOKIE) pAd->OS_Cookie;
1190         pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
1191         tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
1192 #endif
1193 }
1194
1195
1196 #if 0
1197 /*
1198         ========================================================================
1199
1200         Routine Description:
1201         USB_RxPacket initializes a URB and uses the Rx IRP to submit it
1202         to USB. It checks if an Rx Descriptor is available and passes the
1203         the coresponding buffer to be filled. If no descriptor is available
1204         fails the request. When setting the completion routine we pass our
1205         Adapter Object as Context.
1206
1207         Arguments:
1208
1209         Return Value:
1210                 TRUE                    found matched tuple cache
1211                 FALSE                   no matched found
1212
1213         Note:
1214
1215         ========================================================================
1216 */
1217 VOID    RTUSBBulkReceive(
1218         IN      PRTMP_ADAPTER   pAd)
1219 {
1220         PRX_CONTEXT             pRxContext;
1221         PURB                    pUrb;
1222         int                             ret = 0;
1223         unsigned long   IrqFlags;
1224
1225
1226         /* device had been closed */
1227         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS))
1228                 return;
1229
1230         RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1231
1232         // Last is time point between 2 separate URB.
1233         if (pAd->NextRxBulkInPosition == 0)
1234         {
1235                 //pAd->NextRxBulkInIndex = (pAd->NextRxBulkInIndex + 1) % (RX_RING_SIZE);
1236                 INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
1237         }
1238         else if ((pAd->NextRxBulkInPosition&0x1ff) != 0)
1239         {
1240                 //pAd->NextRxBulkInIndex = (pAd->NextRxBulkInIndex + 1) % (RX_RING_SIZE);
1241                 INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
1242                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("pAd->NextRxBulkInPosition = 0x%lx.  End of URB.\n", pAd->NextRxBulkInPosition ));
1243                 pAd->NextRxBulkInPosition = 0;
1244         }
1245
1246         if (pAd->NextRxBulkInPosition == MAX_RXBULK_SIZE)
1247                 pAd->NextRxBulkInPosition = 0;
1248
1249         pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
1250
1251         // TODO: Why need to check if pRxContext->InUsed == TRUE?
1252         //if ((pRxContext->InUse == TRUE) || (pRxContext->Readable == TRUE))
1253         if ((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE))
1254         {
1255                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("pRxContext[%d] InUse = %d.pRxContext->Readable = %d.  Return.\n", pAd->NextRxBulkInIndex,pRxContext->InUse, pRxContext->Readable ));
1256                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1257
1258                 // read RxContext, Since not
1259 #ifdef CONFIG_STA_SUPPORT
1260                 STARxDoneInterruptHandle(pAd, TRUE);
1261 #endif // CONFIG_STA_SUPPORT //
1262
1263                 //return;
1264         }
1265         pRxContext->InUse = TRUE;
1266         pRxContext->IRPPending= TRUE;
1267
1268         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1269
1270         // Init Rx context descriptor
1271         NdisZeroMemory(pRxContext->TransferBuffer, BUFFER_SIZE);
1272         RTUSBInitRxDesc(pAd, pRxContext);
1273
1274         pUrb = pRxContext->pUrb;
1275         if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1276         {
1277                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
1278                 return;
1279         }
1280         else // success
1281         {
1282                 NdisInterlockedIncrement(&pAd->PendingRx);
1283                 pAd->BulkInReq++;
1284         }
1285
1286         // read RxContext, Since not
1287 #ifdef CONFIG_STA_SUPPORT
1288         STARxDoneInterruptHandle(pAd, FALSE);
1289 #endif // CONFIG_STA_SUPPORT //
1290 }
1291
1292 /*
1293         ========================================================================
1294
1295         Routine Description:
1296                 This routine process Rx Irp and call rx complete function.
1297
1298         Arguments:
1299                 DeviceObject    Pointer to the device object for next lower
1300                                                 device. DeviceObject passed in here belongs to
1301                                                 the next lower driver in the stack because we
1302                                                 were invoked via IoCallDriver in USB_RxPacket
1303                                                 AND it is not OUR device object
1304           Irp                           Ptr to completed IRP
1305           Context                       Ptr to our Adapter object (context specified
1306                                                 in IoSetCompletionRoutine
1307
1308         Return Value:
1309                 Always returns STATUS_MORE_PROCESSING_REQUIRED
1310
1311         Note:
1312                 Always returns STATUS_MORE_PROCESSING_REQUIRED
1313         ========================================================================
1314 */
1315 VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
1316 {
1317 #if 0
1318         PRX_CONTEXT                     pRxContext;
1319         PRTMP_ADAPTER           pAd;
1320         NTSTATUS                        Status;
1321 //      POS_COOKIE                      pObj;
1322
1323         pRxContext      = (PRX_CONTEXT)pUrb->context;
1324         pAd             = pRxContext->pAd;
1325 //      pObj            = (POS_COOKIE) pAd->OS_Cookie;
1326
1327
1328         Status = pUrb->status;
1329         //pRxContext->pIrp = NULL;
1330
1331         pRxContext->InUse = FALSE;
1332         pRxContext->IRPPending = FALSE;
1333
1334         if (Status == USB_ST_NOERROR)
1335         {
1336                 pAd->BulkInComplete++;
1337                 pRxContext->Readable = TRUE;
1338                 pAd->NextRxBulkInPosition = 0;
1339
1340         }
1341         else     // STATUS_OTHER
1342         {
1343                 pAd->BulkInCompleteFail++;
1344                 // Still read this packet although it may comtain wrong bytes.
1345                 pRxContext->Readable = FALSE;
1346                 // Parsing all packets. because after reset, the index will reset to all zero.
1347
1348                 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1349                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET)) &&
1350                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1351                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1352                 {
1353
1354                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status = %d\n", Status));
1355                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("==>NextRxBulkInIndex=0x%x, NextRxBulkInReadIndex=0x%x, TransferBufferLength= 0x%x\n",
1356                                 pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
1357
1358                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
1359                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
1360                 }
1361                 //pUrb = NULL;
1362         }
1363
1364         if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1365                 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET)) &&
1366 //              (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) &&
1367                 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) &&
1368                 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1369                 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1370         {
1371                 RTUSBBulkReceive(pAd);
1372 #if 0
1373 #if 1
1374                 STARxDoneInterruptHandle(pAd, FALSE);
1375 #else
1376                 pObj->rx_bh.data = (unsigned long)pUrb;
1377                 tasklet_schedule(&pObj->rx_bh);
1378 #endif
1379 #endif
1380         }
1381
1382         // Call RxPacket to process packet and return the status
1383         NdisInterlockedDecrement(&pAd->PendingRx);
1384 #else
1385
1386
1387         // use a receive tasklet to handle received packets;
1388         // or sometimes hardware IRQ will be disabled here, so we can not
1389         // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
1390         PRX_CONTEXT             pRxContext;
1391         PRTMP_ADAPTER   pAd;
1392         POS_COOKIE              pObj;
1393
1394
1395         pRxContext      = (PRX_CONTEXT)pUrb->context;
1396         pAd             = pRxContext->pAd;
1397         pObj            = (POS_COOKIE) pAd->OS_Cookie;
1398
1399         pObj->rx_done_task.data = (unsigned long)pUrb;
1400         tasklet_hi_schedule(&pObj->rx_done_task);
1401 #endif
1402 }
1403
1404 #else
1405
1406 VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
1407 {
1408         PRX_CONTEXT             pRxContext;
1409         PURB                    pUrb;
1410         int                             ret = 0;
1411         unsigned long   IrqFlags;
1412
1413         RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1414         pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
1415         if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
1416         {
1417                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1418                 return;
1419         }
1420         pRxContext->InUse = TRUE;
1421         pRxContext->IRPPending = TRUE;
1422         pAd->PendingRx++;
1423         pAd->BulkInReq++;
1424         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1425
1426         // Init Rx context descriptor
1427         NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
1428         RTUSBInitRxDesc(pAd, pRxContext);
1429
1430         pUrb = pRxContext->pUrb;
1431         if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1432         {       // fail
1433
1434                 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1435                 pRxContext->InUse = FALSE;
1436                 pRxContext->IRPPending = FALSE;
1437                 pAd->PendingRx--;
1438                 pAd->BulkInReq--;
1439                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1440                 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
1441         }
1442         else
1443         {       // success
1444 #if 0
1445                 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1446                 pRxContext->IRPPending = TRUE;
1447                 //NdisInterlockedIncrement(&pAd->PendingRx);
1448                 pAd->PendingRx++;
1449                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1450                 pAd->BulkInReq++;
1451 #endif
1452                 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
1453                 //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
1454         }
1455 }
1456
1457
1458 /*
1459         ========================================================================
1460
1461         Routine Description:
1462         USB_RxPacket initializes a URB and uses the Rx IRP to submit it
1463         to USB. It checks if an Rx Descriptor is available and passes the
1464         the coresponding buffer to be filled. If no descriptor is available
1465         fails the request. When setting the completion routine we pass our
1466         Adapter Object as Context.
1467
1468         Arguments:
1469
1470         Return Value:
1471                 TRUE                    found matched tuple cache
1472                 FALSE                   no matched found
1473
1474         Note:
1475
1476         ========================================================================
1477 */
1478 #define fRTMP_ADAPTER_NEED_STOP_RX              \
1479                 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
1480                  fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
1481                  fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
1482
1483 #define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX       \
1484                 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
1485                  fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
1486                  fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
1487
1488 VOID    RTUSBBulkReceive(
1489         IN      PRTMP_ADAPTER   pAd)
1490 {
1491         PRX_CONTEXT             pRxContext;
1492         unsigned long   IrqFlags;
1493
1494
1495         /* sanity check */
1496         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
1497                 return;
1498
1499         while(1)
1500         {
1501
1502                 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1503                 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
1504                 if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) &&
1505                         (pRxContext->bRxHandling == FALSE))
1506                 {
1507                         pRxContext->bRxHandling = TRUE;
1508                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1509
1510                         // read RxContext, Since not
1511 #ifdef CONFIG_STA_SUPPORT
1512                         IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1513                                 STARxDoneInterruptHandle(pAd, TRUE);
1514 #endif // CONFIG_STA_SUPPORT //
1515
1516                         // Finish to handle this bulkIn buffer.
1517                         RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1518                         pRxContext->BulkInOffset = 0;
1519                         pRxContext->Readable = FALSE;
1520                         pRxContext->bRxHandling = FALSE;
1521                         pAd->ReadPosition = 0;
1522                         pAd->TransferBufferLength = 0;
1523                         INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE);
1524                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1525
1526                 }
1527                 else
1528                 {
1529                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1530                         break;
1531                 }
1532         }
1533
1534         if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
1535                 DoBulkIn(pAd);
1536
1537 }
1538
1539
1540 /*
1541         ========================================================================
1542
1543         Routine Description:
1544                 This routine process Rx Irp and call rx complete function.
1545
1546         Arguments:
1547                 DeviceObject    Pointer to the device object for next lower
1548                                                 device. DeviceObject passed in here belongs to
1549                                                 the next lower driver in the stack because we
1550                                                 were invoked via IoCallDriver in USB_RxPacket
1551                                                 AND it is not OUR device object
1552           Irp                           Ptr to completed IRP
1553           Context                       Ptr to our Adapter object (context specified
1554                                                 in IoSetCompletionRoutine
1555
1556         Return Value:
1557                 Always returns STATUS_MORE_PROCESSING_REQUIRED
1558
1559         Note:
1560                 Always returns STATUS_MORE_PROCESSING_REQUIRED
1561         ========================================================================
1562 */
1563 VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
1564 {
1565         // use a receive tasklet to handle received packets;
1566         // or sometimes hardware IRQ will be disabled here, so we can not
1567         // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
1568         PRX_CONTEXT             pRxContext;
1569         PRTMP_ADAPTER   pAd;
1570         POS_COOKIE              pObj;
1571
1572
1573         pRxContext      = (PRX_CONTEXT)pUrb->context;
1574         pAd             = pRxContext->pAd;
1575         pObj            = (POS_COOKIE) pAd->OS_Cookie;
1576
1577         pObj->rx_done_task.data = (unsigned long)pUrb;
1578         tasklet_hi_schedule(&pObj->rx_done_task);
1579
1580 }
1581
1582 #endif
1583
1584
1585
1586 /*
1587         ========================================================================
1588
1589         Routine Description:
1590
1591         Arguments:
1592
1593         Return Value:
1594
1595         Note:
1596
1597         ========================================================================
1598 */
1599 VOID    RTUSBKickBulkOut(
1600         IN      PRTMP_ADAPTER pAd)
1601 {
1602         // BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
1603         if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
1604 #ifdef RALINK_ATE
1605                 && !(ATE_ON(pAd))
1606 #endif // RALINK_ATE //
1607                 )
1608         {
1609 #if 0   // not used now in RT28xx, but may used latter.
1610                 // 1. Data Fragment has highest priority
1611                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG))
1612                 {
1613                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1614                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1615                                 ))
1616                         {
1617                                 RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
1618                         }
1619                 }
1620                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_2))
1621                 {
1622                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1623                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1624                                 ))
1625                         {
1626                                 RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
1627                         }
1628                 }
1629                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_3))
1630                 {
1631                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1632                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1633                                 ))
1634                         {
1635                                 RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
1636                         }
1637                 }
1638                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_4))
1639                 {
1640                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1641                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1642                                 ))
1643                         {
1644                                 RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
1645                         }
1646                 }
1647 #endif
1648
1649                 // 2. PS-Poll frame is next
1650                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
1651                 {
1652                         RTUSBBulkOutPsPoll(pAd);
1653                 }
1654
1655                 // 5. Mlme frame is next
1656                 else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) &&
1657                                  (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
1658                 {
1659                         RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
1660                 }
1661
1662                 // 6. Data frame normal is next
1663                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
1664                 {
1665                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1666                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1667                                 ))
1668                         {
1669                                 RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
1670                         }
1671                 }
1672                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
1673                 {
1674                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1675                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1676                                 ))
1677                         {
1678                                 RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
1679                         }
1680                 }
1681                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
1682                 {
1683                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1684                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1685                                 ))
1686                         {
1687                                 RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
1688                         }
1689                 }
1690                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
1691                 {
1692                         if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1693                                 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1694                                 ))
1695                         {
1696                                 RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
1697                         }
1698                 }
1699
1700                 // 7. Null frame is the last
1701                 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
1702                 {
1703                         if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1704                         {
1705                                 RTUSBBulkOutNullFrame(pAd);
1706                         }
1707                 }
1708
1709                 // 8. No data avaliable
1710                 else
1711                 {
1712
1713                 }
1714         }
1715 #ifdef RALINK_ATE
1716         /* If the mode is in ATE mode. */
1717         else if((ATE_ON(pAd)) &&
1718                 !RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX))// PETER : watch out !
1719         {
1720                 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE))
1721                 {
1722                         ATE_RTUSBBulkOutDataPacket(pAd, 0);
1723                 }
1724         }
1725 #endif // RALINK_ATE //
1726
1727 }
1728
1729 /*
1730         ========================================================================
1731
1732         Routine Description:
1733         Call from Reset action after BulkOut failed.
1734         Arguments:
1735
1736         Return Value:
1737
1738         Note:
1739
1740         ========================================================================
1741 */
1742 VOID    RTUSBCleanUpDataBulkOutQueue(
1743         IN      PRTMP_ADAPTER   pAd)
1744 {
1745         UCHAR                   Idx;
1746         PHT_TX_CONTEXT  pTxContext;
1747
1748         DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
1749
1750         for (Idx = 0; Idx < 4; Idx++)
1751         {
1752                 pTxContext = &pAd->TxContext[Idx];
1753
1754                 pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
1755                 pTxContext->LastOne = FALSE;
1756                 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1757                 pAd->BulkOutPending[Idx] = FALSE;
1758                 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1759         }
1760
1761         DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
1762 }
1763
1764 /*
1765         ========================================================================
1766
1767         Routine Description:
1768
1769         Arguments:
1770
1771         Return Value:
1772
1773         Note:
1774
1775         ========================================================================
1776 */
1777 VOID    RTUSBCleanUpMLMEBulkOutQueue(
1778         IN      PRTMP_ADAPTER   pAd)
1779 {
1780         DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
1781
1782 #if 0   // Do nothing!
1783         NdisAcquireSpinLock(&pAd->MLMEBulkOutLock);
1784         while (pAd->PrioRingTxCnt > 0)
1785         {
1786                 pAd->MLMEContext[pAd->PrioRingFirstIndex].InUse = FALSE;
1787
1788                 pAd->PrioRingFirstIndex++;
1789                 if (pAd->PrioRingFirstIndex >= MGMT_RING_SIZE)
1790                 {
1791                         pAd->PrioRingFirstIndex = 0;
1792                 }
1793
1794                 pAd->PrioRingTxCnt--;
1795         }
1796         NdisReleaseSpinLock(&pAd->MLMEBulkOutLock);
1797 #endif
1798
1799         DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
1800 }
1801
1802
1803 /*
1804         ========================================================================
1805
1806         Routine Description:
1807
1808         Arguments:
1809
1810         Return Value:
1811
1812
1813         Note:
1814
1815         ========================================================================
1816 */
1817 VOID    RTUSBCancelPendingIRPs(
1818         IN      PRTMP_ADAPTER   pAd)
1819 {
1820         RTUSBCancelPendingBulkInIRP(pAd);
1821         RTUSBCancelPendingBulkOutIRP(pAd);
1822 }
1823
1824 /*
1825         ========================================================================
1826
1827         Routine Description:
1828
1829         Arguments:
1830
1831         Return Value:
1832
1833         Note:
1834
1835         ========================================================================
1836 */
1837 VOID    RTUSBCancelPendingBulkInIRP(
1838         IN      PRTMP_ADAPTER   pAd)
1839 {
1840         PRX_CONTEXT             pRxContext;
1841         UINT                    i;
1842
1843         DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
1844         for ( i = 0; i < (RX_RING_SIZE); i++)
1845         {
1846                 pRxContext = &(pAd->RxContext[i]);
1847                 if(pRxContext->IRPPending == TRUE)
1848                 {
1849                         RTUSB_UNLINK_URB(pRxContext->pUrb);
1850                         pRxContext->IRPPending = FALSE;
1851                         pRxContext->InUse = FALSE;
1852                         //NdisInterlockedDecrement(&pAd->PendingRx);
1853                         //pAd->PendingRx--;
1854                 }
1855         }
1856         DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
1857 }
1858
1859
1860 /*
1861         ========================================================================
1862
1863         Routine Description:
1864
1865         Arguments:
1866
1867         Return Value:
1868
1869         Note:
1870
1871         ========================================================================
1872 */
1873 VOID    RTUSBCancelPendingBulkOutIRP(
1874         IN      PRTMP_ADAPTER   pAd)
1875 {
1876         PHT_TX_CONTEXT          pHTTXContext;
1877         PTX_CONTEXT                     pMLMEContext;
1878         PTX_CONTEXT                     pBeaconContext;
1879         PTX_CONTEXT                     pNullContext;
1880         PTX_CONTEXT                     pPsPollContext;
1881         PTX_CONTEXT                     pRTSContext;
1882         UINT                            i, Idx;
1883 //      unsigned int            IrqFlags;
1884 //      NDIS_SPIN_LOCK          *pLock;
1885 //      BOOLEAN                         *pPending;
1886
1887
1888 //      pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
1889 //      pPending = &pAd->BulkOutPending[MGMTPIPEIDX];
1890
1891         for (Idx = 0; Idx < 4; Idx++)
1892         {
1893                 pHTTXContext = &(pAd->TxContext[Idx]);
1894
1895                 if (pHTTXContext->IRPPending == TRUE)
1896                 {
1897
1898                         // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1899                         // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1900                         //      when the last IRP on the list has been  cancelled; that's how we exit this loop
1901                         //
1902
1903                         RTUSB_UNLINK_URB(pHTTXContext->pUrb);
1904
1905                         // Sleep 200 microseconds to give cancellation time to work
1906                         RTMPusecDelay(200);
1907                 }
1908
1909 #ifdef RALINK_ATE
1910                 pHTTXContext->bCopySavePad = 0;
1911                 pHTTXContext->CurWritePosition = 0;
1912                 pHTTXContext->CurWriteRealPos = 0;
1913                 pHTTXContext->bCurWriting = FALSE;
1914                 pHTTXContext->NextBulkOutPosition = 0;
1915                 pHTTXContext->ENextBulkOutPosition = 0;
1916 #endif // RALINK_ATE //
1917                 pAd->BulkOutPending[Idx] = FALSE;
1918         }
1919
1920         //RTMP_IRQ_LOCK(pLock, IrqFlags);
1921         for (i = 0; i < MGMT_RING_SIZE; i++)
1922         {
1923                 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
1924                 if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
1925                 {
1926
1927                         // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1928                         // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1929                         //      when the last IRP on the list has been  cancelled; that's how we exit this loop
1930                         //
1931
1932                         RTUSB_UNLINK_URB(pMLMEContext->pUrb);
1933                         pMLMEContext->IRPPending = FALSE;
1934
1935                         // Sleep 200 microsecs to give cancellation time to work
1936                         RTMPusecDelay(200);
1937                 }
1938         }
1939         pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1940         //RTMP_IRQ_UNLOCK(pLock, IrqFlags);
1941
1942
1943         for (i = 0; i < BEACON_RING_SIZE; i++)
1944         {
1945                 pBeaconContext = &(pAd->BeaconContext[i]);
1946
1947                 if(pBeaconContext->IRPPending == TRUE)
1948                 {
1949
1950                         // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1951                         // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1952                         //      when the last IRP on the list has been  cancelled; that's how we exit this loop
1953                         //
1954
1955                         RTUSB_UNLINK_URB(pBeaconContext->pUrb);
1956
1957                         // Sleep 200 microsecs to give cancellation time to work
1958                         RTMPusecDelay(200);
1959                 }
1960         }
1961
1962         pNullContext = &(pAd->NullContext);
1963         if (pNullContext->IRPPending == TRUE)
1964                 RTUSB_UNLINK_URB(pNullContext->pUrb);
1965
1966         pRTSContext = &(pAd->RTSContext);
1967         if (pRTSContext->IRPPending == TRUE)
1968                 RTUSB_UNLINK_URB(pRTSContext->pUrb);
1969
1970         pPsPollContext = &(pAd->PsPollContext);
1971         if (pPsPollContext->IRPPending == TRUE)
1972                 RTUSB_UNLINK_URB(pPsPollContext->pUrb);
1973
1974         for (Idx = 0; Idx < 4; Idx++)
1975         {
1976                 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1977                 pAd->BulkOutPending[Idx] = FALSE;
1978                 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1979         }
1980 }
1981