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