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