Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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