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