Commit | Line | Data |
---|---|---|
ca97b838 | 1 | /* |
c55519ff GKH |
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 | ||
ca97b838 BZ |
40 | #ifdef RTMP_MAC_USB |
41 | ||
c55519ff | 42 | #include "../rt_config.h" |
9f548a2a | 43 | /* Match total 6 bulkout endpoint to corresponding queue. */ |
51126deb | 44 | u8 EpToQueue[6] = |
66cd8d6e | 45 | { FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT }; |
c55519ff | 46 | |
9f548a2a | 47 | /*static BOOLEAN SingleBulkOut = FALSE; */ |
c55519ff | 48 | |
66cd8d6e BZ |
49 | void RTUSB_FILL_BULK_URB(struct urb *pUrb, |
50 | struct usb_device *pUsb_Dev, | |
51 | unsigned int bulkpipe, | |
52 | void *pTransferBuf, | |
53 | int BufSize, usb_complete_t Complete, void *pContext) | |
c55519ff GKH |
54 | { |
55 | ||
66cd8d6e BZ |
56 | usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, |
57 | (usb_complete_t) Complete, pContext); | |
c55519ff GKH |
58 | |
59 | } | |
60 | ||
62eb734b BZ |
61 | void RTUSBInitTxDesc(struct rt_rtmp_adapter *pAd, |
62 | struct rt_tx_context *pTxContext, | |
51126deb | 63 | u8 BulkOutPipeId, IN usb_complete_t Func) |
c55519ff | 64 | { |
66cd8d6e | 65 | PURB pUrb; |
51126deb | 66 | u8 *pSrc = NULL; |
8a10a546 | 67 | struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; |
c55519ff GKH |
68 | |
69 | pUrb = pTxContext->pUrb; | |
70 | ASSERT(pUrb); | |
71 | ||
9f548a2a | 72 | /* Store BulkOut PipeId */ |
c55519ff GKH |
73 | pTxContext->BulkOutPipeId = BulkOutPipeId; |
74 | ||
66cd8d6e | 75 | if (pTxContext->bAggregatible) { |
c55519ff | 76 | pSrc = &pTxContext->TransferBuffer->Aggregation[2]; |
66cd8d6e BZ |
77 | } else { |
78 | pSrc = | |
51126deb | 79 | (u8 *)pTxContext->TransferBuffer->field.WirelessPacket; |
c55519ff GKH |
80 | } |
81 | ||
9f548a2a | 82 | /*Initialize a tx bulk urb */ |
c55519ff | 83 | RTUSB_FILL_BULK_URB(pUrb, |
66cd8d6e BZ |
84 | pObj->pUsb_Dev, |
85 | usb_sndbulkpipe(pObj->pUsb_Dev, | |
86 | pAd->BulkOutEpAddr[BulkOutPipeId]), | |
87 | pSrc, pTxContext->BulkOutSize, Func, pTxContext); | |
c55519ff | 88 | |
c55519ff | 89 | if (pTxContext->bAggregatible) |
66cd8d6e BZ |
90 | pUrb->transfer_dma = |
91 | (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2); | |
c55519ff | 92 | else |
66cd8d6e | 93 | pUrb->transfer_dma = pTxContext->data_dma; |
c55519ff GKH |
94 | |
95 | pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | |
c55519ff GKH |
96 | |
97 | } | |
98 | ||
62eb734b BZ |
99 | void RTUSBInitHTTxDesc(struct rt_rtmp_adapter *pAd, |
100 | struct rt_ht_tx_context *pTxContext, | |
51126deb BZ |
101 | u8 BulkOutPipeId, |
102 | unsigned long BulkOutSize, IN usb_complete_t Func) | |
c55519ff | 103 | { |
66cd8d6e | 104 | PURB pUrb; |
51126deb | 105 | u8 *pSrc = NULL; |
8a10a546 | 106 | struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; |
c55519ff GKH |
107 | |
108 | pUrb = pTxContext->pUrb; | |
109 | ASSERT(pUrb); | |
110 | ||
9f548a2a | 111 | /* Store BulkOut PipeId */ |
c55519ff GKH |
112 | pTxContext->BulkOutPipeId = BulkOutPipeId; |
113 | ||
66cd8d6e BZ |
114 | pSrc = |
115 | &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext-> | |
116 | NextBulkOutPosition]; | |
c55519ff | 117 | |
9f548a2a | 118 | /*Initialize a tx bulk urb */ |
c55519ff | 119 | RTUSB_FILL_BULK_URB(pUrb, |
66cd8d6e BZ |
120 | pObj->pUsb_Dev, |
121 | usb_sndbulkpipe(pObj->pUsb_Dev, | |
122 | pAd->BulkOutEpAddr[BulkOutPipeId]), | |
123 | pSrc, BulkOutSize, Func, pTxContext); | |
124 | ||
125 | pUrb->transfer_dma = | |
126 | (pTxContext->data_dma + pTxContext->NextBulkOutPosition); | |
c55519ff | 127 | pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
c55519ff GKH |
128 | |
129 | } | |
130 | ||
62eb734b | 131 | void RTUSBInitRxDesc(struct rt_rtmp_adapter *pAd, struct rt_rx_context *pRxContext) |
c55519ff | 132 | { |
66cd8d6e | 133 | PURB pUrb; |
8a10a546 | 134 | struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; |
51126deb | 135 | unsigned long RX_bulk_size; |
c55519ff GKH |
136 | |
137 | pUrb = pRxContext->pUrb; | |
138 | ASSERT(pUrb); | |
139 | ||
66cd8d6e | 140 | if (pAd->BulkInMaxPacketSize == 64) |
c55519ff GKH |
141 | RX_bulk_size = 4096; |
142 | else | |
143 | RX_bulk_size = MAX_RXBULK_SIZE; | |
144 | ||
9f548a2a | 145 | /*Initialize a rx bulk urb */ |
c55519ff | 146 | RTUSB_FILL_BULK_URB(pUrb, |
66cd8d6e BZ |
147 | pObj->pUsb_Dev, |
148 | usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr), | |
149 | &(pRxContext-> | |
150 | TransferBuffer[pAd->NextRxBulkInPosition]), | |
151 | RX_bulk_size - (pAd->NextRxBulkInPosition), | |
152 | (usb_complete_t) RTUSBBulkRxComplete, | |
153 | (void *)pRxContext); | |
154 | ||
155 | pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition; | |
c55519ff | 156 | pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
c55519ff | 157 | |
c55519ff GKH |
158 | } |
159 | ||
160 | /* | |
161 | ======================================================================== | |
162 | ||
163 | Routine Description: | |
164 | ||
165 | Arguments: | |
166 | ||
167 | Return Value: | |
168 | ||
169 | Note: | |
170 | ||
171 | ======================================================================== | |
172 | */ | |
173 | ||
174 | #define BULK_OUT_LOCK(pLock, IrqFlags) \ | |
d24e4497 | 175 | if (1 /*!(in_interrupt() & 0xffff0000)*/) \ |
c55519ff GKH |
176 | RTMP_IRQ_LOCK((pLock), IrqFlags); |
177 | ||
178 | #define BULK_OUT_UNLOCK(pLock, IrqFlags) \ | |
d24e4497 | 179 | if (1 /*!(in_interrupt() & 0xffff0000)*/) \ |
c55519ff GKH |
180 | RTMP_IRQ_UNLOCK((pLock), IrqFlags); |
181 | ||
62eb734b | 182 | void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd, |
51126deb | 183 | u8 BulkOutPipeId, u8 Index) |
c55519ff GKH |
184 | { |
185 | ||
62eb734b | 186 | struct rt_ht_tx_context *pHTTXContext; |
66cd8d6e BZ |
187 | PURB pUrb; |
188 | int ret = 0; | |
62eb734b | 189 | struct rt_txinfo *pTxInfo, *pLastTxInfo = NULL; |
d24e4497 | 190 | struct rt_txwi *pTxWI; |
51126deb | 191 | unsigned long TmpBulkEndPos, ThisBulkSize; |
66cd8d6e | 192 | unsigned long IrqFlags = 0, IrqFlags2 = 0; |
51126deb | 193 | u8 *pWirelessPkt, *pAppendant; |
66cd8d6e | 194 | BOOLEAN bTxQLastRound = FALSE; |
51126deb | 195 | u8 allzero[4] = { 0x0, 0x0, 0x0, 0x0 }; |
c55519ff GKH |
196 | |
197 | BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); | |
66cd8d6e BZ |
198 | if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) |
199 | || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { | |
c55519ff GKH |
200 | BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); |
201 | return; | |
202 | } | |
203 | pAd->BulkOutPending[BulkOutPipeId] = TRUE; | |
204 | ||
205 | if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) | |
66cd8d6e | 206 | ) { |
c55519ff GKH |
207 | pAd->BulkOutPending[BulkOutPipeId] = FALSE; |
208 | BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); | |
209 | return; | |
210 | } | |
211 | BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); | |
212 | ||
c55519ff GKH |
213 | pHTTXContext = &(pAd->TxContext[BulkOutPipeId]); |
214 | ||
215 | BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); | |
66cd8d6e BZ |
216 | if ((pHTTXContext->ENextBulkOutPosition == |
217 | pHTTXContext->CurWritePosition) | |
218 | || ((pHTTXContext->ENextBulkOutPosition - 8) == | |
219 | pHTTXContext->CurWritePosition)) { | |
220 | BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], | |
221 | IrqFlags2); | |
c55519ff GKH |
222 | |
223 | BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); | |
224 | pAd->BulkOutPending[BulkOutPipeId] = FALSE; | |
225 | ||
9f548a2a | 226 | /* Clear Data flag */ |
66cd8d6e BZ |
227 | RTUSB_CLEAR_BULK_FLAG(pAd, |
228 | (fRTUSB_BULK_OUT_DATA_FRAG << | |
229 | BulkOutPipeId)); | |
230 | RTUSB_CLEAR_BULK_FLAG(pAd, | |
231 | (fRTUSB_BULK_OUT_DATA_NORMAL << | |
232 | BulkOutPipeId)); | |
c55519ff GKH |
233 | |
234 | BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); | |
235 | return; | |
236 | } | |
9f548a2a | 237 | /* Clear Data flag */ |
66cd8d6e BZ |
238 | RTUSB_CLEAR_BULK_FLAG(pAd, |
239 | (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); | |
240 | RTUSB_CLEAR_BULK_FLAG(pAd, | |
241 | (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); | |
c55519ff | 242 | |
9f548a2a BZ |
243 | /*DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(), */ |
244 | /* pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, */ | |
245 | /* pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); */ | |
c55519ff GKH |
246 | pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition; |
247 | ThisBulkSize = 0; | |
248 | TmpBulkEndPos = pHTTXContext->NextBulkOutPosition; | |
249 | pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0]; | |
250 | ||
66cd8d6e BZ |
251 | if ((pHTTXContext->bCopySavePad == TRUE)) { |
252 | if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero, 4)) { | |
253 | DBGPRINT_RAW(RT_DEBUG_ERROR, | |
254 | ("e1, allzero : %x %x %x %x %x %x %x %x \n", | |
255 | pHTTXContext->SavedPad[0], | |
256 | pHTTXContext->SavedPad[1], | |
257 | pHTTXContext->SavedPad[2], | |
258 | pHTTXContext->SavedPad[3] | |
259 | , pHTTXContext->SavedPad[4], | |
260 | pHTTXContext->SavedPad[5], | |
261 | pHTTXContext->SavedPad[6], | |
262 | pHTTXContext->SavedPad[7])); | |
c55519ff | 263 | } |
66cd8d6e BZ |
264 | NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], |
265 | pHTTXContext->SavedPad, 8); | |
c55519ff GKH |
266 | pHTTXContext->bCopySavePad = FALSE; |
267 | if (pAd->bForcePrintTX == TRUE) | |
66cd8d6e BZ |
268 | DBGPRINT(RT_DEBUG_TRACE, |
269 | ("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", | |
270 | pHTTXContext->CurWritePosition, | |
271 | pHTTXContext->NextBulkOutPosition, | |
272 | pHTTXContext->ENextBulkOutPosition)); | |
c55519ff GKH |
273 | } |
274 | ||
66cd8d6e | 275 | do { |
d24e4497 | 276 | pTxInfo = (struct rt_txinfo *)&pWirelessPkt[TmpBulkEndPos]; |
66cd8d6e | 277 | pTxWI = |
d24e4497 | 278 | (struct rt_txwi *)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE]; |
c55519ff GKH |
279 | |
280 | if (pAd->bForcePrintTX == TRUE) | |
66cd8d6e BZ |
281 | DBGPRINT(RT_DEBUG_TRACE, |
282 | ("RTUSBBulkOutDataPacket AMPDU = %d.\n", | |
283 | pTxWI->AMPDU)); | |
c55519ff | 284 | |
9f548a2a BZ |
285 | /* add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items */ |
286 | /*if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */ | |
66cd8d6e BZ |
287 | if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) { |
288 | if (((ThisBulkSize & 0xffff8000) != 0) | |
289 | || ((ThisBulkSize & 0x1000) == 0x1000)) { | |
9f548a2a | 290 | /* Limit BulkOut size to about 4k bytes. */ |
66cd8d6e BZ |
291 | pHTTXContext->ENextBulkOutPosition = |
292 | TmpBulkEndPos; | |
c55519ff | 293 | break; |
66cd8d6e BZ |
294 | } else |
295 | if (((pAd->BulkOutMaxPacketSize < 512) | |
296 | && ((ThisBulkSize & 0xfffff800) != | |
297 | 0)) | |
298 | /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */ | |
299 | ) { | |
9f548a2a | 300 | /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ |
25985edc | 301 | /* For performance in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */ |
66cd8d6e BZ |
302 | pHTTXContext->ENextBulkOutPosition = |
303 | TmpBulkEndPos; | |
c55519ff GKH |
304 | break; |
305 | } | |
306 | } | |
9f548a2a | 307 | /* end Iverson */ |
66cd8d6e | 308 | else { |
9f548a2a | 309 | if (((ThisBulkSize & 0xffff8000) != 0) || ((ThisBulkSize & 0x6000) == 0x6000)) { /* Limit BulkOut size to about 24k bytes. */ |
66cd8d6e BZ |
310 | pHTTXContext->ENextBulkOutPosition = |
311 | TmpBulkEndPos; | |
c55519ff | 312 | break; |
d24e4497 | 313 | } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize & 0xfffff800) != 0)) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */) { /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ |
25985edc | 314 | /* For performance in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */ |
66cd8d6e BZ |
315 | pHTTXContext->ENextBulkOutPosition = |
316 | TmpBulkEndPos; | |
c55519ff GKH |
317 | break; |
318 | } | |
319 | } | |
320 | ||
66cd8d6e | 321 | if (TmpBulkEndPos == pHTTXContext->CurWritePosition) { |
c55519ff GKH |
322 | pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; |
323 | break; | |
324 | } | |
325 | ||
66cd8d6e BZ |
326 | if (pTxInfo->QSEL != FIFO_EDCA) { |
327 | DBGPRINT(RT_DEBUG_ERROR, | |
328 | ("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", | |
d24e4497 | 329 | __func__, pTxInfo->QSEL)); |
66cd8d6e BZ |
330 | DBGPRINT(RT_DEBUG_ERROR, |
331 | ("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", | |
332 | pHTTXContext->CurWritePosition, | |
333 | pHTTXContext->NextBulkOutPosition, | |
334 | pHTTXContext->ENextBulkOutPosition, | |
335 | pHTTXContext->bCopySavePad)); | |
336 | hex_dump("Wrong QSel Pkt:", | |
d24e4497 | 337 | (u8 *)&pWirelessPkt[TmpBulkEndPos], |
66cd8d6e BZ |
338 | (pHTTXContext->CurWritePosition - |
339 | pHTTXContext->NextBulkOutPosition)); | |
c55519ff GKH |
340 | } |
341 | ||
66cd8d6e BZ |
342 | if (pTxInfo->USBDMATxPktLen <= 8) { |
343 | BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], | |
344 | IrqFlags2); | |
345 | DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE */ , | |
346 | ("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n", | |
347 | pHTTXContext->BulkOutSize, | |
348 | pHTTXContext->bCopySavePad, | |
349 | pHTTXContext->CurWritePosition, | |
350 | pHTTXContext->NextBulkOutPosition, | |
351 | pHTTXContext->CurWriteRealPos)); | |
c55519ff | 352 | { |
66cd8d6e BZ |
353 | DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE */ |
354 | , | |
355 | ("%x %x %x %x %x %x %x %x \n", | |
356 | pHTTXContext->SavedPad[0], | |
357 | pHTTXContext->SavedPad[1], | |
358 | pHTTXContext->SavedPad[2], | |
359 | pHTTXContext->SavedPad[3] | |
360 | , pHTTXContext->SavedPad[4], | |
361 | pHTTXContext->SavedPad[5], | |
362 | pHTTXContext->SavedPad[6], | |
363 | pHTTXContext->SavedPad[7])); | |
c55519ff GKH |
364 | } |
365 | pAd->bForcePrintTX = TRUE; | |
66cd8d6e BZ |
366 | BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], |
367 | IrqFlags); | |
c55519ff | 368 | pAd->BulkOutPending[BulkOutPipeId] = FALSE; |
66cd8d6e BZ |
369 | BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], |
370 | IrqFlags); | |
9f548a2a | 371 | /*DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen)); */ |
c55519ff GKH |
372 | return; |
373 | } | |
9f548a2a | 374 | /* Increase Total transmit byte counter */ |
66cd8d6e BZ |
375 | pAd->RalinkCounters.OneSecTransmittedByteCount += |
376 | pTxWI->MPDUtotalByteCount; | |
377 | pAd->RalinkCounters.TransmittedByteCount += | |
378 | pTxWI->MPDUtotalByteCount; | |
c55519ff GKH |
379 | |
380 | pLastTxInfo = pTxInfo; | |
381 | ||
9f548a2a | 382 | /* Make sure we use EDCA QUEUE. */ |
ca97b838 | 383 | pTxInfo->QSEL = FIFO_EDCA; |
66cd8d6e BZ |
384 | ThisBulkSize += (pTxInfo->USBDMATxPktLen + 4); |
385 | TmpBulkEndPos += (pTxInfo->USBDMATxPktLen + 4); | |
c55519ff GKH |
386 | |
387 | if (TmpBulkEndPos != pHTTXContext->CurWritePosition) | |
388 | pTxInfo->USBDMANextVLD = 1; | |
389 | ||
66cd8d6e | 390 | if (pTxInfo->SwUseLastRound == 1) { |
c55519ff GKH |
391 | if (pHTTXContext->CurWritePosition == 8) |
392 | pTxInfo->USBDMANextVLD = 0; | |
393 | pTxInfo->SwUseLastRound = 0; | |
394 | ||
395 | bTxQLastRound = TRUE; | |
396 | pHTTXContext->ENextBulkOutPosition = 8; | |
397 | ||
c55519ff GKH |
398 | break; |
399 | } | |
ca97b838 | 400 | |
66cd8d6e | 401 | } while (TRUE); |
c55519ff | 402 | |
9f548a2a | 403 | /* adjust the pTxInfo->USBDMANextVLD value of last pTxInfo. */ |
d24e4497 | 404 | if (pLastTxInfo) |
c55519ff | 405 | pLastTxInfo->USBDMANextVLD = 0; |
c55519ff GKH |
406 | |
407 | /* | |
66cd8d6e BZ |
408 | We need to copy SavedPad when following condition matched! |
409 | 1. Not the last round of the TxQueue and | |
410 | 2. any match of following cases: | |
411 | (1). The End Position of this bulk out is reach to the Currenct Write position and | |
412 | the TxInfo and related header already write to the CurWritePosition. | |
413 | =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition) | |
414 | ||
415 | (2). The EndPosition of the bulk out is not reach to the Current Write Position. | |
416 | =>(ENextBulkOutPosition != CurWritePosition) | |
417 | */ | |
c55519ff | 418 | if ((bTxQLastRound == FALSE) && |
66cd8d6e BZ |
419 | (((pHTTXContext->ENextBulkOutPosition == |
420 | pHTTXContext->CurWritePosition) | |
421 | && (pHTTXContext->CurWriteRealPos > | |
422 | pHTTXContext->CurWritePosition)) | |
423 | || (pHTTXContext->ENextBulkOutPosition != | |
424 | pHTTXContext->CurWritePosition)) | |
425 | ) { | |
426 | NdisMoveMemory(pHTTXContext->SavedPad, | |
427 | &pWirelessPkt[pHTTXContext-> | |
428 | ENextBulkOutPosition], 8); | |
c55519ff | 429 | pHTTXContext->bCopySavePad = TRUE; |
66cd8d6e | 430 | if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero, 4)) { |
51126deb | 431 | u8 *pBuf = &pHTTXContext->SavedPad[0]; |
66cd8d6e BZ |
432 | DBGPRINT_RAW(RT_DEBUG_ERROR, |
433 | ("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n", | |
434 | pBuf[0], pBuf[1], pBuf[2], pBuf[3], | |
435 | pBuf[4], pBuf[5], pBuf[6], pBuf[7], | |
436 | pHTTXContext->CurWritePosition, | |
437 | pHTTXContext->CurWriteRealPos, | |
438 | pHTTXContext->bCurWriting, | |
439 | pHTTXContext->NextBulkOutPosition, | |
440 | TmpBulkEndPos, ThisBulkSize)); | |
c55519ff GKH |
441 | |
442 | pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition]; | |
66cd8d6e BZ |
443 | DBGPRINT_RAW(RT_DEBUG_ERROR, |
444 | ("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", | |
445 | pBuf[0], pBuf[1], pBuf[2], pBuf[3], | |
446 | pBuf[4], pBuf[5], pBuf[6], pBuf[7])); | |
c55519ff | 447 | } |
9f548a2a | 448 | /*DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad)); */ |
c55519ff GKH |
449 | } |
450 | ||
451 | if (pAd->bForcePrintTX == TRUE) | |
66cd8d6e BZ |
452 | DBGPRINT(RT_DEBUG_TRACE, |
453 | ("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", | |
454 | ThisBulkSize, pHTTXContext->CurWritePosition, | |
455 | pHTTXContext->NextBulkOutPosition, | |
456 | pHTTXContext->ENextBulkOutPosition, | |
457 | pHTTXContext->bCopySavePad)); | |
9f548a2a | 458 | /*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)); */ |
c55519ff | 459 | |
9f548a2a | 460 | /* USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize. */ |
c55519ff GKH |
461 | pAppendant = &pWirelessPkt[TmpBulkEndPos]; |
462 | NdisZeroMemory(pAppendant, 8); | |
66cd8d6e BZ |
463 | ThisBulkSize += 4; |
464 | pHTTXContext->LastOne = TRUE; | |
465 | if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0) | |
c55519ff | 466 | ThisBulkSize += 4; |
c55519ff GKH |
467 | pHTTXContext->BulkOutSize = ThisBulkSize; |
468 | ||
469 | pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1; | |
470 | BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); | |
471 | ||
9f548a2a | 472 | /* Init Tx context descriptor */ |
66cd8d6e BZ |
473 | RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, |
474 | (usb_complete_t) RTUSBBulkOutDataPacketComplete); | |
c55519ff GKH |
475 | |
476 | pUrb = pHTTXContext->pUrb; | |
699910dd JP |
477 | ret = RTUSB_SUBMIT_URB(pUrb); |
478 | if (ret != 0) { | |
66cd8d6e BZ |
479 | DBGPRINT(RT_DEBUG_ERROR, |
480 | ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", | |
481 | ret)); | |
c55519ff GKH |
482 | |
483 | BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); | |
484 | pAd->BulkOutPending[BulkOutPipeId] = FALSE; | |
485 | pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0; | |
486 | BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); | |
487 | ||
488 | return; | |
489 | } | |
490 | ||
491 | BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); | |
492 | pHTTXContext->IRPPending = TRUE; | |
493 | BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); | |
494 | pAd->BulkOutReq++; | |
495 | ||
496 | } | |
497 | ||
8a10a546 | 498 | void RTUSBBulkOutDataPacketComplete(struct urb *pUrb, struct pt_regs * pt_regs) |
c55519ff | 499 | { |
62eb734b BZ |
500 | struct rt_ht_tx_context *pHTTXContext; |
501 | struct rt_rtmp_adapter *pAd; | |
8a10a546 | 502 | struct os_cookie *pObj; |
51126deb | 503 | u8 BulkOutPipeId; |
c55519ff | 504 | |
62eb734b | 505 | pHTTXContext = (struct rt_ht_tx_context *)pUrb->context; |
66cd8d6e | 506 | pAd = pHTTXContext->pAd; |
8a10a546 | 507 | pObj = (struct os_cookie *)pAd->OS_Cookie; |
c55519ff | 508 | |
9f548a2a | 509 | /* Store BulkOut PipeId */ |
66cd8d6e | 510 | BulkOutPipeId = pHTTXContext->BulkOutPipeId; |
c55519ff GKH |
511 | pAd->BulkOutDataOneSecCount++; |
512 | ||
66cd8d6e BZ |
513 | switch (BulkOutPipeId) { |
514 | case 0: | |
515 | pObj->ac0_dma_done_task.data = (unsigned long)pUrb; | |
516 | tasklet_hi_schedule(&pObj->ac0_dma_done_task); | |
517 | break; | |
518 | case 1: | |
519 | pObj->ac1_dma_done_task.data = (unsigned long)pUrb; | |
520 | tasklet_hi_schedule(&pObj->ac1_dma_done_task); | |
521 | break; | |
522 | case 2: | |
523 | pObj->ac2_dma_done_task.data = (unsigned long)pUrb; | |
524 | tasklet_hi_schedule(&pObj->ac2_dma_done_task); | |
525 | break; | |
526 | case 3: | |
527 | pObj->ac3_dma_done_task.data = (unsigned long)pUrb; | |
528 | tasklet_hi_schedule(&pObj->ac3_dma_done_task); | |
529 | break; | |
c55519ff | 530 | } |
ca97b838 | 531 | |
c55519ff | 532 | } |
c55519ff | 533 | |
c55519ff GKH |
534 | /* |
535 | ======================================================================== | |
536 | ||
537 | Routine Description: | |
538 | ||
539 | Arguments: | |
540 | ||
541 | Return Value: | |
542 | ||
543 | Note: NULL frame use BulkOutPipeId = 0 | |
544 | ||
545 | ======================================================================== | |
546 | */ | |
62eb734b | 547 | void RTUSBBulkOutNullFrame(struct rt_rtmp_adapter *pAd) |
c55519ff | 548 | { |
62eb734b | 549 | struct rt_tx_context *pNullContext = &(pAd->NullContext); |
66cd8d6e BZ |
550 | PURB pUrb; |
551 | int ret = 0; | |
552 | unsigned long IrqFlags; | |
c55519ff GKH |
553 | |
554 | RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); | |
66cd8d6e BZ |
555 | if ((pAd->BulkOutPending[0] == TRUE) |
556 | || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { | |
c55519ff GKH |
557 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); |
558 | return; | |
559 | } | |
560 | pAd->BulkOutPending[0] = TRUE; | |
561 | pAd->watchDogTxPendingCnt[0] = 1; | |
562 | pNullContext->IRPPending = TRUE; | |
563 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); | |
564 | ||
9f548a2a | 565 | /* Increase Total transmit byte counter */ |
66cd8d6e | 566 | pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize; |
c55519ff | 567 | |
9f548a2a | 568 | /* Clear Null frame bulk flag */ |
c55519ff GKH |
569 | RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); |
570 | ||
9f548a2a | 571 | /* Init Tx context descriptor */ |
66cd8d6e BZ |
572 | RTUSBInitTxDesc(pAd, pNullContext, 0, |
573 | (usb_complete_t) RTUSBBulkOutNullFrameComplete); | |
c55519ff GKH |
574 | |
575 | pUrb = pNullContext->pUrb; | |
699910dd JP |
576 | ret = RTUSB_SUBMIT_URB(pUrb); |
577 | if (ret != 0) { | |
c55519ff GKH |
578 | RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); |
579 | pAd->BulkOutPending[0] = FALSE; | |
580 | pAd->watchDogTxPendingCnt[0] = 0; | |
581 | pNullContext->IRPPending = FALSE; | |
582 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); | |
583 | ||
66cd8d6e BZ |
584 | DBGPRINT(RT_DEBUG_ERROR, |
585 | ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", | |
586 | ret)); | |
c55519ff GKH |
587 | return; |
588 | } | |
589 | ||
590 | } | |
591 | ||
9f548a2a | 592 | /* NULL frame use BulkOutPipeId = 0 */ |
8a10a546 | 593 | void RTUSBBulkOutNullFrameComplete(struct urb *pUrb, struct pt_regs * pt_regs) |
c55519ff | 594 | { |
62eb734b BZ |
595 | struct rt_rtmp_adapter *pAd; |
596 | struct rt_tx_context *pNullContext; | |
51126deb | 597 | int Status; |
8a10a546 | 598 | struct os_cookie *pObj; |
c55519ff | 599 | |
62eb734b | 600 | pNullContext = (struct rt_tx_context *)pUrb->context; |
66cd8d6e BZ |
601 | pAd = pNullContext->pAd; |
602 | Status = pUrb->status; | |
c55519ff | 603 | |
8a10a546 | 604 | pObj = (struct os_cookie *)pAd->OS_Cookie; |
c55519ff GKH |
605 | pObj->null_frame_complete_task.data = (unsigned long)pUrb; |
606 | tasklet_hi_schedule(&pObj->null_frame_complete_task); | |
c55519ff GKH |
607 | } |
608 | ||
c55519ff GKH |
609 | /* |
610 | ======================================================================== | |
611 | ||
612 | Routine Description: | |
613 | ||
614 | Arguments: | |
615 | ||
616 | Return Value: | |
617 | ||
618 | Note: MLME use BulkOutPipeId = 0 | |
619 | ||
620 | ======================================================================== | |
621 | */ | |
62eb734b | 622 | void RTUSBBulkOutMLMEPacket(struct rt_rtmp_adapter *pAd, u8 Index) |
c55519ff | 623 | { |
62eb734b | 624 | struct rt_tx_context *pMLMEContext; |
66cd8d6e BZ |
625 | PURB pUrb; |
626 | int ret = 0; | |
627 | unsigned long IrqFlags; | |
c55519ff | 628 | |
66cd8d6e | 629 | pMLMEContext = |
62eb734b | 630 | (struct rt_tx_context *)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa; |
c55519ff GKH |
631 | pUrb = pMLMEContext->pUrb; |
632 | ||
633 | if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) || | |
66cd8d6e BZ |
634 | (pMLMEContext->InUse == FALSE) || |
635 | (pMLMEContext->bWaitingBulkOut == FALSE)) { | |
c55519ff | 636 | |
9f548a2a | 637 | /* Clear MLME bulk flag */ |
c55519ff GKH |
638 | RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); |
639 | ||
640 | return; | |
641 | } | |
642 | ||
c55519ff | 643 | RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); |
66cd8d6e BZ |
644 | if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) |
645 | || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { | |
c55519ff GKH |
646 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); |
647 | return; | |
648 | } | |
649 | ||
650 | pAd->BulkOutPending[MGMTPIPEIDX] = TRUE; | |
651 | pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1; | |
652 | pMLMEContext->IRPPending = TRUE; | |
653 | pMLMEContext->bWaitingBulkOut = FALSE; | |
654 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); | |
655 | ||
9f548a2a | 656 | /* Increase Total transmit byte counter */ |
66cd8d6e | 657 | pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize; |
c55519ff | 658 | |
9f548a2a | 659 | /* Clear MLME bulk flag */ |
c55519ff GKH |
660 | RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); |
661 | ||
9f548a2a | 662 | /* Init Tx context descriptor */ |
66cd8d6e BZ |
663 | RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, |
664 | (usb_complete_t) RTUSBBulkOutMLMEPacketComplete); | |
c55519ff | 665 | |
9f548a2a | 666 | /*For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping. */ |
66cd8d6e | 667 | pUrb->transfer_dma = 0; |
c55519ff | 668 | pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP); |
c55519ff GKH |
669 | |
670 | pUrb = pMLMEContext->pUrb; | |
699910dd JP |
671 | ret = RTUSB_SUBMIT_URB(pUrb); |
672 | if (ret != 0) { | |
66cd8d6e BZ |
673 | DBGPRINT(RT_DEBUG_ERROR, |
674 | ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", | |
675 | ret)); | |
c55519ff GKH |
676 | RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); |
677 | pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; | |
678 | pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0; | |
679 | pMLMEContext->IRPPending = FALSE; | |
680 | pMLMEContext->bWaitingBulkOut = TRUE; | |
681 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); | |
682 | ||
683 | return; | |
684 | } | |
9f548a2a BZ |
685 | /*DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n")); */ |
686 | /* printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx); */ | |
c55519ff GKH |
687 | } |
688 | ||
8a10a546 | 689 | void RTUSBBulkOutMLMEPacketComplete(struct urb *pUrb, struct pt_regs * pt_regs) |
c55519ff | 690 | { |
62eb734b BZ |
691 | struct rt_tx_context *pMLMEContext; |
692 | struct rt_rtmp_adapter *pAd; | |
51126deb | 693 | int Status; |
8a10a546 | 694 | struct os_cookie *pObj; |
66cd8d6e | 695 | int index; |
c55519ff | 696 | |
9f548a2a | 697 | /*DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n")); */ |
62eb734b | 698 | pMLMEContext = (struct rt_tx_context *)pUrb->context; |
66cd8d6e | 699 | pAd = pMLMEContext->pAd; |
8a10a546 | 700 | pObj = (struct os_cookie *)pAd->OS_Cookie; |
66cd8d6e BZ |
701 | Status = pUrb->status; |
702 | index = pMLMEContext->SelfIdx; | |
c55519ff | 703 | |
c55519ff GKH |
704 | pObj->mgmt_dma_done_task.data = (unsigned long)pUrb; |
705 | tasklet_hi_schedule(&pObj->mgmt_dma_done_task); | |
c55519ff GKH |
706 | } |
707 | ||
c55519ff GKH |
708 | /* |
709 | ======================================================================== | |
710 | ||
711 | Routine Description: | |
712 | ||
713 | Arguments: | |
714 | ||
715 | Return Value: | |
716 | ||
717 | Note: PsPoll use BulkOutPipeId = 0 | |
718 | ||
719 | ======================================================================== | |
720 | */ | |
62eb734b | 721 | void RTUSBBulkOutPsPoll(struct rt_rtmp_adapter *pAd) |
c55519ff | 722 | { |
62eb734b | 723 | struct rt_tx_context *pPsPollContext = &(pAd->PsPollContext); |
66cd8d6e BZ |
724 | PURB pUrb; |
725 | int ret = 0; | |
726 | unsigned long IrqFlags; | |
c55519ff GKH |
727 | |
728 | RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); | |
66cd8d6e BZ |
729 | if ((pAd->BulkOutPending[0] == TRUE) |
730 | || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { | |
c55519ff GKH |
731 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); |
732 | return; | |
733 | } | |
734 | pAd->BulkOutPending[0] = TRUE; | |
735 | pAd->watchDogTxPendingCnt[0] = 1; | |
736 | pPsPollContext->IRPPending = TRUE; | |
737 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); | |
738 | ||
9f548a2a | 739 | /* Clear PS-Poll bulk flag */ |
c55519ff GKH |
740 | RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL); |
741 | ||
9f548a2a | 742 | /* Init Tx context descriptor */ |
66cd8d6e BZ |
743 | RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, |
744 | (usb_complete_t) RTUSBBulkOutPsPollComplete); | |
c55519ff GKH |
745 | |
746 | pUrb = pPsPollContext->pUrb; | |
699910dd JP |
747 | ret = RTUSB_SUBMIT_URB(pUrb); |
748 | if (ret != 0) { | |
c55519ff GKH |
749 | RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); |
750 | pAd->BulkOutPending[0] = FALSE; | |
751 | pAd->watchDogTxPendingCnt[0] = 0; | |
752 | pPsPollContext->IRPPending = FALSE; | |
753 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); | |
754 | ||
66cd8d6e BZ |
755 | DBGPRINT(RT_DEBUG_ERROR, |
756 | ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", | |
757 | ret)); | |
c55519ff GKH |
758 | return; |
759 | } | |
760 | ||
761 | } | |
762 | ||
9f548a2a | 763 | /* PS-Poll frame use BulkOutPipeId = 0 */ |
8a10a546 | 764 | void RTUSBBulkOutPsPollComplete(struct urb *pUrb, struct pt_regs * pt_regs) |
c55519ff | 765 | { |
62eb734b BZ |
766 | struct rt_rtmp_adapter *pAd; |
767 | struct rt_tx_context *pPsPollContext; | |
51126deb | 768 | int Status; |
8a10a546 | 769 | struct os_cookie *pObj; |
c55519ff | 770 | |
62eb734b | 771 | pPsPollContext = (struct rt_tx_context *)pUrb->context; |
c55519ff GKH |
772 | pAd = pPsPollContext->pAd; |
773 | Status = pUrb->status; | |
774 | ||
8a10a546 | 775 | pObj = (struct os_cookie *)pAd->OS_Cookie; |
c55519ff GKH |
776 | pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb; |
777 | tasklet_hi_schedule(&pObj->pspoll_frame_complete_task); | |
c55519ff GKH |
778 | } |
779 | ||
62eb734b | 780 | void DoBulkIn(struct rt_rtmp_adapter *pAd) |
c55519ff | 781 | { |
62eb734b | 782 | struct rt_rx_context *pRxContext; |
66cd8d6e BZ |
783 | PURB pUrb; |
784 | int ret = 0; | |
785 | unsigned long IrqFlags; | |
c55519ff GKH |
786 | |
787 | RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); | |
788 | pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]); | |
66cd8d6e BZ |
789 | if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) |
790 | || (pRxContext->InUse == TRUE)) { | |
c55519ff GKH |
791 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); |
792 | return; | |
793 | } | |
794 | pRxContext->InUse = TRUE; | |
795 | pRxContext->IRPPending = TRUE; | |
796 | pAd->PendingRx++; | |
797 | pAd->BulkInReq++; | |
798 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); | |
799 | ||
9f548a2a | 800 | /* Init Rx context descriptor */ |
c55519ff GKH |
801 | NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset); |
802 | RTUSBInitRxDesc(pAd, pRxContext); | |
803 | ||
804 | pUrb = pRxContext->pUrb; | |
699910dd JP |
805 | ret = RTUSB_SUBMIT_URB(pUrb); |
806 | if (ret != 0) { /* fail */ | |
c55519ff GKH |
807 | |
808 | RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); | |
809 | pRxContext->InUse = FALSE; | |
810 | pRxContext->IRPPending = FALSE; | |
811 | pAd->PendingRx--; | |
812 | pAd->BulkInReq--; | |
813 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); | |
66cd8d6e BZ |
814 | DBGPRINT(RT_DEBUG_ERROR, |
815 | ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret)); | |
9f548a2a | 816 | } else { /* success */ |
c55519ff | 817 | ASSERT((pRxContext->InUse == pRxContext->IRPPending)); |
9f548a2a | 818 | /*printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex); */ |
c55519ff GKH |
819 | } |
820 | } | |
821 | ||
c55519ff GKH |
822 | /* |
823 | ======================================================================== | |
824 | ||
825 | Routine Description: | |
826 | USB_RxPacket initializes a URB and uses the Rx IRP to submit it | |
827 | to USB. It checks if an Rx Descriptor is available and passes the | |
828 | the coresponding buffer to be filled. If no descriptor is available | |
829 | fails the request. When setting the completion routine we pass our | |
830 | Adapter Object as Context. | |
831 | ||
832 | Arguments: | |
833 | ||
834 | Return Value: | |
835 | TRUE found matched tuple cache | |
836 | FALSE no matched found | |
837 | ||
838 | Note: | |
839 | ||
840 | ======================================================================== | |
841 | */ | |
842 | #define fRTMP_ADAPTER_NEED_STOP_RX \ | |
843 | (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \ | |
844 | fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \ | |
845 | fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET) | |
846 | ||
847 | #define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \ | |
848 | (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \ | |
849 | fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \ | |
850 | fRTMP_ADAPTER_REMOVE_IN_PROGRESS) | |
851 | ||
62eb734b | 852 | void RTUSBBulkReceive(struct rt_rtmp_adapter *pAd) |
c55519ff | 853 | { |
62eb734b | 854 | struct rt_rx_context *pRxContext; |
66cd8d6e | 855 | unsigned long IrqFlags; |
c55519ff GKH |
856 | |
857 | /* sanity check */ | |
858 | if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX)) | |
859 | return; | |
860 | ||
66cd8d6e | 861 | while (1) { |
c55519ff GKH |
862 | |
863 | RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); | |
864 | pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]); | |
66cd8d6e BZ |
865 | if (((pRxContext->InUse == FALSE) |
866 | && (pRxContext->Readable == TRUE)) | |
867 | && (pRxContext->bRxHandling == FALSE)) { | |
c55519ff GKH |
868 | pRxContext->bRxHandling = TRUE; |
869 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); | |
870 | ||
9f548a2a | 871 | /* read RxContext, Since not */ |
303ee97d | 872 | STARxDoneInterruptHandle(pAd, TRUE); |
c55519ff | 873 | |
9f548a2a | 874 | /* Finish to handle this bulkIn buffer. */ |
c55519ff GKH |
875 | RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); |
876 | pRxContext->BulkInOffset = 0; | |
877 | pRxContext->Readable = FALSE; | |
878 | pRxContext->bRxHandling = FALSE; | |
879 | pAd->ReadPosition = 0; | |
880 | pAd->TransferBufferLength = 0; | |
66cd8d6e BZ |
881 | INC_RING_INDEX(pAd->NextRxBulkInReadIndex, |
882 | RX_RING_SIZE); | |
c55519ff GKH |
883 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); |
884 | ||
66cd8d6e | 885 | } else { |
c55519ff GKH |
886 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); |
887 | break; | |
888 | } | |
889 | } | |
890 | ||
891 | if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX))) | |
892 | DoBulkIn(pAd); | |
893 | ||
894 | } | |
895 | ||
c55519ff GKH |
896 | /* |
897 | ======================================================================== | |
898 | ||
899 | Routine Description: | |
900 | This routine process Rx Irp and call rx complete function. | |
901 | ||
902 | Arguments: | |
903 | DeviceObject Pointer to the device object for next lower | |
904 | device. DeviceObject passed in here belongs to | |
905 | the next lower driver in the stack because we | |
906 | were invoked via IoCallDriver in USB_RxPacket | |
907 | AND it is not OUR device object | |
908 | Irp Ptr to completed IRP | |
909 | Context Ptr to our Adapter object (context specified | |
910 | in IoSetCompletionRoutine | |
911 | ||
912 | Return Value: | |
913 | Always returns STATUS_MORE_PROCESSING_REQUIRED | |
914 | ||
915 | Note: | |
916 | Always returns STATUS_MORE_PROCESSING_REQUIRED | |
917 | ======================================================================== | |
918 | */ | |
8a10a546 | 919 | void RTUSBBulkRxComplete(struct urb *pUrb, struct pt_regs *pt_regs) |
c55519ff | 920 | { |
9f548a2a BZ |
921 | /* use a receive tasklet to handle received packets; */ |
922 | /* or sometimes hardware IRQ will be disabled here, so we can not */ | |
923 | /* use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :< */ | |
62eb734b BZ |
924 | struct rt_rx_context *pRxContext; |
925 | struct rt_rtmp_adapter *pAd; | |
8a10a546 | 926 | struct os_cookie *pObj; |
c55519ff | 927 | |
62eb734b | 928 | pRxContext = (struct rt_rx_context *)pUrb->context; |
66cd8d6e | 929 | pAd = pRxContext->pAd; |
8a10a546 | 930 | pObj = (struct os_cookie *)pAd->OS_Cookie; |
c55519ff GKH |
931 | |
932 | pObj->rx_done_task.data = (unsigned long)pUrb; | |
933 | tasklet_hi_schedule(&pObj->rx_done_task); | |
934 | ||
935 | } | |
936 | ||
c55519ff GKH |
937 | /* |
938 | ======================================================================== | |
939 | ||
940 | Routine Description: | |
941 | ||
942 | Arguments: | |
943 | ||
944 | Return Value: | |
945 | ||
946 | Note: | |
947 | ||
948 | ======================================================================== | |
949 | */ | |
62eb734b | 950 | void RTUSBKickBulkOut(struct rt_rtmp_adapter *pAd) |
c55519ff | 951 | { |
9f548a2a | 952 | /* BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged. */ |
66cd8d6e BZ |
953 | if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX) |
954 | ) { | |
9f548a2a | 955 | /* 2. PS-Poll frame is next */ |
d24e4497 | 956 | if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL)) |
c55519ff | 957 | RTUSBBulkOutPsPoll(pAd); |
9f548a2a | 958 | /* 5. Mlme frame is next */ |
ca97b838 | 959 | else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) || |
66cd8d6e | 960 | (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE)) { |
c55519ff GKH |
961 | RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx); |
962 | } | |
9f548a2a | 963 | /* 6. Data frame normal is next */ |
66cd8d6e BZ |
964 | if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL)) { |
965 | if (((!RTMP_TEST_FLAG | |
966 | (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) | |
967 | || | |
968 | (!OPSTATUS_TEST_FLAG | |
969 | (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) | |
970 | )) { | |
971 | RTUSBBulkOutDataPacket(pAd, 0, | |
972 | pAd-> | |
973 | NextBulkOutIndex[0]); | |
c55519ff GKH |
974 | } |
975 | } | |
66cd8d6e BZ |
976 | if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2)) { |
977 | if (((!RTMP_TEST_FLAG | |
978 | (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) | |
979 | || | |
980 | (!OPSTATUS_TEST_FLAG | |
981 | (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) | |
982 | )) { | |
983 | RTUSBBulkOutDataPacket(pAd, 1, | |
984 | pAd-> | |
985 | NextBulkOutIndex[1]); | |
c55519ff GKH |
986 | } |
987 | } | |
66cd8d6e BZ |
988 | if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3)) { |
989 | if (((!RTMP_TEST_FLAG | |
990 | (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) | |
991 | || | |
992 | (!OPSTATUS_TEST_FLAG | |
993 | (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) | |
994 | )) { | |
995 | RTUSBBulkOutDataPacket(pAd, 2, | |
996 | pAd-> | |
997 | NextBulkOutIndex[2]); | |
c55519ff GKH |
998 | } |
999 | } | |
66cd8d6e BZ |
1000 | if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4)) { |
1001 | if (((!RTMP_TEST_FLAG | |
1002 | (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) | |
1003 | || | |
1004 | (!OPSTATUS_TEST_FLAG | |
1005 | (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) | |
1006 | )) { | |
1007 | RTUSBBulkOutDataPacket(pAd, 3, | |
1008 | pAd-> | |
1009 | NextBulkOutIndex[3]); | |
c55519ff GKH |
1010 | } |
1011 | } | |
9f548a2a | 1012 | /* 7. Null frame is the last */ |
66cd8d6e BZ |
1013 | else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL)) { |
1014 | if (!RTMP_TEST_FLAG | |
1015 | (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { | |
c55519ff GKH |
1016 | RTUSBBulkOutNullFrame(pAd); |
1017 | } | |
1018 | } | |
25985edc | 1019 | /* 8. No data available */ |
d24e4497 AG |
1020 | else |
1021 | ; | |
c55519ff | 1022 | } |
c55519ff GKH |
1023 | } |
1024 | ||
1025 | /* | |
1026 | ======================================================================== | |
1027 | ||
1028 | Routine Description: | |
1029 | Call from Reset action after BulkOut failed. | |
1030 | Arguments: | |
1031 | ||
1032 | Return Value: | |
1033 | ||
1034 | Note: | |
1035 | ||
1036 | ======================================================================== | |
1037 | */ | |
62eb734b | 1038 | void RTUSBCleanUpDataBulkOutQueue(struct rt_rtmp_adapter *pAd) |
c55519ff | 1039 | { |
51126deb | 1040 | u8 Idx; |
62eb734b | 1041 | struct rt_ht_tx_context *pTxContext; |
c55519ff GKH |
1042 | |
1043 | DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n")); | |
1044 | ||
66cd8d6e | 1045 | for (Idx = 0; Idx < 4; Idx++) { |
c55519ff GKH |
1046 | pTxContext = &pAd->TxContext[Idx]; |
1047 | ||
1048 | pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition; | |
1049 | pTxContext->LastOne = FALSE; | |
1050 | NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]); | |
1051 | pAd->BulkOutPending[Idx] = FALSE; | |
1052 | NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]); | |
1053 | } | |
1054 | ||
1055 | DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n")); | |
1056 | } | |
1057 | ||
1058 | /* | |
1059 | ======================================================================== | |
1060 | ||
1061 | Routine Description: | |
1062 | ||
1063 | Arguments: | |
1064 | ||
1065 | Return Value: | |
1066 | ||
1067 | Note: | |
1068 | ||
1069 | ======================================================================== | |
1070 | */ | |
62eb734b | 1071 | void RTUSBCleanUpMLMEBulkOutQueue(struct rt_rtmp_adapter *pAd) |
c55519ff GKH |
1072 | { |
1073 | DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n")); | |
c55519ff GKH |
1074 | DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n")); |
1075 | } | |
1076 | ||
c55519ff GKH |
1077 | /* |
1078 | ======================================================================== | |
1079 | ||
1080 | Routine Description: | |
1081 | ||
1082 | Arguments: | |
1083 | ||
1084 | Return Value: | |
1085 | ||
c55519ff GKH |
1086 | Note: |
1087 | ||
1088 | ======================================================================== | |
1089 | */ | |
62eb734b | 1090 | void RTUSBCancelPendingIRPs(struct rt_rtmp_adapter *pAd) |
c55519ff GKH |
1091 | { |
1092 | RTUSBCancelPendingBulkInIRP(pAd); | |
1093 | RTUSBCancelPendingBulkOutIRP(pAd); | |
1094 | } | |
1095 | ||
1096 | /* | |
1097 | ======================================================================== | |
1098 | ||
1099 | Routine Description: | |
1100 | ||
1101 | Arguments: | |
1102 | ||
1103 | Return Value: | |
1104 | ||
1105 | Note: | |
1106 | ||
1107 | ======================================================================== | |
1108 | */ | |
62eb734b | 1109 | void RTUSBCancelPendingBulkInIRP(struct rt_rtmp_adapter *pAd) |
c55519ff | 1110 | { |
62eb734b | 1111 | struct rt_rx_context *pRxContext; |
51126deb | 1112 | u32 i; |
c55519ff GKH |
1113 | |
1114 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n")); | |
66cd8d6e | 1115 | for (i = 0; i < (RX_RING_SIZE); i++) { |
c55519ff | 1116 | pRxContext = &(pAd->RxContext[i]); |
66cd8d6e | 1117 | if (pRxContext->IRPPending == TRUE) { |
c55519ff GKH |
1118 | RTUSB_UNLINK_URB(pRxContext->pUrb); |
1119 | pRxContext->IRPPending = FALSE; | |
1120 | pRxContext->InUse = FALSE; | |
9f548a2a BZ |
1121 | /*NdisInterlockedDecrement(&pAd->PendingRx); */ |
1122 | /*pAd->PendingRx--; */ | |
c55519ff GKH |
1123 | } |
1124 | } | |
1125 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n")); | |
1126 | } | |
1127 | ||
c55519ff GKH |
1128 | /* |
1129 | ======================================================================== | |
1130 | ||
1131 | Routine Description: | |
1132 | ||
1133 | Arguments: | |
1134 | ||
1135 | Return Value: | |
1136 | ||
1137 | Note: | |
1138 | ||
1139 | ======================================================================== | |
1140 | */ | |
62eb734b | 1141 | void RTUSBCancelPendingBulkOutIRP(struct rt_rtmp_adapter *pAd) |
c55519ff | 1142 | { |
62eb734b BZ |
1143 | struct rt_ht_tx_context *pHTTXContext; |
1144 | struct rt_tx_context *pMLMEContext; | |
1145 | struct rt_tx_context *pBeaconContext; | |
1146 | struct rt_tx_context *pNullContext; | |
1147 | struct rt_tx_context *pPsPollContext; | |
1148 | struct rt_tx_context *pRTSContext; | |
51126deb | 1149 | u32 i, Idx; |
9f548a2a | 1150 | /* unsigned int IrqFlags; */ |
8a10a546 | 1151 | /* spinlock_t *pLock; */ |
9f548a2a | 1152 | /* BOOLEAN *pPending; */ |
66cd8d6e | 1153 | |
9f548a2a BZ |
1154 | /* pLock = &pAd->BulkOutLock[MGMTPIPEIDX]; */ |
1155 | /* pPending = &pAd->BulkOutPending[MGMTPIPEIDX]; */ | |
66cd8d6e BZ |
1156 | |
1157 | for (Idx = 0; Idx < 4; Idx++) { | |
c55519ff GKH |
1158 | pHTTXContext = &(pAd->TxContext[Idx]); |
1159 | ||
66cd8d6e | 1160 | if (pHTTXContext->IRPPending == TRUE) { |
c55519ff | 1161 | |
9f548a2a BZ |
1162 | /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */ |
1163 | /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */ | |
1164 | /* when the last IRP on the list has been cancelled; that's how we exit this loop */ | |
1165 | /* */ | |
c55519ff GKH |
1166 | |
1167 | RTUSB_UNLINK_URB(pHTTXContext->pUrb); | |
1168 | ||
9f548a2a | 1169 | /* Sleep 200 microseconds to give cancellation time to work */ |
c55519ff GKH |
1170 | RTMPusecDelay(200); |
1171 | } | |
1172 | ||
c55519ff GKH |
1173 | pAd->BulkOutPending[Idx] = FALSE; |
1174 | } | |
1175 | ||
9f548a2a | 1176 | /*RTMP_IRQ_LOCK(pLock, IrqFlags); */ |
66cd8d6e | 1177 | for (i = 0; i < MGMT_RING_SIZE; i++) { |
62eb734b | 1178 | pMLMEContext = (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa; |
66cd8d6e | 1179 | if (pMLMEContext && (pMLMEContext->IRPPending == TRUE)) { |
c55519ff | 1180 | |
9f548a2a BZ |
1181 | /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */ |
1182 | /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */ | |
1183 | /* when the last IRP on the list has been cancelled; that's how we exit this loop */ | |
1184 | /* */ | |
c55519ff GKH |
1185 | |
1186 | RTUSB_UNLINK_URB(pMLMEContext->pUrb); | |
1187 | pMLMEContext->IRPPending = FALSE; | |
1188 | ||
9f548a2a | 1189 | /* Sleep 200 microsecs to give cancellation time to work */ |
c55519ff GKH |
1190 | RTMPusecDelay(200); |
1191 | } | |
1192 | } | |
1193 | pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; | |
9f548a2a | 1194 | /*RTMP_IRQ_UNLOCK(pLock, IrqFlags); */ |
c55519ff | 1195 | |
66cd8d6e | 1196 | for (i = 0; i < BEACON_RING_SIZE; i++) { |
c55519ff GKH |
1197 | pBeaconContext = &(pAd->BeaconContext[i]); |
1198 | ||
66cd8d6e | 1199 | if (pBeaconContext->IRPPending == TRUE) { |
c55519ff | 1200 | |
9f548a2a BZ |
1201 | /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */ |
1202 | /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */ | |
1203 | /* when the last IRP on the list has been cancelled; that's how we exit this loop */ | |
1204 | /* */ | |
c55519ff GKH |
1205 | |
1206 | RTUSB_UNLINK_URB(pBeaconContext->pUrb); | |
1207 | ||
9f548a2a | 1208 | /* Sleep 200 microsecs to give cancellation time to work */ |
c55519ff GKH |
1209 | RTMPusecDelay(200); |
1210 | } | |
1211 | } | |
1212 | ||
1213 | pNullContext = &(pAd->NullContext); | |
1214 | if (pNullContext->IRPPending == TRUE) | |
1215 | RTUSB_UNLINK_URB(pNullContext->pUrb); | |
1216 | ||
1217 | pRTSContext = &(pAd->RTSContext); | |
1218 | if (pRTSContext->IRPPending == TRUE) | |
1219 | RTUSB_UNLINK_URB(pRTSContext->pUrb); | |
1220 | ||
1221 | pPsPollContext = &(pAd->PsPollContext); | |
1222 | if (pPsPollContext->IRPPending == TRUE) | |
1223 | RTUSB_UNLINK_URB(pPsPollContext->pUrb); | |
1224 | ||
66cd8d6e | 1225 | for (Idx = 0; Idx < 4; Idx++) { |
c55519ff GKH |
1226 | NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]); |
1227 | pAd->BulkOutPending[Idx] = FALSE; | |
1228 | NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]); | |
1229 | } | |
1230 | } | |
1231 | ||
9f548a2a | 1232 | #endif /* RTMP_MAC_USB // */ |