1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * 25 * Copyright 2014 Garrett D'Amore <garrett@damore.org> 26 * Copyright 2016 Joyent, Inc. 27 */ 28 29 30 /* 31 * USBA: Solaris USB Architecture support 32 * 33 * all functions exposed to client drivers have prefix usb_ while all USBA 34 * internal functions or functions exposed to HCD or hubd only have prefix 35 * usba_ 36 * 37 * this file contains all USBAI pipe management 38 * usb_pipe_open() 39 * usb_pipe_close() 40 * usb_pipe_set_private() 41 * usb_pipe_get_private() 42 * usb_pipe_abort() 43 * usb_pipe_reset() 44 * usb_pipe_drain_reqs() 45 */ 46 #define USBA_FRAMEWORK 47 #include <sys/usb/usba/usba_impl.h> 48 #include <sys/usb/usba/hcdi_impl.h> 49 #include <sys/atomic.h> 50 51 extern pri_t maxclsyspri; 52 extern pri_t minclsyspri; 53 54 /* function prototypes */ 55 static void usba_pipe_do_async_func_thread(void *arg); 56 static int usba_pipe_sync_close(dev_info_t *, usba_ph_impl_t *, 57 usba_pipe_async_req_t *, usb_flags_t); 58 static int usba_pipe_sync_reset(dev_info_t *, usba_ph_impl_t *, 59 usba_pipe_async_req_t *, usb_flags_t); 60 static int usba_pipe_sync_drain_reqs(dev_info_t *, usba_ph_impl_t *, 61 usba_pipe_async_req_t *, usb_flags_t); 62 63 /* local tunables */ 64 int usba_drain_timeout = 1000; /* in ms */ 65 66 /* return the default pipe for this device */ 67 usb_pipe_handle_t 68 usba_get_dflt_pipe_handle(dev_info_t *dip) 69 { 70 usba_device_t *usba_device; 71 usb_pipe_handle_t pipe_handle = NULL; 72 73 if (dip) { 74 usba_device = usba_get_usba_device(dip); 75 if (usba_device) { 76 pipe_handle = 77 (usb_pipe_handle_t)&usba_device->usb_ph_list[0]; 78 } 79 } 80 81 return (pipe_handle); 82 } 83 84 85 /* return dip owner of pipe_handle */ 86 dev_info_t * 87 usba_get_dip(usb_pipe_handle_t pipe_handle) 88 { 89 usba_ph_impl_t *ph_impl = (usba_ph_impl_t *)pipe_handle; 90 dev_info_t *dip = NULL; 91 92 if (ph_impl) { 93 mutex_enter(&ph_impl->usba_ph_mutex); 94 dip = ph_impl->usba_ph_dip; 95 mutex_exit(&ph_impl->usba_ph_mutex); 96 } 97 98 return (dip); 99 } 100 101 102 usb_pipe_handle_t 103 usba_usbdev_to_dflt_pipe_handle(usba_device_t *usba_device) 104 { 105 usb_pipe_handle_t pipe_handle = NULL; 106 107 if ((usba_device) && 108 (usba_device->usb_ph_list[0].usba_ph_data != NULL)) { 109 pipe_handle = (usb_pipe_handle_t)&usba_device->usb_ph_list[0]; 110 } 111 112 return (pipe_handle); 113 } 114 115 116 usba_pipe_handle_data_t * 117 usba_get_ph_data(usb_pipe_handle_t pipe_handle) 118 { 119 usba_ph_impl_t *ph_impl = (usba_ph_impl_t *)pipe_handle; 120 usba_pipe_handle_data_t *ph_data = NULL; 121 122 if (ph_impl) { 123 mutex_enter(&ph_impl->usba_ph_mutex); 124 ASSERT(ph_impl->usba_ph_ref_count >= 0); 125 ph_data = ph_impl->usba_ph_data; 126 mutex_exit(&ph_impl->usba_ph_mutex); 127 } 128 129 return (ph_data); 130 } 131 132 133 usb_pipe_handle_t 134 usba_get_pipe_handle(usba_pipe_handle_data_t *ph_data) 135 { 136 usb_pipe_handle_t ph = NULL; 137 138 if (ph_data) { 139 mutex_enter(&ph_data->p_mutex); 140 ASSERT(ph_data->p_req_count >= 0); 141 ph = (usb_pipe_handle_t)ph_data->p_ph_impl; 142 mutex_exit(&ph_data->p_mutex); 143 } 144 145 return (ph); 146 } 147 148 149 /* 150 * opaque to pipe handle impl translation with incr of ref count. The caller 151 * must release ph_data when done. Increment the ref count ensures that 152 * the ph_data will not be freed underneath us. 153 */ 154 usba_pipe_handle_data_t * 155 usba_hold_ph_data(usb_pipe_handle_t pipe_handle) 156 { 157 usba_ph_impl_t *ph_impl = (usba_ph_impl_t *)pipe_handle; 158 usba_pipe_handle_data_t *ph_data = NULL; 159 160 if (ph_impl) { 161 mutex_enter(&ph_impl->usba_ph_mutex); 162 163 switch (ph_impl->usba_ph_state) { 164 case USB_PIPE_STATE_IDLE: 165 case USB_PIPE_STATE_ACTIVE: 166 case USB_PIPE_STATE_ERROR: 167 ph_data = ph_impl->usba_ph_data; 168 ph_impl->usba_ph_ref_count++; 169 break; 170 case USB_PIPE_STATE_CLOSED: 171 case USB_PIPE_STATE_CLOSING: 172 default: 173 break; 174 } 175 176 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 177 "usba_hold_ph_data: ph_impl=0x%p state=%d ref=%d", 178 (void *)ph_impl, ph_impl->usba_ph_state, 179 ph_impl->usba_ph_ref_count); 180 181 mutex_exit(&ph_impl->usba_ph_mutex); 182 } 183 184 return (ph_data); 185 } 186 187 188 void 189 usba_release_ph_data(usba_ph_impl_t *ph_impl) 190 { 191 if (ph_impl) { 192 mutex_enter(&ph_impl->usba_ph_mutex); 193 194 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 195 "usba_release_ph_data: " 196 "ph_impl=0x%p state=%d ref=%d", 197 (void *)ph_impl, ph_impl->usba_ph_state, 198 ph_impl->usba_ph_ref_count); 199 200 #ifndef __lock_lint 201 if (ph_impl->usba_ph_data) { 202 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 203 "usba_release_ph_data: req_count=%d", 204 ph_impl->usba_ph_data->p_req_count); 205 ASSERT(ph_impl->usba_ph_data->p_req_count >= 0); 206 } 207 #endif 208 ph_impl->usba_ph_ref_count--; 209 ASSERT(ph_impl->usba_ph_ref_count >= 0); 210 211 mutex_exit(&ph_impl->usba_ph_mutex); 212 } 213 } 214 215 216 /* 217 * get pipe state from ph_data 218 */ 219 usb_pipe_state_t 220 usba_get_ph_state(usba_pipe_handle_data_t *ph_data) 221 { 222 usba_ph_impl_t *ph_impl = ph_data->p_ph_impl; 223 usb_pipe_state_t pipe_state; 224 225 ASSERT(mutex_owned(&ph_data->p_mutex)); 226 mutex_enter(&ph_impl->usba_ph_mutex); 227 pipe_state = ph_impl->usba_ph_state; 228 mutex_exit(&ph_impl->usba_ph_mutex); 229 230 return (pipe_state); 231 } 232 233 234 /* 235 * get ref_count from ph_data 236 */ 237 int 238 usba_get_ph_ref_count(usba_pipe_handle_data_t *ph_data) 239 { 240 usba_ph_impl_t *ph_impl = ph_data->p_ph_impl; 241 int ref_count; 242 243 mutex_enter(&ph_impl->usba_ph_mutex); 244 ref_count = ph_impl->usba_ph_ref_count; 245 mutex_exit(&ph_impl->usba_ph_mutex); 246 247 return (ref_count); 248 } 249 250 251 /* 252 * new pipe state 253 * We need to hold both pipe mutex and ph_impl mutex 254 */ 255 void 256 usba_pipe_new_state(usba_pipe_handle_data_t *ph_data, usb_pipe_state_t state) 257 { 258 usba_ph_impl_t *ph_impl = ph_data->p_ph_impl; 259 260 ASSERT(mutex_owned(&ph_data->p_mutex)); 261 262 mutex_enter(&ph_impl->usba_ph_mutex); 263 ASSERT(ph_data->p_req_count >= 0); 264 ASSERT(ph_impl->usba_ph_ref_count >= 0); 265 266 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 267 "usba_pipe_new_state: " 268 "ph_data=0x%p old=%s new=%s ref=%d req=%d", 269 (void *)ph_data, usb_str_pipe_state(ph_impl->usba_ph_state), 270 usb_str_pipe_state(state), 271 ph_impl->usba_ph_ref_count, ph_data->p_req_count); 272 273 switch (ph_impl->usba_ph_state) { 274 case USB_PIPE_STATE_IDLE: 275 case USB_PIPE_STATE_ACTIVE: 276 case USB_PIPE_STATE_ERROR: 277 case USB_PIPE_STATE_CLOSED: 278 ph_impl->usba_ph_state = state; 279 break; 280 case USB_PIPE_STATE_CLOSING: 281 default: 282 break; 283 } 284 mutex_exit(&ph_impl->usba_ph_mutex); 285 } 286 287 288 /* 289 * async function execution support 290 * Arguments: 291 * dip - devinfo pointer 292 * sync_func - function to be executed 293 * ph_impl - impl pipehandle 294 * arg - opaque arg 295 * usb_flags - none 296 * callback - function to be called on completion, may be NULL 297 * callback_arg - argument for callback function 298 * 299 * Note: The caller must do a hold on ph_data 300 * We sleep for memory resources and taskq_dispatch which will ensure 301 * that this function succeeds 302 */ 303 int 304 usba_pipe_setup_func_call( 305 dev_info_t *dip, 306 int (*sync_func)(dev_info_t *, 307 usba_ph_impl_t *, usba_pipe_async_req_t *, 308 usb_flags_t), 309 usba_ph_impl_t *ph_impl, 310 usb_opaque_t arg, 311 usb_flags_t usb_flags, 312 void (*callback)(usb_pipe_handle_t, 313 usb_opaque_t, int, usb_cb_flags_t), 314 usb_opaque_t callback_arg) 315 { 316 usba_pipe_async_req_t *request; 317 usb_pipe_handle_t pipe_handle = (usb_pipe_handle_t)ph_impl; 318 usba_pipe_handle_data_t *ph_data = ph_impl->usba_ph_data; 319 int rval = USB_SUCCESS; 320 usb_cb_flags_t callback_flags; 321 322 USB_DPRINTF_L3(DPRINT_MASK_USBAI, usbai_log_handle, 323 "usba_pipe_setup_func_call: ph_impl=0x%p, func=0x%p", 324 (void *)ph_impl, (void *)sync_func); 325 326 if (((usb_flags & USB_FLAGS_SLEEP) == 0) && (callback == NULL)) { 327 usba_release_ph_data(ph_impl); 328 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 329 "usba_pipe_setup_func_call: async request with " 330 "no callback"); 331 332 return (USB_INVALID_ARGS); 333 } 334 335 request = kmem_zalloc(sizeof (usba_pipe_async_req_t), KM_SLEEP); 336 request->dip = dip; 337 request->ph_impl = ph_impl; 338 request->arg = arg; 339 340 /* 341 * OR in sleep flag. regardless of calling sync_func directly 342 * or in a new thread, we will always wait for completion 343 */ 344 request->usb_flags = usb_flags | USB_FLAGS_SLEEP; 345 request->sync_func = sync_func; 346 request->callback = callback; 347 request->callback_arg = callback_arg; 348 349 if (usb_flags & USB_FLAGS_SLEEP) { 350 rval = sync_func(dip, ph_impl, request, usb_flags); 351 kmem_free(request, sizeof (usba_pipe_async_req_t)); 352 353 } else if (usba_async_ph_req(ph_data, 354 usba_pipe_do_async_func_thread, 355 (void *)request, USB_FLAGS_SLEEP) != USB_SUCCESS) { 356 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 357 "usb_async_req failed: ph_impl=0x%p, func=0x%p", 358 (void *)ph_impl, (void *)sync_func); 359 360 if (callback) { 361 callback_flags = 362 usba_check_intr_context(USB_CB_ASYNC_REQ_FAILED); 363 callback(pipe_handle, callback_arg, USB_FAILURE, 364 callback_flags); 365 } 366 367 kmem_free(request, sizeof (usba_pipe_async_req_t)); 368 usba_release_ph_data(ph_impl); 369 } 370 371 return (rval); 372 } 373 374 375 /* 376 * taskq thread function to execute function synchronously 377 * Note: caller must have done a hold on ph_data 378 */ 379 static void 380 usba_pipe_do_async_func_thread(void *arg) 381 { 382 usba_pipe_async_req_t *request = (usba_pipe_async_req_t *)arg; 383 usba_ph_impl_t *ph_impl = request->ph_impl; 384 usb_pipe_handle_t pipe_handle = (usb_pipe_handle_t)ph_impl; 385 int rval; 386 usb_cb_flags_t cb_flags = USB_CB_NO_INFO; 387 388 if ((rval = request->sync_func(request->dip, ph_impl, 389 request, request->usb_flags | USB_FLAGS_SLEEP)) != 390 USB_SUCCESS) { 391 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 392 "sync func failed (%d)", rval); 393 } 394 395 if (request->callback) { 396 request->callback(pipe_handle, request->callback_arg, rval, 397 cb_flags); 398 } 399 400 kmem_free(request, sizeof (usba_pipe_async_req_t)); 401 } 402 403 404 /* 405 * default endpoint descriptor and pipe policy 406 */ 407 usb_ep_descr_t usba_default_ep_descr = 408 {7, 5, 0, USB_EP_ATTR_CONTROL, 8, 0}; 409 410 /* set some meaningful defaults */ 411 static usb_pipe_policy_t usba_default_ep_pipe_policy = {3}; 412 413 414 /* 415 * usb_get_ep_index: create an index from endpoint address that can 416 * be used to index into endpoint pipe lists 417 */ 418 uchar_t 419 usb_get_ep_index(uint8_t ep_addr) 420 { 421 return ((ep_addr & USB_EP_NUM_MASK) + 422 ((ep_addr & USB_EP_DIR_MASK) ? 16 : 0)); 423 } 424 425 426 /* 427 * pipe management 428 * utility functions to init and destroy a pipehandle 429 */ 430 static int 431 usba_init_pipe_handle(dev_info_t *dip, 432 usba_device_t *usba_device, 433 usb_ep_descr_t *ep, 434 usb_ep_xdescr_t *ep_xdescr, 435 usb_pipe_policy_t *pipe_policy, 436 usba_ph_impl_t *ph_impl) 437 { 438 usb_ep_xdescr_t xep; 439 int instance = ddi_get_instance(dip); 440 unsigned int def_instance = instance; 441 static unsigned int anon_instance = 0; 442 char tq_name[TASKQ_NAMELEN]; 443 444 usba_pipe_handle_data_t *ph_data = ph_impl->usba_ph_data; 445 ddi_iblock_cookie_t iblock_cookie = 446 usba_hcdi_get_hcdi(usba_device->usb_root_hub_dip)-> 447 hcdi_iblock_cookie; 448 449 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 450 "usba_init_pipe_handle: " 451 "usba_device=0x%p ep=0x%x", (void *)usba_device, 452 ep->bEndpointAddress); 453 mutex_init(&ph_data->p_mutex, NULL, MUTEX_DRIVER, iblock_cookie); 454 455 /* just to keep warlock happy, there is no contention yet */ 456 mutex_enter(&ph_data->p_mutex); 457 mutex_enter(&usba_device->usb_mutex); 458 459 ASSERT(pipe_policy->pp_max_async_reqs); 460 461 if (instance != -1) { 462 (void) snprintf(tq_name, sizeof (tq_name), 463 "USB_%s_%x_pipehndl_tq_%d", 464 ddi_driver_name(dip), ep->bEndpointAddress, instance); 465 } else { 466 def_instance = atomic_inc_32_nv(&anon_instance); 467 468 (void) snprintf(tq_name, sizeof (tq_name), 469 "USB_%s_%x_pipehndl_tq_%d_", 470 ddi_driver_name(dip), ep->bEndpointAddress, def_instance); 471 } 472 473 ph_data->p_taskq = taskq_create(tq_name, 474 pipe_policy->pp_max_async_reqs + 1, 475 ((ep->bmAttributes & USB_EP_ATTR_MASK) == 476 USB_EP_ATTR_ISOCH) ? 477 (maxclsyspri - 5) : minclsyspri, 478 2 * (pipe_policy->pp_max_async_reqs + 1), 479 8 * (pipe_policy->pp_max_async_reqs + 1), 480 TASKQ_PREPOPULATE); 481 482 /* 483 * Create a shared taskq. 484 */ 485 if (ph_data->p_spec_flag & USBA_PH_FLAG_TQ_SHARE) { 486 int iface = usb_get_if_number(dip); 487 if (iface < 0) { 488 /* we own the device, use first entry */ 489 iface = 0; 490 } 491 492 if (instance != -1) { 493 (void) snprintf(tq_name, sizeof (tq_name), 494 "USB_%s_%x_shared_tq_%d", 495 ddi_driver_name(dip), ep->bEndpointAddress, 496 instance); 497 } else { 498 (void) snprintf(tq_name, sizeof (tq_name), 499 "USB_%s_%x_shared_tq_%d_", 500 ddi_driver_name(dip), ep->bEndpointAddress, 501 def_instance); 502 } 503 504 if (usba_device->usb_shared_taskq_ref_count[iface] == 0) { 505 usba_device->usb_shared_taskq[iface] = 506 taskq_create(tq_name, 507 1, /* Number threads. */ 508 maxclsyspri - 5, /* Priority */ 509 1, /* minalloc */ 510 USBA_N_ENDPOINTS + 4, /* maxalloc */ 511 TASKQ_PREPOPULATE); 512 ASSERT(usba_device->usb_shared_taskq[iface] != NULL); 513 } 514 usba_device->usb_shared_taskq_ref_count[iface]++; 515 } 516 517 /* 518 * In the future, when we may have different versions of the extended 519 * endpoint descriptor, they should be normalized to the current version 520 * here such that all of the HCI drivers have a consistent view of the 521 * world. The extended descriptor may be NULL if we are opening the 522 * default control endpoint; however, we create a uniform view for the 523 * HCI drivers. 524 */ 525 if (ep_xdescr == NULL) { 526 bzero(&xep, sizeof (usb_ep_xdescr_t)); 527 xep.uex_version = USB_EP_XDESCR_CURRENT_VERSION; 528 xep.uex_ep = *ep; 529 ep_xdescr = &xep; 530 } 531 532 ph_data->p_dip = dip; 533 ph_data->p_usba_device = usba_device; 534 ph_data->p_ep = *ep; 535 ph_data->p_xep = *ep_xdescr; 536 ph_data->p_ph_impl = ph_impl; 537 if ((ep->bmAttributes & USB_EP_ATTR_MASK) == 538 USB_EP_ATTR_ISOCH) { 539 ph_data->p_spec_flag |= USBA_PH_FLAG_USE_SOFT_INTR; 540 } 541 542 /* fix up the MaxPacketSize if it is the default endpoint descr */ 543 if ((ep == &usba_default_ep_descr) && usba_device) { 544 uint16_t maxpktsize; 545 546 maxpktsize = usba_device->usb_dev_descr->bMaxPacketSize0; 547 USB_DPRINTF_L3(DPRINT_MASK_USBAI, usbai_log_handle, 548 "adjusting max packet size from %d to %d", 549 ph_data->p_ep.wMaxPacketSize, maxpktsize); 550 551 ph_data->p_ep.wMaxPacketSize = maxpktsize; 552 } 553 554 /* now update usba_ph_impl structure */ 555 mutex_enter(&ph_impl->usba_ph_mutex); 556 ph_impl->usba_ph_dip = dip; 557 ph_impl->usba_ph_ep = ph_data->p_ep; 558 ph_impl->usba_ph_policy = ph_data->p_policy = *pipe_policy; 559 mutex_exit(&ph_impl->usba_ph_mutex); 560 561 usba_init_list(&ph_data->p_queue, (usb_opaque_t)ph_data, iblock_cookie); 562 usba_init_list(&ph_data->p_cb_queue, (usb_opaque_t)ph_data, 563 iblock_cookie); 564 mutex_exit(&usba_device->usb_mutex); 565 mutex_exit(&ph_data->p_mutex); 566 567 return (USB_SUCCESS); 568 } 569 570 571 static void 572 usba_taskq_destroy(void *arg) 573 { 574 taskq_destroy((taskq_t *)arg); 575 } 576 577 578 static void 579 usba_destroy_pipe_handle(usba_pipe_handle_data_t *ph_data) 580 { 581 usba_ph_impl_t *ph_impl = ph_data->p_ph_impl; 582 int timeout; 583 usba_device_t *usba_device; 584 585 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 586 "usba_destroy_pipe_handle: ph_data=0x%p", (void *)ph_data); 587 588 mutex_enter(&ph_data->p_mutex); 589 mutex_enter(&ph_impl->usba_ph_mutex); 590 591 /* check for all activity to drain */ 592 for (timeout = 0; timeout < usba_drain_timeout; timeout++) { 593 if ((ph_impl->usba_ph_ref_count <= 1) && 594 (ph_data->p_req_count == 0)) { 595 596 break; 597 } 598 mutex_exit(&ph_data->p_mutex); 599 mutex_exit(&ph_impl->usba_ph_mutex); 600 delay(drv_usectohz(1000)); 601 mutex_enter(&ph_data->p_mutex); 602 mutex_enter(&ph_impl->usba_ph_mutex); 603 } 604 605 /* 606 * set state to closed here so any other thread 607 * that is waiting for the CLOSED state will 608 * continue. Otherwise, taskq_destroy might deadlock 609 */ 610 ph_impl->usba_ph_data = NULL; 611 ph_impl->usba_ph_ref_count = 0; 612 ph_impl->usba_ph_state = USB_PIPE_STATE_CLOSED; 613 614 if (ph_data->p_taskq) { 615 mutex_exit(&ph_data->p_mutex); 616 mutex_exit(&ph_impl->usba_ph_mutex); 617 if (taskq_member(ph_data->p_taskq, curthread)) { 618 /* 619 * use system taskq to destroy ph's taskq to avoid 620 * deadlock 621 */ 622 (void) taskq_dispatch(system_taskq, 623 usba_taskq_destroy, ph_data->p_taskq, TQ_SLEEP); 624 } else { 625 taskq_destroy(ph_data->p_taskq); 626 } 627 } else { 628 mutex_exit(&ph_data->p_mutex); 629 mutex_exit(&ph_impl->usba_ph_mutex); 630 } 631 632 usba_device = ph_data->p_usba_device; 633 mutex_enter(&ph_data->p_mutex); 634 if (ph_data->p_spec_flag & USBA_PH_FLAG_TQ_SHARE) { 635 int iface = usb_get_if_number(ph_data->p_dip); 636 if (iface < 0) { 637 /* we own the device, use the first entry */ 638 iface = 0; 639 } 640 mutex_enter(&usba_device->usb_mutex); 641 if (--usba_device->usb_shared_taskq_ref_count[iface] == 0) { 642 ph_data->p_spec_flag &= ~USBA_PH_FLAG_TQ_SHARE; 643 if (taskq_member(usba_device->usb_shared_taskq[iface], 644 curthread)) { 645 (void) taskq_dispatch( 646 system_taskq, 647 usba_taskq_destroy, 648 usba_device->usb_shared_taskq[iface], 649 TQ_SLEEP); 650 } else { 651 taskq_destroy( 652 usba_device->usb_shared_taskq[iface]); 653 } 654 } 655 mutex_exit(&usba_device->usb_mutex); 656 } 657 mutex_exit(&ph_data->p_mutex); 658 659 660 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 661 "usba_destroy_pipe_handle: destroying ph_data=0x%p", 662 (void *)ph_data); 663 664 usba_destroy_list(&ph_data->p_queue); 665 usba_destroy_list(&ph_data->p_cb_queue); 666 667 /* destroy mutexes */ 668 mutex_destroy(&ph_data->p_mutex); 669 670 kmem_free(ph_data, sizeof (usba_pipe_handle_data_t)); 671 } 672 673 674 /* 675 * usba_drain_cbs: 676 * Drain the request callbacks on the pipe handle 677 */ 678 int 679 usba_drain_cbs(usba_pipe_handle_data_t *ph_data, usb_cb_flags_t cb_flags, 680 usb_cr_t cr) 681 { 682 usba_req_wrapper_t *req_wrp; 683 int flush_requests = 1; 684 usba_ph_impl_t *ph_impl = ph_data->p_ph_impl; 685 int timeout; 686 int rval = USB_SUCCESS; 687 688 ASSERT(mutex_owned(&ph_data->p_mutex)); 689 690 mutex_enter(&ph_impl->usba_ph_mutex); 691 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 692 "usba_drain_cbs: ph_data=0x%p ref=%d req=%d cb=0x%x cr=%d", 693 (void *)ph_data, ph_impl->usba_ph_ref_count, ph_data->p_req_count, 694 cb_flags, cr); 695 ASSERT(ph_data->p_req_count >= 0); 696 mutex_exit(&ph_impl->usba_ph_mutex); 697 698 if (ph_data->p_dip) { 699 if (USBA_IS_DEFAULT_PIPE(ph_data)) { 700 USB_DPRINTF_L4(DPRINT_MASK_USBAI, 701 usbai_log_handle, 702 "no flushing on default pipe!"); 703 704 flush_requests = 0; 705 } 706 } 707 708 if (flush_requests) { 709 /* flush all requests in the pipehandle queue */ 710 while ((req_wrp = (usba_req_wrapper_t *) 711 usba_rm_first_pvt_from_list(&ph_data->p_queue)) != NULL) { 712 mutex_exit(&ph_data->p_mutex); 713 usba_do_req_exc_cb(req_wrp, cr, cb_flags); 714 mutex_enter(&ph_data->p_mutex); 715 } 716 } 717 718 /* 719 * wait for any callbacks in progress but don't wait for 720 * for queued requests on the default pipe 721 */ 722 for (timeout = 0; (timeout < usba_drain_timeout) && 723 (ph_data->p_req_count > 724 usba_list_entry_count(&ph_data->p_queue)); 725 timeout++) { 726 mutex_exit(&ph_data->p_mutex); 727 delay(drv_usectohz(1000)); 728 mutex_enter(&ph_data->p_mutex); 729 } 730 731 mutex_enter(&ph_impl->usba_ph_mutex); 732 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 733 "usba_drain_cbs done: ph_data=0x%p ref=%d req=%d", 734 (void *)ph_data, ph_impl->usba_ph_ref_count, ph_data->p_req_count); 735 mutex_exit(&ph_impl->usba_ph_mutex); 736 737 if (timeout == usba_drain_timeout) { 738 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 739 "draining callbacks timed out!"); 740 741 rval = USB_FAILURE; 742 } 743 744 return (rval); 745 } 746 747 748 /* 749 * usb_pipe_open(): 750 * 751 * Before using any pipe including the default pipe, it should be opened 752 * using usb_pipe_open(). On a successful open, a pipe handle is returned 753 * for use in other usb_pipe_*() functions 754 * 755 * The default pipe can only be opened by the hub driver 756 * 757 * The bandwidth has been allocated and guaranteed on successful 758 * opening of an isoc/intr pipes. 759 * 760 * Only the default pipe can be shared. all other control pipes 761 * are excusively opened by default. 762 * A pipe policy and endpoint descriptor must always be provided 763 * except for default pipe 764 * 765 * Arguments: 766 * dip - devinfo ptr 767 * ep - endpoint descriptor pointer 768 * pipe_policy - pointer to pipe policy which provides hints on how 769 * the pipe will be used. 770 * flags - USB_FLAGS_SLEEP wait for resources 771 * to become available 772 * pipe_handle - a pipe handle pointer. On a successful open, 773 * a pipe_handle is returned in this pointer. 774 * 775 * Return values: 776 * USB_SUCCESS - open succeeded 777 * USB_FAILURE - unspecified open failure or pipe is already open 778 * USB_NO_RESOURCES - no resources were available to complete the open 779 * USB_NO_BANDWIDTH - no bandwidth available (isoc/intr pipes) 780 * USB_* - refer to usbai.h 781 */ 782 int 783 usb_pipe_xopen( 784 dev_info_t *dip, 785 usb_ep_xdescr_t *ep_xdesc, 786 usb_pipe_policy_t *pipe_policy, 787 usb_flags_t usb_flags, 788 usb_pipe_handle_t *pipe_handle) 789 { 790 usb_ep_descr_t *ep; 791 usba_device_t *usba_device; 792 int rval; 793 usba_pipe_handle_data_t *ph_data; 794 usba_ph_impl_t *ph_impl; 795 uchar_t ep_index; 796 int kmflag; 797 size_t size; 798 799 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 800 "usb_pipe_open:\n\t" 801 "dip=0x%p ep_xdesc=0x%p pp=0x%p uf=0x%x ph=0x%p", 802 (void *)dip, (void *)ep_xdesc, (void *)pipe_policy, usb_flags, 803 (void *)pipe_handle); 804 805 if ((dip == NULL) || (pipe_handle == NULL)) { 806 807 return (USB_INVALID_ARGS); 808 } 809 810 if ((ep_xdesc != NULL) && 811 ((ep_xdesc->uex_version != USB_EP_XDESCR_CURRENT_VERSION) || 812 ((ep_xdesc->uex_flags & ~USB_EP_XFLAGS_SS_COMP) != 0))) { 813 814 return (USB_INVALID_ARGS); 815 } 816 817 if (servicing_interrupt() && (usb_flags & USB_FLAGS_SLEEP)) { 818 819 return (USB_INVALID_CONTEXT); 820 } 821 usba_device = usba_get_usba_device(dip); 822 823 /* 824 * Check the device's speed. If we're being asked to open anything other 825 * than the default endpoint and the device is superspeed or greater and 826 * we only have a usb_ep_descr_t and not the full endpoint data, then 827 * this was coming through usb_pipe_open() and we need to fail this 828 * call. 829 * 830 * Some drivers technically cheat and open the default control endpoint 831 * even though they're not supposed to. ugen appears to be the main 832 * offender. To deal with this, we check to see if the endpoint 833 * descriptor bcmps to our default and give them a break, since we don't 834 * need extended info for default control endpoints. 835 */ 836 if (ep_xdesc != NULL && ep_xdesc->uex_flags == 0 && 837 bcmp(&ep_xdesc->uex_ep, &usba_default_ep_descr, 838 sizeof (usb_ep_descr_t)) != 0 && 839 usba_device->usb_port_status >= USBA_SUPER_SPEED_DEV) { 840 const char *dname = ddi_driver_name(dip); 841 const char *prod, *mfg; 842 843 prod = usba_device->usb_product_str; 844 if (prod == NULL) 845 prod = "Unknown Device"; 846 mfg = usba_device->usb_mfg_str; 847 if (mfg == NULL) 848 mfg = "Unknown Manufacturer"; 849 cmn_err(CE_NOTE, "driver %s attempting to open non-default " 850 "of a USB 3.0 or newer device through usb_pipe_open(). " 851 "%s must be updated to use usb_pipe_xopen() to work with " 852 "USB device %s %s.", dname, dname, mfg, prod); 853 return (USB_FAILURE); 854 } 855 856 if ((ep_xdesc != NULL) && (pipe_policy == NULL)) { 857 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 858 "usb_pipe_open: null pipe policy"); 859 860 return (USB_INVALID_ARGS); 861 } 862 863 /* is the device still connected? */ 864 if ((ep_xdesc != NULL) & DEVI_IS_DEVICE_REMOVED(dip)) { 865 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 866 "usb_pipe_open: device has been removed"); 867 868 return (USB_FAILURE); 869 } 870 871 872 /* 873 * if a null endpoint pointer was passed, use the default 874 * endpoint descriptor 875 */ 876 if (ep_xdesc == NULL) { 877 if ((usb_flags & USBA_FLAGS_PRIVILEGED) == 0) { 878 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 879 "usb_pipe_open: not allowed to open def pipe"); 880 881 return (USB_INVALID_PERM); 882 } 883 884 ep = &usba_default_ep_descr; 885 pipe_policy = &usba_default_ep_pipe_policy; 886 } else { 887 ep = &ep_xdesc->uex_ep; 888 } 889 890 if (usb_flags & USB_FLAGS_SERIALIZED_CB) { 891 if (((ep->bmAttributes & USB_EP_ATTR_MASK) == 892 USB_EP_ATTR_CONTROL) || 893 ((ep->bmAttributes & USB_EP_ATTR_MASK) == 894 USB_EP_ATTR_ISOCH)) { 895 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 896 "usb_pipe_open: shared taskq not allowed with " 897 "ctrl or isoch pipe"); 898 899 return (USB_INVALID_ARGS); 900 } 901 } 902 903 kmflag = (usb_flags & USB_FLAGS_SLEEP) ? KM_SLEEP : KM_NOSLEEP; 904 size = sizeof (usba_pipe_handle_data_t); 905 906 if ((ph_data = kmem_zalloc(size, kmflag)) == NULL) { 907 908 return (USB_NO_RESOURCES); 909 } 910 911 /* check if pipe is already open and if so fail */ 912 ep_index = usb_get_ep_index(ep->bEndpointAddress); 913 ph_impl = &usba_device->usb_ph_list[ep_index]; 914 915 mutex_enter(&usba_device->usb_mutex); 916 mutex_enter(&ph_impl->usba_ph_mutex); 917 918 if (ph_impl->usba_ph_data) { 919 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 920 "usb_pipe_open: pipe to ep %d already open", ep_index); 921 mutex_exit(&ph_impl->usba_ph_mutex); 922 mutex_exit(&usba_device->usb_mutex); 923 kmem_free(ph_data, size); 924 925 return (USB_BUSY); 926 } 927 928 ph_impl->usba_ph_data = ph_data; 929 930 mutex_exit(&ph_impl->usba_ph_mutex); 931 mutex_exit(&usba_device->usb_mutex); 932 933 if (usb_flags & USB_FLAGS_SERIALIZED_CB) { 934 mutex_enter(&ph_data->p_mutex); 935 ph_data->p_spec_flag |= USBA_PH_FLAG_TQ_SHARE; 936 mutex_exit(&ph_data->p_mutex); 937 } 938 939 /* 940 * allocate and initialize the pipe handle 941 */ 942 if ((rval = usba_init_pipe_handle(dip, usba_device, 943 ep, ep_xdesc, pipe_policy, ph_impl)) != USB_SUCCESS) { 944 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 945 "usb_pipe_open: pipe init failed (%d)", rval); 946 947 return (rval); 948 } 949 ph_data = ph_impl->usba_ph_data; 950 951 /* 952 * ask the hcd to open the pipe 953 */ 954 if ((rval = usba_device->usb_hcdi_ops->usba_hcdi_pipe_open(ph_data, 955 usb_flags)) != USB_SUCCESS) { 956 usba_destroy_pipe_handle(ph_data); 957 958 *pipe_handle = NULL; 959 } else { 960 *pipe_handle = (usb_pipe_handle_t)ph_impl; 961 962 /* set the pipe state after a successful hcd open */ 963 mutex_enter(&ph_data->p_mutex); 964 usba_pipe_new_state(ph_data, USB_PIPE_STATE_IDLE); 965 mutex_exit(&ph_data->p_mutex); 966 } 967 968 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 969 "usb_pipe_open: ph_impl=0x%p (0x%p)", 970 (void *)ph_impl, (void *)ph_data); 971 972 return (rval); 973 } 974 975 int 976 usb_pipe_open( 977 dev_info_t *dip, 978 usb_ep_descr_t *ep, 979 usb_pipe_policy_t *pipe_policy, 980 usb_flags_t usb_flags, 981 usb_pipe_handle_t *pipe_handle) 982 { 983 usb_ep_xdescr_t xdesc, *xp = NULL; 984 985 /* 986 * ep may be NULL if trying to open the default control endpoint. 987 */ 988 if (ep != NULL) { 989 bzero(&xdesc, sizeof (usb_ep_xdescr_t)); 990 xdesc.uex_version = USB_EP_XDESCR_CURRENT_VERSION; 991 xdesc.uex_ep = *ep; 992 xp = &xdesc; 993 } 994 995 return (usb_pipe_xopen(dip, xp, pipe_policy, usb_flags, 996 pipe_handle)); 997 } 998 999 /* 1000 * usb_pipe_close/sync_close: 1001 * 1002 * Close a pipe and release all resources and free the pipe_handle. 1003 * Automatic polling, if active, will be terminated 1004 * 1005 * Arguments: 1006 * dip - devinfo ptr 1007 * pipehandle - pointer to pipehandle. The pipehandle will be 1008 * zeroed on successful completion 1009 * flags - USB_FLAGS_SLEEP: 1010 * wait for resources, pipe 1011 * to become free, all callbacks completed 1012 * callback - If USB_FLAGS_SLEEP has not been specified, a 1013 * callback will be performed. 1014 * callback_arg - the first argument of the callback. Note that 1015 * the pipehandle will be zeroed and not passed 1016 * 1017 * Notes: 1018 * Pipe close will always succeed regardless whether USB_FLAGS_SLEEP has been 1019 * specified or not. 1020 * An async close will always succeed if the hint in the pipe policy 1021 * has been correct about the max number of async taskq requests required. 1022 * If there are really no resources, the pipe handle will be linked into 1023 * a garbage pipe list and periodically checked by USBA until it can be 1024 * closed. This may cause a hang in the detach of the driver. 1025 * USBA will prevent the client from submitting more requests to a pipe 1026 * that is being closed 1027 * Subsequent usb_pipe_close() requests on the same pipe to USBA will 1028 * wait for the previous close(s) to finish. 1029 * 1030 * Note that once we start closing a pipe, we cannot go back anymore 1031 * to a normal pipe state 1032 */ 1033 void 1034 usb_pipe_close(dev_info_t *dip, 1035 usb_pipe_handle_t pipe_handle, 1036 usb_flags_t usb_flags, 1037 void (*callback)( 1038 usb_pipe_handle_t pipe_handle, 1039 usb_opaque_t arg, 1040 int rval, 1041 usb_cb_flags_t flags), 1042 usb_opaque_t callback_arg) 1043 { 1044 usba_pipe_handle_data_t *ph_data; 1045 usba_ph_impl_t *ph_impl = (usba_ph_impl_t *)pipe_handle; 1046 usb_cb_flags_t callback_flags; 1047 1048 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 1049 "usb_pipe_close: ph=0x%p", (void *)pipe_handle); 1050 1051 callback_flags = usba_check_intr_context(USB_CB_NO_INFO); 1052 if ((dip == NULL) || (pipe_handle == NULL)) { 1053 if (callback) { 1054 callback(pipe_handle, callback_arg, 1055 USB_INVALID_ARGS, callback_flags); 1056 } else { 1057 USB_DPRINTF_L2(DPRINT_MASK_USBAI, 1058 usbai_log_handle, 1059 "usb_pipe_close: invalid arguments"); 1060 } 1061 1062 return; 1063 } 1064 1065 if ((usb_flags & USBA_FLAGS_PRIVILEGED) == 0) { 1066 /* 1067 * It is the client driver doing the pipe close, 1068 * the pipe is no longer persistent then. 1069 */ 1070 mutex_enter(&ph_impl->usba_ph_mutex); 1071 ph_impl->usba_ph_flags &= ~USBA_PH_DATA_PERSISTENT; 1072 mutex_exit(&ph_impl->usba_ph_mutex); 1073 } 1074 1075 if (servicing_interrupt() && (usb_flags & USB_FLAGS_SLEEP)) { 1076 if (callback) { 1077 callback(pipe_handle, callback_arg, 1078 USB_INVALID_CONTEXT, callback_flags); 1079 } else { 1080 USB_DPRINTF_L2(DPRINT_MASK_USBAI, 1081 usbai_log_handle, 1082 "usb_pipe_close: invalid context"); 1083 } 1084 1085 return; 1086 } 1087 1088 if ((ph_data = usba_hold_ph_data(pipe_handle)) == NULL) { 1089 1090 /* hold pipehandle anyways since we will decrement later */ 1091 mutex_enter(&ph_impl->usba_ph_mutex); 1092 ph_impl->usba_ph_ref_count++; 1093 mutex_exit(&ph_impl->usba_ph_mutex); 1094 1095 (void) usba_pipe_setup_func_call(dip, usba_pipe_sync_close, 1096 ph_impl, NULL, usb_flags, callback, callback_arg); 1097 1098 return; 1099 } 1100 1101 mutex_enter(&ph_data->p_mutex); 1102 1103 if (USBA_IS_DEFAULT_PIPE(ph_data) && 1104 ((usb_flags & USBA_FLAGS_PRIVILEGED) == 0)) { 1105 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 1106 "usb_pipe_close: not allowed to close def pipe"); 1107 mutex_exit(&ph_data->p_mutex); 1108 1109 usba_release_ph_data(ph_impl); 1110 1111 if (callback) { 1112 callback(pipe_handle, callback_arg, 1113 USB_INVALID_PIPE, callback_flags); 1114 } else { 1115 USB_DPRINTF_L2(DPRINT_MASK_USBAI, 1116 usbai_log_handle, 1117 "usb_pipe_close: invalid pipe"); 1118 } 1119 1120 return; 1121 } 1122 1123 mutex_exit(&ph_data->p_mutex); 1124 1125 (void) usba_pipe_setup_func_call(dip, usba_pipe_sync_close, 1126 ph_impl, NULL, usb_flags, callback, callback_arg); 1127 } 1128 1129 1130 /*ARGSUSED*/ 1131 static int 1132 usba_pipe_sync_close(dev_info_t *dip, usba_ph_impl_t *ph_impl, 1133 usba_pipe_async_req_t *request, usb_flags_t usb_flags) 1134 { 1135 usba_device_t *usba_device; 1136 usba_pipe_handle_data_t *ph_data = usba_get_ph_data( 1137 (usb_pipe_handle_t)ph_impl); 1138 int attribute; 1139 uchar_t dir; 1140 int timeout; 1141 1142 if (ph_impl == NULL) { 1143 1144 return (USB_SUCCESS); 1145 } 1146 1147 mutex_enter(&ph_impl->usba_ph_mutex); 1148 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 1149 "usba_pipe_sync_close: dip=0x%p ph_data=0x%p state=%d ref=%d", 1150 (void *)dip, (void *)ph_data, ph_impl->usba_ph_state, 1151 ph_impl->usba_ph_ref_count); 1152 1153 /* 1154 * if another thread opens the pipe again, this loop could 1155 * be truly forever 1156 */ 1157 if ((ph_data == NULL) || 1158 (ph_impl->usba_ph_state == USB_PIPE_STATE_CLOSING) || 1159 (ph_impl->usba_ph_state == USB_PIPE_STATE_CLOSED)) { 1160 /* wait forever till really closed */ 1161 mutex_exit(&ph_impl->usba_ph_mutex); 1162 usba_release_ph_data(ph_impl); 1163 1164 while (usba_get_ph_data((usb_pipe_handle_t)ph_impl)) { 1165 delay(1); 1166 } 1167 1168 return (USB_SUCCESS); 1169 } 1170 ph_impl->usba_ph_state = USB_PIPE_STATE_CLOSING; 1171 mutex_exit(&ph_impl->usba_ph_mutex); 1172 1173 mutex_enter(&ph_data->p_mutex); 1174 mutex_enter(&ph_impl->usba_ph_mutex); 1175 1176 attribute = ph_data->p_ep.bmAttributes & USB_EP_ATTR_MASK; 1177 dir = ph_data->p_ep.bEndpointAddress & USB_EP_DIR_MASK; 1178 1179 usba_device = ph_data->p_usba_device; 1180 1181 /* 1182 * For control and bulk, we will drain till ref_count <= 1 and 1183 * req_count == 0 but for isoc and intr IN, we can only wait 1184 * till the ref_count === 1 as the req_count will never go to 0 1185 */ 1186 for (timeout = 0; timeout < usba_drain_timeout; timeout++) { 1187 switch (attribute) { 1188 case USB_EP_ATTR_CONTROL: 1189 case USB_EP_ATTR_BULK: 1190 if ((ph_data->p_req_count == 0) && 1191 (ph_impl->usba_ph_ref_count <= 1)) { 1192 goto done; 1193 } 1194 break; 1195 case USB_EP_ATTR_INTR: 1196 case USB_EP_ATTR_ISOCH: 1197 if (dir == USB_EP_DIR_IN) { 1198 if (ph_impl->usba_ph_ref_count <= 1) { 1199 goto done; 1200 } 1201 } else if ((ph_data->p_req_count == 0) && 1202 (ph_impl->usba_ph_ref_count <= 1)) { 1203 goto done; 1204 } 1205 break; 1206 } 1207 mutex_exit(&ph_impl->usba_ph_mutex); 1208 mutex_exit(&ph_data->p_mutex); 1209 delay(drv_usectohz(1000)); 1210 mutex_enter(&ph_data->p_mutex); 1211 mutex_enter(&ph_impl->usba_ph_mutex); 1212 } 1213 done: 1214 1215 mutex_exit(&ph_impl->usba_ph_mutex); 1216 mutex_exit(&ph_data->p_mutex); 1217 1218 if (timeout >= usba_drain_timeout) { 1219 int draining_succeeded; 1220 1221 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 1222 "timeout on draining requests, resetting pipe 0x%p", 1223 (void *)ph_impl); 1224 1225 (void) usba_device->usb_hcdi_ops->usba_hcdi_pipe_reset(ph_data, 1226 USB_FLAGS_SLEEP); 1227 1228 mutex_enter(&ph_data->p_mutex); 1229 draining_succeeded = usba_drain_cbs(ph_data, USB_CB_RESET_PIPE, 1230 USB_CR_PIPE_RESET); 1231 /* this MUST have succeeded */ 1232 ASSERT(draining_succeeded == USB_SUCCESS); 1233 mutex_exit(&ph_data->p_mutex); 1234 1235 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 1236 "draining requests done"); 1237 } 1238 1239 if (usba_device->usb_hcdi_ops->usba_hcdi_pipe_close(ph_data, 1240 usb_flags) != USB_SUCCESS) { 1241 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 1242 "usba_pipe_sync_close: hcd close failed"); 1243 /* carry on regardless! */ 1244 } 1245 1246 usba_destroy_pipe_handle(ph_data); 1247 1248 return (USB_SUCCESS); 1249 } 1250 1251 1252 /* 1253 * usb_pipe_set_private: 1254 * set private client date in the pipe handle 1255 */ 1256 int 1257 usb_pipe_set_private(usb_pipe_handle_t pipe_handle, usb_opaque_t data) 1258 { 1259 usba_pipe_handle_data_t *ph_data = usba_hold_ph_data(pipe_handle); 1260 1261 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 1262 "usb_pipe_set_private: "); 1263 1264 if (ph_data == NULL) { 1265 1266 return (USB_INVALID_PIPE); 1267 } 1268 if (USBA_IS_DEFAULT_PIPE(ph_data)) { 1269 usba_release_ph_data(ph_data->p_ph_impl); 1270 1271 return (USB_INVALID_PERM); 1272 } 1273 1274 mutex_enter(&ph_data->p_mutex); 1275 ph_data->p_client_private = data; 1276 mutex_exit(&ph_data->p_mutex); 1277 1278 usba_release_ph_data(ph_data->p_ph_impl); 1279 1280 return (USB_SUCCESS); 1281 } 1282 1283 1284 /* 1285 * usb_pipe_get_private: 1286 * get private client date from the pipe handle 1287 */ 1288 usb_opaque_t 1289 usb_pipe_get_private(usb_pipe_handle_t pipe_handle) 1290 { 1291 usba_pipe_handle_data_t *ph_data = usba_hold_ph_data(pipe_handle); 1292 usb_opaque_t data; 1293 1294 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 1295 "usb_pipe_get_private:"); 1296 1297 if (ph_data == NULL) { 1298 1299 return (NULL); 1300 } 1301 1302 mutex_enter(&ph_data->p_mutex); 1303 data = ph_data->p_client_private; 1304 mutex_exit(&ph_data->p_mutex); 1305 1306 usba_release_ph_data(ph_data->p_ph_impl); 1307 1308 return (data); 1309 } 1310 1311 1312 /* 1313 * usb_pipe_reset 1314 * Arguments: 1315 * dip - devinfo pointer 1316 * pipe_handle - opaque pipe handle 1317 * Returns: 1318 * USB_SUCCESS - pipe successfully reset or request queued 1319 * USB_FAILURE - undetermined failure 1320 * USB_INVALID_PIPE - pipe is invalid or already closed 1321 */ 1322 void 1323 usb_pipe_reset(dev_info_t *dip, 1324 usb_pipe_handle_t pipe_handle, 1325 usb_flags_t usb_flags, 1326 void (*callback)( 1327 usb_pipe_handle_t ph, 1328 usb_opaque_t arg, 1329 int rval, 1330 usb_cb_flags_t flags), 1331 usb_opaque_t callback_arg) 1332 { 1333 usba_ph_impl_t *ph_impl = (usba_ph_impl_t *)pipe_handle; 1334 usba_pipe_handle_data_t *ph_data = usba_hold_ph_data(pipe_handle); 1335 usb_cb_flags_t callback_flags; 1336 1337 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 1338 "usb_pipe_reset: dip=0x%p ph=0x%p uf=0x%x", 1339 (void *)dip, (void *)pipe_handle, usb_flags); 1340 1341 callback_flags = usba_check_intr_context(USB_CB_NO_INFO); 1342 1343 if ((dip == NULL) || (ph_data == NULL)) { 1344 if (callback) { 1345 callback(pipe_handle, callback_arg, 1346 USB_INVALID_ARGS, callback_flags); 1347 } else { 1348 USB_DPRINTF_L2(DPRINT_MASK_USBAI, 1349 usbai_log_handle, 1350 "usb_pipe_reset: invalid arguments"); 1351 } 1352 1353 usba_release_ph_data(ph_impl); 1354 1355 return; 1356 } 1357 if (servicing_interrupt() && (usb_flags & USB_FLAGS_SLEEP)) { 1358 if (callback) { 1359 callback(pipe_handle, callback_arg, 1360 USB_INVALID_CONTEXT, callback_flags); 1361 } else { 1362 USB_DPRINTF_L2(DPRINT_MASK_USBAI, 1363 usbai_log_handle, 1364 "usb_pipe_reset: invalid context"); 1365 } 1366 1367 usba_release_ph_data(ph_impl); 1368 1369 return; 1370 } 1371 1372 mutex_enter(&ph_data->p_mutex); 1373 1374 /* is this the default pipe? */ 1375 if (USBA_IS_DEFAULT_PIPE(ph_data)) { 1376 if ((usb_flags & USBA_FLAGS_PRIVILEGED) == 0) { 1377 USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, 1378 "usb_pipe_reset: not allowed to reset def pipe"); 1379 mutex_exit(&ph_data->p_mutex); 1380 1381 if (callback) { 1382 callback(pipe_handle, callback_arg, 1383 USB_INVALID_PIPE, callback_flags); 1384 } else { 1385 USB_DPRINTF_L2(DPRINT_MASK_USBAI, 1386 usbai_log_handle, 1387 "usb_pipe_reset: invalid pipe"); 1388 } 1389 usba_release_ph_data(ph_impl); 1390 1391 return; 1392 } 1393 } 1394 mutex_exit(&ph_data->p_mutex); 1395 1396 (void) usba_pipe_setup_func_call(dip, 1397 usba_pipe_sync_reset, ph_impl, NULL, usb_flags, callback, 1398 callback_arg); 1399 } 1400 1401 1402 /*ARGSUSED*/ 1403 int 1404 usba_pipe_sync_reset(dev_info_t *dip, 1405 usba_ph_impl_t *ph_impl, 1406 usba_pipe_async_req_t *request, 1407 usb_flags_t usb_flags) 1408 { 1409 int rval, draining_succeeded; 1410 usba_pipe_handle_data_t *ph_data = usba_get_ph_data((usb_pipe_handle_t) 1411 ph_impl); 1412 usba_device_t *usba_device; 1413 1414 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 1415 "usba_pipe_sync_reset: dip=0x%p ph_data=0x%p uf=0x%x", 1416 (void *)dip, (void *)ph_data, usb_flags); 1417 1418 mutex_enter(&ph_data->p_mutex); 1419 usba_device = ph_data->p_usba_device; 1420 mutex_exit(&ph_data->p_mutex); 1421 1422 rval = usba_device->usb_hcdi_ops->usba_hcdi_pipe_reset(ph_data, 1423 usb_flags); 1424 mutex_enter(&ph_data->p_mutex); 1425 1426 /* 1427 * The host controller has stopped polling of the endpoint. 1428 */ 1429 draining_succeeded = usba_drain_cbs(ph_data, USB_CB_RESET_PIPE, 1430 USB_CR_PIPE_RESET); 1431 1432 /* this MUST have succeeded */ 1433 ASSERT(draining_succeeded == USB_SUCCESS); 1434 1435 usba_pipe_new_state(ph_data, USB_PIPE_STATE_IDLE); 1436 mutex_exit(&ph_data->p_mutex); 1437 1438 /* 1439 * if there are requests still queued on the default pipe, 1440 * start them now 1441 */ 1442 usba_start_next_req(ph_data); 1443 1444 usba_release_ph_data(ph_impl); 1445 1446 return (rval); 1447 } 1448 1449 1450 /* 1451 * usba_pipe_clear: 1452 * call hcd to clear pipe but don't wait for draining 1453 */ 1454 void 1455 usba_pipe_clear(usb_pipe_handle_t pipe_handle) 1456 { 1457 usba_pipe_handle_data_t *ph_data = usba_get_ph_data(pipe_handle); 1458 usba_device_t *usba_device; 1459 usba_req_wrapper_t *req_wrp; 1460 int flush_requests = 1; 1461 1462 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 1463 "usba_pipe_clear: ph_data=0x%p", (void *)ph_data); 1464 1465 if (ph_data == NULL) { 1466 1467 return; 1468 } 1469 1470 mutex_enter(&ph_data->p_mutex); 1471 if (USBA_PIPE_CLOSING(usba_get_ph_state(ph_data))) { 1472 mutex_exit(&ph_data->p_mutex); 1473 1474 return; 1475 } 1476 usba_device = ph_data->p_usba_device; 1477 mutex_exit(&ph_data->p_mutex); 1478 1479 (void) usba_device->usb_hcdi_ops->usba_hcdi_pipe_reset(ph_data, 1480 USB_FLAGS_SLEEP); 1481 1482 mutex_enter(&ph_data->p_mutex); 1483 if (ph_data->p_dip) { 1484 if (USBA_IS_DEFAULT_PIPE(ph_data)) { 1485 USB_DPRINTF_L4(DPRINT_MASK_USBAI, 1486 usbai_log_handle, 1487 "no flushing on default pipe!"); 1488 1489 flush_requests = 0; 1490 } 1491 } 1492 1493 if (flush_requests) { 1494 /* flush all requests in the pipehandle queue */ 1495 while ((req_wrp = (usba_req_wrapper_t *) 1496 usba_rm_first_pvt_from_list(&ph_data->p_queue)) != NULL) { 1497 mutex_exit(&ph_data->p_mutex); 1498 usba_do_req_exc_cb(req_wrp, USB_CR_FLUSHED, 1499 USB_CB_RESET_PIPE); 1500 mutex_enter(&ph_data->p_mutex); 1501 } 1502 } 1503 1504 usba_pipe_new_state(ph_data, USB_PIPE_STATE_IDLE); 1505 mutex_exit(&ph_data->p_mutex); 1506 } 1507 1508 1509 /* 1510 * 1511 * usb_pipe_drain_reqs 1512 * this function blocks until there are no more requests 1513 * owned by this dip on the pipe 1514 * 1515 * Arguments: 1516 * dip - devinfo pointer 1517 * pipe_handle - opaque pipe handle 1518 * timeout - timeout in seconds 1519 * flags - USB_FLAGS_SLEEP: 1520 * wait for completion. 1521 * cb - if USB_FLAGS_SLEEP has not been specified 1522 * this callback function will be called on 1523 * completion. This callback may be NULL 1524 * and no notification of completion will then 1525 * be provided. 1526 * cb_arg - 2nd argument to callback function. 1527 * 1528 * callback and callback_arg should be NULL if USB_FLAGS_SLEEP has 1529 * been specified 1530 * 1531 * Returns: 1532 * USB_SUCCESS - pipe successfully reset or request queued 1533 * USB_FAILURE - timeout 1534 * USB_* - refer to usbai.h 1535 */ 1536 int 1537 usb_pipe_drain_reqs(dev_info_t *dip, 1538 usb_pipe_handle_t pipe_handle, 1539 uint_t time, 1540 usb_flags_t usb_flags, 1541 void (*cb)( 1542 usb_pipe_handle_t ph, 1543 usb_opaque_t arg, /* cb arg */ 1544 int rval, 1545 usb_cb_flags_t flags), 1546 usb_opaque_t cb_arg) 1547 { 1548 usba_ph_impl_t *ph_impl = (usba_ph_impl_t *)pipe_handle; 1549 usba_pipe_handle_data_t *ph_data = usba_hold_ph_data(pipe_handle); 1550 1551 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 1552 "usb_pipe_drain_reqs: dip=0x%p ph_data=0x%p tm=%d uf=0x%x", 1553 (void *)dip, (void *)ph_data, time, usb_flags); 1554 1555 if (ph_data == NULL) { 1556 1557 return (USB_INVALID_PIPE); 1558 } 1559 if (dip == NULL) { 1560 usba_release_ph_data(ph_impl); 1561 1562 return (USB_INVALID_ARGS); 1563 } 1564 1565 if ((usb_flags & USB_FLAGS_SLEEP) && servicing_interrupt()) { 1566 usba_release_ph_data(ph_impl); 1567 1568 return (USB_INVALID_CONTEXT); 1569 } 1570 1571 (void) usba_pipe_setup_func_call(dip, usba_pipe_sync_drain_reqs, 1572 ph_impl, (usb_opaque_t)((uintptr_t)time), usb_flags, cb, cb_arg); 1573 1574 return (USB_SUCCESS); 1575 } 1576 1577 1578 /* 1579 * usba_pipe_sync_drain_reqs 1580 * this function blocks until there are no more requests 1581 * owned by this dip on the pipe 1582 * 1583 * Arguments: 1584 * dip - devinfo pointer 1585 * ph_impl - pipe impl handle 1586 * timeout - timeout in seconds 1587 * Returns: 1588 * USB_SUCCESS - pipe successfully reset or request queued 1589 * USB_FAILURE - timeout 1590 * USB_* - see usbai.h 1591 */ 1592 /*ARGSUSED*/ 1593 int 1594 usba_pipe_sync_drain_reqs(dev_info_t *dip, 1595 usba_ph_impl_t *ph_impl, 1596 usba_pipe_async_req_t *request, 1597 usb_flags_t usb_flags) 1598 { 1599 usba_pipe_handle_data_t *ph_data = usba_get_ph_data((usb_pipe_handle_t) 1600 ph_impl); 1601 int i; 1602 int timeout = 100 * (int)((uintptr_t)(request->arg)); 1603 /* delay will be 10 ms */ 1604 1605 mutex_enter(&ph_data->p_mutex); 1606 1607 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 1608 "usba_pipe_sync_drain_reqs: " 1609 "dip=0x%p ph_data=0x%p timeout=%d ref=%d req=%d", 1610 (void *)dip, (void *)ph_data, timeout, 1611 usba_get_ph_ref_count(ph_data), 1612 ph_data->p_req_count); 1613 1614 ASSERT(ph_data->p_req_count >= 0); 1615 1616 /* 1617 * for default pipe, we need to check the active request 1618 * and the queue 1619 * Note that a pipe reset on the default pipe doesn't flush 1620 * the queue 1621 * for all other pipes we just check ref and req count since 1622 * these pipes are unshared 1623 */ 1624 if (USBA_IS_DEFAULT_PIPE(ph_data)) { 1625 for (i = 0; (i < timeout) || (request->arg == 0); i++) { 1626 usba_list_entry_t *next, *tmpnext; 1627 usba_req_wrapper_t *req_wrp = (usba_req_wrapper_t *) 1628 ph_data->p_active_cntrl_req_wrp; 1629 int found = 0; 1630 int count = 0; 1631 1632 /* active_req_wrp is only for control pipes */ 1633 if ((req_wrp == NULL) || (req_wrp->wr_dip != dip)) { 1634 /* walk the queue */ 1635 mutex_enter(&ph_data->p_queue.list_mutex); 1636 next = ph_data->p_queue.next; 1637 while (next != NULL) { 1638 mutex_enter(&next->list_mutex); 1639 req_wrp = (usba_req_wrapper_t *) 1640 next->private; 1641 found = (req_wrp->wr_dip == dip); 1642 if (found) { 1643 mutex_exit(&next->list_mutex); 1644 1645 break; 1646 } 1647 tmpnext = next->next; 1648 mutex_exit(&next->list_mutex); 1649 next = tmpnext; 1650 count++; 1651 } 1652 mutex_exit(&ph_data->p_queue.list_mutex); 1653 if (found == 0) { 1654 break; 1655 } 1656 } 1657 1658 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 1659 "usb_pipe_sync_drain_reqs: " 1660 "cnt=%d active_req_wrp=0x%p", 1661 count, (void *)ph_data->p_active_cntrl_req_wrp); 1662 1663 mutex_exit(&ph_data->p_mutex); 1664 delay(drv_usectohz(10000)); 1665 mutex_enter(&ph_data->p_mutex); 1666 } 1667 } else { 1668 mutex_enter(&ph_data->p_ph_impl->usba_ph_mutex); 1669 for (i = 0; (i < timeout) || (request->arg == 0); i++) { 1670 ASSERT(ph_data->p_req_count >= 0); 1671 if (ph_data->p_req_count || 1672 (ph_data->p_ph_impl->usba_ph_ref_count > 1)) { 1673 mutex_exit(&ph_data->p_ph_impl->usba_ph_mutex); 1674 mutex_exit(&ph_data->p_mutex); 1675 delay(drv_usectohz(10000)); 1676 mutex_enter(&ph_data->p_mutex); 1677 mutex_enter(&ph_data->p_ph_impl->usba_ph_mutex); 1678 } else { 1679 break; 1680 } 1681 } 1682 mutex_exit(&ph_data->p_ph_impl->usba_ph_mutex); 1683 } 1684 1685 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 1686 "usb_pipe_sync_drain_reqs: timeout=%d active_req_wrp=0x%p req=%d", 1687 i, (void *)ph_data->p_active_cntrl_req_wrp, ph_data->p_req_count); 1688 1689 mutex_exit(&ph_data->p_mutex); 1690 1691 usba_release_ph_data(ph_impl); 1692 1693 return (i >= timeout ? USB_FAILURE : USB_SUCCESS); 1694 } 1695 1696 1697 /* 1698 * usba_persistent_pipe_open 1699 * Open all the pipes marked persistent for this device 1700 */ 1701 int 1702 usba_persistent_pipe_open(usba_device_t *usba_device) 1703 { 1704 usba_ph_impl_t *ph_impl; 1705 usb_pipe_handle_t pipe_handle; 1706 int i; 1707 int rval = USB_SUCCESS; 1708 1709 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 1710 "usba_persistent_pipe_open: usba_device=0x%p", (void *)usba_device); 1711 1712 if (usba_device != NULL) { 1713 /* default pipe is the first one to be opened */ 1714 mutex_enter(&usba_device->usb_mutex); 1715 for (i = 0; (rval == USB_SUCCESS) && 1716 (i < USBA_N_ENDPOINTS); i++) { 1717 1718 ph_impl = &usba_device->usb_ph_list[i]; 1719 mutex_enter(&ph_impl->usba_ph_mutex); 1720 if (ph_impl->usba_ph_flags & USBA_PH_DATA_PERSISTENT) { 1721 ph_impl->usba_ph_flags &= 1722 ~USBA_PH_DATA_PERSISTENT; 1723 mutex_exit(&ph_impl->usba_ph_mutex); 1724 mutex_exit(&usba_device->usb_mutex); 1725 1726 rval = usb_pipe_open(ph_impl->usba_ph_dip, 1727 &ph_impl->usba_ph_ep, 1728 &ph_impl->usba_ph_policy, 1729 USB_FLAGS_SLEEP | USBA_FLAGS_PRIVILEGED, 1730 &pipe_handle); 1731 1732 USB_DPRINTF_L3(DPRINT_MASK_USBAI, 1733 usbai_log_handle, 1734 "usba_persistent_pipe_open: " 1735 "ep_index=%d, rval=%d", i, rval); 1736 mutex_enter(&usba_device->usb_mutex); 1737 mutex_enter(&ph_impl->usba_ph_mutex); 1738 } 1739 mutex_exit(&ph_impl->usba_ph_mutex); 1740 } 1741 mutex_exit(&usba_device->usb_mutex); 1742 } 1743 1744 return (rval); 1745 } 1746 1747 1748 /* 1749 * usba_persistent_pipe_close 1750 * Close all pipes of this device and mark them persistent 1751 */ 1752 void 1753 usba_persistent_pipe_close(usba_device_t *usba_device) 1754 { 1755 usba_ph_impl_t *ph_impl; 1756 usb_pipe_handle_t pipe_handle; 1757 int i; 1758 1759 USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, 1760 "usba_persistent_pipe_close: usba_device=0x%p", 1761 (void *)usba_device); 1762 1763 if (usba_device != NULL) { 1764 /* default pipe is the last one to be closed */ 1765 mutex_enter(&usba_device->usb_mutex); 1766 1767 for (i = (USBA_N_ENDPOINTS - 1); i >= 0; i--) { 1768 ph_impl = &usba_device->usb_ph_list[i]; 1769 if (ph_impl->usba_ph_data != NULL) { 1770 mutex_enter(&ph_impl->usba_ph_mutex); 1771 ph_impl->usba_ph_flags |= 1772 USBA_PH_DATA_PERSISTENT; 1773 mutex_exit(&ph_impl->usba_ph_mutex); 1774 mutex_exit(&usba_device->usb_mutex); 1775 1776 pipe_handle = (usb_pipe_handle_t)ph_impl; 1777 1778 usb_pipe_close(ph_impl->usba_ph_dip, 1779 pipe_handle, 1780 USB_FLAGS_SLEEP | USBA_FLAGS_PRIVILEGED, 1781 NULL, NULL); 1782 mutex_enter(&usba_device->usb_mutex); 1783 ASSERT(ph_impl->usba_ph_data == NULL); 1784 } 1785 } 1786 mutex_exit(&usba_device->usb_mutex); 1787 } 1788 } 1789