blob: 97efd87ddddb1150ae267be625bedc9ee4778f8b [file] [log] [blame]
Forest Bond92b96792009-06-13 07:38:31 -04001/*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 *
20 * File: usbpipe.c
21 *
22 * Purpose: Handle USB control endpoint
23 *
24 * Author: Warren Hsu
25 *
26 * Date: Mar. 29, 2005
27 *
28 * Functions:
29 * CONTROLnsRequestOut - Write variable length bytes to MEM/BB/MAC/EEPROM
30 * CONTROLnsRequestIn - Read variable length bytes from MEM/BB/MAC/EEPROM
31 * ControlvWriteByte - Write one byte to MEM/BB/MAC/EEPROM
32 * ControlvReadByte - Read one byte from MEM/BB/MAC/EEPROM
33 * ControlvMaskByte - Read one byte from MEM/BB/MAC/EEPROM and clear/set some bits in the same address
34 *
35 * Revision History:
36 * 04-05-2004 Jerry Chen: Initial release
37 * 11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,ControlvMaskByte
38 *
39 */
40
41#if !defined(__UMEM_H__)
42#include "umem.h"
43#endif
44#if !defined(__INT_H__)
45#include "int.h"
46#endif
47#if !defined(__RXTX_H__)
48#include "rxtx.h"
49#endif
50#if !defined(__DPC_H__)
51#include "dpc.h"
52#endif
53#if !defined(__CONTROL_H__)
54#include "control.h"
55#endif
56#if !defined(__DESC_H__)
57#include "desc.h"
58#endif
59#if !defined(__DEVICE_H__)
60#include "device.h"
61#endif
62
63
64/*--------------------- Static Definitions -------------------------*/
65//endpoint def
66//endpoint 0: control
67//endpoint 1: interrupt
68//endpoint 2: read bulk
69//endpoint 3: write bulk
70
71//RequestType:
72//#define REQUEST_OUT (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) // 0x40
73//#define REQUEST_IN (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE ) //0xc0
74//static int msglevel =MSG_LEVEL_DEBUG;
75static int msglevel =MSG_LEVEL_INFO;
76
77
78#define USB_CTL_WAIT 500 //ms
79
80#ifndef URB_ASYNC_UNLINK
81#define URB_ASYNC_UNLINK 0
82#endif
83
84/*--------------------- Static Classes ----------------------------*/
85
86/*--------------------- Static Variables --------------------------*/
87
88/*--------------------- Static Functions --------------------------*/
Forest Bond92b96792009-06-13 07:38:31 -040089static
90VOID
91s_nsInterruptUsbIoCompleteRead(
92 IN struct urb *urb
93 );
94
95
96static
97VOID
98s_nsBulkInUsbIoCompleteRead(
99 IN struct urb *urb
100 );
101
102
103static
104VOID
105s_nsBulkOutIoCompleteWrite(
106 IN struct urb *urb
107 );
108
109
110static
111VOID
112s_nsControlInUsbIoCompleteRead(
113 IN struct urb *urb
114 );
115
116static
117VOID
118s_nsControlInUsbIoCompleteWrite(
119 IN struct urb *urb
120 );
121
Forest Bond92b96792009-06-13 07:38:31 -0400122/*--------------------- Export Variables --------------------------*/
123
124/*--------------------- Export Functions --------------------------*/
125
126
127
128NTSTATUS
129PIPEnsControlOutAsyn(
130 IN PSDevice pDevice,
131 IN BYTE byRequest,
132 IN WORD wValue,
133 IN WORD wIndex,
134 IN WORD wLength,
135 IN PBYTE pbyBuffer
136 )
137{
138 NTSTATUS ntStatus;
139
140
141 if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
142 return STATUS_FAILURE;
143
144
145 if (MP_TEST_FLAG(pDevice, fMP_CONTROL_WRITES)) {
146 return STATUS_FAILURE;
147 }
148
149 if (in_interrupt()) {
150 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"in_interrupt return ..byRequest %x\n", byRequest);
151 return STATUS_FAILURE;
152 }
153
154 ntStatus = usb_control_msg(
155 pDevice->usb,
156 usb_sndctrlpipe(pDevice->usb , 0),
157 byRequest,
158 0x40, // RequestType
159 wValue,
160 wIndex,
161 (PVOID) pbyBuffer,
162 wLength,
163 HZ
164 );
165 if (ntStatus >= 0) {
166 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"usb_sndctrlpipe ntStatus= %d\n", ntStatus);
167 ntStatus = 0;
168 } else {
169 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"usb_sndctrlpipe fail, ntStatus= %d\n", ntStatus);
170 }
171
172 return ntStatus;
173}
174
175
176
177
178
179NTSTATUS
180PIPEnsControlOut(
181 IN PSDevice pDevice,
182 IN BYTE byRequest,
183 IN WORD wValue,
184 IN WORD wIndex,
185 IN WORD wLength,
186 IN PBYTE pbyBuffer
187 )
188{
189 NTSTATUS ntStatus = 0;
190 int ii;
191
192
193 if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
194 return STATUS_FAILURE;
195
196 if (MP_TEST_FLAG(pDevice, fMP_CONTROL_WRITES)) {
197 return STATUS_FAILURE;
198 }
199
200 pDevice->sUsbCtlRequest.bRequestType = 0x40;
201 pDevice->sUsbCtlRequest.bRequest = byRequest;
202 pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue);
203 pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex);
204 pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength);
205 pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK;
206 pDevice->pControlURB->actual_length = 0;
207 // Notice, pbyBuffer limited point to variable buffer, can't be constant.
208 usb_fill_control_urb(pDevice->pControlURB, pDevice->usb,
209 usb_sndctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest,
210 pbyBuffer, wLength, s_nsControlInUsbIoCompleteWrite, pDevice);
211
212 if ((ntStatus = vntwusb_submit_urb(pDevice->pControlURB) != 0)) {
213 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control send request submission failed: %d\n", ntStatus);
214 return STATUS_FAILURE;
215 }
216 else {
217 MP_SET_FLAG(pDevice, fMP_CONTROL_WRITES);
218 }
219 spin_unlock_irq(&pDevice->lock);
220 for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
221 if (MP_TEST_FLAG(pDevice, fMP_CONTROL_WRITES))
222 mdelay(1);
223 else
224 break;
225 if (ii >= USB_CTL_WAIT) {
226 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control send request submission timeout \n");
227 spin_lock_irq(&pDevice->lock);
228 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
229 return STATUS_FAILURE;
230 }
231 }
232 spin_lock_irq(&pDevice->lock);
233
234 return STATUS_SUCCESS;
235}
236
237
238
239
240NTSTATUS
241PIPEnsControlIn(
242 IN PSDevice pDevice,
243 IN BYTE byRequest,
244 IN WORD wValue,
245 IN WORD wIndex,
246 IN WORD wLength,
247 IN OUT PBYTE pbyBuffer
248 )
249{
250 NTSTATUS ntStatus = 0;
251 int ii;
252
253 if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
254 return STATUS_FAILURE;
255
256 if (MP_TEST_FLAG(pDevice, fMP_CONTROL_READS)) {
257 return STATUS_FAILURE;
258 }
259 pDevice->sUsbCtlRequest.bRequestType = 0xC0;
260 pDevice->sUsbCtlRequest.bRequest = byRequest;
261 pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue);
262 pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex);
263 pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength);
264 pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK;
265 pDevice->pControlURB->actual_length = 0;
266 usb_fill_control_urb(pDevice->pControlURB, pDevice->usb,
267 usb_rcvctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest,
268 pbyBuffer, wLength, s_nsControlInUsbIoCompleteRead, pDevice);
269
270 if ((ntStatus = vntwusb_submit_urb(pDevice->pControlURB) != 0)) {
271 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control request submission failed: %d\n", ntStatus);
272 }else {
273 MP_SET_FLAG(pDevice, fMP_CONTROL_READS);
274 }
275
276 spin_unlock_irq(&pDevice->lock);
277 for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
278 if (MP_TEST_FLAG(pDevice, fMP_CONTROL_READS))
279 mdelay(1);
280 else {
281 break;
282 }
283 if (ii >= USB_CTL_WAIT) {
284 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control rcv request submission timeout \n");
285 spin_lock_irq(&pDevice->lock);
286 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
287 return STATUS_FAILURE;
288 }
289 }
290 spin_lock_irq(&pDevice->lock);
291
292 return ntStatus;
293}
294
Forest Bond92b96792009-06-13 07:38:31 -0400295static
296VOID
297s_nsControlInUsbIoCompleteWrite(
298 IN struct urb *urb
299 )
Forest Bond92b96792009-06-13 07:38:31 -0400300{
301 PSDevice pDevice;
302
303 pDevice = urb->context;
304 switch (urb->status) {
305 case 0:
306 break;
307 case -EINPROGRESS:
308 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status EINPROGRESS%d\n", urb->status);
309 break;
310 case -ENOENT:
311 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status ENOENT %d\n", urb->status);
312 break;
313 default:
314 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status %d\n", urb->status);
315 }
316
317 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
318}
319
320
321
322/*
323 * Description:
324 * Complete function of usb Control callback
325 *
326 * Parameters:
327 * In:
328 * pDevice - Pointer to the adapter
329 *
330 * Out:
331 * none
332 *
333 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
334 *
335 */
Forest Bond92b96792009-06-13 07:38:31 -0400336static
337VOID
338s_nsControlInUsbIoCompleteRead(
339 IN struct urb *urb
340 )
Forest Bond92b96792009-06-13 07:38:31 -0400341{
342 PSDevice pDevice;
343
344 pDevice = urb->context;
345 switch (urb->status) {
346 case 0:
347 break;
348 case -EINPROGRESS:
349 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status EINPROGRESS%d\n", urb->status);
350 break;
351 case -ENOENT:
352 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status = ENOENT %d\n", urb->status);
353 break;
354 default:
355 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status %d\n", urb->status);
356 }
357
358 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
359}
360
361
362
363
364/*
365 * Description:
366 * Allocates an usb interrupt in irp and calls USBD.
367 *
368 * Parameters:
369 * In:
370 * pDevice - Pointer to the adapter
371 * Out:
372 * none
373 *
374 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
375 *
376 */
377NTSTATUS
378PIPEnsInterruptRead(
379 IN PSDevice pDevice
380 )
381{
382 NTSTATUS ntStatus = STATUS_FAILURE;
383
384
385 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartInterruptUsbRead()\n");
386
387 if(pDevice->intBuf.bInUse == TRUE){
388 return (STATUS_FAILURE);
389 }
390 pDevice->intBuf.bInUse = TRUE;
391// pDevice->bEventAvailable = FALSE;
392 pDevice->ulIntInPosted++;
393
394 //
395 // Now that we have created the urb, we will send a
396 // request to the USB device object.
397 //
398#if 0 //reserve int URB submit
399 usb_fill_int_urb(pDevice->pInterruptURB,
400 pDevice->usb,
401 usb_rcvintpipe(pDevice->usb, 1),
402 (PVOID) pDevice->intBuf.pDataBuf,
403 MAX_INTERRUPT_SIZE,
404 s_nsInterruptUsbIoCompleteRead,
405 pDevice,
406 pDevice->int_interval
407 );
408#else //replace int URB submit by bulk transfer
409#ifndef Safe_Close
410 usb_fill_int_urb(pDevice->pInterruptURB,
411 pDevice->usb,
412 usb_rcvintpipe(pDevice->usb, 1),
413 (PVOID) pDevice->intBuf.pDataBuf,
414 MAX_INTERRUPT_SIZE,
415 s_nsInterruptUsbIoCompleteRead,
416 pDevice,
417 pDevice->int_interval
418 );
419#else
420
Forest Bond92b96792009-06-13 07:38:31 -0400421 pDevice->pInterruptURB->interval = pDevice->int_interval;
Forest Bond92b96792009-06-13 07:38:31 -0400422
423usb_fill_bulk_urb(pDevice->pInterruptURB,
424 pDevice->usb,
425 usb_rcvbulkpipe(pDevice->usb, 1),
426 (PVOID) pDevice->intBuf.pDataBuf,
427 MAX_INTERRUPT_SIZE,
428 s_nsInterruptUsbIoCompleteRead,
429 pDevice);
430#endif
431#endif
432
Forest Bond92b96792009-06-13 07:38:31 -0400433 if ((ntStatus = vntwusb_submit_urb(pDevice->pInterruptURB)) != 0) {
434 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
435 }
436
Forest Bond92b96792009-06-13 07:38:31 -0400437 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----s_nsStartInterruptUsbRead Return(%x)\n",ntStatus);
438 return ntStatus;
439}
440
441
442/*
443 * Description:
444 * Complete function of usb interrupt in irp.
445 *
446 * Parameters:
447 * In:
448 * pDevice - Pointer to the adapter
449 *
450 * Out:
451 * none
452 *
453 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
454 *
455 */
Forest Bond92b96792009-06-13 07:38:31 -0400456static
457VOID
458s_nsInterruptUsbIoCompleteRead(
459 IN struct urb *urb
460 )
461
Forest Bond92b96792009-06-13 07:38:31 -0400462{
463 PSDevice pDevice;
464 NTSTATUS ntStatus;
465
466
467 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptUsbIoCompleteRead\n");
468 //
469 // The context given to IoSetCompletionRoutine is the receive buffer object
470 //
471 pDevice = (PSDevice)urb->context;
472
473 //
474 // We have a number of cases:
475 // 1) The USB read timed out and we received no data.
476 // 2) The USB read timed out and we received some data.
477 // 3) The USB read was successful and fully filled our irp buffer.
478 // 4) The irp was cancelled.
479 // 5) Some other failure from the USB device object.
480 //
481 ntStatus = urb->status;
482
483 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_nsInterruptUsbIoCompleteRead Status %d\n", ntStatus);
484
485 // if we were not successful, we need to free the int buffer for future use right here
486 // otherwise interrupt data handler will free int buffer after it handle it.
487 if (( ntStatus != STATUS_SUCCESS )) {
488 pDevice->ulBulkInError++;
489 pDevice->intBuf.bInUse = FALSE;
490
491// if (ntStatus == USBD_STATUS_CRC) {
492// pDevice->ulIntInContCRCError++;
493// }
494
495// if (ntStatus == STATUS_NOT_CONNECTED )
496// {
497 pDevice->fKillEventPollingThread = TRUE;
498// }
499 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"IntUSBIoCompleteControl STATUS = %d\n", ntStatus );
500 }
501 else {
502 pDevice->ulIntInBytesRead += (ULONG)urb->actual_length;
503 pDevice->ulIntInContCRCError = 0;
504 pDevice->bEventAvailable = TRUE;
505 INTnsProcessData(pDevice);
506 }
507
508 STAvUpdateUSBCounter(&pDevice->scStatistic.USB_InterruptStat, ntStatus);
509
510
511 if (pDevice->fKillEventPollingThread != TRUE) {
512 #if 0 //reserve int URB submit
Forest Bond92b96792009-06-13 07:38:31 -0400513 if ((ntStatus = vntwusb_submit_urb(urb)) != 0) {
514 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Re-Submit int URB failed %d\n", ntStatus);
515 }
Forest Bond92b96792009-06-13 07:38:31 -0400516 #else //replace int URB submit by bulk transfer
517 #ifdef Safe_Close
518 usb_fill_bulk_urb(pDevice->pInterruptURB,
519 pDevice->usb,
520 usb_rcvbulkpipe(pDevice->usb, 1),
521 (PVOID) pDevice->intBuf.pDataBuf,
522 MAX_INTERRUPT_SIZE,
523 s_nsInterruptUsbIoCompleteRead,
524 pDevice);
525
Forest Bond92b96792009-06-13 07:38:31 -0400526 if ((ntStatus = vntwusb_submit_urb(pDevice->pInterruptURB)) != 0) {
527 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
528 }
529
Forest Bond92b96792009-06-13 07:38:31 -0400530 #else
531 tasklet_schedule(&pDevice->EventWorkItem);
532 #endif
533#endif
534 }
535 //
536 // We return STATUS_MORE_PROCESSING_REQUIRED so that the completion
537 // routine (IofCompleteRequest) will stop working on the irp.
538 //
539 return ;
540}
541
542/*
543 * Description:
544 * Allocates an usb BulkIn irp and calls USBD.
545 *
546 * Parameters:
547 * In:
548 * pDevice - Pointer to the adapter
549 * Out:
550 * none
551 *
552 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
553 *
554 */
555NTSTATUS
556PIPEnsBulkInUsbRead(
557 IN PSDevice pDevice,
558 IN PRCB pRCB
559 )
560{
561 NTSTATUS ntStatus= 0;
562 struct urb *pUrb;
563
564
565 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartBulkInUsbRead\n");
566
567 if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
568 return STATUS_FAILURE;
569
570 pDevice->ulBulkInPosted++;
571
572
573 pUrb = pRCB->pUrb;
574 //
575 // Now that we have created the urb, we will send a
576 // request to the USB device object.
577 //
578 if (pRCB->skb == NULL) {
579 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pRCB->skb is null \n");
580 return ntStatus;
581 }
582
583 usb_fill_bulk_urb(pUrb,
584 pDevice->usb,
585 usb_rcvbulkpipe(pDevice->usb, 2),
586 (PVOID) (pRCB->skb->data),
587 MAX_TOTAL_SIZE_WITH_ALL_HEADERS,
588 s_nsBulkInUsbIoCompleteRead,
589 pRCB);
590
591 if((ntStatus = vntwusb_submit_urb(pUrb)!=0)){
592 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Rx URB failed %d\n", ntStatus);
593 return STATUS_FAILURE ;
594 }
595 pRCB->Ref = 1;
596 pRCB->bBoolInUse= TRUE;
597
598 return ntStatus;
599}
600
601
602
603
604/*
605 * Description:
606 * Complete function of usb BulkIn irp.
607 *
608 * Parameters:
609 * In:
610 * pDevice - Pointer to the adapter
611 *
612 * Out:
613 * none
614 *
615 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
616 *
617 */
Forest Bond92b96792009-06-13 07:38:31 -0400618static
619VOID
620s_nsBulkInUsbIoCompleteRead(
621 IN struct urb *urb
622 )
623
Forest Bond92b96792009-06-13 07:38:31 -0400624{
625 PRCB pRCB = (PRCB)urb->context;
626 PSDevice pDevice = (PSDevice)pRCB->pDevice;
627 ULONG bytesRead;
628 BOOLEAN bIndicateReceive = FALSE;
629 BOOL bReAllocSkb = FALSE;
630 NTSTATUS status;
631
632
633
634 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkInUsbIoCompleteRead\n");
635 status = urb->status;
636 bytesRead = urb->actual_length;
637
638 if (status) {
639 pDevice->ulBulkInError++;
640 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK In failed %d\n", status);
641
642 #ifdef Calcu_LinkQual
643 pDevice->scStatistic.RxFcsErrCnt ++;
644 #endif
645//todo...xxxxxx
646// if (status == USBD_STATUS_CRC) {
647// pDevice->ulBulkInContCRCError++;
648// }
649// if (status == STATUS_DEVICE_NOT_CONNECTED )
650// {
651// MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
652// }
653 } else {
654 bIndicateReceive = TRUE;
655 pDevice->ulBulkInContCRCError = 0;
656 pDevice->ulBulkInBytesRead += bytesRead;
657
658 #ifdef Calcu_LinkQual
659 pDevice->scStatistic.RxOkCnt ++;
660 #endif
661 }
662
663
664 STAvUpdateUSBCounter(&pDevice->scStatistic.USB_BulkInStat, status);
665
666 if (bIndicateReceive) {
667 spin_lock(&pDevice->lock);
668 if (RXbBulkInProcessData(pDevice, pRCB, bytesRead) == TRUE)
669 bReAllocSkb = TRUE;
670 spin_unlock(&pDevice->lock);
671 }
672 pRCB->Ref--;
673 if (pRCB->Ref == 0)
674 {
675 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeNormal %d \n",pDevice->NumRecvFreeList);
676 spin_lock(&pDevice->lock);
677 RXvFreeRCB(pRCB, bReAllocSkb);
678 spin_unlock(&pDevice->lock);
679 }
680
681
682 return;
683}
684
685/*
686 * Description:
687 * Allocates an usb BulkOut irp and calls USBD.
688 *
689 * Parameters:
690 * In:
691 * pDevice - Pointer to the adapter
692 * Out:
693 * none
694 *
695 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
696 *
697 */
698NDIS_STATUS
699PIPEnsSendBulkOut(
700 IN PSDevice pDevice,
701 IN PUSB_SEND_CONTEXT pContext
702 )
703{
704 NTSTATUS status;
705 struct urb *pUrb;
706
707
708
709 pDevice->bPWBitOn = FALSE;
710
711/*
712 if (pDevice->pPendingBulkOutContext != NULL) {
713 pDevice->NumContextsQueued++;
714 EnqueueContext(pDevice->FirstTxContextQueue, pDevice->LastTxContextQueue, pContext);
715 status = STATUS_PENDING;
716 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send pending!\n");
717 return status;
718 }
719*/
720
721 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_nsSendBulkOut\n");
722
723 if(MP_IS_READY(pDevice) && MP_TEST_FLAG(pDevice, fMP_POST_WRITES)) {
724
725 pUrb = pContext->pUrb;
726 pDevice->ulBulkOutPosted++;
727// pDevice->pPendingBulkOutContext = pContext;
728 usb_fill_bulk_urb(
729 pUrb,
730 pDevice->usb,
731 usb_sndbulkpipe(pDevice->usb, 3),
732 (PVOID) &(pContext->Data[0]),
733 pContext->uBufLen,
734 s_nsBulkOutIoCompleteWrite,
735 pContext);
736
737 if((status = vntwusb_submit_urb(pUrb))!=0)
738 {
739 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Tx URB failed %d\n", status);
740 return STATUS_FAILURE;
741 }
742 return STATUS_PENDING;
743 }
744 else {
745 pContext->bBoolInUse = FALSE;
746 return STATUS_RESOURCES;
747 }
748}
749
750/*
751 * Description: s_nsBulkOutIoCompleteWrite
752 * 1a) Indicate to the protocol the status of the write.
753 * 1b) Return ownership of the packet to the protocol.
754 *
755 * 2) If any more packets are queue for sending, send another packet
756 * to USBD.
757 * If the attempt to send the packet to the driver fails,
758 * return ownership of the packet to the protocol and
759 * try another packet (until one succeeds).
760 *
761 * Parameters:
762 * In:
763 * pdoUsbDevObj - pointer to the USB device object which
764 * completed the irp
765 * pIrp - the irp which was completed by the
766 * device object
767 * pContext - the context given to IoSetCompletionRoutine
768 * before calling IoCallDriver on the irp
769 * The pContext is a pointer to the USB device object.
770 * Out:
771 * none
772 *
773 * Return Value: STATUS_MORE_PROCESSING_REQUIRED - allows the completion routine
774 * (IofCompleteRequest) to stop working on the irp.
775 *
776 */
Forest Bond92b96792009-06-13 07:38:31 -0400777static
778VOID
779s_nsBulkOutIoCompleteWrite(
780 IN struct urb *urb
781 )
Forest Bond92b96792009-06-13 07:38:31 -0400782{
783 PSDevice pDevice;
784 NTSTATUS status;
785 CONTEXT_TYPE ContextType;
786 ULONG ulBufLen;
787 PUSB_SEND_CONTEXT pContext;
788
789
790 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkOutIoCompleteWrite\n");
791 //
792 // The context given to IoSetCompletionRoutine is an USB_CONTEXT struct
793 //
794 pContext = (PUSB_SEND_CONTEXT) urb->context;
795 ASSERT( NULL != pContext );
796
797 pDevice = pContext->pDevice;
798 ContextType = pContext->Type;
799 ulBufLen = pContext->uBufLen;
800
801 if (!netif_device_present(pDevice->dev))
802 return;
803
804 //
805 // Perform various IRP, URB, and buffer 'sanity checks'
806 //
807
808 status = urb->status;
809 //we should have failed, succeeded, or cancelled, but NOT be pending
810 STAvUpdateUSBCounter(&pDevice->scStatistic.USB_BulkOutStat, status);
811
812 if(status == STATUS_SUCCESS) {
813 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Write %d bytes\n",(int)ulBufLen);
814 pDevice->ulBulkOutBytesWrite += ulBufLen;
815 pDevice->ulBulkOutContCRCError = 0;
816 //2007-0115-06<Add>by MikeLiu
817 #ifdef TxInSleep
818 pDevice->nTxDataTimeCout = 0;
819 #endif
820
821 } else {
822 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK Out failed %d\n", status);
823 pDevice->ulBulkOutError++;
824 }
825
826// pDevice->ulCheckForHangCount = 0;
827// pDevice->pPendingBulkOutContext = NULL;
828
829 if ( CONTEXT_DATA_PACKET == ContextType ) {
830 // Indicate to the protocol the status of the sent packet and return
831 // ownership of the packet.
832 if (pContext->pPacket != NULL) {
833 dev_kfree_skb_irq(pContext->pPacket);
834 pContext->pPacket = NULL;
835 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"tx %d bytes\n",(int)ulBufLen);
836 }
837
838 pDevice->dev->trans_start = jiffies;
839
840
841 if (status == STATUS_SUCCESS) {
842 pDevice->packetsSent++;
843 }
844 else {
845 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send USB error! [%08xh]\n", status);
846 pDevice->packetsSentDropped++;
847 }
848
849 }
850 if (pDevice->bLinkPass == TRUE) {
851 if (netif_queue_stopped(pDevice->dev))
852 netif_wake_queue(pDevice->dev);
853 }
854 pContext->bBoolInUse = FALSE;
855
856 return;
857}