1 /* 2 * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #define ATH_MODULE_NAME hif 21 #include "a_debug.h" 22 #include "hif_usb_internal.h" 23 #include "if_usb.h" 24 #include "cds_api.h" 25 #include "hif_debug.h" 26 27 #define IS_BULK_EP(attr) (((attr) & 3) == 0x02) 28 #define IS_INT_EP(attr) (((attr) & 3) == 0x03) 29 #define IS_ISOC_EP(attr) (((attr) & 3) == 0x01) 30 #define IS_DIR_IN(addr) ((addr) & 0x80) 31 32 #define IS_FW_CRASH_DUMP(x)(((x == FW_ASSERT_PATTERN) || \ 33 (x == FW_REG_PATTERN) || \ 34 ((x & FW_RAMDUMP_PATTERN_MASK) == \ 35 FW_RAMDUMP_PATTERN)) ? 1 : 0) 36 37 static void usb_hif_post_recv_transfers(struct HIF_USB_PIPE *recv_pipe, 38 int buffer_length); 39 static void usb_hif_post_recv_bundle_transfers 40 (struct HIF_USB_PIPE *recv_pipe, 41 int buffer_length); 42 static void usb_hif_cleanup_recv_urb(struct HIF_URB_CONTEXT *urb_context); 43 44 45 /** 46 * usb_hif_free_urb_to_pipe() - add urb back to urb list of a pipe 47 * @pipe: pointer to struct HIF_USB_PIPE 48 * @urb_context: pointer to struct HIF_URB_CONTEXT 49 * 50 * Return: none 51 */ 52 static void usb_hif_free_urb_to_pipe(struct HIF_USB_PIPE *pipe, 53 struct HIF_URB_CONTEXT *urb_context) 54 { 55 qdf_spin_lock_irqsave(&pipe->device->cs_lock); 56 pipe->urb_cnt++; 57 DL_ListAdd(&pipe->urb_list_head, &urb_context->link); 58 qdf_spin_unlock_irqrestore(&pipe->device->cs_lock); 59 } 60 61 /** 62 * usb_hif_alloc_urb_from_pipe() - remove urb back from urb list of a pipe 63 * @pipe: pointer to struct HIF_USB_PIPE 64 * 65 * Return: struct HIF_URB_CONTEXT urb context removed from the urb list 66 */ 67 struct HIF_URB_CONTEXT *usb_hif_alloc_urb_from_pipe(struct HIF_USB_PIPE *pipe) 68 { 69 struct HIF_URB_CONTEXT *urb_context = NULL; 70 DL_LIST *item; 71 72 qdf_spin_lock_irqsave(&pipe->device->cs_lock); 73 item = dl_list_remove_item_from_head(&pipe->urb_list_head); 74 if (item) { 75 urb_context = A_CONTAINING_STRUCT(item, struct HIF_URB_CONTEXT, 76 link); 77 pipe->urb_cnt--; 78 } 79 qdf_spin_unlock_irqrestore(&pipe->device->cs_lock); 80 81 return urb_context; 82 } 83 84 /** 85 * usb_hif_dequeue_pending_transfer() - remove urb from pending xfer list 86 * @pipe: pointer to struct HIF_USB_PIPE 87 * 88 * Return: struct HIF_URB_CONTEXT urb context removed from the pending xfer list 89 */ 90 static struct HIF_URB_CONTEXT *usb_hif_dequeue_pending_transfer 91 (struct HIF_USB_PIPE *pipe) 92 { 93 struct HIF_URB_CONTEXT *urb_context = NULL; 94 DL_LIST *item; 95 96 qdf_spin_lock_irqsave(&pipe->device->cs_lock); 97 item = dl_list_remove_item_from_head(&pipe->urb_pending_list); 98 if (item) 99 urb_context = A_CONTAINING_STRUCT(item, struct HIF_URB_CONTEXT, 100 link); 101 qdf_spin_unlock_irqrestore(&pipe->device->cs_lock); 102 103 return urb_context; 104 } 105 106 /** 107 * usb_hif_enqueue_pending_transfer() - add urb to pending xfer list 108 * @pipe: pointer to struct HIF_USB_PIPE 109 * @urb_context: pointer to struct HIF_URB_CONTEXT to be added to the xfer list 110 * 111 * Return: none 112 */ 113 void usb_hif_enqueue_pending_transfer(struct HIF_USB_PIPE *pipe, 114 struct HIF_URB_CONTEXT *urb_context) 115 { 116 qdf_spin_lock_irqsave(&pipe->device->cs_lock); 117 dl_list_insert_tail(&pipe->urb_pending_list, &urb_context->link); 118 qdf_spin_unlock_irqrestore(&pipe->device->cs_lock); 119 } 120 121 122 /** 123 * usb_hif_remove_pending_transfer() - remove urb from its own list 124 * @urb_context: pointer to struct HIF_URB_CONTEXT to be removed 125 * 126 * Return: none 127 */ 128 void 129 usb_hif_remove_pending_transfer(struct HIF_URB_CONTEXT *urb_context) 130 { 131 qdf_spin_lock_irqsave(&urb_context->pipe->device->cs_lock); 132 dl_list_remove(&urb_context->link); 133 qdf_spin_unlock_irqrestore(&urb_context->pipe->device->cs_lock); 134 } 135 136 /** 137 * usb_hif_alloc_pipe_resources() - allocate urb_cnt urbs to a HIF pipe 138 * @pipe: pointer to struct HIF_USB_PIPE to which resources will be allocated 139 * @urb_cnt: number of urbs to be added to the HIF pipe 140 * 141 * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error 142 */ 143 static QDF_STATUS usb_hif_alloc_pipe_resources 144 (struct HIF_USB_PIPE *pipe, int urb_cnt) 145 { 146 QDF_STATUS status = QDF_STATUS_SUCCESS; 147 int i; 148 struct HIF_URB_CONTEXT *urb_context; 149 150 DL_LIST_INIT(&pipe->urb_list_head); 151 DL_LIST_INIT(&pipe->urb_pending_list); 152 153 for (i = 0; i < urb_cnt; i++) { 154 urb_context = qdf_mem_malloc(sizeof(*urb_context)); 155 if (!urb_context) { 156 status = QDF_STATUS_E_NOMEM; 157 break; 158 } 159 urb_context->pipe = pipe; 160 urb_context->urb = usb_alloc_urb(0, GFP_KERNEL); 161 162 if (!urb_context->urb) { 163 status = QDF_STATUS_E_NOMEM; 164 qdf_mem_free(urb_context); 165 hif_err("urb_context->urb is null"); 166 break; 167 } 168 169 /* note we are only allocate the urb contexts here, the actual 170 * URB is 171 * allocated from the kernel as needed to do a transaction 172 */ 173 pipe->urb_alloc++; 174 175 usb_hif_free_urb_to_pipe(pipe, urb_context); 176 } 177 178 hif_debug("athusb: alloc resources lpipe:%d hpipe:0x%X urbs:%d", 179 pipe->logical_pipe_num, 180 pipe->usb_pipe_handle, 181 pipe->urb_alloc); 182 return status; 183 } 184 185 /** 186 * usb_hif_free_pipe_resources() - free urb resources allocated to a HIF pipe 187 * @pipe: pointer to struct HIF_USB_PIPE 188 * 189 * Return: none 190 */ 191 static void usb_hif_free_pipe_resources(struct HIF_USB_PIPE *pipe) 192 { 193 struct HIF_URB_CONTEXT *urb_context; 194 195 if (!pipe->device) { 196 /* nothing allocated for this pipe */ 197 hif_err("pipe->device is null"); 198 return; 199 } 200 201 hif_info("athusb: free resources lpipe:%d hpipe:0x%X urbs:%d avail:%d", 202 pipe->logical_pipe_num, 203 pipe->usb_pipe_handle, pipe->urb_alloc, 204 pipe->urb_cnt); 205 206 if (pipe->urb_alloc != pipe->urb_cnt) { 207 hif_err("athusb: urb leak! lpipe:%d hpipe:0x%X urbs:%d avail:%d", 208 pipe->logical_pipe_num, 209 pipe->usb_pipe_handle, pipe->urb_alloc, 210 pipe->urb_cnt); 211 } 212 213 while (true) { 214 urb_context = usb_hif_alloc_urb_from_pipe(pipe); 215 if (!urb_context) 216 break; 217 218 if (urb_context->buf) { 219 qdf_nbuf_free(urb_context->buf); 220 urb_context->buf = NULL; 221 } 222 223 usb_free_urb(urb_context->urb); 224 urb_context->urb = NULL; 225 qdf_mem_free(urb_context); 226 } 227 228 } 229 230 #ifdef QCN7605_SUPPORT 231 /** 232 * usb_hif_get_logical_pipe_num() - get pipe number for a particular endpoint 233 * @device: pointer to HIF_DEVICE_USB structure 234 * @ep_address: endpoint address 235 * @urb_count: number of urb resources to be allocated to the pipe 236 * 237 * Return: uint8_t pipe number corresponding to ep_address 238 */ 239 static uint8_t usb_hif_get_logical_pipe_num(struct HIF_DEVICE_USB *device, 240 uint8_t ep_address, 241 int *urb_count) 242 { 243 uint8_t pipe_num = HIF_USB_PIPE_INVALID; 244 245 switch (ep_address) { 246 case USB_EP_ADDR_APP_CTRL_IN: 247 pipe_num = HIF_RX_CTRL_PIPE; 248 *urb_count = RX_URB_COUNT; 249 break; 250 case USB_EP_ADDR_APP_DATA_IN: 251 pipe_num = HIF_RX_DATA_PIPE; 252 *urb_count = RX_URB_COUNT; 253 break; 254 break; 255 case USB_EP_ADDR_APP_CTRL_OUT: 256 pipe_num = HIF_TX_CTRL_PIPE; 257 *urb_count = TX_URB_COUNT; 258 break; 259 case USB_EP_ADDR_APP_DATA_OUT: 260 pipe_num = HIF_TX_DATA_LP_PIPE; 261 *urb_count = TX_URB_COUNT; 262 break; 263 default: 264 /* note: there may be endpoints not currently used */ 265 break; 266 } 267 268 return pipe_num; 269 } 270 #else 271 /** 272 * usb_hif_get_logical_pipe_num() - get pipe number for a particular endpoint 273 * @device: pointer to HIF_DEVICE_USB structure 274 * @ep_address: endpoint address 275 * @urb_count: number of urb resources to be allocated to the pipe 276 * 277 * Return: uint8_t pipe number corresponding to ep_address 278 */ 279 static uint8_t usb_hif_get_logical_pipe_num 280 (struct HIF_DEVICE_USB *device, 281 uint8_t ep_address, 282 int *urb_count) 283 { 284 uint8_t pipe_num = HIF_USB_PIPE_INVALID; 285 286 switch (ep_address) { 287 case USB_EP_ADDR_APP_CTRL_IN: 288 pipe_num = HIF_RX_CTRL_PIPE; 289 *urb_count = RX_URB_COUNT; 290 break; 291 case USB_EP_ADDR_APP_DATA_IN: 292 pipe_num = HIF_RX_DATA_PIPE; 293 *urb_count = RX_URB_COUNT; 294 break; 295 case USB_EP_ADDR_APP_INT_IN: 296 pipe_num = HIF_RX_INT_PIPE; 297 *urb_count = RX_URB_COUNT; 298 break; 299 case USB_EP_ADDR_APP_DATA2_IN: 300 pipe_num = HIF_RX_DATA2_PIPE; 301 *urb_count = RX_URB_COUNT; 302 break; 303 case USB_EP_ADDR_APP_CTRL_OUT: 304 pipe_num = HIF_TX_CTRL_PIPE; 305 *urb_count = TX_URB_COUNT; 306 break; 307 case USB_EP_ADDR_APP_DATA_LP_OUT: 308 pipe_num = HIF_TX_DATA_LP_PIPE; 309 *urb_count = TX_URB_COUNT; 310 break; 311 case USB_EP_ADDR_APP_DATA_MP_OUT: 312 pipe_num = HIF_TX_DATA_MP_PIPE; 313 *urb_count = TX_URB_COUNT; 314 break; 315 case USB_EP_ADDR_APP_DATA_HP_OUT: 316 pipe_num = HIF_TX_DATA_HP_PIPE; 317 *urb_count = TX_URB_COUNT; 318 break; 319 default: 320 /* note: there may be endpoints not currently used */ 321 break; 322 } 323 324 return pipe_num; 325 } 326 #endif /* QCN7605_SUPPORT */ 327 328 /** 329 * usb_hif_get_logical_pipe_num() - setup urb resources for all pipes 330 * @device: pointer to HIF_DEVICE_USB structure 331 * 332 * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error 333 */ 334 QDF_STATUS usb_hif_setup_pipe_resources(struct HIF_DEVICE_USB *device) 335 { 336 struct usb_interface *interface = device->interface; 337 struct usb_host_interface *iface_desc = interface->cur_altsetting; 338 struct usb_endpoint_descriptor *endpoint; 339 int i; 340 int urbcount; 341 QDF_STATUS status = QDF_STATUS_SUCCESS; 342 struct HIF_USB_PIPE *pipe; 343 uint8_t pipe_num; 344 345 /* walk descriptors and setup pipes */ 346 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { 347 endpoint = &iface_desc->endpoint[i].desc; 348 349 if (IS_BULK_EP(endpoint->bmAttributes)) { 350 hif_debug("%s Bulk Ep:0x%2.2X maxpktsz:%d", 351 IS_DIR_IN(endpoint->bEndpointAddress) ? 352 "RX" : "TX", 353 endpoint->bEndpointAddress, 354 qdf_le16_to_cpu(endpoint->wMaxPacketSize)); 355 } else if (IS_INT_EP(endpoint->bmAttributes)) { 356 hif_debug("%s Int Ep:0x%2.2X maxpktsz:%d interval:%d", 357 IS_DIR_IN(endpoint->bEndpointAddress) ? 358 "RX" : "TX", 359 endpoint->bEndpointAddress, 360 qdf_le16_to_cpu(endpoint->wMaxPacketSize), 361 endpoint->bInterval); 362 } else if (IS_ISOC_EP(endpoint->bmAttributes)) { 363 /* TODO for ISO */ 364 hif_debug("%s ISOC Ep:0x%2.2X maxpktsz:%d interval:%d", 365 IS_DIR_IN(endpoint->bEndpointAddress) ? 366 "RX" : "TX", 367 endpoint->bEndpointAddress, 368 qdf_le16_to_cpu(endpoint->wMaxPacketSize), 369 endpoint->bInterval); 370 } 371 urbcount = 0; 372 373 pipe_num = usb_hif_get_logical_pipe_num(device, 374 endpoint->bEndpointAddress, 375 &urbcount); 376 if (HIF_USB_PIPE_INVALID == pipe_num) 377 continue; 378 379 pipe = &device->pipes[pipe_num]; 380 if (pipe->device) { 381 /*pipe was already setup */ 382 continue; 383 } 384 385 pipe->device = device; 386 pipe->logical_pipe_num = pipe_num; 387 pipe->ep_address = endpoint->bEndpointAddress; 388 pipe->max_packet_size = 389 qdf_le16_to_cpu(endpoint->wMaxPacketSize); 390 391 if (IS_BULK_EP(endpoint->bmAttributes)) { 392 if (IS_DIR_IN(pipe->ep_address)) { 393 pipe->usb_pipe_handle = 394 usb_rcvbulkpipe(device->udev, 395 pipe->ep_address); 396 } else { 397 pipe->usb_pipe_handle = 398 usb_sndbulkpipe(device->udev, 399 pipe->ep_address); 400 } 401 } else if (IS_INT_EP(endpoint->bmAttributes)) { 402 if (IS_DIR_IN(pipe->ep_address)) { 403 pipe->usb_pipe_handle = 404 usb_rcvintpipe(device->udev, 405 pipe->ep_address); 406 } else { 407 pipe->usb_pipe_handle = 408 usb_sndintpipe(device->udev, 409 pipe->ep_address); 410 } 411 } else if (IS_ISOC_EP(endpoint->bmAttributes)) { 412 /* TODO for ISO */ 413 if (IS_DIR_IN(pipe->ep_address)) { 414 pipe->usb_pipe_handle = 415 usb_rcvisocpipe(device->udev, 416 pipe->ep_address); 417 } else { 418 pipe->usb_pipe_handle = 419 usb_sndisocpipe(device->udev, 420 pipe->ep_address); 421 } 422 } 423 pipe->ep_desc = endpoint; 424 425 if (!IS_DIR_IN(pipe->ep_address)) 426 pipe->flags |= HIF_USB_PIPE_FLAG_TX; 427 428 status = usb_hif_alloc_pipe_resources(pipe, urbcount); 429 430 if (!QDF_IS_STATUS_SUCCESS(status)) 431 break; 432 433 } 434 435 return status; 436 } 437 438 439 /** 440 * usb_hif_cleanup_pipe_resources() - free urb resources for all pipes 441 * @device: pointer to HIF_DEVICE_USB structure 442 * 443 * Return: none 444 */ 445 void usb_hif_cleanup_pipe_resources(struct HIF_DEVICE_USB *device) 446 { 447 int i; 448 449 for (i = 0; i < HIF_USB_PIPE_MAX; i++) 450 usb_hif_free_pipe_resources(&device->pipes[i]); 451 } 452 453 /** 454 * usb_hif_flush_pending_transfers() - kill pending urbs for a pipe 455 * @pipe: pointer to struct HIF_USB_PIPE structure 456 * 457 * Return: none 458 */ 459 static void usb_hif_flush_pending_transfers(struct HIF_USB_PIPE *pipe) 460 { 461 struct HIF_URB_CONTEXT *urb_context; 462 463 hif_info("+ pipe: %d", pipe->logical_pipe_num); 464 465 while (1) { 466 urb_context = usb_hif_dequeue_pending_transfer(pipe); 467 if (!urb_context) { 468 hif_warn("urb_context is NULL"); 469 break; 470 } 471 hif_info("pending urb ctxt: 0x%pK", urb_context); 472 if (urb_context->urb) { 473 hif_info("killing urb: 0x%pK", urb_context->urb); 474 /* killing the URB will cause the completion routines to 475 * run 476 */ 477 usb_kill_urb(urb_context->urb); 478 } 479 } 480 hif_info("-"); 481 } 482 483 /** 484 * usb_hif_flush_all() - flush pending transfers for all pipes for a usb bus 485 * @device: pointer to HIF_DEVICE_USB structure 486 * 487 * Return: none 488 */ 489 void usb_hif_flush_all(struct HIF_DEVICE_USB *device) 490 { 491 int i; 492 struct HIF_USB_PIPE *pipe; 493 494 hif_info("+"); 495 496 for (i = 0; i < HIF_USB_PIPE_MAX; i++) { 497 if (device->pipes[i].device) { 498 usb_hif_flush_pending_transfers(&device->pipes[i]); 499 pipe = &device->pipes[i]; 500 501 HIF_USB_FLUSH_WORK(pipe); 502 } 503 } 504 505 hif_info("-"); 506 } 507 508 /** 509 * usb_hif_cleanup_recv_urb() - cleanup recv urb 510 * @urb_context: pointer to struct HIF_URB_CONTEXT structure 511 * 512 * Return: none 513 */ 514 static void usb_hif_cleanup_recv_urb(struct HIF_URB_CONTEXT *urb_context) 515 { 516 517 if (urb_context->buf) { 518 qdf_nbuf_free(urb_context->buf); 519 urb_context->buf = NULL; 520 } 521 522 usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context); 523 } 524 525 /** 526 * usb_hif_cleanup_transmit_urb() - cleanup transmit urb 527 * @urb_context: pointer to struct HIF_URB_CONTEXT structure 528 * 529 * Return: none 530 */ 531 void usb_hif_cleanup_transmit_urb(struct HIF_URB_CONTEXT *urb_context) 532 { 533 usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context); 534 } 535 536 /** 537 * usb_hif_usb_recv_prestart_complete() - completion routine for prestart rx urb 538 * @urb: urb for which the completion routine is being called 539 * 540 * Return: none 541 */ 542 static void usb_hif_usb_recv_prestart_complete 543 (struct urb *urb) 544 { 545 struct HIF_URB_CONTEXT *urb_context = 546 (struct HIF_URB_CONTEXT *) urb->context; 547 QDF_STATUS status = QDF_STATUS_SUCCESS; 548 qdf_nbuf_t buf = NULL; 549 struct HIF_USB_PIPE *pipe = urb_context->pipe; 550 struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device); 551 552 hif_debug("+: recv pipe: %d, stat:%d,len:%d urb:0x%pK", 553 pipe->logical_pipe_num, 554 urb->status, urb->actual_length, 555 urb); 556 557 /* this urb is not pending anymore */ 558 usb_hif_remove_pending_transfer(urb_context); 559 do { 560 if (urb->status != 0) { 561 status = A_ECOMM; 562 switch (urb->status) { 563 case -ECONNRESET: 564 case -ENOENT: 565 case -ESHUTDOWN: 566 /* NOTE: no need to spew these errors when 567 * device is removed 568 * or urb is killed due to driver shutdown 569 */ 570 status = A_ECANCELED; 571 break; 572 default: 573 hif_err("recv pipe: %d (ep:0x%2.2X), status: %d", 574 pipe->logical_pipe_num, 575 pipe->ep_address, 576 urb->status); 577 break; 578 } 579 break; 580 } 581 if (urb->actual_length == 0) 582 break; 583 buf = urb_context->buf; 584 /* we are going to pass it up */ 585 urb_context->buf = NULL; 586 qdf_nbuf_put_tail(buf, urb->actual_length); 587 588 if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) { 589 uint8_t *data; 590 uint32_t len; 591 592 qdf_nbuf_peek_header(buf, &data, &len); 593 debug_dump_bytes(data, len, "hif recv data"); 594 } 595 /* note: queue implements a lock */ 596 skb_queue_tail(&pipe->io_comp_queue, buf); 597 598 HIF_USB_SCHEDULE_WORK(pipe); 599 } while (false); 600 601 usb_hif_cleanup_recv_urb(urb_context); 602 603 /* Prestart URBs runs out and now start working receive pipe. */ 604 qdf_spin_lock_irqsave(&pipe->device->rx_prestart_lock); 605 if ((--pipe->urb_prestart_cnt == 0) && !sc->suspend_state) 606 usb_hif_start_recv_pipes(pipe->device); 607 qdf_spin_unlock_irqrestore(&pipe->device->rx_prestart_lock); 608 609 hif_debug("-"); 610 } 611 612 /** 613 * usb_hif_usb_recv_complete() - completion routine for rx urb 614 * @urb: urb for which the completion routine is being called 615 * 616 * Return: none 617 */ 618 static void usb_hif_usb_recv_complete(struct urb *urb) 619 { 620 struct HIF_URB_CONTEXT *urb_context = 621 (struct HIF_URB_CONTEXT *) urb->context; 622 QDF_STATUS status = QDF_STATUS_SUCCESS; 623 qdf_nbuf_t buf = NULL; 624 struct HIF_USB_PIPE *pipe = urb_context->pipe; 625 struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device); 626 627 hif_debug("+: recv pipe: %d, stat:%d,len:%d urb:0x%pK", 628 pipe->logical_pipe_num, 629 urb->status, urb->actual_length, 630 urb); 631 632 /* this urb is not pending anymore */ 633 usb_hif_remove_pending_transfer(urb_context); 634 635 do { 636 637 if (urb->status != 0) { 638 status = A_ECOMM; 639 switch (urb->status) { 640 #ifdef RX_SG_SUPPORT 641 case -EOVERFLOW: 642 urb->actual_length = HIF_USB_RX_BUFFER_SIZE; 643 status = QDF_STATUS_SUCCESS; 644 break; 645 #endif 646 case -ECONNRESET: 647 case -ENOENT: 648 case -ESHUTDOWN: 649 /* NOTE: no need to spew these errors when 650 * device is removed 651 * or urb is killed due to driver shutdown 652 */ 653 status = A_ECANCELED; 654 break; 655 default: 656 hif_err("recv pipe: %d (ep:0x%2.2X), status: %d", 657 pipe->logical_pipe_num, 658 pipe->ep_address, 659 urb->status); 660 break; 661 } 662 break; 663 } 664 if (urb->actual_length == 0) 665 break; 666 buf = urb_context->buf; 667 /* we are going to pass it up */ 668 urb_context->buf = NULL; 669 qdf_nbuf_put_tail(buf, urb->actual_length); 670 if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) { 671 uint8_t *data; 672 uint32_t len; 673 674 qdf_nbuf_peek_header(buf, &data, &len); 675 debug_dump_bytes(data, len, "hif recv data"); 676 } 677 /* note: queue implements a lock */ 678 skb_queue_tail(&pipe->io_comp_queue, buf); 679 680 if (pipe->device->htc_callbacks.update_bundle_stats) 681 pipe->device->htc_callbacks.update_bundle_stats 682 (pipe->device->htc_callbacks.Context, 1); 683 684 HIF_USB_SCHEDULE_WORK(pipe); 685 } while (false); 686 687 usb_hif_cleanup_recv_urb(urb_context); 688 689 /* Only re-submit URB when STATUS is success and HIF is not at the 690 * suspend state. 691 */ 692 if (QDF_IS_STATUS_SUCCESS(status) && !sc->suspend_state) { 693 if (pipe->urb_cnt >= pipe->urb_cnt_thresh) { 694 /* our free urbs are piling up, post more transfers */ 695 usb_hif_post_recv_transfers(pipe, 696 HIF_USB_RX_BUFFER_SIZE); 697 } 698 } else { 699 hif_err("pipe: %d, fail to post URB: status: %d suspend: %d", 700 pipe->logical_pipe_num, 701 urb->status, 702 sc->suspend_state); 703 } 704 705 hif_debug("-"); 706 } 707 708 /** 709 * usb_hif_usb_recv_bundle_complete() - completion routine for rx bundling urb 710 * @urb: urb for which the completion routine is being called 711 * 712 * Return: none 713 */ 714 static void usb_hif_usb_recv_bundle_complete(struct urb *urb) 715 { 716 struct HIF_URB_CONTEXT *urb_context = 717 (struct HIF_URB_CONTEXT *) urb->context; 718 QDF_STATUS status = QDF_STATUS_SUCCESS; 719 qdf_nbuf_t buf = NULL; 720 struct HIF_USB_PIPE *pipe = urb_context->pipe; 721 uint8_t *netdata, *netdata_new; 722 uint32_t netlen, netlen_new; 723 HTC_FRAME_HDR *HtcHdr; 724 uint16_t payloadLen; 725 qdf_nbuf_t new_skb = NULL; 726 uint8_t no_of_pkt_in_bundle; 727 728 hif_debug("+: recv pipe: %d, stat:%d,len:%d urb:0x%pK", 729 pipe->logical_pipe_num, 730 urb->status, urb->actual_length, 731 urb); 732 733 /* this urb is not pending anymore */ 734 usb_hif_remove_pending_transfer(urb_context); 735 736 do { 737 738 if (urb->status != 0) { 739 status = A_ECOMM; 740 switch (urb->status) { 741 case -ECONNRESET: 742 case -ENOENT: 743 case -ESHUTDOWN: 744 /* NOTE: no need to spew these errors when 745 * device is removed 746 * or urb is killed due to driver shutdown 747 */ 748 status = A_ECANCELED; 749 break; 750 default: 751 hif_err("recv pipe: %d (ep:0x%2.2X), status: %d", 752 pipe->logical_pipe_num, 753 pipe->ep_address, 754 urb->status); 755 break; 756 } 757 break; 758 } 759 if (urb->actual_length == 0) 760 break; 761 buf = urb_context->buf; 762 if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) { 763 uint8_t *data; 764 uint32_t len; 765 766 qdf_nbuf_peek_header(buf, &data, &len); 767 debug_dump_bytes(data, len, "hif recv data"); 768 } 769 770 qdf_nbuf_peek_header(buf, &netdata, &netlen); 771 netlen = urb->actual_length; 772 no_of_pkt_in_bundle = 0; 773 774 do { 775 uint16_t frame_len; 776 777 if (IS_FW_CRASH_DUMP(*(uint32_t *) netdata)) 778 frame_len = netlen; 779 else { 780 /* Hack into HTC header for bundle processing */ 781 HtcHdr = (HTC_FRAME_HDR *) netdata; 782 if (HtcHdr->EndpointID >= ENDPOINT_MAX) { 783 hif_err("athusb: Rx: invalid EndpointID=%d", 784 HtcHdr->EndpointID); 785 break; 786 } 787 788 payloadLen = HtcHdr->PayloadLen; 789 payloadLen = qdf_le16_to_cpu(payloadLen); 790 791 if (payloadLen > HIF_USB_RX_BUFFER_SIZE) { 792 hif_err("athusb: payloadLen too long %u", 793 payloadLen); 794 break; 795 } 796 frame_len = (HTC_HDR_LENGTH + payloadLen); 797 } 798 799 if (netlen < frame_len) { 800 hif_err("athusb: subframe length %d not fitted into bundle packet length %d" 801 , netlen, frame_len); 802 break; 803 } 804 805 /* allocate a new skb and copy */ 806 new_skb = 807 qdf_nbuf_alloc(NULL, frame_len, 0, 4, false); 808 if (!new_skb) { 809 hif_err("athusb: allocate skb (len=%u) failed" 810 , frame_len); 811 break; 812 } 813 814 qdf_nbuf_peek_header(new_skb, &netdata_new, 815 &netlen_new); 816 qdf_mem_copy(netdata_new, netdata, frame_len); 817 qdf_nbuf_put_tail(new_skb, frame_len); 818 skb_queue_tail(&pipe->io_comp_queue, new_skb); 819 new_skb = NULL; 820 netdata += frame_len; 821 netlen -= frame_len; 822 no_of_pkt_in_bundle++; 823 } while (netlen); 824 825 if (pipe->device->htc_callbacks.update_bundle_stats) 826 pipe->device->htc_callbacks.update_bundle_stats 827 (pipe->device->htc_callbacks.Context, 828 no_of_pkt_in_bundle); 829 830 HIF_USB_SCHEDULE_WORK(pipe); 831 } while (false); 832 833 if (!urb_context->buf) 834 hif_err("athusb: buffer in urb_context is NULL"); 835 836 /* reset urb_context->buf ==> seems not necessary */ 837 usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context); 838 839 if (QDF_IS_STATUS_SUCCESS(status)) { 840 if (pipe->urb_cnt >= pipe->urb_cnt_thresh) { 841 /* our free urbs are piling up, post more transfers */ 842 usb_hif_post_recv_bundle_transfers(pipe, 843 pipe->device->rx_bundle_buf_len); 844 } 845 } 846 847 hif_debug("-"); 848 } 849 850 /** 851 * usb_hif_post_recv_prestart_transfers() - post prestart recv urbs for a pipe 852 * @recv_pipe: rx data pipe 853 * @prestart_urb: number of prestart recv urbs to be posted 854 * 855 * Return: none 856 */ 857 static void usb_hif_post_recv_prestart_transfers(struct HIF_USB_PIPE *recv_pipe, 858 int prestart_urb) 859 { 860 struct HIF_URB_CONTEXT *urb_context; 861 uint8_t *data; 862 uint32_t len; 863 struct urb *urb; 864 int i, usb_status, buffer_length = HIF_USB_RX_BUFFER_SIZE; 865 866 hif_info("+"); 867 868 qdf_spin_lock_irqsave(&recv_pipe->device->rx_prestart_lock); 869 for (i = 0; i < prestart_urb; i++) { 870 urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe); 871 if (!urb_context) 872 break; 873 874 urb_context->buf = 875 qdf_nbuf_alloc(NULL, buffer_length, 0, 4, false); 876 if (!urb_context->buf) { 877 usb_hif_cleanup_recv_urb(urb_context); 878 break; 879 } 880 881 qdf_nbuf_peek_header(urb_context->buf, &data, &len); 882 883 urb = urb_context->urb; 884 885 usb_fill_bulk_urb(urb, 886 recv_pipe->device->udev, 887 recv_pipe->usb_pipe_handle, 888 data, 889 buffer_length, 890 usb_hif_usb_recv_prestart_complete, 891 urb_context); 892 893 hif_debug("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK", 894 recv_pipe->logical_pipe_num, 895 recv_pipe->usb_pipe_handle, 896 recv_pipe->ep_address, buffer_length, 897 urb_context->buf); 898 899 usb_hif_enqueue_pending_transfer(recv_pipe, urb_context); 900 usb_status = usb_submit_urb(urb, GFP_ATOMIC); 901 902 if (usb_status) { 903 hif_err("athusb : usb bulk recv failed %d", 904 usb_status); 905 usb_hif_remove_pending_transfer(urb_context); 906 usb_hif_cleanup_recv_urb(urb_context); 907 break; 908 } 909 recv_pipe->urb_prestart_cnt++; 910 } 911 qdf_spin_unlock_irqrestore(&recv_pipe->device->rx_prestart_lock); 912 913 hif_info("-"); 914 } 915 916 /** 917 * usb_hif_post_recv_transfers() - post recv urbs for a given pipe 918 * @recv_pipe: recv pipe for which urbs need to be posted 919 * @buffer_length: buffer length of the recv urbs 920 * 921 * Return: none 922 */ 923 static void usb_hif_post_recv_transfers(struct HIF_USB_PIPE *recv_pipe, 924 int buffer_length) 925 { 926 struct HIF_URB_CONTEXT *urb_context; 927 uint8_t *data; 928 uint32_t len; 929 struct urb *urb; 930 int usb_status; 931 932 while (1) { 933 934 urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe); 935 if (!urb_context) 936 break; 937 938 urb_context->buf = qdf_nbuf_alloc(NULL, buffer_length, 0, 939 4, false); 940 if (!urb_context->buf) { 941 usb_hif_cleanup_recv_urb(urb_context); 942 break; 943 } 944 945 qdf_nbuf_peek_header(urb_context->buf, &data, &len); 946 947 urb = urb_context->urb; 948 949 usb_fill_bulk_urb(urb, 950 recv_pipe->device->udev, 951 recv_pipe->usb_pipe_handle, 952 data, 953 buffer_length, 954 usb_hif_usb_recv_complete, urb_context); 955 956 hif_debug("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK", 957 recv_pipe->logical_pipe_num, 958 recv_pipe->usb_pipe_handle, 959 recv_pipe->ep_address, buffer_length, 960 urb_context->buf); 961 962 usb_hif_enqueue_pending_transfer(recv_pipe, urb_context); 963 964 usb_status = usb_submit_urb(urb, GFP_ATOMIC); 965 966 if (usb_status) { 967 hif_err("athusb : usb bulk recv failed %d", 968 usb_status); 969 usb_hif_remove_pending_transfer(urb_context); 970 usb_hif_cleanup_recv_urb(urb_context); 971 break; 972 } 973 } 974 975 } 976 977 /** 978 * usb_hif_post_recv_bundle_transfers() - post recv urbs for a given pipe 979 * @recv_pipe: recv pipe for which urbs need to be posted 980 * @buffer_length: maximum length of rx bundle 981 * 982 * Return: none 983 */ 984 static void usb_hif_post_recv_bundle_transfers(struct HIF_USB_PIPE *recv_pipe, 985 int buffer_length) 986 { 987 struct HIF_URB_CONTEXT *urb_context; 988 uint8_t *data; 989 uint32_t len; 990 struct urb *urb; 991 int usb_status; 992 993 while (1) { 994 995 urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe); 996 if (!urb_context) 997 break; 998 999 if (!urb_context->buf) { 1000 urb_context->buf = 1001 qdf_nbuf_alloc(NULL, buffer_length, 0, 4, false); 1002 if (!urb_context->buf) { 1003 usb_hif_cleanup_recv_urb(urb_context); 1004 break; 1005 } 1006 } 1007 1008 qdf_nbuf_peek_header(urb_context->buf, &data, &len); 1009 1010 urb = urb_context->urb; 1011 usb_fill_bulk_urb(urb, 1012 recv_pipe->device->udev, 1013 recv_pipe->usb_pipe_handle, 1014 data, 1015 buffer_length, 1016 usb_hif_usb_recv_bundle_complete, 1017 urb_context); 1018 1019 hif_debug("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK", 1020 recv_pipe->logical_pipe_num, 1021 recv_pipe->usb_pipe_handle, 1022 recv_pipe->ep_address, buffer_length, 1023 urb_context->buf); 1024 1025 usb_hif_enqueue_pending_transfer(recv_pipe, urb_context); 1026 1027 usb_status = usb_submit_urb(urb, GFP_ATOMIC); 1028 1029 if (usb_status) { 1030 hif_err("athusb : usb bulk recv failed %d", 1031 usb_status); 1032 usb_hif_remove_pending_transfer(urb_context); 1033 usb_hif_free_urb_to_pipe(urb_context->pipe, 1034 urb_context); 1035 break; 1036 } 1037 1038 } 1039 1040 } 1041 1042 /** 1043 * usb_hif_prestart_recv_pipes() - post prestart recv urbs 1044 * @device: HIF device for which prestart recv urbs need to be posted 1045 * 1046 * Return: none 1047 */ 1048 void usb_hif_prestart_recv_pipes(struct HIF_DEVICE_USB *device) 1049 { 1050 struct HIF_USB_PIPE *pipe; 1051 int prestart_cnt = 8; 1052 1053 if (device->rx_ctrl_pipe_supported) { 1054 pipe = &device->pipes[HIF_RX_CTRL_PIPE]; 1055 prestart_cnt = 4; 1056 usb_hif_post_recv_prestart_transfers(pipe, prestart_cnt); 1057 } 1058 /* 1059 * USB driver learn to support bundle or not until the firmware 1060 * download and ready. Only allocate some URBs for control message 1061 * communication during the initial phase then start the final 1062 * working pipe after all information understood. 1063 */ 1064 pipe = &device->pipes[HIF_RX_DATA_PIPE]; 1065 usb_hif_post_recv_prestart_transfers(pipe, prestart_cnt); 1066 } 1067 1068 /** 1069 * usb_hif_start_recv_pipes() - start recv urbs 1070 * @device: HIF device for which recv urbs need to be posted 1071 * 1072 * This function is called after all prestart recv urbs are exhausted 1073 * 1074 * Return: none 1075 */ 1076 void usb_hif_start_recv_pipes(struct HIF_DEVICE_USB *device) 1077 { 1078 struct HIF_USB_PIPE *pipe; 1079 uint32_t buf_len; 1080 1081 HIF_ENTER(); 1082 pipe = &device->pipes[HIF_RX_DATA_PIPE]; 1083 pipe->urb_cnt_thresh = pipe->urb_alloc / 2; 1084 1085 hif_info("Post URBs to RX_DATA_PIPE: %d is_bundle %d", 1086 device->pipes[HIF_RX_DATA_PIPE].urb_cnt, 1087 device->is_bundle_enabled); 1088 if (device->is_bundle_enabled) { 1089 usb_hif_post_recv_bundle_transfers(pipe, 1090 pipe->device->rx_bundle_buf_len); 1091 } else { 1092 buf_len = HIF_USB_RX_BUFFER_SIZE; 1093 usb_hif_post_recv_transfers(pipe, buf_len); 1094 } 1095 1096 hif_debug("athusb bulk recv len %d", buf_len); 1097 1098 if (!hif_usb_disable_rxdata2) { 1099 hif_info("Post URBs to RX_DATA2_PIPE: %d", 1100 device->pipes[HIF_RX_DATA2_PIPE].urb_cnt); 1101 1102 pipe = &device->pipes[HIF_RX_DATA2_PIPE]; 1103 pipe->urb_cnt_thresh = pipe->urb_alloc / 2; 1104 usb_hif_post_recv_transfers(pipe, HIF_USB_RX_BUFFER_SIZE); 1105 } 1106 1107 if (device->rx_ctrl_pipe_supported) { 1108 hif_info("Post URBs to RX_CONTROL_PIPE: %d", 1109 device->pipes[HIF_RX_CTRL_PIPE].urb_cnt); 1110 1111 pipe = &device->pipes[HIF_RX_CTRL_PIPE]; 1112 pipe->urb_cnt_thresh = pipe->urb_alloc / 2; 1113 usb_hif_post_recv_transfers(pipe, HIF_USB_RX_BUFFER_SIZE); 1114 } 1115 HIF_EXIT(); 1116 } 1117 1118 /** 1119 * usb_hif_submit_ctrl_out() - send out a ctrl urb 1120 * @device: HIF device for which urb needs to be posted 1121 * @req: request value for the ctrl message 1122 * @value: USB message value 1123 * @index: USB message index value 1124 * @data: pointer to data containing ctrl message to send 1125 * @size: size of the control message to send 1126 * 1127 * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error 1128 */ 1129 QDF_STATUS usb_hif_submit_ctrl_out(struct HIF_DEVICE_USB *device, 1130 uint8_t req, uint16_t value, uint16_t index, 1131 void *data, uint32_t size) 1132 { 1133 int32_t result = 0; 1134 QDF_STATUS ret = QDF_STATUS_SUCCESS; 1135 uint8_t *buf = NULL; 1136 1137 do { 1138 1139 if (size > 0) { 1140 buf = qdf_mem_malloc(size); 1141 if (!buf) { 1142 ret = QDF_STATUS_E_NOMEM; 1143 break; 1144 } 1145 qdf_mem_copy(buf, (uint8_t *) data, size); 1146 } 1147 1148 hif_debug("ctrl-out req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d", 1149 req, value, index, size); 1150 1151 result = usb_control_msg(device->udev, 1152 usb_sndctrlpipe(device->udev, 0), 1153 req, 1154 USB_DIR_OUT | USB_TYPE_VENDOR | 1155 USB_RECIP_DEVICE, value, index, buf, 1156 size, 2 * HZ); 1157 1158 if (result < 0) { 1159 hif_err("usb_control_msg failed, (result=%d)", result); 1160 ret = QDF_STATUS_E_FAILURE; 1161 } 1162 1163 } while (false); 1164 1165 if (buf) 1166 qdf_mem_free(buf); 1167 1168 return ret; 1169 } 1170 1171 /** 1172 * usb_hif_submit_ctrl_in() - recv a response to the ctrl message sent out 1173 * @device: HIF device for which urb needs to be received 1174 * @req: request value for the ctrl message 1175 * @value: USB message value 1176 * @index: USB message index value 1177 * @data: pointer to data containing ctrl message to be received 1178 * @size: size of the control message to be received 1179 * 1180 * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error 1181 */ 1182 QDF_STATUS usb_hif_submit_ctrl_in(struct HIF_DEVICE_USB *device, 1183 uint8_t req, uint16_t value, uint16_t index, 1184 void *data, uint32_t size) 1185 { 1186 int32_t result = 0; 1187 QDF_STATUS ret = QDF_STATUS_SUCCESS; 1188 uint8_t *buf = NULL; 1189 1190 do { 1191 1192 if (size > 0) { 1193 buf = qdf_mem_malloc(size); 1194 if (!buf) { 1195 ret = QDF_STATUS_E_NOMEM; 1196 break; 1197 } 1198 } 1199 1200 hif_debug("ctrl-in req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d", 1201 req, value, index, size); 1202 1203 result = usb_control_msg(device->udev, 1204 usb_rcvctrlpipe(device->udev, 0), 1205 req, 1206 USB_DIR_IN | USB_TYPE_VENDOR | 1207 USB_RECIP_DEVICE, value, index, buf, 1208 size, 2 * HZ); 1209 1210 if (result < 0) { 1211 hif_err("usb_control_msg failed, (result=%d)", result); 1212 ret = QDF_STATUS_E_FAILURE; 1213 break; 1214 } 1215 1216 qdf_mem_copy((uint8_t *) data, buf, size); 1217 1218 } while (false); 1219 1220 if (buf) 1221 qdf_mem_free(buf); 1222 1223 return ret; 1224 } 1225 1226 /** 1227 * usb_hif_io_complete() - transmit call back for tx urb 1228 * @pipe: pointer to struct HIF_USB_PIPE 1229 * 1230 * Return: none 1231 */ 1232 static void usb_hif_io_complete(struct HIF_USB_PIPE *pipe) 1233 { 1234 qdf_nbuf_t buf; 1235 struct HIF_DEVICE_USB *device; 1236 HTC_FRAME_HDR *HtcHdr; 1237 uint8_t *data; 1238 uint32_t len; 1239 struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device); 1240 1241 device = pipe->device; 1242 HIF_ENTER(); 1243 while ((buf = skb_dequeue(&pipe->io_comp_queue))) { 1244 if (pipe->flags & HIF_USB_PIPE_FLAG_TX) { 1245 hif_debug("+athusb xmit callback buf:0x%pK", buf); 1246 HtcHdr = (HTC_FRAME_HDR *) 1247 qdf_nbuf_get_frag_vaddr(buf, 0); 1248 1249 #ifdef ATH_11AC_TXCOMPACT 1250 /* ATH_11AC_TXCOMPACT does not support High Latency mode */ 1251 #else 1252 device->htc_callbacks.txCompletionHandler(device-> 1253 htc_callbacks. 1254 Context, buf, 1255 HtcHdr-> 1256 EndpointID, 0); 1257 #endif 1258 hif_debug("-athusb xmit callback"); 1259 } else { 1260 hif_debug("+athusb recv callback buf: 0x%pK", buf); 1261 qdf_nbuf_peek_header(buf, &data, &len); 1262 1263 if (IS_FW_CRASH_DUMP(*((uint32_t *) data))) { 1264 sc->fw_data = data; 1265 sc->fw_data_len = len; 1266 device->htc_callbacks.fwEventHandler( 1267 device->htc_callbacks.Context, 1268 QDF_STATUS_E_USB_ERROR); 1269 qdf_nbuf_free(buf); 1270 } else { 1271 device->htc_callbacks.rxCompletionHandler( 1272 device->htc_callbacks.Context, buf, 1273 pipe->logical_pipe_num); 1274 } 1275 hif_debug("-athusb recv callback"); 1276 } 1277 } 1278 1279 HIF_EXIT(); 1280 } 1281 1282 #ifdef HIF_USB_TASKLET 1283 /** 1284 * usb_hif_io_comp_tasklet() - per pipe tasklet routine 1285 * @context: pointer to HIF USB pipe 1286 * 1287 * Return: none 1288 */ 1289 void usb_hif_io_comp_tasklet(unsigned long context) 1290 { 1291 struct HIF_USB_PIPE *pipe = (struct HIF_USB_PIPE *) context; 1292 1293 usb_hif_io_complete(pipe); 1294 } 1295 1296 #else 1297 /** 1298 * usb_hif_io_comp_work() - per pipe work queue 1299 * @work: pointer to struct work_struct 1300 * 1301 * Return: none 1302 */ 1303 void usb_hif_io_comp_work(struct work_struct *work) 1304 { 1305 struct HIF_USB_PIPE *pipe = container_of(work, struct HIF_USB_PIPE, 1306 io_complete_work); 1307 1308 usb_hif_io_complete(pipe); 1309 } 1310 #endif 1311