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