1 /* 2 * Copyright (c) 2013-2019 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) { 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) 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 (!urb_context) { 155 status = QDF_STATUS_E_NOMEM; 156 break; 157 } 158 urb_context->pipe = pipe; 159 urb_context->urb = usb_alloc_urb(0, GFP_KERNEL); 160 161 if (!urb_context->urb) { 162 status = QDF_STATUS_E_NOMEM; 163 qdf_mem_free(urb_context); 164 HIF_ERROR("urb_context->urb is null"); 165 break; 166 } 167 168 /* note we are only allocate the urb contexts here, the actual 169 * URB is 170 * allocated from the kernel as needed to do a transaction 171 */ 172 pipe->urb_alloc++; 173 174 usb_hif_free_urb_to_pipe(pipe, urb_context); 175 } 176 177 HIF_DBG("athusb: alloc resources lpipe:%d hpipe:0x%X urbs:%d", 178 pipe->logical_pipe_num, 179 pipe->usb_pipe_handle, 180 pipe->urb_alloc); 181 return status; 182 } 183 184 /** 185 * usb_hif_free_pipe_resources() - free urb resources allocated to a HIF pipe 186 * @pipe: pointer to struct HIF_USB_PIPE 187 * 188 * Return: none 189 */ 190 static void usb_hif_free_pipe_resources(struct HIF_USB_PIPE *pipe) 191 { 192 struct HIF_URB_CONTEXT *urb_context; 193 194 if (!pipe->device) { 195 /* nothing allocated for this pipe */ 196 HIF_ERROR("pipe->device is null"); 197 return; 198 } 199 200 HIF_TRACE("athusb: free resources lpipe:%d hpipe:0x%X urbs:%d avail:%d", 201 pipe->logical_pipe_num, 202 pipe->usb_pipe_handle, pipe->urb_alloc, 203 pipe->urb_cnt); 204 205 if (pipe->urb_alloc != pipe->urb_cnt) { 206 HIF_ERROR("athusb: urb leak! lpipe:%d hpipe:0x%X urbs:%d avail:%d", 207 pipe->logical_pipe_num, 208 pipe->usb_pipe_handle, pipe->urb_alloc, 209 pipe->urb_cnt); 210 } 211 212 while (true) { 213 urb_context = usb_hif_alloc_urb_from_pipe(pipe); 214 if (!urb_context) 215 break; 216 217 if (urb_context->buf) { 218 qdf_nbuf_free(urb_context->buf); 219 urb_context->buf = NULL; 220 } 221 222 usb_free_urb(urb_context->urb); 223 urb_context->urb = NULL; 224 qdf_mem_free(urb_context); 225 } 226 227 } 228 229 #ifdef QCN7605_SUPPORT 230 /** 231 * usb_hif_get_logical_pipe_num() - get pipe number for a particular enpoint 232 * @device: pointer to HIF_DEVICE_USB structure 233 * @ep_address: endpoint address 234 * @urb_count: number of urb resources to be allocated to the pipe 235 * 236 * Return: uint8_t pipe number corresponding to ep_address 237 */ 238 static uint8_t usb_hif_get_logical_pipe_num(struct HIF_DEVICE_USB *device, 239 uint8_t ep_address, 240 int *urb_count) 241 { 242 uint8_t pipe_num = HIF_USB_PIPE_INVALID; 243 244 switch (ep_address) { 245 case USB_EP_ADDR_APP_CTRL_IN: 246 pipe_num = HIF_RX_CTRL_PIPE; 247 *urb_count = RX_URB_COUNT; 248 break; 249 case USB_EP_ADDR_APP_DATA_IN: 250 pipe_num = HIF_RX_DATA_PIPE; 251 *urb_count = RX_URB_COUNT; 252 break; 253 break; 254 case USB_EP_ADDR_APP_CTRL_OUT: 255 pipe_num = HIF_TX_CTRL_PIPE; 256 *urb_count = TX_URB_COUNT; 257 break; 258 case USB_EP_ADDR_APP_DATA_OUT: 259 pipe_num = HIF_TX_DATA_LP_PIPE; 260 *urb_count = TX_URB_COUNT; 261 break; 262 default: 263 /* note: there may be endpoints not currently used */ 264 break; 265 } 266 267 return pipe_num; 268 } 269 #else 270 /** 271 * usb_hif_get_logical_pipe_num() - get pipe number for a particular enpoint 272 * @device: pointer to HIF_DEVICE_USB structure 273 * @ep_address: endpoint address 274 * @urb_count: number of urb resources to be allocated to the pipe 275 * 276 * Return: uint8_t pipe number corresponding to ep_address 277 */ 278 static uint8_t usb_hif_get_logical_pipe_num 279 (struct HIF_DEVICE_USB *device, 280 uint8_t ep_address, 281 int *urb_count) 282 { 283 uint8_t pipe_num = HIF_USB_PIPE_INVALID; 284 285 switch (ep_address) { 286 case USB_EP_ADDR_APP_CTRL_IN: 287 pipe_num = HIF_RX_CTRL_PIPE; 288 *urb_count = RX_URB_COUNT; 289 break; 290 case USB_EP_ADDR_APP_DATA_IN: 291 pipe_num = HIF_RX_DATA_PIPE; 292 *urb_count = RX_URB_COUNT; 293 break; 294 case USB_EP_ADDR_APP_INT_IN: 295 pipe_num = HIF_RX_INT_PIPE; 296 *urb_count = RX_URB_COUNT; 297 break; 298 case USB_EP_ADDR_APP_DATA2_IN: 299 pipe_num = HIF_RX_DATA2_PIPE; 300 *urb_count = RX_URB_COUNT; 301 break; 302 case USB_EP_ADDR_APP_CTRL_OUT: 303 pipe_num = HIF_TX_CTRL_PIPE; 304 *urb_count = TX_URB_COUNT; 305 break; 306 case USB_EP_ADDR_APP_DATA_LP_OUT: 307 pipe_num = HIF_TX_DATA_LP_PIPE; 308 *urb_count = TX_URB_COUNT; 309 break; 310 case USB_EP_ADDR_APP_DATA_MP_OUT: 311 pipe_num = HIF_TX_DATA_MP_PIPE; 312 *urb_count = TX_URB_COUNT; 313 break; 314 case USB_EP_ADDR_APP_DATA_HP_OUT: 315 pipe_num = HIF_TX_DATA_HP_PIPE; 316 *urb_count = TX_URB_COUNT; 317 break; 318 default: 319 /* note: there may be endpoints not currently used */ 320 break; 321 } 322 323 return pipe_num; 324 } 325 #endif /* QCN7605_SUPPORT */ 326 327 /** 328 * usb_hif_get_logical_pipe_num() - setup urb resources for all pipes 329 * @device: pointer to HIF_DEVICE_USB structure 330 * 331 * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error 332 */ 333 QDF_STATUS usb_hif_setup_pipe_resources(struct HIF_DEVICE_USB *device) 334 { 335 struct usb_interface *interface = device->interface; 336 struct usb_host_interface *iface_desc = interface->cur_altsetting; 337 struct usb_endpoint_descriptor *endpoint; 338 int i; 339 int urbcount; 340 QDF_STATUS status = QDF_STATUS_SUCCESS; 341 struct HIF_USB_PIPE *pipe; 342 uint8_t pipe_num; 343 344 /* walk decriptors and setup pipes */ 345 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { 346 endpoint = &iface_desc->endpoint[i].desc; 347 348 if (IS_BULK_EP(endpoint->bmAttributes)) { 349 HIF_DBG("%s Bulk Ep:0x%2.2X maxpktsz:%d", 350 IS_DIR_IN(endpoint->bEndpointAddress) ? 351 "RX" : "TX", 352 endpoint->bEndpointAddress, 353 qdf_le16_to_cpu(endpoint->wMaxPacketSize)); 354 } else if (IS_INT_EP(endpoint->bmAttributes)) { 355 HIF_DBG("%s Int Ep:0x%2.2X maxpktsz:%d interval:%d", 356 IS_DIR_IN(endpoint->bEndpointAddress) ? 357 "RX" : "TX", 358 endpoint->bEndpointAddress, 359 qdf_le16_to_cpu(endpoint->wMaxPacketSize), 360 endpoint->bInterval); 361 } else if (IS_ISOC_EP(endpoint->bmAttributes)) { 362 /* TODO for ISO */ 363 HIF_DBG("%s ISOC Ep:0x%2.2X maxpktsz:%d interval:%d", 364 IS_DIR_IN(endpoint->bEndpointAddress) ? 365 "RX" : "TX", 366 endpoint->bEndpointAddress, 367 qdf_le16_to_cpu(endpoint->wMaxPacketSize), 368 endpoint->bInterval); 369 } 370 urbcount = 0; 371 372 pipe_num = usb_hif_get_logical_pipe_num(device, 373 endpoint->bEndpointAddress, 374 &urbcount); 375 if (HIF_USB_PIPE_INVALID == pipe_num) 376 continue; 377 378 pipe = &device->pipes[pipe_num]; 379 if (pipe->device) { 380 /*pipe was already setup */ 381 continue; 382 } 383 384 pipe->device = device; 385 pipe->logical_pipe_num = pipe_num; 386 pipe->ep_address = endpoint->bEndpointAddress; 387 pipe->max_packet_size = 388 qdf_le16_to_cpu(endpoint->wMaxPacketSize); 389 390 if (IS_BULK_EP(endpoint->bmAttributes)) { 391 if (IS_DIR_IN(pipe->ep_address)) { 392 pipe->usb_pipe_handle = 393 usb_rcvbulkpipe(device->udev, 394 pipe->ep_address); 395 } else { 396 pipe->usb_pipe_handle = 397 usb_sndbulkpipe(device->udev, 398 pipe->ep_address); 399 } 400 } else if (IS_INT_EP(endpoint->bmAttributes)) { 401 if (IS_DIR_IN(pipe->ep_address)) { 402 pipe->usb_pipe_handle = 403 usb_rcvintpipe(device->udev, 404 pipe->ep_address); 405 } else { 406 pipe->usb_pipe_handle = 407 usb_sndintpipe(device->udev, 408 pipe->ep_address); 409 } 410 } else if (IS_ISOC_EP(endpoint->bmAttributes)) { 411 /* TODO for ISO */ 412 if (IS_DIR_IN(pipe->ep_address)) { 413 pipe->usb_pipe_handle = 414 usb_rcvisocpipe(device->udev, 415 pipe->ep_address); 416 } else { 417 pipe->usb_pipe_handle = 418 usb_sndisocpipe(device->udev, 419 pipe->ep_address); 420 } 421 } 422 pipe->ep_desc = endpoint; 423 424 if (!IS_DIR_IN(pipe->ep_address)) 425 pipe->flags |= HIF_USB_PIPE_FLAG_TX; 426 427 status = usb_hif_alloc_pipe_resources(pipe, urbcount); 428 429 if (!QDF_IS_STATUS_SUCCESS(status)) 430 break; 431 432 } 433 434 return status; 435 } 436 437 438 /** 439 * usb_hif_cleanup_pipe_resources() - free urb resources for all pipes 440 * @device: pointer to HIF_DEVICE_USB structure 441 * 442 * Return: none 443 */ 444 void usb_hif_cleanup_pipe_resources(struct HIF_DEVICE_USB *device) 445 { 446 int i; 447 448 for (i = 0; i < HIF_USB_PIPE_MAX; i++) 449 usb_hif_free_pipe_resources(&device->pipes[i]); 450 } 451 452 /** 453 * usb_hif_flush_pending_transfers() - kill pending urbs for a pipe 454 * @pipe: pointer to struct HIF_USB_PIPE structure 455 * 456 * Return: none 457 */ 458 static void usb_hif_flush_pending_transfers(struct HIF_USB_PIPE *pipe) 459 { 460 struct HIF_URB_CONTEXT *urb_context; 461 462 HIF_TRACE("+%s pipe : %d", __func__, pipe->logical_pipe_num); 463 464 while (1) { 465 urb_context = usb_hif_dequeue_pending_transfer(pipe); 466 if (!urb_context) { 467 HIF_WARN("urb_context is NULL"); 468 break; 469 } 470 HIF_TRACE(" pending urb ctxt: 0x%pK", urb_context); 471 if (urb_context->urb) { 472 HIF_TRACE(" killing urb: 0x%pK", urb_context->urb); 473 /* killing the URB will cause the completion routines to 474 * run 475 */ 476 usb_kill_urb(urb_context->urb); 477 } 478 } 479 HIF_TRACE("-%s", __func__); 480 } 481 482 /** 483 * usb_hif_flush_all() - flush pending transfers for all pipes for a usb bus 484 * @device: pointer to HIF_DEVICE_USB structure 485 * 486 * Return: none 487 */ 488 void usb_hif_flush_all(struct HIF_DEVICE_USB *device) 489 { 490 int i; 491 struct HIF_USB_PIPE *pipe; 492 493 HIF_TRACE("+%s", __func__); 494 495 for (i = 0; i < HIF_USB_PIPE_MAX; i++) { 496 if (device->pipes[i].device) { 497 usb_hif_flush_pending_transfers(&device->pipes[i]); 498 pipe = &device->pipes[i]; 499 500 HIF_USB_FLUSH_WORK(pipe); 501 } 502 } 503 504 HIF_TRACE("-%s", __func__); 505 } 506 507 /** 508 * usb_hif_cleanup_recv_urb() - cleanup recv urb 509 * @urb_context: pointer to struct HIF_URB_CONTEXT structure 510 * 511 * Return: none 512 */ 513 static void usb_hif_cleanup_recv_urb(struct HIF_URB_CONTEXT *urb_context) 514 { 515 516 if (urb_context->buf) { 517 qdf_nbuf_free(urb_context->buf); 518 urb_context->buf = NULL; 519 } 520 521 usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context); 522 } 523 524 /** 525 * usb_hif_cleanup_transmit_urb() - cleanup transmit urb 526 * @urb_context: pointer to struct HIF_URB_CONTEXT structure 527 * 528 * Return: none 529 */ 530 void usb_hif_cleanup_transmit_urb(struct HIF_URB_CONTEXT *urb_context) 531 { 532 usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context); 533 } 534 535 /** 536 * usb_hif_usb_recv_prestart_complete() - completion routine for prestart rx urb 537 * @urb: urb for which the completion routine is being called 538 * 539 * Return: none 540 */ 541 static void usb_hif_usb_recv_prestart_complete 542 (struct urb *urb) 543 { 544 struct HIF_URB_CONTEXT *urb_context = 545 (struct HIF_URB_CONTEXT *) urb->context; 546 QDF_STATUS status = QDF_STATUS_SUCCESS; 547 qdf_nbuf_t buf = NULL; 548 struct HIF_USB_PIPE *pipe = urb_context->pipe; 549 struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device); 550 551 HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%pK", 552 __func__, 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_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d", 574 __func__, 575 pipe->logical_pipe_num, 576 pipe->ep_address, 577 urb->status); 578 break; 579 } 580 break; 581 } 582 if (urb->actual_length == 0) 583 break; 584 buf = urb_context->buf; 585 /* we are going to pass it up */ 586 urb_context->buf = NULL; 587 qdf_nbuf_put_tail(buf, urb->actual_length); 588 589 if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) { 590 uint8_t *data; 591 uint32_t len; 592 593 qdf_nbuf_peek_header(buf, &data, &len); 594 debug_dump_bytes(data, len, "hif recv data"); 595 } 596 /* note: queue implements a lock */ 597 skb_queue_tail(&pipe->io_comp_queue, buf); 598 599 HIF_USB_SCHEDULE_WORK(pipe); 600 } while (false); 601 602 usb_hif_cleanup_recv_urb(urb_context); 603 604 /* Prestart URBs runs out and now start working receive pipe. */ 605 qdf_spin_lock_irqsave(&pipe->device->rx_prestart_lock); 606 if ((--pipe->urb_prestart_cnt == 0) && !sc->suspend_state) 607 usb_hif_start_recv_pipes(pipe->device); 608 qdf_spin_unlock_irqrestore(&pipe->device->rx_prestart_lock); 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 683 if (pipe->device->htc_callbacks.update_bundle_stats) 684 pipe->device->htc_callbacks.update_bundle_stats 685 (pipe->device->htc_callbacks.Context, 1); 686 687 HIF_USB_SCHEDULE_WORK(pipe); 688 } while (false); 689 690 usb_hif_cleanup_recv_urb(urb_context); 691 692 /* Only re-submit URB when STATUS is success and HIF is not at the 693 * suspend state. 694 */ 695 if (QDF_IS_STATUS_SUCCESS(status) && !sc->suspend_state) { 696 if (pipe->urb_cnt >= pipe->urb_cnt_thresh) { 697 /* our free urbs are piling up, post more transfers */ 698 usb_hif_post_recv_transfers(pipe, 699 HIF_USB_RX_BUFFER_SIZE); 700 } 701 } else { 702 HIF_ERROR("%s: pipe: %d, fail to post URB: status(%d) suspend (%d)", 703 __func__, 704 pipe->logical_pipe_num, 705 urb->status, 706 sc->suspend_state); 707 } 708 709 HIF_DBG("-%s", __func__); 710 } 711 712 /** 713 * usb_hif_usb_recv_bundle_complete() - completion routine for rx bundling urb 714 * @urb: urb for which the completion routine is being called 715 * 716 * Return: none 717 */ 718 static void usb_hif_usb_recv_bundle_complete(struct urb *urb) 719 { 720 struct HIF_URB_CONTEXT *urb_context = 721 (struct HIF_URB_CONTEXT *) urb->context; 722 QDF_STATUS status = QDF_STATUS_SUCCESS; 723 qdf_nbuf_t buf = NULL; 724 struct HIF_USB_PIPE *pipe = urb_context->pipe; 725 uint8_t *netdata, *netdata_new; 726 uint32_t netlen, netlen_new; 727 HTC_FRAME_HDR *HtcHdr; 728 uint16_t payloadLen; 729 qdf_nbuf_t new_skb = NULL; 730 uint8_t no_of_pkt_in_bundle; 731 732 HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%pK", 733 __func__, 734 pipe->logical_pipe_num, 735 urb->status, urb->actual_length, 736 urb); 737 738 /* this urb is not pending anymore */ 739 usb_hif_remove_pending_transfer(urb_context); 740 741 do { 742 743 if (urb->status != 0) { 744 status = A_ECOMM; 745 switch (urb->status) { 746 case -ECONNRESET: 747 case -ENOENT: 748 case -ESHUTDOWN: 749 /* NOTE: no need to spew these errors when 750 * device is removed 751 * or urb is killed due to driver shutdown 752 */ 753 status = A_ECANCELED; 754 break; 755 default: 756 HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d", 757 __func__, 758 pipe->logical_pipe_num, 759 pipe->ep_address, 760 urb->status); 761 break; 762 } 763 break; 764 } 765 if (urb->actual_length == 0) 766 break; 767 buf = urb_context->buf; 768 if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) { 769 uint8_t *data; 770 uint32_t len; 771 772 qdf_nbuf_peek_header(buf, &data, &len); 773 debug_dump_bytes(data, len, "hif recv data"); 774 } 775 776 qdf_nbuf_peek_header(buf, &netdata, &netlen); 777 netlen = urb->actual_length; 778 no_of_pkt_in_bundle = 0; 779 780 do { 781 uint16_t frame_len; 782 783 if (IS_FW_CRASH_DUMP(*(uint32_t *) netdata)) 784 frame_len = netlen; 785 else { 786 /* Hack into HTC header for bundle processing */ 787 HtcHdr = (HTC_FRAME_HDR *) netdata; 788 if (HtcHdr->EndpointID >= ENDPOINT_MAX) { 789 HIF_ERROR("athusb: Rx: invalid EndpointID=%d", 790 HtcHdr->EndpointID); 791 break; 792 } 793 794 payloadLen = HtcHdr->PayloadLen; 795 payloadLen = qdf_le16_to_cpu(payloadLen); 796 797 if (payloadLen > HIF_USB_RX_BUFFER_SIZE) { 798 HIF_ERROR("athusb: payloadLen too long %u", 799 payloadLen); 800 break; 801 } 802 frame_len = (HTC_HDR_LENGTH + payloadLen); 803 } 804 805 if (netlen < frame_len) { 806 HIF_ERROR("athusb: subframe length %d not fitted into bundle packet length %d" 807 , netlen, frame_len); 808 break; 809 } 810 811 /* allocate a new skb and copy */ 812 new_skb = 813 qdf_nbuf_alloc(NULL, frame_len, 0, 4, false); 814 if (!new_skb) { 815 HIF_ERROR("athusb: allocate skb (len=%u) failed" 816 , frame_len); 817 break; 818 } 819 820 qdf_nbuf_peek_header(new_skb, &netdata_new, 821 &netlen_new); 822 qdf_mem_copy(netdata_new, netdata, frame_len); 823 qdf_nbuf_put_tail(new_skb, frame_len); 824 skb_queue_tail(&pipe->io_comp_queue, new_skb); 825 new_skb = NULL; 826 netdata += frame_len; 827 netlen -= frame_len; 828 no_of_pkt_in_bundle++; 829 } while (netlen); 830 831 if (pipe->device->htc_callbacks.update_bundle_stats) 832 pipe->device->htc_callbacks.update_bundle_stats 833 (pipe->device->htc_callbacks.Context, 834 no_of_pkt_in_bundle); 835 836 HIF_USB_SCHEDULE_WORK(pipe); 837 } while (false); 838 839 if (!urb_context->buf) 840 HIF_ERROR("athusb: buffer in urb_context is NULL"); 841 842 /* reset urb_context->buf ==> seems not necessary */ 843 usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context); 844 845 if (QDF_IS_STATUS_SUCCESS(status)) { 846 if (pipe->urb_cnt >= pipe->urb_cnt_thresh) { 847 /* our free urbs are piling up, post more transfers */ 848 usb_hif_post_recv_bundle_transfers(pipe, 849 pipe->device->rx_bundle_buf_len); 850 } 851 } 852 853 HIF_DBG("-%s", __func__); 854 } 855 856 /** 857 * usb_hif_post_recv_prestart_transfers() - post prestart recv urbs for a pipe 858 * @recv_pipe: rx data pipe 859 * @prestart_urb: number of prestart recv urbs to be posted 860 * 861 * Return: none 862 */ 863 static void usb_hif_post_recv_prestart_transfers(struct HIF_USB_PIPE *recv_pipe, 864 int prestart_urb) 865 { 866 struct HIF_URB_CONTEXT *urb_context; 867 uint8_t *data; 868 uint32_t len; 869 struct urb *urb; 870 int i, usb_status, buffer_length = HIF_USB_RX_BUFFER_SIZE; 871 872 HIF_TRACE("+%s", __func__); 873 874 qdf_spin_lock_irqsave(&recv_pipe->device->rx_prestart_lock); 875 for (i = 0; i < prestart_urb; i++) { 876 urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe); 877 if (!urb_context) 878 break; 879 880 urb_context->buf = 881 qdf_nbuf_alloc(NULL, buffer_length, 0, 4, false); 882 if (!urb_context->buf) { 883 usb_hif_cleanup_recv_urb(urb_context); 884 break; 885 } 886 887 qdf_nbuf_peek_header(urb_context->buf, &data, &len); 888 889 urb = urb_context->urb; 890 891 usb_fill_bulk_urb(urb, 892 recv_pipe->device->udev, 893 recv_pipe->usb_pipe_handle, 894 data, 895 buffer_length, 896 usb_hif_usb_recv_prestart_complete, 897 urb_context); 898 899 HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK", 900 recv_pipe->logical_pipe_num, 901 recv_pipe->usb_pipe_handle, 902 recv_pipe->ep_address, buffer_length, 903 urb_context->buf); 904 905 usb_hif_enqueue_pending_transfer(recv_pipe, urb_context); 906 usb_status = usb_submit_urb(urb, GFP_ATOMIC); 907 908 if (usb_status) { 909 HIF_ERROR("athusb : usb bulk recv failed %d", 910 usb_status); 911 usb_hif_remove_pending_transfer(urb_context); 912 usb_hif_cleanup_recv_urb(urb_context); 913 break; 914 } 915 recv_pipe->urb_prestart_cnt++; 916 } 917 qdf_spin_unlock_irqrestore(&recv_pipe->device->rx_prestart_lock); 918 919 HIF_TRACE("-%s", __func__); 920 } 921 922 /** 923 * usb_hif_post_recv_transfers() - post recv urbs for a given pipe 924 * @recv_pipe: recv pipe for which urbs need to be posted 925 * @buffer_length: buffer length of the recv urbs 926 * 927 * Return: none 928 */ 929 static void usb_hif_post_recv_transfers(struct HIF_USB_PIPE *recv_pipe, 930 int buffer_length) 931 { 932 struct HIF_URB_CONTEXT *urb_context; 933 uint8_t *data; 934 uint32_t len; 935 struct urb *urb; 936 int usb_status; 937 938 while (1) { 939 940 urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe); 941 if (!urb_context) 942 break; 943 944 urb_context->buf = qdf_nbuf_alloc(NULL, buffer_length, 0, 945 4, false); 946 if (!urb_context->buf) { 947 usb_hif_cleanup_recv_urb(urb_context); 948 break; 949 } 950 951 qdf_nbuf_peek_header(urb_context->buf, &data, &len); 952 953 urb = urb_context->urb; 954 955 usb_fill_bulk_urb(urb, 956 recv_pipe->device->udev, 957 recv_pipe->usb_pipe_handle, 958 data, 959 buffer_length, 960 usb_hif_usb_recv_complete, urb_context); 961 962 HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK", 963 recv_pipe->logical_pipe_num, 964 recv_pipe->usb_pipe_handle, 965 recv_pipe->ep_address, buffer_length, 966 urb_context->buf); 967 968 usb_hif_enqueue_pending_transfer(recv_pipe, urb_context); 969 970 usb_status = usb_submit_urb(urb, GFP_ATOMIC); 971 972 if (usb_status) { 973 HIF_ERROR("athusb : usb bulk recv failed %d", 974 usb_status); 975 usb_hif_remove_pending_transfer(urb_context); 976 usb_hif_cleanup_recv_urb(urb_context); 977 break; 978 } 979 } 980 981 } 982 983 /** 984 * usb_hif_post_recv_bundle_transfers() - post recv urbs for a given pipe 985 * @recv_pipe: recv pipe for which urbs need to be posted 986 * @buffer_length: maximum length of rx bundle 987 * 988 * Return: none 989 */ 990 static void usb_hif_post_recv_bundle_transfers(struct HIF_USB_PIPE *recv_pipe, 991 int buffer_length) 992 { 993 struct HIF_URB_CONTEXT *urb_context; 994 uint8_t *data; 995 uint32_t len; 996 struct urb *urb; 997 int usb_status; 998 999 while (1) { 1000 1001 urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe); 1002 if (!urb_context) 1003 break; 1004 1005 if (!urb_context->buf) { 1006 urb_context->buf = 1007 qdf_nbuf_alloc(NULL, buffer_length, 0, 4, false); 1008 if (!urb_context->buf) { 1009 usb_hif_cleanup_recv_urb(urb_context); 1010 break; 1011 } 1012 } 1013 1014 qdf_nbuf_peek_header(urb_context->buf, &data, &len); 1015 1016 urb = urb_context->urb; 1017 usb_fill_bulk_urb(urb, 1018 recv_pipe->device->udev, 1019 recv_pipe->usb_pipe_handle, 1020 data, 1021 buffer_length, 1022 usb_hif_usb_recv_bundle_complete, 1023 urb_context); 1024 1025 HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%pK", 1026 recv_pipe->logical_pipe_num, 1027 recv_pipe->usb_pipe_handle, 1028 recv_pipe->ep_address, buffer_length, 1029 urb_context->buf); 1030 1031 usb_hif_enqueue_pending_transfer(recv_pipe, urb_context); 1032 1033 usb_status = usb_submit_urb(urb, GFP_ATOMIC); 1034 1035 if (usb_status) { 1036 HIF_ERROR("athusb : usb bulk recv failed %d", 1037 usb_status); 1038 usb_hif_remove_pending_transfer(urb_context); 1039 usb_hif_free_urb_to_pipe(urb_context->pipe, 1040 urb_context); 1041 break; 1042 } 1043 1044 } 1045 1046 } 1047 1048 /** 1049 * usb_hif_prestart_recv_pipes() - post prestart recv urbs 1050 * @device: HIF device for which prestart recv urbs need to be posted 1051 * 1052 * Return: none 1053 */ 1054 void usb_hif_prestart_recv_pipes(struct HIF_DEVICE_USB *device) 1055 { 1056 struct HIF_USB_PIPE *pipe; 1057 int prestart_cnt = 8; 1058 1059 if (device->rx_ctrl_pipe_supported) { 1060 pipe = &device->pipes[HIF_RX_CTRL_PIPE]; 1061 prestart_cnt = 4; 1062 usb_hif_post_recv_prestart_transfers(pipe, prestart_cnt); 1063 } 1064 /* 1065 * USB driver learn to support bundle or not until the firmware 1066 * download and ready. Only allocate some URBs for control message 1067 * communication during the initial phase then start the final 1068 * working pipe after all information understood. 1069 */ 1070 pipe = &device->pipes[HIF_RX_DATA_PIPE]; 1071 usb_hif_post_recv_prestart_transfers(pipe, prestart_cnt); 1072 } 1073 1074 /** 1075 * usb_hif_start_recv_pipes() - start recv urbs 1076 * @device: HIF device for which recv urbs need to be posted 1077 * 1078 * This function is called after all prestart recv urbs are exhausted 1079 * 1080 * Return: none 1081 */ 1082 void usb_hif_start_recv_pipes(struct HIF_DEVICE_USB *device) 1083 { 1084 struct HIF_USB_PIPE *pipe; 1085 uint32_t buf_len; 1086 1087 HIF_ENTER(); 1088 pipe = &device->pipes[HIF_RX_DATA_PIPE]; 1089 pipe->urb_cnt_thresh = pipe->urb_alloc / 2; 1090 1091 HIF_TRACE("Post URBs to RX_DATA_PIPE: %d is_bundle %d", 1092 device->pipes[HIF_RX_DATA_PIPE].urb_cnt, 1093 device->is_bundle_enabled); 1094 if (device->is_bundle_enabled) { 1095 usb_hif_post_recv_bundle_transfers(pipe, 1096 pipe->device->rx_bundle_buf_len); 1097 } else { 1098 buf_len = HIF_USB_RX_BUFFER_SIZE; 1099 usb_hif_post_recv_transfers(pipe, buf_len); 1100 } 1101 1102 HIF_DBG("athusb bulk recv len %d", buf_len); 1103 1104 if (!hif_usb_disable_rxdata2) { 1105 HIF_TRACE("Post URBs to RX_DATA2_PIPE: %d", 1106 device->pipes[HIF_RX_DATA2_PIPE].urb_cnt); 1107 1108 pipe = &device->pipes[HIF_RX_DATA2_PIPE]; 1109 pipe->urb_cnt_thresh = pipe->urb_alloc / 2; 1110 usb_hif_post_recv_transfers(pipe, HIF_USB_RX_BUFFER_SIZE); 1111 } 1112 1113 if (device->rx_ctrl_pipe_supported) { 1114 HIF_TRACE("Post URBs to RX_CONTROL_PIPE: %d", 1115 device->pipes[HIF_RX_CTRL_PIPE].urb_cnt); 1116 1117 pipe = &device->pipes[HIF_RX_CTRL_PIPE]; 1118 pipe->urb_cnt_thresh = pipe->urb_alloc / 2; 1119 usb_hif_post_recv_transfers(pipe, HIF_USB_RX_BUFFER_SIZE); 1120 } 1121 HIF_EXIT(); 1122 } 1123 1124 /** 1125 * usb_hif_submit_ctrl_out() - send out a ctrl urb 1126 * @device: HIF device for which urb needs to be posted 1127 * @req: request value for the ctrl message 1128 * @value: USB message value 1129 * @index: USB message index value 1130 * @data: pointer to data containing ctrl message to send 1131 * @size: size of the control message to send 1132 * 1133 * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error 1134 */ 1135 QDF_STATUS usb_hif_submit_ctrl_out(struct HIF_DEVICE_USB *device, 1136 uint8_t req, uint16_t value, uint16_t index, 1137 void *data, uint32_t size) 1138 { 1139 int32_t result = 0; 1140 QDF_STATUS ret = QDF_STATUS_SUCCESS; 1141 uint8_t *buf = NULL; 1142 1143 do { 1144 1145 if (size > 0) { 1146 buf = qdf_mem_malloc(size); 1147 if (!buf) { 1148 ret = QDF_STATUS_E_NOMEM; 1149 break; 1150 } 1151 qdf_mem_copy(buf, (uint8_t *) data, size); 1152 } 1153 1154 HIF_DBG("ctrl-out req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d", 1155 req, value, index, size); 1156 1157 result = usb_control_msg(device->udev, 1158 usb_sndctrlpipe(device->udev, 0), 1159 req, 1160 USB_DIR_OUT | USB_TYPE_VENDOR | 1161 USB_RECIP_DEVICE, value, index, buf, 1162 size, 2 * HZ); 1163 1164 if (result < 0) { 1165 HIF_ERROR("%s failed,result = %d", __func__, result); 1166 ret = QDF_STATUS_E_FAILURE; 1167 } 1168 1169 } while (false); 1170 1171 if (buf) 1172 qdf_mem_free(buf); 1173 1174 return ret; 1175 } 1176 1177 /** 1178 * usb_hif_submit_ctrl_in() - recv a resonse to the ctrl message sent out 1179 * @device: HIF device for which urb needs to be received 1180 * @req: request value for the ctrl message 1181 * @value: USB message value 1182 * @index: USB message index value 1183 * @data: pointer to data containing ctrl message to be received 1184 * @size: size of the control message to be received 1185 * 1186 * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error 1187 */ 1188 QDF_STATUS usb_hif_submit_ctrl_in(struct HIF_DEVICE_USB *device, 1189 uint8_t req, uint16_t value, uint16_t index, 1190 void *data, uint32_t size) 1191 { 1192 int32_t result = 0; 1193 QDF_STATUS ret = QDF_STATUS_SUCCESS; 1194 uint8_t *buf = NULL; 1195 1196 do { 1197 1198 if (size > 0) { 1199 buf = qdf_mem_malloc(size); 1200 if (!buf) { 1201 ret = QDF_STATUS_E_NOMEM; 1202 break; 1203 } 1204 } 1205 1206 HIF_DBG("ctrl-in req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d", 1207 req, value, index, size); 1208 1209 result = usb_control_msg(device->udev, 1210 usb_rcvctrlpipe(device->udev, 0), 1211 req, 1212 USB_DIR_IN | USB_TYPE_VENDOR | 1213 USB_RECIP_DEVICE, value, index, buf, 1214 size, 2 * HZ); 1215 1216 if (result < 0) { 1217 HIF_ERROR("%s failed, result = %d", __func__, result); 1218 ret = QDF_STATUS_E_FAILURE; 1219 break; 1220 } 1221 1222 qdf_mem_copy((uint8_t *) data, buf, size); 1223 1224 } while (false); 1225 1226 if (buf) 1227 qdf_mem_free(buf); 1228 1229 return ret; 1230 } 1231 1232 /** 1233 * usb_hif_io_complete() - transmit call back for tx urb 1234 * @pipe: pointer to struct HIF_USB_PIPE 1235 * 1236 * Return: none 1237 */ 1238 static void usb_hif_io_complete(struct HIF_USB_PIPE *pipe) 1239 { 1240 qdf_nbuf_t buf; 1241 struct HIF_DEVICE_USB *device; 1242 HTC_FRAME_HDR *HtcHdr; 1243 uint8_t *data; 1244 uint32_t len; 1245 struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device); 1246 1247 device = pipe->device; 1248 HIF_ENTER(); 1249 while ((buf = skb_dequeue(&pipe->io_comp_queue))) { 1250 if (pipe->flags & HIF_USB_PIPE_FLAG_TX) { 1251 HIF_DBG("+athusb xmit callback buf:0x%pK", buf); 1252 HtcHdr = (HTC_FRAME_HDR *) 1253 qdf_nbuf_get_frag_vaddr(buf, 0); 1254 1255 #ifdef ATH_11AC_TXCOMPACT 1256 /* ATH_11AC_TXCOMPACT does not support High Latency mode */ 1257 #else 1258 device->htc_callbacks.txCompletionHandler(device-> 1259 htc_callbacks. 1260 Context, buf, 1261 HtcHdr-> 1262 EndpointID, 0); 1263 #endif 1264 HIF_DBG("-athusb xmit callback"); 1265 } else { 1266 HIF_DBG("+athusb recv callback buf: 0x%pK", buf); 1267 qdf_nbuf_peek_header(buf, &data, &len); 1268 1269 if (IS_FW_CRASH_DUMP(*((uint32_t *) data))) { 1270 sc->fw_data = data; 1271 sc->fw_data_len = len; 1272 device->htc_callbacks.fwEventHandler( 1273 device->htc_callbacks.Context, 1274 QDF_STATUS_E_USB_ERROR); 1275 qdf_nbuf_free(buf); 1276 } else { 1277 device->htc_callbacks.rxCompletionHandler( 1278 device->htc_callbacks.Context, buf, 1279 pipe->logical_pipe_num); 1280 } 1281 HIF_DBG("-athusb recv callback"); 1282 } 1283 } 1284 1285 HIF_EXIT(); 1286 } 1287 1288 #ifdef HIF_USB_TASKLET 1289 /** 1290 * usb_hif_io_comp_tasklet() - per pipe tasklet routine 1291 * @context: pointer to HIF USB pipe 1292 * 1293 * Return: none 1294 */ 1295 void usb_hif_io_comp_tasklet(unsigned long context) 1296 { 1297 struct HIF_USB_PIPE *pipe = (struct HIF_USB_PIPE *) context; 1298 1299 usb_hif_io_complete(pipe); 1300 } 1301 1302 #else 1303 /** 1304 * usb_hif_io_comp_work() - per pipe work queue 1305 * @work: pointer to struct work_struct 1306 * 1307 * Return: none 1308 */ 1309 void usb_hif_io_comp_work(struct work_struct *work) 1310 { 1311 struct HIF_USB_PIPE *pipe = container_of(work, struct HIF_USB_PIPE, 1312 io_complete_work); 1313 1314 usb_hif_io_complete(pipe); 1315 } 1316 #endif 1317