blob: 625ffb60e6314c725d6cbabee04712c0cef1e382 [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 --------------------------*/
89//2007-0508-02<Add>by MikeLiu
90#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
91
92static
93VOID
94s_nsInterruptUsbIoCompleteRead(
95 IN struct urb *urb,
96 IN struct pt_regs *regs
97 );
98
99
100static
101VOID
102s_nsBulkInUsbIoCompleteRead(
103 IN struct urb *urb,
104 IN struct pt_regs *regs
105 );
106
107
108static
109VOID
110s_nsBulkOutIoCompleteWrite(
111 IN struct urb *urb,
112 IN struct pt_regs *regs
113 );
114
115
116static
117VOID
118s_nsControlInUsbIoCompleteRead(
119 IN struct urb *urb,
120 IN struct pt_regs *regs
121 );
122
123static
124VOID
125s_nsControlInUsbIoCompleteWrite(
126 IN struct urb *urb,
127 IN struct pt_regs *regs
128 );
129
130#else
131
132static
133VOID
134s_nsInterruptUsbIoCompleteRead(
135 IN struct urb *urb
136 );
137
138
139static
140VOID
141s_nsBulkInUsbIoCompleteRead(
142 IN struct urb *urb
143 );
144
145
146static
147VOID
148s_nsBulkOutIoCompleteWrite(
149 IN struct urb *urb
150 );
151
152
153static
154VOID
155s_nsControlInUsbIoCompleteRead(
156 IN struct urb *urb
157 );
158
159static
160VOID
161s_nsControlInUsbIoCompleteWrite(
162 IN struct urb *urb
163 );
164
165#endif
166
167
168/*--------------------- Export Variables --------------------------*/
169
170/*--------------------- Export Functions --------------------------*/
171
172
173
174NTSTATUS
175PIPEnsControlOutAsyn(
176 IN PSDevice pDevice,
177 IN BYTE byRequest,
178 IN WORD wValue,
179 IN WORD wIndex,
180 IN WORD wLength,
181 IN PBYTE pbyBuffer
182 )
183{
184 NTSTATUS ntStatus;
185
186
187 if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
188 return STATUS_FAILURE;
189
190
191 if (MP_TEST_FLAG(pDevice, fMP_CONTROL_WRITES)) {
192 return STATUS_FAILURE;
193 }
194
195 if (in_interrupt()) {
196 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"in_interrupt return ..byRequest %x\n", byRequest);
197 return STATUS_FAILURE;
198 }
199
200 ntStatus = usb_control_msg(
201 pDevice->usb,
202 usb_sndctrlpipe(pDevice->usb , 0),
203 byRequest,
204 0x40, // RequestType
205 wValue,
206 wIndex,
207 (PVOID) pbyBuffer,
208 wLength,
209 HZ
210 );
211 if (ntStatus >= 0) {
212 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"usb_sndctrlpipe ntStatus= %d\n", ntStatus);
213 ntStatus = 0;
214 } else {
215 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"usb_sndctrlpipe fail, ntStatus= %d\n", ntStatus);
216 }
217
218 return ntStatus;
219}
220
221
222
223
224
225NTSTATUS
226PIPEnsControlOut(
227 IN PSDevice pDevice,
228 IN BYTE byRequest,
229 IN WORD wValue,
230 IN WORD wIndex,
231 IN WORD wLength,
232 IN PBYTE pbyBuffer
233 )
234{
235 NTSTATUS ntStatus = 0;
236 int ii;
237
238
239 if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
240 return STATUS_FAILURE;
241
242 if (MP_TEST_FLAG(pDevice, fMP_CONTROL_WRITES)) {
243 return STATUS_FAILURE;
244 }
245
246 pDevice->sUsbCtlRequest.bRequestType = 0x40;
247 pDevice->sUsbCtlRequest.bRequest = byRequest;
248 pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue);
249 pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex);
250 pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength);
251 pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK;
252 pDevice->pControlURB->actual_length = 0;
253 // Notice, pbyBuffer limited point to variable buffer, can't be constant.
254 usb_fill_control_urb(pDevice->pControlURB, pDevice->usb,
255 usb_sndctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest,
256 pbyBuffer, wLength, s_nsControlInUsbIoCompleteWrite, pDevice);
257
258 if ((ntStatus = vntwusb_submit_urb(pDevice->pControlURB) != 0)) {
259 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control send request submission failed: %d\n", ntStatus);
260 return STATUS_FAILURE;
261 }
262 else {
263 MP_SET_FLAG(pDevice, fMP_CONTROL_WRITES);
264 }
265 spin_unlock_irq(&pDevice->lock);
266 for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
267 if (MP_TEST_FLAG(pDevice, fMP_CONTROL_WRITES))
268 mdelay(1);
269 else
270 break;
271 if (ii >= USB_CTL_WAIT) {
272 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control send request submission timeout \n");
273 spin_lock_irq(&pDevice->lock);
274 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
275 return STATUS_FAILURE;
276 }
277 }
278 spin_lock_irq(&pDevice->lock);
279
280 return STATUS_SUCCESS;
281}
282
283
284
285
286NTSTATUS
287PIPEnsControlIn(
288 IN PSDevice pDevice,
289 IN BYTE byRequest,
290 IN WORD wValue,
291 IN WORD wIndex,
292 IN WORD wLength,
293 IN OUT PBYTE pbyBuffer
294 )
295{
296 NTSTATUS ntStatus = 0;
297 int ii;
298
299 if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
300 return STATUS_FAILURE;
301
302 if (MP_TEST_FLAG(pDevice, fMP_CONTROL_READS)) {
303 return STATUS_FAILURE;
304 }
305 pDevice->sUsbCtlRequest.bRequestType = 0xC0;
306 pDevice->sUsbCtlRequest.bRequest = byRequest;
307 pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue);
308 pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex);
309 pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength);
310 pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK;
311 pDevice->pControlURB->actual_length = 0;
312 usb_fill_control_urb(pDevice->pControlURB, pDevice->usb,
313 usb_rcvctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest,
314 pbyBuffer, wLength, s_nsControlInUsbIoCompleteRead, pDevice);
315
316 if ((ntStatus = vntwusb_submit_urb(pDevice->pControlURB) != 0)) {
317 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control request submission failed: %d\n", ntStatus);
318 }else {
319 MP_SET_FLAG(pDevice, fMP_CONTROL_READS);
320 }
321
322 spin_unlock_irq(&pDevice->lock);
323 for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
324 if (MP_TEST_FLAG(pDevice, fMP_CONTROL_READS))
325 mdelay(1);
326 else {
327 break;
328 }
329 if (ii >= USB_CTL_WAIT) {
330 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control rcv request submission timeout \n");
331 spin_lock_irq(&pDevice->lock);
332 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
333 return STATUS_FAILURE;
334 }
335 }
336 spin_lock_irq(&pDevice->lock);
337
338 return ntStatus;
339}
340
341//2007-0508-03<Add>by MikeLiu
342#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
343
344static
345VOID
346s_nsControlInUsbIoCompleteWrite(
347 IN struct urb *urb,
348 IN struct pt_regs *regs
349 )
350#else
351
352static
353VOID
354s_nsControlInUsbIoCompleteWrite(
355 IN struct urb *urb
356 )
357#endif
358{
359 PSDevice pDevice;
360
361 pDevice = urb->context;
362 switch (urb->status) {
363 case 0:
364 break;
365 case -EINPROGRESS:
366 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status EINPROGRESS%d\n", urb->status);
367 break;
368 case -ENOENT:
369 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status ENOENT %d\n", urb->status);
370 break;
371 default:
372 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status %d\n", urb->status);
373 }
374
375 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
376}
377
378
379
380/*
381 * Description:
382 * Complete function of usb Control callback
383 *
384 * Parameters:
385 * In:
386 * pDevice - Pointer to the adapter
387 *
388 * Out:
389 * none
390 *
391 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
392 *
393 */
394
395//2007-0508-04<Add>by MikeLiu
396#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
397static
398VOID
399s_nsControlInUsbIoCompleteRead(
400 IN struct urb *urb,
401 IN struct pt_regs *regs
402 )
403#else
404
405static
406VOID
407s_nsControlInUsbIoCompleteRead(
408 IN struct urb *urb
409 )
410#endif
411{
412 PSDevice pDevice;
413
414 pDevice = urb->context;
415 switch (urb->status) {
416 case 0:
417 break;
418 case -EINPROGRESS:
419 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status EINPROGRESS%d\n", urb->status);
420 break;
421 case -ENOENT:
422 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status = ENOENT %d\n", urb->status);
423 break;
424 default:
425 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status %d\n", urb->status);
426 }
427
428 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
429}
430
431
432
433
434/*
435 * Description:
436 * Allocates an usb interrupt in irp and calls USBD.
437 *
438 * Parameters:
439 * In:
440 * pDevice - Pointer to the adapter
441 * Out:
442 * none
443 *
444 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
445 *
446 */
447NTSTATUS
448PIPEnsInterruptRead(
449 IN PSDevice pDevice
450 )
451{
452 NTSTATUS ntStatus = STATUS_FAILURE;
453
454
455 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartInterruptUsbRead()\n");
456
457 if(pDevice->intBuf.bInUse == TRUE){
458 return (STATUS_FAILURE);
459 }
460 pDevice->intBuf.bInUse = TRUE;
461// pDevice->bEventAvailable = FALSE;
462 pDevice->ulIntInPosted++;
463
464 //
465 // Now that we have created the urb, we will send a
466 // request to the USB device object.
467 //
468#if 0 //reserve int URB submit
469 usb_fill_int_urb(pDevice->pInterruptURB,
470 pDevice->usb,
471 usb_rcvintpipe(pDevice->usb, 1),
472 (PVOID) pDevice->intBuf.pDataBuf,
473 MAX_INTERRUPT_SIZE,
474 s_nsInterruptUsbIoCompleteRead,
475 pDevice,
476 pDevice->int_interval
477 );
478#else //replace int URB submit by bulk transfer
479#ifndef Safe_Close
480 usb_fill_int_urb(pDevice->pInterruptURB,
481 pDevice->usb,
482 usb_rcvintpipe(pDevice->usb, 1),
483 (PVOID) pDevice->intBuf.pDataBuf,
484 MAX_INTERRUPT_SIZE,
485 s_nsInterruptUsbIoCompleteRead,
486 pDevice,
487 pDevice->int_interval
488 );
489#else
490
491//2008-0526-01<Add>by MikeLiu
492#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
493 pDevice->pInterruptURB->interval = pDevice->int_interval;
494#endif
495
496usb_fill_bulk_urb(pDevice->pInterruptURB,
497 pDevice->usb,
498 usb_rcvbulkpipe(pDevice->usb, 1),
499 (PVOID) pDevice->intBuf.pDataBuf,
500 MAX_INTERRUPT_SIZE,
501 s_nsInterruptUsbIoCompleteRead,
502 pDevice);
503#endif
504#endif
505
506#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
507 if ((ntStatus = vntwusb_submit_urb(pDevice->pInterruptURB)) != 0) {
508 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
509 }
510
511#else
512 if (pDevice->bEventAvailable == FALSE) {
513 if ((ntStatus = vntwusb_submit_urb(pDevice->pInterruptURB)) != 0) {
514 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
515 }
516 }
517#endif
518
519 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----s_nsStartInterruptUsbRead Return(%x)\n",ntStatus);
520 return ntStatus;
521}
522
523
524/*
525 * Description:
526 * Complete function of usb interrupt in irp.
527 *
528 * Parameters:
529 * In:
530 * pDevice - Pointer to the adapter
531 *
532 * Out:
533 * none
534 *
535 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
536 *
537 */
538//2007-0508-05<Add>by MikeLiu
539#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
540static
541VOID
542s_nsInterruptUsbIoCompleteRead(
543 IN struct urb *urb,
544 IN struct pt_regs *regs
545 )
546#else
547
548static
549VOID
550s_nsInterruptUsbIoCompleteRead(
551 IN struct urb *urb
552 )
553
554#endif
555{
556 PSDevice pDevice;
557 NTSTATUS ntStatus;
558
559
560 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptUsbIoCompleteRead\n");
561 //
562 // The context given to IoSetCompletionRoutine is the receive buffer object
563 //
564 pDevice = (PSDevice)urb->context;
565
566 //
567 // We have a number of cases:
568 // 1) The USB read timed out and we received no data.
569 // 2) The USB read timed out and we received some data.
570 // 3) The USB read was successful and fully filled our irp buffer.
571 // 4) The irp was cancelled.
572 // 5) Some other failure from the USB device object.
573 //
574 ntStatus = urb->status;
575
576 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_nsInterruptUsbIoCompleteRead Status %d\n", ntStatus);
577
578 // if we were not successful, we need to free the int buffer for future use right here
579 // otherwise interrupt data handler will free int buffer after it handle it.
580 if (( ntStatus != STATUS_SUCCESS )) {
581 pDevice->ulBulkInError++;
582 pDevice->intBuf.bInUse = FALSE;
583
584// if (ntStatus == USBD_STATUS_CRC) {
585// pDevice->ulIntInContCRCError++;
586// }
587
588// if (ntStatus == STATUS_NOT_CONNECTED )
589// {
590 pDevice->fKillEventPollingThread = TRUE;
591// }
592 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"IntUSBIoCompleteControl STATUS = %d\n", ntStatus );
593 }
594 else {
595 pDevice->ulIntInBytesRead += (ULONG)urb->actual_length;
596 pDevice->ulIntInContCRCError = 0;
597 pDevice->bEventAvailable = TRUE;
598 INTnsProcessData(pDevice);
599 }
600
601 STAvUpdateUSBCounter(&pDevice->scStatistic.USB_InterruptStat, ntStatus);
602
603
604 if (pDevice->fKillEventPollingThread != TRUE) {
605 #if 0 //reserve int URB submit
606 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
607 if ((ntStatus = vntwusb_submit_urb(urb)) != 0) {
608 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Re-Submit int URB failed %d\n", ntStatus);
609 }
610
611 #else
612 if (pDevice->bEventAvailable == FALSE) {
613 if ((ntStatus = vntwusb_submit_urb(urb)) != 0) {
614 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Re-Submit int URB failed %d\n", ntStatus);
615 }
616 }
617 #endif
618 #else //replace int URB submit by bulk transfer
619 #ifdef Safe_Close
620 usb_fill_bulk_urb(pDevice->pInterruptURB,
621 pDevice->usb,
622 usb_rcvbulkpipe(pDevice->usb, 1),
623 (PVOID) pDevice->intBuf.pDataBuf,
624 MAX_INTERRUPT_SIZE,
625 s_nsInterruptUsbIoCompleteRead,
626 pDevice);
627
628 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
629 if ((ntStatus = vntwusb_submit_urb(pDevice->pInterruptURB)) != 0) {
630 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
631 }
632
633 #else
634 if (pDevice->bEventAvailable == FALSE) {
635 if ((ntStatus = vntwusb_submit_urb(pDevice->pInterruptURB)) != 0) {
636 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
637 }
638 }
639 #endif
640 #else
641 tasklet_schedule(&pDevice->EventWorkItem);
642 #endif
643#endif
644 }
645 //
646 // We return STATUS_MORE_PROCESSING_REQUIRED so that the completion
647 // routine (IofCompleteRequest) will stop working on the irp.
648 //
649 return ;
650}
651
652/*
653 * Description:
654 * Allocates an usb BulkIn irp and calls USBD.
655 *
656 * Parameters:
657 * In:
658 * pDevice - Pointer to the adapter
659 * Out:
660 * none
661 *
662 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
663 *
664 */
665NTSTATUS
666PIPEnsBulkInUsbRead(
667 IN PSDevice pDevice,
668 IN PRCB pRCB
669 )
670{
671 NTSTATUS ntStatus= 0;
672 struct urb *pUrb;
673
674
675 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartBulkInUsbRead\n");
676
677 if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
678 return STATUS_FAILURE;
679
680 pDevice->ulBulkInPosted++;
681
682
683 pUrb = pRCB->pUrb;
684 //
685 // Now that we have created the urb, we will send a
686 // request to the USB device object.
687 //
688 if (pRCB->skb == NULL) {
689 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pRCB->skb is null \n");
690 return ntStatus;
691 }
692
693 usb_fill_bulk_urb(pUrb,
694 pDevice->usb,
695 usb_rcvbulkpipe(pDevice->usb, 2),
696 (PVOID) (pRCB->skb->data),
697 MAX_TOTAL_SIZE_WITH_ALL_HEADERS,
698 s_nsBulkInUsbIoCompleteRead,
699 pRCB);
700
701 if((ntStatus = vntwusb_submit_urb(pUrb)!=0)){
702 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Rx URB failed %d\n", ntStatus);
703 return STATUS_FAILURE ;
704 }
705 pRCB->Ref = 1;
706 pRCB->bBoolInUse= TRUE;
707
708 return ntStatus;
709}
710
711
712
713
714/*
715 * Description:
716 * Complete function of usb BulkIn irp.
717 *
718 * Parameters:
719 * In:
720 * pDevice - Pointer to the adapter
721 *
722 * Out:
723 * none
724 *
725 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
726 *
727 */
728//2007-0508-06<Add>by MikeLiu
729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
730static
731VOID
732s_nsBulkInUsbIoCompleteRead(
733 IN struct urb *urb,
734 IN struct pt_regs *regs
735 )
736#else
737
738static
739VOID
740s_nsBulkInUsbIoCompleteRead(
741 IN struct urb *urb
742 )
743
744#endif
745{
746 PRCB pRCB = (PRCB)urb->context;
747 PSDevice pDevice = (PSDevice)pRCB->pDevice;
748 ULONG bytesRead;
749 BOOLEAN bIndicateReceive = FALSE;
750 BOOL bReAllocSkb = FALSE;
751 NTSTATUS status;
752
753
754
755 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkInUsbIoCompleteRead\n");
756 status = urb->status;
757 bytesRead = urb->actual_length;
758
759 if (status) {
760 pDevice->ulBulkInError++;
761 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK In failed %d\n", status);
762
763 #ifdef Calcu_LinkQual
764 pDevice->scStatistic.RxFcsErrCnt ++;
765 #endif
766//todo...xxxxxx
767// if (status == USBD_STATUS_CRC) {
768// pDevice->ulBulkInContCRCError++;
769// }
770// if (status == STATUS_DEVICE_NOT_CONNECTED )
771// {
772// MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
773// }
774 } else {
775 bIndicateReceive = TRUE;
776 pDevice->ulBulkInContCRCError = 0;
777 pDevice->ulBulkInBytesRead += bytesRead;
778
779 #ifdef Calcu_LinkQual
780 pDevice->scStatistic.RxOkCnt ++;
781 #endif
782 }
783
784
785 STAvUpdateUSBCounter(&pDevice->scStatistic.USB_BulkInStat, status);
786
787 if (bIndicateReceive) {
788 spin_lock(&pDevice->lock);
789 if (RXbBulkInProcessData(pDevice, pRCB, bytesRead) == TRUE)
790 bReAllocSkb = TRUE;
791 spin_unlock(&pDevice->lock);
792 }
793 pRCB->Ref--;
794 if (pRCB->Ref == 0)
795 {
796 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeNormal %d \n",pDevice->NumRecvFreeList);
797 spin_lock(&pDevice->lock);
798 RXvFreeRCB(pRCB, bReAllocSkb);
799 spin_unlock(&pDevice->lock);
800 }
801
802
803 return;
804}
805
806/*
807 * Description:
808 * Allocates an usb BulkOut irp and calls USBD.
809 *
810 * Parameters:
811 * In:
812 * pDevice - Pointer to the adapter
813 * Out:
814 * none
815 *
816 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
817 *
818 */
819NDIS_STATUS
820PIPEnsSendBulkOut(
821 IN PSDevice pDevice,
822 IN PUSB_SEND_CONTEXT pContext
823 )
824{
825 NTSTATUS status;
826 struct urb *pUrb;
827
828
829
830 pDevice->bPWBitOn = FALSE;
831
832/*
833 if (pDevice->pPendingBulkOutContext != NULL) {
834 pDevice->NumContextsQueued++;
835 EnqueueContext(pDevice->FirstTxContextQueue, pDevice->LastTxContextQueue, pContext);
836 status = STATUS_PENDING;
837 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send pending!\n");
838 return status;
839 }
840*/
841
842 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_nsSendBulkOut\n");
843
844 if(MP_IS_READY(pDevice) && MP_TEST_FLAG(pDevice, fMP_POST_WRITES)) {
845
846 pUrb = pContext->pUrb;
847 pDevice->ulBulkOutPosted++;
848// pDevice->pPendingBulkOutContext = pContext;
849 usb_fill_bulk_urb(
850 pUrb,
851 pDevice->usb,
852 usb_sndbulkpipe(pDevice->usb, 3),
853 (PVOID) &(pContext->Data[0]),
854 pContext->uBufLen,
855 s_nsBulkOutIoCompleteWrite,
856 pContext);
857
858 if((status = vntwusb_submit_urb(pUrb))!=0)
859 {
860 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Tx URB failed %d\n", status);
861 return STATUS_FAILURE;
862 }
863 return STATUS_PENDING;
864 }
865 else {
866 pContext->bBoolInUse = FALSE;
867 return STATUS_RESOURCES;
868 }
869}
870
871/*
872 * Description: s_nsBulkOutIoCompleteWrite
873 * 1a) Indicate to the protocol the status of the write.
874 * 1b) Return ownership of the packet to the protocol.
875 *
876 * 2) If any more packets are queue for sending, send another packet
877 * to USBD.
878 * If the attempt to send the packet to the driver fails,
879 * return ownership of the packet to the protocol and
880 * try another packet (until one succeeds).
881 *
882 * Parameters:
883 * In:
884 * pdoUsbDevObj - pointer to the USB device object which
885 * completed the irp
886 * pIrp - the irp which was completed by the
887 * device object
888 * pContext - the context given to IoSetCompletionRoutine
889 * before calling IoCallDriver on the irp
890 * The pContext is a pointer to the USB device object.
891 * Out:
892 * none
893 *
894 * Return Value: STATUS_MORE_PROCESSING_REQUIRED - allows the completion routine
895 * (IofCompleteRequest) to stop working on the irp.
896 *
897 */
898//2007-0508-07<Add>by MikeLiu
899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
900static
901VOID
902s_nsBulkOutIoCompleteWrite(
903 IN struct urb *urb,
904 IN struct pt_regs *regs
905 )
906#else
907
908static
909VOID
910s_nsBulkOutIoCompleteWrite(
911 IN struct urb *urb
912 )
913#endif
914{
915 PSDevice pDevice;
916 NTSTATUS status;
917 CONTEXT_TYPE ContextType;
918 ULONG ulBufLen;
919 PUSB_SEND_CONTEXT pContext;
920
921
922 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkOutIoCompleteWrite\n");
923 //
924 // The context given to IoSetCompletionRoutine is an USB_CONTEXT struct
925 //
926 pContext = (PUSB_SEND_CONTEXT) urb->context;
927 ASSERT( NULL != pContext );
928
929 pDevice = pContext->pDevice;
930 ContextType = pContext->Type;
931 ulBufLen = pContext->uBufLen;
932
933 if (!netif_device_present(pDevice->dev))
934 return;
935
936 //
937 // Perform various IRP, URB, and buffer 'sanity checks'
938 //
939
940 status = urb->status;
941 //we should have failed, succeeded, or cancelled, but NOT be pending
942 STAvUpdateUSBCounter(&pDevice->scStatistic.USB_BulkOutStat, status);
943
944 if(status == STATUS_SUCCESS) {
945 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Write %d bytes\n",(int)ulBufLen);
946 pDevice->ulBulkOutBytesWrite += ulBufLen;
947 pDevice->ulBulkOutContCRCError = 0;
948 //2007-0115-06<Add>by MikeLiu
949 #ifdef TxInSleep
950 pDevice->nTxDataTimeCout = 0;
951 #endif
952
953 } else {
954 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK Out failed %d\n", status);
955 pDevice->ulBulkOutError++;
956 }
957
958// pDevice->ulCheckForHangCount = 0;
959// pDevice->pPendingBulkOutContext = NULL;
960
961 if ( CONTEXT_DATA_PACKET == ContextType ) {
962 // Indicate to the protocol the status of the sent packet and return
963 // ownership of the packet.
964 if (pContext->pPacket != NULL) {
965 dev_kfree_skb_irq(pContext->pPacket);
966 pContext->pPacket = NULL;
967 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"tx %d bytes\n",(int)ulBufLen);
968 }
969
970 pDevice->dev->trans_start = jiffies;
971
972
973 if (status == STATUS_SUCCESS) {
974 pDevice->packetsSent++;
975 }
976 else {
977 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send USB error! [%08xh]\n", status);
978 pDevice->packetsSentDropped++;
979 }
980
981 }
982 if (pDevice->bLinkPass == TRUE) {
983 if (netif_queue_stopped(pDevice->dev))
984 netif_wake_queue(pDevice->dev);
985 }
986 pContext->bBoolInUse = FALSE;
987
988 return;
989}