1 /* 2 * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #define ATH_MODULE_NAME hif 20 #include "a_debug.h" 21 #include "hif_usb_internal.h" 22 #include "if_usb.h" 23 #include "cds_api.h" 24 #include "hif_debug.h" 25 26 #define IS_BULK_EP(attr) (((attr) & 3) == 0x02) 27 #define IS_INT_EP(attr) (((attr) & 3) == 0x03) 28 #define IS_ISOC_EP(attr) (((attr) & 3) == 0x01) 29 #define IS_DIR_IN(addr) ((addr) & 0x80) 30 31 #define IS_FW_CRASH_DUMP(x)(((x == FW_ASSERT_PATTERN) || \ 32 (x == FW_REG_PATTERN) || \ 33 ((x & FW_RAMDUMP_PATTERN_MASK) == \ 34 FW_RAMDUMP_PATTERN)) ? 1 : 0) 35 36 static void usb_hif_post_recv_transfers(struct HIF_USB_PIPE *recv_pipe, 37 int buffer_length); 38 static void usb_hif_post_recv_bundle_transfers 39 (struct HIF_USB_PIPE *recv_pipe, 40 int buffer_length); 41 static void usb_hif_cleanup_recv_urb(struct HIF_URB_CONTEXT *urb_context); 42 43 44 /** 45 * usb_hif_free_urb_to_pipe() - add urb back to urb list of a pipe 46 * @pipe: pointer to struct HIF_USB_PIPE 47 * @urb_context: pointer to struct HIF_URB_CONTEXT 48 * 49 * Return: none 50 */ 51 static void usb_hif_free_urb_to_pipe(struct HIF_USB_PIPE *pipe, 52 struct HIF_URB_CONTEXT *urb_context) 53 { 54 qdf_spin_lock_irqsave(&pipe->device->cs_lock); 55 pipe->urb_cnt++; 56 DL_ListAdd(&pipe->urb_list_head, &urb_context->link); 57 qdf_spin_unlock_irqrestore(&pipe->device->cs_lock); 58 } 59 60 /** 61 * usb_hif_alloc_urb_from_pipe() - remove urb back from urb list of a pipe 62 * @pipe: pointer to struct HIF_USB_PIPE 63 * 64 * Return: struct HIF_URB_CONTEXT urb context removed from the urb list 65 */ 66 struct HIF_URB_CONTEXT *usb_hif_alloc_urb_from_pipe(struct HIF_USB_PIPE *pipe) 67 { 68 struct HIF_URB_CONTEXT *urb_context = NULL; 69 DL_LIST *item; 70 71 qdf_spin_lock_irqsave(&pipe->device->cs_lock); 72 item = dl_list_remove_item_from_head(&pipe->urb_list_head); 73 if (item != NULL) { 74 urb_context = A_CONTAINING_STRUCT(item, struct HIF_URB_CONTEXT, 75 link); 76 pipe->urb_cnt--; 77 } 78 qdf_spin_unlock_irqrestore(&pipe->device->cs_lock); 79 80 return urb_context; 81 } 82 83 /** 84 * usb_hif_dequeue_pending_transfer() - remove urb from pending xfer list 85 * @pipe: pointer to struct HIF_USB_PIPE 86 * 87 * Return: struct HIF_URB_CONTEXT urb context removed from the pending xfer list 88 */ 89 static struct HIF_URB_CONTEXT *usb_hif_dequeue_pending_transfer 90 (struct HIF_USB_PIPE *pipe) 91 { 92 struct HIF_URB_CONTEXT *urb_context = NULL; 93 DL_LIST *item; 94 95 qdf_spin_lock_irqsave(&pipe->device->cs_lock); 96 item = dl_list_remove_item_from_head(&pipe->urb_pending_list); 97 if (item != NULL) 98 urb_context = A_CONTAINING_STRUCT(item, struct HIF_URB_CONTEXT, 99 link); 100 qdf_spin_unlock_irqrestore(&pipe->device->cs_lock); 101 102 return urb_context; 103 } 104 105 /** 106 * usb_hif_enqueue_pending_transfer() - add urb to pending xfer list 107 * @pipe: pointer to struct HIF_USB_PIPE 108 * @urb_context: pointer to struct HIF_URB_CONTEXT to be added to the xfer list 109 * 110 * Return: none 111 */ 112 void usb_hif_enqueue_pending_transfer(struct HIF_USB_PIPE *pipe, 113 struct HIF_URB_CONTEXT *urb_context) 114 { 115 qdf_spin_lock_irqsave(&pipe->device->cs_lock); 116 dl_list_insert_tail(&pipe->urb_pending_list, &urb_context->link); 117 qdf_spin_unlock_irqrestore(&pipe->device->cs_lock); 118 } 119 120 121 /** 122 * usb_hif_remove_pending_transfer() - remove urb from its own list 123 * @urb_context: pointer to struct HIF_URB_CONTEXT to be removed 124 * 125 * Return: none 126 */ 127 void 128 usb_hif_remove_pending_transfer(struct HIF_URB_CONTEXT *urb_context) 129 { 130 qdf_spin_lock_irqsave(&urb_context->pipe->device->cs_lock); 131 dl_list_remove(&urb_context->link); 132 qdf_spin_unlock_irqrestore(&urb_context->pipe->device->cs_lock); 133 } 134 135 /** 136 * usb_hif_alloc_pipe_resources() - allocate urb_cnt urbs to a HIF pipe 137 * @pipe: pointer to struct HIF_USB_PIPE to which resources will be allocated 138 * @urb_cnt: number of urbs to be added to the HIF pipe 139 * 140 * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error 141 */ 142 static QDF_STATUS usb_hif_alloc_pipe_resources 143 (struct HIF_USB_PIPE *pipe, int urb_cnt) 144 { 145 QDF_STATUS status = QDF_STATUS_SUCCESS; 146 int i; 147 struct HIF_URB_CONTEXT *urb_context; 148 149 DL_LIST_INIT(&pipe->urb_list_head); 150 DL_LIST_INIT(&pipe->urb_pending_list); 151 152 for (i = 0; i < urb_cnt; i++) { 153 urb_context = qdf_mem_malloc(sizeof(*urb_context)); 154 if (NULL == urb_context) { 155 status = QDF_STATUS_E_NOMEM; 156 HIF_ERROR("urb_context is null"); 157 break; 158 } 159 urb_context->pipe = pipe; 160 urb_context->urb = usb_alloc_urb(0, GFP_KERNEL); 161 162 if (NULL == urb_context->urb) { 163 status = QDF_STATUS_E_NOMEM; 164 qdf_mem_free(urb_context); 165 HIF_ERROR("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_DBG("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 (NULL == pipe->device) { 196 /* nothing allocated for this pipe */ 197 HIF_ERROR("pipe->device is null"); 198 return; 199 } 200 201 HIF_TRACE("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_ERROR("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 (NULL == 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 CONFIG_QCN7605 231 /** 232 * usb_hif_get_logical_pipe_num() - get pipe number for a particular enpoint 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 enpoint 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 /* CONFIG_QCN7605 */ 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 decriptors 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_DBG("%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_DBG("%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_DBG("%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 != NULL) { 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_TRACE("+%s pipe : %d", __func__, pipe->logical_pipe_num); 464 465 while (1) { 466 urb_context = usb_hif_dequeue_pending_transfer(pipe); 467 if (NULL == urb_context) { 468 HIF_WARN("urb_context is NULL"); 469 break; 470 } 471 HIF_TRACE(" pending urb ctxt: 0x%pK", urb_context); 472 if (urb_context->urb != NULL) { 473 HIF_TRACE(" 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_TRACE("-%s", __func__); 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_TRACE("+%s", __func__); 495 496 for (i = 0; i < HIF_USB_PIPE_MAX; i++) { 497 if (device->pipes[i].device != NULL) { 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_TRACE("-%s", __func__); 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 HIF_TRACE("+%s", __func__); 517 518 if (urb_context->buf != NULL) { 519 qdf_nbuf_free(urb_context->buf); 520 urb_context->buf = NULL; 521 } 522 523 usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context); 524 HIF_TRACE("-%s", __func__); 525 } 526 527 /** 528 * usb_hif_cleanup_transmit_urb() - cleanup transmit urb 529 * @urb_context: pointer to struct HIF_URB_CONTEXT structure 530 * 531 * Return: none 532 */ 533 void usb_hif_cleanup_transmit_urb(struct HIF_URB_CONTEXT *urb_context) 534 { 535 usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context); 536 } 537 538 /** 539 * usb_hif_usb_recv_prestart_complete() - completion routine for prestart rx urb 540 * @urb: urb for which the completion routine is being called 541 * 542 * Return: none 543 */ 544 static void usb_hif_usb_recv_prestart_complete 545 (struct urb *urb) 546 { 547 struct HIF_URB_CONTEXT *urb_context = 548 (struct HIF_URB_CONTEXT *) urb->context; 549 QDF_STATUS status = QDF_STATUS_SUCCESS; 550 qdf_nbuf_t buf = NULL; 551 struct HIF_USB_PIPE *pipe = urb_context->pipe; 552 553 HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%pK", 554 __func__, 555 pipe->logical_pipe_num, 556 urb->status, urb->actual_length, 557 urb); 558 559 /* this urb is not pending anymore */ 560 usb_hif_remove_pending_transfer(urb_context); 561 do { 562 if (urb->status != 0) { 563 status = A_ECOMM; 564 switch (urb->status) { 565 case -ECONNRESET: 566 case -ENOENT: 567 case -ESHUTDOWN: 568 /* NOTE: no need to spew these errors when 569 * device is removed 570 * or urb is killed due to driver shutdown 571 */ 572 status = A_ECANCELED; 573 break; 574 default: 575 HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d", 576 __func__, 577 pipe->logical_pipe_num, 578 pipe->ep_address, 579 urb->status); 580 break; 581 } 582 break; 583 } 584 if (urb->actual_length == 0) 585 break; 586 buf = urb_context->buf; 587 /* we are going to pass it up */ 588 urb_context->buf = NULL; 589 qdf_nbuf_put_tail(buf, urb->actual_length); 590 591 if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) { 592 uint8_t *data; 593 uint32_t len; 594 595 qdf_nbuf_peek_header(buf, &data, &len); 596 debug_dump_bytes(data, len, "hif recv data"); 597 } 598 /* note: queue implements a lock */ 599 skb_queue_tail(&pipe->io_comp_queue, buf); 600 601 HIF_USB_SCHEDULE_WORK(pipe); 602 } while (false); 603 604 usb_hif_cleanup_recv_urb(urb_context); 605 606 /* Prestart URBs runs out and now start working receive pipe. */ 607 if (--pipe->urb_prestart_cnt == 0) 608 usb_hif_start_recv_pipes(pipe->device); 609 610 HIF_DBG("-%s", __func__); 611 } 612 613 /** 614 * usb_hif_usb_recv_complete() - completion routine for rx urb 615 * @urb: urb for which the completion routine is being called 616 * 617 * Return: none 618 */ 619 static void usb_hif_usb_recv_complete(struct urb *urb) 620 { 621 struct HIF_URB_CONTEXT *urb_context = 622 (struct HIF_URB_CONTEXT *) urb->context; 623 QDF_STATUS status = QDF_STATUS_SUCCESS; 624 qdf_nbuf_t buf = NULL; 625 struct HIF_USB_PIPE *pipe = urb_context->pipe; 626 struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device); 627 628 HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%pK", 629 __func__, 630 pipe->logical_pipe_num, 631 urb->status, urb->actual_length, 632 urb); 633 634 /* this urb is not pending anymore */ 635 usb_hif_remove_pending_transfer(urb_context); 636 637 do { 638 639 if (urb->status != 0) { 640 status = A_ECOMM; 641 switch (urb->status) { 642 #ifdef RX_SG_SUPPORT 643 case -EOVERFLOW: 644 urb->actual_length = HIF_USB_RX_BUFFER_SIZE; 645 status = QDF_STATUS_SUCCESS; 646 break; 647 #endif 648 case -ECONNRESET: 649 case -ENOENT: 650 case -ESHUTDOWN: 651 /* NOTE: no need to spew these errors when 652 * device is removed 653 * or urb is killed due to driver shutdown 654 */ 655 status = A_ECANCELED; 656 break; 657 default: 658 HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d", 659 __func__, 660 pipe->logical_pipe_num, 661 pipe->ep_address, 662 urb->status); 663 break; 664 } 665 break; 666 } 667 if (urb->actual_length == 0) 668 break; 669 buf = urb_context->buf; 670 /* we are going to pass it up */ 671 urb_context->buf = NULL; 672 qdf_nbuf_put_tail(buf, urb->actual_length); 673 if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) { 674 uint8_t *data; 675 uint32_t len; 676 677 qdf_nbuf_peek_header(buf, &data, &len); 678 debug_dump_bytes(data, len, "hif recv data"); 679 } 680 /* note: queue implements a lock */ 681 skb_queue_tail(&pipe->io_comp_queue, buf); 682 HIF_USB_SCHEDULE_WORK(pipe); 683 } while (false); 684 685 usb_hif_cleanup_recv_urb(urb_context); 686 687 /* Only re-submit URB when STATUS is success and HIF is not at the 688 * suspend state. 689 */ 690 if (QDF_IS_STATUS_SUCCESS(status) && !sc->suspend_state) { 691 if (pipe->urb_cnt >= pipe->urb_cnt_thresh) { 692 /* our free urbs are piling up, post more transfers */ 693 usb_hif_post_recv_transfers(pipe, 694 HIF_USB_RX_BUFFER_SIZE); 695 } 696 } else { 697 HIF_ERROR("%s: pipe: %d, fail to post URB: status(%d) suspend (%d)", 698 __func__, 699 pipe->logical_pipe_num, 700 urb->status, 701 sc->suspend_state); 702 } 703 704 HIF_DBG("-%s", __func__); 705 } 706 707 /** 708 * usb_hif_usb_recv_bundle_complete() - completion routine for rx bundling urb 709 * @urb: urb for which the completion routine is being called 710 * 711 * Return: none 712 */ 713 static void usb_hif_usb_recv_bundle_complete(struct urb *urb) 714 { 715 struct HIF_URB_CONTEXT *urb_context = 716 (struct HIF_URB_CONTEXT *) urb->context; 717 QDF_STATUS status = QDF_STATUS_SUCCESS; 718 qdf_nbuf_t buf = NULL; 719 struct HIF_USB_PIPE *pipe = urb_context->pipe; 720 uint8_t *netdata, *netdata_new; 721 uint32_t netlen, netlen_new; 722 HTC_FRAME_HDR *HtcHdr; 723 uint16_t payloadLen; 724 qdf_nbuf_t new_skb = NULL; 725 726 HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%pK", 727 __func__, 728 pipe->logical_pipe_num, 729 urb->status, urb->actual_length, 730 urb); 731 732 /* this urb is not pending anymore */ 733 usb_hif_remove_pending_transfer(urb_context); 734 735 do { 736 737 if (urb->status != 0) { 738 status = A_ECOMM; 739 switch (urb->status) { 740 case -ECONNRESET: 741 case -ENOENT: 742 case -ESHUTDOWN: 743 /* NOTE: no need to spew these errors when 744 * device is removed 745 * or urb is killed due to driver shutdown 746 */ 747 status = A_ECANCELED; 748 break; 749 default: 750 HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d", 751 __func__, 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 773 do { 774 uint16_t frame_len; 775 776 if (IS_FW_CRASH_DUMP(*(uint32_t *) netdata)) 777 frame_len = netlen; 778 else { 779 /* Hack into HTC header for bundle processing */ 780 HtcHdr = (HTC_FRAME_HDR *) netdata; 781 if (HtcHdr->EndpointID >= ENDPOINT_MAX) { 782 HIF_ERROR("athusb: Rx: invalid EndpointID=%d", 783 HtcHdr->EndpointID); 784 break; 785 } 786 787 payloadLen = HtcHdr->PayloadLen; 788 payloadLen = qdf_le16_to_cpu(payloadLen); 789 790 if (payloadLen > HIF_USB_RX_BUFFER_SIZE) { 791 HIF_ERROR("athusb: payloadLen too long %u", 792 payloadLen); 793 break; 794 } 795 frame_len = (HTC_HDR_LENGTH + payloadLen); 796 } 797 798 if (netlen < frame_len) { 799 HIF_ERROR("athusb: subframe length %d not fitted into bundle packet length %d" 800 , netlen, frame_len); 801 break; 802 } 803 804 /* allocate a new skb and copy */ 805 new_skb = 806 qdf_nbuf_alloc(NULL, frame_len, 0, 4, false); 807 if (new_skb == NULL) { 808 HIF_ERROR("athusb: allocate skb (len=%u) failed" 809 , frame_len); 810 break; 811 } 812 813 qdf_nbuf_peek_header(new_skb, &netdata_new, 814 &netlen_new); 815 qdf_mem_copy(netdata_new, netdata, frame_len); 816 qdf_nbuf_put_tail(new_skb, frame_len); 817 skb_queue_tail(&pipe->io_comp_queue, new_skb); 818 new_skb = NULL; 819 netdata += frame_len; 820 netlen -= frame_len; 821 } while (netlen); 822 HIF_USB_SCHEDULE_WORK(pipe); 823 } while (false); 824 825 if (urb_context->buf == NULL) 826 HIF_ERROR("athusb: buffer in urb_context is NULL"); 827 828 /* reset urb_context->buf ==> seems not necessary */ 829 usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context); 830 831 if (QDF_IS_STATUS_SUCCESS(status)) { 832 if (pipe->urb_cnt >= pipe->urb_cnt_thresh) { 833 /* our free urbs are piling up, post more transfers */ 834 usb_hif_post_recv_bundle_transfers(pipe, 835 pipe->device->rx_bundle_buf_len); 836 } 837 } 838 839 HIF_DBG("-%s", __func__); 840 } 841 842 /** 843 * usb_hif_post_recv_prestart_transfers() - post prestart recv urbs for a pipe 844 * @recv_pipe: rx data pipe 845 * @prestart_urb: number of prestart recv urbs to be posted 846 * 847 * Return: none 848 */ 849 static void usb_hif_post_recv_prestart_transfers(struct HIF_USB_PIPE *recv_pipe, 850 int prestart_urb) 851 { 852 struct HIF_URB_CONTEXT *urb_context; 853 uint8_t *data; 854 uint32_t len; 855 struct urb *urb; 856 int i, usb_status, buffer_length = HIF_USB_RX_BUFFER_SIZE; 857 858 HIF_TRACE("+%s", __func__); 859 860 for (i = 0; i < prestart_urb; i++) { 861 urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe); 862 if (NULL == urb_context) 863 break; 864 865 urb_context->buf = 866 qdf_nbuf_alloc(NULL, buffer_length, 0, 4, false); 867 if (NULL == urb_context->buf) { 868 usb_hif_cleanup_recv_urb(urb_context); 869 break; 870 } 871 872 qdf_nbuf_peek_header(urb_context->buf, &data, &len); 873 874 urb = urb_context->urb; 875 876 usb_fill_bulk_urb(urb, 877 recv_pipe->device->udev, 878 recv_pipe->usb_pipe_handle, 879 data, 880 buffer_length, 881 usb_hif_usb_recv_prestart_complete, 882 urb_context); 883 884 HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK", 885 recv_pipe->logical_pipe_num, 886 recv_pipe->usb_pipe_handle, 887 recv_pipe->ep_address, buffer_length, 888 urb_context->buf); 889 890 usb_hif_enqueue_pending_transfer(recv_pipe, urb_context); 891 892 usb_status = usb_submit_urb(urb, GFP_ATOMIC); 893 894 if (usb_status) { 895 HIF_ERROR("athusb : usb bulk recv failed %d", 896 usb_status); 897 usb_hif_remove_pending_transfer(urb_context); 898 usb_hif_cleanup_recv_urb(urb_context); 899 break; 900 } 901 recv_pipe->urb_prestart_cnt++; 902 } 903 904 HIF_TRACE("-%s", __func__); 905 } 906 907 /** 908 * usb_hif_post_recv_transfers() - post recv urbs for a given pipe 909 * @recv_pipe: recv pipe for which urbs need to be posted 910 * @buffer_length: buffer length of the recv urbs 911 * 912 * Return: none 913 */ 914 static void usb_hif_post_recv_transfers(struct HIF_USB_PIPE *recv_pipe, 915 int buffer_length) 916 { 917 struct HIF_URB_CONTEXT *urb_context; 918 uint8_t *data; 919 uint32_t len; 920 struct urb *urb; 921 int usb_status; 922 923 HIF_TRACE("+%s", __func__); 924 925 while (1) { 926 927 urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe); 928 if (NULL == urb_context) 929 break; 930 931 urb_context->buf = qdf_nbuf_alloc(NULL, buffer_length, 0, 932 4, false); 933 if (NULL == urb_context->buf) { 934 usb_hif_cleanup_recv_urb(urb_context); 935 break; 936 } 937 938 qdf_nbuf_peek_header(urb_context->buf, &data, &len); 939 940 urb = urb_context->urb; 941 942 usb_fill_bulk_urb(urb, 943 recv_pipe->device->udev, 944 recv_pipe->usb_pipe_handle, 945 data, 946 buffer_length, 947 usb_hif_usb_recv_complete, urb_context); 948 949 HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK", 950 recv_pipe->logical_pipe_num, 951 recv_pipe->usb_pipe_handle, 952 recv_pipe->ep_address, buffer_length, 953 urb_context->buf); 954 955 usb_hif_enqueue_pending_transfer(recv_pipe, urb_context); 956 957 usb_status = usb_submit_urb(urb, GFP_ATOMIC); 958 959 if (usb_status) { 960 HIF_ERROR("athusb : usb bulk recv failed %d", 961 usb_status); 962 usb_hif_remove_pending_transfer(urb_context); 963 usb_hif_cleanup_recv_urb(urb_context); 964 break; 965 } 966 } 967 968 HIF_TRACE("-%s", __func__); 969 970 } 971 972 /** 973 * usb_hif_post_recv_bundle_transfers() - post recv urbs for a given pipe 974 * @recv_pipe: recv pipe for which urbs need to be posted 975 * @buffer_length: maximum length of rx bundle 976 * 977 * Return: none 978 */ 979 static void usb_hif_post_recv_bundle_transfers(struct HIF_USB_PIPE *recv_pipe, 980 int buffer_length) 981 { 982 struct HIF_URB_CONTEXT *urb_context; 983 uint8_t *data; 984 uint32_t len; 985 struct urb *urb; 986 int usb_status; 987 988 HIF_TRACE("+%s", __func__); 989 990 while (1) { 991 992 urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe); 993 if (NULL == urb_context) 994 break; 995 996 if (NULL == urb_context->buf) { 997 urb_context->buf = 998 qdf_nbuf_alloc(NULL, buffer_length, 0, 4, false); 999 if (NULL == urb_context->buf) { 1000 usb_hif_cleanup_recv_urb(urb_context); 1001 break; 1002 } 1003 } 1004 1005 qdf_nbuf_peek_header(urb_context->buf, &data, &len); 1006 1007 urb = urb_context->urb; 1008 usb_fill_bulk_urb(urb, 1009 recv_pipe->device->udev, 1010 recv_pipe->usb_pipe_handle, 1011 data, 1012 buffer_length, 1013 usb_hif_usb_recv_bundle_complete, 1014 urb_context); 1015 1016 HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK", 1017 recv_pipe->logical_pipe_num, 1018 recv_pipe->usb_pipe_handle, 1019 recv_pipe->ep_address, buffer_length, 1020 urb_context->buf); 1021 1022 usb_hif_enqueue_pending_transfer(recv_pipe, urb_context); 1023 1024 usb_status = usb_submit_urb(urb, GFP_ATOMIC); 1025 1026 if (usb_status) { 1027 HIF_ERROR("athusb : usb bulk recv failed %d", 1028 usb_status); 1029 usb_hif_remove_pending_transfer(urb_context); 1030 usb_hif_free_urb_to_pipe(urb_context->pipe, 1031 urb_context); 1032 break; 1033 } 1034 1035 } 1036 1037 HIF_TRACE("-%s", __func__); 1038 1039 } 1040 1041 /** 1042 * usb_hif_prestart_recv_pipes() - post prestart recv urbs 1043 * @device: HIF device for which prestart recv urbs need to be posted 1044 * 1045 * Return: none 1046 */ 1047 void usb_hif_prestart_recv_pipes(struct HIF_DEVICE_USB *device) 1048 { 1049 struct HIF_USB_PIPE *pipe; 1050 int prestart_cnt = 8; 1051 1052 if (device->rx_ctrl_pipe_supported) { 1053 pipe = &device->pipes[HIF_RX_CTRL_PIPE]; 1054 prestart_cnt = 4; 1055 usb_hif_post_recv_prestart_transfers(pipe, prestart_cnt); 1056 } 1057 /* 1058 * USB driver learn to support bundle or not until the firmware 1059 * download and ready. Only allocate some URBs for control message 1060 * communication during the initial phase then start the final 1061 * working pipe after all information understood. 1062 */ 1063 pipe = &device->pipes[HIF_RX_DATA_PIPE]; 1064 usb_hif_post_recv_prestart_transfers(pipe, prestart_cnt); 1065 } 1066 1067 /** 1068 * usb_hif_start_recv_pipes() - start recv urbs 1069 * @device: HIF device for which recv urbs need to be posted 1070 * 1071 * This function is called after all prestart recv urbs are exhausted 1072 * 1073 * Return: none 1074 */ 1075 void usb_hif_start_recv_pipes(struct HIF_DEVICE_USB *device) 1076 { 1077 struct HIF_USB_PIPE *pipe; 1078 uint32_t buf_len; 1079 1080 HIF_ENTER(); 1081 pipe = &device->pipes[HIF_RX_DATA_PIPE]; 1082 pipe->urb_cnt_thresh = pipe->urb_alloc / 2; 1083 1084 HIF_TRACE("Post URBs to RX_DATA_PIPE: %d", 1085 device->pipes[HIF_RX_DATA_PIPE].urb_cnt); 1086 if (device->is_bundle_enabled) { 1087 usb_hif_post_recv_bundle_transfers(pipe, 1088 pipe->device->rx_bundle_buf_len); 1089 } else { 1090 buf_len = HIF_USB_RX_BUFFER_SIZE; 1091 usb_hif_post_recv_transfers(pipe, buf_len); 1092 } 1093 1094 HIF_DBG("athusb bulk recv len %d", buf_len); 1095 1096 if (!hif_usb_disable_rxdata2) { 1097 HIF_TRACE("Post URBs to RX_DATA2_PIPE: %d", 1098 device->pipes[HIF_RX_DATA2_PIPE].urb_cnt); 1099 1100 pipe = &device->pipes[HIF_RX_DATA2_PIPE]; 1101 pipe->urb_cnt_thresh = pipe->urb_alloc / 2; 1102 usb_hif_post_recv_transfers(pipe, HIF_USB_RX_BUFFER_SIZE); 1103 } 1104 1105 if (device->rx_ctrl_pipe_supported) { 1106 HIF_TRACE("Post URBs to RX_CONTROL_PIPE: %d", 1107 device->pipes[HIF_RX_CTRL_PIPE].urb_cnt); 1108 1109 pipe = &device->pipes[HIF_RX_CTRL_PIPE]; 1110 pipe->urb_cnt_thresh = pipe->urb_alloc / 2; 1111 usb_hif_post_recv_transfers(pipe, HIF_USB_RX_BUFFER_SIZE); 1112 } 1113 HIF_EXIT(); 1114 } 1115 1116 /** 1117 * usb_hif_submit_ctrl_out() - send out a ctrl urb 1118 * @device: HIF device for which urb needs to be posted 1119 * @req: request value for the ctrl message 1120 * @value: USB message value 1121 * @index: USB message index value 1122 * @data: pointer to data containing ctrl message to send 1123 * @size: size of the control message to send 1124 * 1125 * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error 1126 */ 1127 QDF_STATUS usb_hif_submit_ctrl_out(struct HIF_DEVICE_USB *device, 1128 uint8_t req, uint16_t value, uint16_t index, 1129 void *data, uint32_t size) 1130 { 1131 int32_t result = 0; 1132 QDF_STATUS ret = QDF_STATUS_SUCCESS; 1133 uint8_t *buf = NULL; 1134 1135 do { 1136 1137 if (size > 0) { 1138 buf = qdf_mem_malloc(size); 1139 if (NULL == buf) { 1140 ret = QDF_STATUS_E_NOMEM; 1141 break; 1142 } 1143 qdf_mem_copy(buf, (uint8_t *) data, size); 1144 } 1145 1146 HIF_DBG("ctrl-out req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d", 1147 req, value, index, size); 1148 1149 result = usb_control_msg(device->udev, 1150 usb_sndctrlpipe(device->udev, 0), 1151 req, 1152 USB_DIR_OUT | USB_TYPE_VENDOR | 1153 USB_RECIP_DEVICE, value, index, buf, 1154 size, 2 * HZ); 1155 1156 if (result < 0) { 1157 HIF_ERROR("%s failed,result = %d", __func__, result); 1158 ret = QDF_STATUS_E_FAILURE; 1159 } 1160 1161 } while (false); 1162 1163 if (buf != NULL) 1164 qdf_mem_free(buf); 1165 1166 return ret; 1167 } 1168 1169 /** 1170 * usb_hif_submit_ctrl_in() - recv a resonse to the ctrl message sent out 1171 * @device: HIF device for which urb needs to be received 1172 * @req: request value for the ctrl message 1173 * @value: USB message value 1174 * @index: USB message index value 1175 * @data: pointer to data containing ctrl message to be received 1176 * @size: size of the control message to be received 1177 * 1178 * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error 1179 */ 1180 QDF_STATUS usb_hif_submit_ctrl_in(struct HIF_DEVICE_USB *device, 1181 uint8_t req, uint16_t value, uint16_t index, 1182 void *data, uint32_t size) 1183 { 1184 int32_t result = 0; 1185 QDF_STATUS ret = QDF_STATUS_SUCCESS; 1186 uint8_t *buf = NULL; 1187 1188 do { 1189 1190 if (size > 0) { 1191 buf = qdf_mem_malloc(size); 1192 if (NULL == buf) { 1193 ret = QDF_STATUS_E_NOMEM; 1194 break; 1195 } 1196 } 1197 1198 HIF_DBG("ctrl-in req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d", 1199 req, value, index, size); 1200 1201 result = usb_control_msg(device->udev, 1202 usb_rcvctrlpipe(device->udev, 0), 1203 req, 1204 USB_DIR_IN | USB_TYPE_VENDOR | 1205 USB_RECIP_DEVICE, value, index, buf, 1206 size, 2 * HZ); 1207 1208 if (result < 0) { 1209 HIF_ERROR("%s failed, result = %d", __func__, result); 1210 ret = QDF_STATUS_E_FAILURE; 1211 break; 1212 } 1213 1214 qdf_mem_copy((uint8_t *) data, buf, size); 1215 1216 } while (false); 1217 1218 if (buf != NULL) 1219 qdf_mem_free(buf); 1220 1221 return ret; 1222 } 1223 1224 /** 1225 * usb_hif_io_complete() - transmit call back for tx urb 1226 * @pipe: pointer to struct HIF_USB_PIPE 1227 * 1228 * Return: none 1229 */ 1230 static void usb_hif_io_complete(struct HIF_USB_PIPE *pipe) 1231 { 1232 qdf_nbuf_t buf; 1233 struct HIF_DEVICE_USB *device; 1234 HTC_FRAME_HDR *HtcHdr; 1235 uint8_t *data; 1236 uint32_t len; 1237 struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device); 1238 1239 device = pipe->device; 1240 HIF_ENTER(); 1241 while ((buf = skb_dequeue(&pipe->io_comp_queue))) { 1242 if (pipe->flags & HIF_USB_PIPE_FLAG_TX) { 1243 HIF_DBG("+athusb xmit callback buf:0x%pK", buf); 1244 HtcHdr = (HTC_FRAME_HDR *) 1245 qdf_nbuf_get_frag_vaddr(buf, 0); 1246 1247 #ifdef ATH_11AC_TXCOMPACT 1248 /* ATH_11AC_TXCOMPACT does not support High Latency mode */ 1249 #else 1250 device->htc_callbacks.txCompletionHandler(device-> 1251 htc_callbacks. 1252 Context, buf, 1253 HtcHdr-> 1254 EndpointID, 0); 1255 #endif 1256 HIF_DBG("-athusb xmit callback"); 1257 } else { 1258 HIF_DBG("+athusb recv callback buf: 0x%pK", buf); 1259 qdf_nbuf_peek_header(buf, &data, &len); 1260 1261 if (IS_FW_CRASH_DUMP(*((uint32_t *) data))) { 1262 sc->fw_data = data; 1263 sc->fw_data_len = len; 1264 device->htc_callbacks.fwEventHandler( 1265 device->htc_callbacks.Context, 1266 QDF_STATUS_E_USB_ERROR); 1267 qdf_nbuf_free(buf); 1268 } else { 1269 device->htc_callbacks.rxCompletionHandler( 1270 device->htc_callbacks.Context, buf, 1271 pipe->logical_pipe_num); 1272 } 1273 HIF_DBG("-athusb recv callback"); 1274 } 1275 } 1276 1277 HIF_EXIT(); 1278 } 1279 1280 #ifdef HIF_USB_TASKLET 1281 /** 1282 * usb_hif_io_comp_tasklet() - per pipe tasklet routine 1283 * @context: pointer to HIF USB pipe 1284 * 1285 * Return: none 1286 */ 1287 void usb_hif_io_comp_tasklet(unsigned long context) 1288 { 1289 struct HIF_USB_PIPE *pipe = (struct HIF_USB_PIPE *) context; 1290 1291 usb_hif_io_complete(pipe); 1292 } 1293 1294 #else 1295 /** 1296 * usb_hif_io_comp_work() - per pipe work queue 1297 * @work: pointer to struct work_struct 1298 * 1299 * Return: none 1300 */ 1301 void usb_hif_io_comp_work(struct work_struct *work) 1302 { 1303 struct HIF_USB_PIPE *pipe = container_of(work, struct HIF_USB_PIPE, 1304 io_complete_work); 1305 1306 usb_hif_io_complete(pipe); 1307 } 1308 #endif 1309