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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 /* 28 * Universal Host Controller Driver (UHCI) 29 * 30 * The UHCI driver is a driver which interfaces to the Universal 31 * Serial Bus Architecture (USBA) and the Host Controller (HC). The interface to 32 * the Host Controller is defined by the Universal Host Controller Interface. 33 * This file contains code for auto-configuration entry points and interrupt 34 * handling. 35 */ 36 #include <sys/usb/hcd/uhci/uhcid.h> 37 #include <sys/usb/hcd/uhci/uhcihub.h> 38 #include <sys/usb/hcd/uhci/uhciutil.h> 39 40 /* 41 * Prototype Declarations for cb_ops and dev_ops 42 */ 43 static int uhci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 44 static int uhci_add_intrs(uhci_state_t *uhcip, int intr_type); 45 static int uhci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 46 static void uhci_rem_intrs(uhci_state_t *uhcip); 47 static int uhci_open(dev_t *devp, int flags, int otyp, cred_t *credp); 48 static int uhci_close(dev_t dev, int flag, int otyp, cred_t *credp); 49 static int uhci_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, 50 cred_t *credp, int *rvalp); 51 static int uhci_reset(dev_info_t *dip, ddi_reset_cmd_t cmd); 52 static int uhci_quiesce(dev_info_t *dip); 53 static int uhci_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 54 void **result); 55 56 /* extern */ 57 int usba_hubdi_root_hub_power(dev_info_t *dip, int comp, int level); 58 59 static struct cb_ops uhci_cb_ops = { 60 uhci_open, /* Open */ 61 uhci_close, /* Close */ 62 nodev, /* Strategy */ 63 nodev, /* Print */ 64 nodev, /* Dump */ 65 nodev, /* Read */ 66 nodev, /* Write */ 67 uhci_ioctl, /* Ioctl */ 68 nodev, /* Devmap */ 69 nodev, /* Mmap */ 70 nodev, /* Segmap */ 71 nochpoll, /* Poll */ 72 ddi_prop_op, /* cb_prop_op */ 73 NULL, /* Streamtab */ 74 D_MP /* Driver compatibility flag */ 75 }; 76 77 static struct dev_ops uhci_ops = { 78 DEVO_REV, /* Devo_rev */ 79 0, /* Refcnt */ 80 uhci_info, /* Info */ 81 nulldev, /* Identify */ 82 nulldev, /* Probe */ 83 uhci_attach, /* Attach */ 84 uhci_detach, /* Detach */ 85 uhci_reset, /* Reset */ 86 &uhci_cb_ops, /* Driver operations */ 87 &usba_hubdi_busops, /* Bus operations */ 88 usba_hubdi_root_hub_power, /* Power */ 89 uhci_quiesce /* quiesce */ 90 }; 91 92 static struct modldrv modldrv = { 93 &mod_driverops, /* Type of module. This one is a driver */ 94 "USB UHCI Controller Driver", /* Name of the module. */ 95 &uhci_ops, /* Driver ops */ 96 }; 97 98 static struct modlinkage modlinkage = { 99 MODREV_1, (void *)&modldrv, NULL 100 }; 101 102 /* 103 * Globals 104 */ 105 void *uhci_statep; 106 uint_t uhci_errlevel = USB_LOG_L2; 107 uint_t uhci_errmask = PRINT_MASK_ALL; 108 uint_t uhci_instance_debug = (uint_t)-1; 109 110 uint_t uhci_td_pool_size = 256; /* Num TDs */ 111 uint_t uhci_qh_pool_size = 130; /* Num QHs */ 112 ushort_t uhci_tree_bottom_nodes[NUM_FRAME_LST_ENTRIES]; 113 114 115 /* 116 * UHCI MSI tunable: 117 * 118 * By default MSI is enabled on all supported platforms. 119 */ 120 boolean_t uhci_enable_msi = B_TRUE; 121 122 /* 123 * tunable, delay during attach in seconds 124 */ 125 int uhci_attach_wait = 0; 126 127 /* function prototypes */ 128 static void uhci_handle_intr_td_errors(uhci_state_t *uhcip, uhci_td_t *td, 129 uhci_trans_wrapper_t *tw, uhci_pipe_private_t *pp); 130 static void uhci_handle_one_xfer_completion(uhci_state_t *uhcip, 131 usb_cr_t usb_err, uhci_td_t *td); 132 static uint_t uhci_intr(caddr_t arg1, caddr_t arg2); 133 static int uhci_cleanup(uhci_state_t *uhcip); 134 static int uhci_cpr_suspend(uhci_state_t *uhcip); 135 static int uhci_cpr_resume(uhci_state_t *uhcip); 136 137 138 int 139 _init(void) 140 { 141 int error; 142 ushort_t i, j, k, *temp, num_of_nodes; 143 144 /* Initialize the soft state structures */ 145 if ((error = ddi_soft_state_init(&uhci_statep, sizeof (uhci_state_t), 146 UHCI_MAX_INSTS)) != 0) { 147 148 return (error); 149 } 150 151 /* Install the loadable module */ 152 if ((error = mod_install(&modlinkage)) != 0) { 153 ddi_soft_state_fini(&uhci_statep); 154 155 return (error); 156 } 157 158 /* 159 * Build the tree bottom shared by all instances 160 */ 161 temp = kmem_zalloc(NUM_FRAME_LST_ENTRIES * 2, KM_SLEEP); 162 163 num_of_nodes = 1; 164 for (i = 0; i < log_2(NUM_FRAME_LST_ENTRIES); i++) { 165 for (j = 0, k = 0; k < num_of_nodes; k++, j++) { 166 uhci_tree_bottom_nodes[j++] = temp[k]; 167 uhci_tree_bottom_nodes[j] = temp[k] + pow_2(i); 168 } 169 170 num_of_nodes *= 2; 171 for (k = 0; k < num_of_nodes; k++) 172 temp[k] = uhci_tree_bottom_nodes[k]; 173 174 } 175 kmem_free(temp, (NUM_FRAME_LST_ENTRIES*2)); 176 177 178 return (error); 179 } 180 181 182 int 183 _info(struct modinfo *modinfop) 184 { 185 return (mod_info(&modlinkage, modinfop)); 186 } 187 188 189 int 190 _fini(void) 191 { 192 int error; 193 194 error = mod_remove(&modlinkage); 195 196 if (error == 0) { 197 /* Release per module resources */ 198 ddi_soft_state_fini(&uhci_statep); 199 } 200 201 return (error); 202 } 203 204 /* 205 * The following simulated polling is for debugging purposes only. 206 * It is activated on x86 by setting usb-polling=true in GRUB or uhci.conf. 207 */ 208 static int 209 uhci_is_polled(dev_info_t *dip) 210 { 211 int ret; 212 char *propval; 213 214 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, 215 "usb-polling", &propval) != DDI_SUCCESS) 216 217 return (0); 218 219 ret = (strcmp(propval, "true") == 0); 220 ddi_prop_free(propval); 221 222 return (ret); 223 } 224 225 static void 226 uhci_poll_intr(void *arg) 227 { 228 /* poll every msec */ 229 for (;;) { 230 (void) uhci_intr(arg, NULL); 231 delay(drv_usectohz(1000)); 232 } 233 } 234 235 /* 236 * Host Controller Driver (HCD) Auto configuration entry points 237 */ 238 239 /* 240 * Function Name : uhci_attach: 241 * Description : Attach entry point - called by the Kernel. 242 * Allocates of per controller data structure. 243 * Initializes the controller. 244 * Output : DDI_SUCCESS / DDI_FAILURE 245 */ 246 static int 247 uhci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 248 { 249 int instance, polled; 250 int i, intr_types; 251 uhci_state_t *uhcip = NULL; 252 usba_hcdi_register_args_t hcdi_args; 253 254 USB_DPRINTF_L4(PRINT_MASK_ATTA, NULL, "uhci_attach:"); 255 256 switch (cmd) { 257 case DDI_ATTACH: 258 break; 259 case DDI_RESUME: 260 uhcip = uhci_obtain_state(dip); 261 262 return (uhci_cpr_resume(uhcip)); 263 default: 264 265 return (DDI_FAILURE); 266 } 267 268 /* Get the instance and create soft state */ 269 instance = ddi_get_instance(dip); 270 271 /* Allocate the soft state structure for this instance of the driver */ 272 if (ddi_soft_state_zalloc(uhci_statep, instance) != 0) { 273 274 return (DDI_FAILURE); 275 } 276 277 if ((uhcip = ddi_get_soft_state(uhci_statep, instance)) == NULL) { 278 279 return (DDI_FAILURE); 280 } 281 282 uhcip->uhci_log_hdl = usb_alloc_log_hdl(dip, "uhci", &uhci_errlevel, 283 &uhci_errmask, &uhci_instance_debug, 0); 284 285 /* Set host controller soft state to initialization */ 286 uhcip->uhci_hc_soft_state = UHCI_CTLR_INIT_STATE; 287 288 /* Save the dip and instance */ 289 uhcip->uhci_dip = dip; 290 uhcip->uhci_instance = instance; 291 292 polled = uhci_is_polled(dip); 293 if (polled) 294 295 goto skip_intr; 296 297 /* Get supported interrupt types */ 298 if (ddi_intr_get_supported_types(uhcip->uhci_dip, 299 &intr_types) != DDI_SUCCESS) { 300 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 301 "uhci_attach: ddi_intr_get_supported_types failed"); 302 303 usb_free_log_hdl(uhcip->uhci_log_hdl); 304 ddi_soft_state_free(uhci_statep, instance); 305 306 return (DDI_FAILURE); 307 } 308 309 USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 310 "uhci_attach: supported interrupt types 0x%x", intr_types); 311 312 if ((intr_types & DDI_INTR_TYPE_MSI) && uhci_enable_msi) { 313 if (uhci_add_intrs(uhcip, DDI_INTR_TYPE_MSI) 314 != DDI_SUCCESS) { 315 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 316 "uhci_attach: MSI registration failed, " 317 "trying FIXED interrupt \n"); 318 } else { 319 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 320 "uhci_attach: Using MSI interrupt type\n"); 321 322 uhcip->uhci_intr_type = DDI_INTR_TYPE_MSI; 323 } 324 } 325 326 if (!(uhcip->uhci_htable) && (intr_types & DDI_INTR_TYPE_FIXED)) { 327 if (uhci_add_intrs(uhcip, DDI_INTR_TYPE_FIXED) 328 != DDI_SUCCESS) { 329 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 330 "uhci_attach: FIXED interrupt registration " 331 "failed\n"); 332 333 usb_free_log_hdl(uhcip->uhci_log_hdl); 334 ddi_soft_state_free(uhci_statep, instance); 335 336 return (DDI_FAILURE); 337 } 338 339 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 340 "uhci_attach: Using FIXED interrupt type\n"); 341 342 uhcip->uhci_intr_type = DDI_INTR_TYPE_FIXED; 343 } 344 345 skip_intr: 346 /* Semaphore to serialize opens and closes */ 347 sema_init(&uhcip->uhci_ocsem, 1, NULL, SEMA_DRIVER, NULL); 348 349 /* Create prototype condition variable */ 350 cv_init(&uhcip->uhci_cv_SOF, NULL, CV_DRIVER, NULL); 351 352 /* Initialize the DMA attributes */ 353 uhci_set_dma_attributes(uhcip); 354 355 /* Initialize the kstat structures */ 356 uhci_create_stats(uhcip); 357 358 /* Create the td and ed pools */ 359 if (uhci_allocate_pools(uhcip) != USB_SUCCESS) { 360 361 goto fail; 362 } 363 364 /* Map the registers */ 365 if (uhci_map_regs(uhcip) != USB_SUCCESS) { 366 367 goto fail; 368 } 369 370 /* Enable all interrupts */ 371 if (polled) { 372 extern pri_t maxclsyspri; 373 374 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 375 "uhci_attach: running in simulated polled mode."); 376 377 /* create thread to poll */ 378 (void) thread_create(NULL, 0, uhci_poll_intr, uhcip, 0, &p0, 379 TS_RUN, maxclsyspri); 380 } else if (uhcip->uhci_intr_cap & DDI_INTR_FLAG_BLOCK) { 381 /* Call ddi_intr_block_enable() for MSI interrupts */ 382 (void) ddi_intr_block_enable(uhcip->uhci_htable, 383 uhcip->uhci_intr_cnt); 384 } else { 385 /* Call ddi_intr_enable for MSI or FIXED interrupts */ 386 for (i = 0; i < uhcip->uhci_intr_cnt; i++) 387 (void) ddi_intr_enable(uhcip->uhci_htable[i]); 388 } 389 390 391 /* Initialize the controller */ 392 if (uhci_init_ctlr(uhcip) != USB_SUCCESS) { 393 394 goto fail; 395 } 396 397 /* 398 * At this point, the hardware will be okay. 399 * Initialize the usba_hcdi structure 400 */ 401 uhcip->uhci_hcdi_ops = uhci_alloc_hcdi_ops(uhcip); 402 403 /* 404 * Make this HCD instance known to USBA 405 * (dma_attr must be passed for USBA busctl's) 406 */ 407 hcdi_args.usba_hcdi_register_version = HCDI_REGISTER_VERSION; 408 hcdi_args.usba_hcdi_register_dip = dip; 409 hcdi_args.usba_hcdi_register_ops = uhcip->uhci_hcdi_ops; 410 hcdi_args.usba_hcdi_register_dma_attr = &uhcip->uhci_dma_attr; 411 hcdi_args.usba_hcdi_register_iblock_cookie = 412 (ddi_iblock_cookie_t)(uintptr_t)uhcip->uhci_intr_pri; 413 414 if (usba_hcdi_register(&hcdi_args, 0) != USB_SUCCESS) { 415 416 goto fail; 417 } 418 419 #ifndef __sparc 420 /* 421 * On NCR system, the driver seen failure of some commands 422 * while booting. This delay mysteriously solved the problem. 423 */ 424 delay(drv_usectohz(uhci_attach_wait*1000000)); 425 #endif 426 427 /* 428 * Create another timeout handler to check whether any 429 * control/bulk/interrupt commands failed. 430 * This gets called every second. 431 */ 432 uhcip->uhci_cmd_timeout_id = timeout(uhci_cmd_timeout_hdlr, 433 (void *)uhcip, UHCI_ONE_SECOND); 434 435 mutex_enter(&uhcip->uhci_int_mutex); 436 437 /* 438 * Set HcInterruptEnable to enable all interrupts except Root 439 * Hub Status change and SOF interrupts. 440 */ 441 Set_OpReg16(USBINTR, ENABLE_ALL_INTRS); 442 443 /* Test the SOF interrupt */ 444 if (uhci_wait_for_sof(uhcip) != USB_SUCCESS) { 445 USB_DPRINTF_L0(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 446 "No SOF interrupts have been received, this USB UHCI host" 447 " controller is unusable"); 448 mutex_exit(&uhcip->uhci_int_mutex); 449 450 goto fail; 451 } 452 453 mutex_exit(&uhcip->uhci_int_mutex); 454 455 /* This should be the last step which might fail during attaching */ 456 if (uhci_init_root_hub(uhcip) != USB_SUCCESS) { 457 458 goto fail; 459 } 460 461 /* Display information in the banner */ 462 ddi_report_dev(dip); 463 464 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 465 "uhci_attach successful"); 466 467 return (DDI_SUCCESS); 468 469 fail: 470 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 471 "failed to attach"); 472 473 (void) uhci_cleanup(uhcip); 474 475 return (DDI_FAILURE); 476 } 477 478 479 /* 480 * uhci_add_intrs: 481 * 482 * Register FIXED or MSI interrupts. 483 */ 484 static int 485 uhci_add_intrs(uhci_state_t *uhcip, 486 int intr_type) 487 { 488 int actual, avail, intr_size, count = 0; 489 int i, flag, ret; 490 491 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 492 "uhci_add_intrs: interrupt type 0x%x", intr_type); 493 494 /* Get number of interrupts */ 495 ret = ddi_intr_get_nintrs(uhcip->uhci_dip, intr_type, &count); 496 if ((ret != DDI_SUCCESS) || (count == 0)) { 497 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 498 "uhci_add_intrs: ddi_intr_get_nintrs() failure, " 499 "ret: %d, count: %d", ret, count); 500 501 return (DDI_FAILURE); 502 } 503 504 /* Get number of available interrupts */ 505 ret = ddi_intr_get_navail(uhcip->uhci_dip, intr_type, &avail); 506 if ((ret != DDI_SUCCESS) || (avail == 0)) { 507 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 508 "uhci_add_intrs: ddi_intr_get_navail() failure, " 509 "ret: %d, count: %d", ret, count); 510 511 return (DDI_FAILURE); 512 } 513 514 if (avail < count) { 515 USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 516 "uhci_add_intrs: uhci_add_intrs: nintrs () " 517 "returned %d, navail returned %d\n", count, avail); 518 } 519 520 /* Allocate an array of interrupt handles */ 521 intr_size = count * sizeof (ddi_intr_handle_t); 522 uhcip->uhci_htable = kmem_zalloc(intr_size, KM_SLEEP); 523 524 flag = (intr_type == DDI_INTR_TYPE_MSI) ? 525 DDI_INTR_ALLOC_STRICT:DDI_INTR_ALLOC_NORMAL; 526 527 /* call ddi_intr_alloc() */ 528 ret = ddi_intr_alloc(uhcip->uhci_dip, uhcip->uhci_htable, 529 intr_type, 0, count, &actual, flag); 530 531 if ((ret != DDI_SUCCESS) || (actual == 0)) { 532 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 533 "uhci_add_intrs: ddi_intr_alloc() failed %d", ret); 534 535 kmem_free(uhcip->uhci_htable, intr_size); 536 537 return (DDI_FAILURE); 538 } 539 540 if (actual < count) { 541 USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 542 "uhci_add_intrs: Requested: %d, Received: %d\n", 543 count, actual); 544 545 for (i = 0; i < actual; i++) 546 (void) ddi_intr_free(uhcip->uhci_htable[i]); 547 548 kmem_free(uhcip->uhci_htable, intr_size); 549 550 return (DDI_FAILURE); 551 } 552 553 uhcip->uhci_intr_cnt = actual; 554 555 if ((ret = ddi_intr_get_pri(uhcip->uhci_htable[0], 556 &uhcip->uhci_intr_pri)) != DDI_SUCCESS) { 557 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 558 "uhci_add_intrs: ddi_intr_get_pri() failed %d", ret); 559 560 for (i = 0; i < actual; i++) 561 (void) ddi_intr_free(uhcip->uhci_htable[i]); 562 563 kmem_free(uhcip->uhci_htable, intr_size); 564 565 return (DDI_FAILURE); 566 } 567 568 USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 569 "uhci_add_intrs: Supported Interrupt priority 0x%x", 570 uhcip->uhci_intr_pri); 571 572 /* Test for high level mutex */ 573 if (uhcip->uhci_intr_pri >= ddi_intr_get_hilevel_pri()) { 574 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 575 "uhci_add_intrs: Hi level interrupt not supported"); 576 577 for (i = 0; i < actual; i++) 578 (void) ddi_intr_free(uhcip->uhci_htable[i]); 579 580 kmem_free(uhcip->uhci_htable, intr_size); 581 582 return (DDI_FAILURE); 583 } 584 585 /* Initialize the mutex */ 586 mutex_init(&uhcip->uhci_int_mutex, NULL, MUTEX_DRIVER, 587 DDI_INTR_PRI(uhcip->uhci_intr_pri)); 588 589 /* Call ddi_intr_add_handler() */ 590 for (i = 0; i < actual; i++) { 591 if ((ret = ddi_intr_add_handler(uhcip->uhci_htable[i], 592 uhci_intr, (caddr_t)uhcip, 593 (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) { 594 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 595 "uhci_add_intrs: ddi_intr_add_handler() " 596 "failed %d", ret); 597 598 for (i = 0; i < actual; i++) 599 (void) ddi_intr_free(uhcip->uhci_htable[i]); 600 601 mutex_destroy(&uhcip->uhci_int_mutex); 602 kmem_free(uhcip->uhci_htable, intr_size); 603 604 return (DDI_FAILURE); 605 } 606 } 607 608 if ((ret = ddi_intr_get_cap(uhcip->uhci_htable[0], 609 &uhcip->uhci_intr_cap)) != DDI_SUCCESS) { 610 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 611 "uhci_add_intrs: ddi_intr_get_cap() failed %d", ret); 612 613 for (i = 0; i < actual; i++) { 614 (void) ddi_intr_remove_handler(uhcip->uhci_htable[i]); 615 (void) ddi_intr_free(uhcip->uhci_htable[i]); 616 } 617 618 mutex_destroy(&uhcip->uhci_int_mutex); 619 kmem_free(uhcip->uhci_htable, intr_size); 620 621 return (DDI_FAILURE); 622 } 623 624 return (DDI_SUCCESS); 625 } 626 627 628 /* 629 * Function Name: uhci_detach 630 * Description: Detach entry point - called by the Kernel. 631 * Deallocates all the memory 632 * Unregisters the interrupt handle and other resources. 633 * Output: DDI_SUCCESS / DDI_FAILURE 634 */ 635 static int 636 uhci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 637 { 638 uhci_state_t *uhcip = uhci_obtain_state(dip); 639 640 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 641 "uhci_detach:"); 642 643 switch (cmd) { 644 case DDI_DETACH: 645 646 return (uhci_cleanup(uhcip) == USB_SUCCESS ? 647 DDI_SUCCESS : DDI_FAILURE); 648 case DDI_SUSPEND: 649 650 return (uhci_cpr_suspend(uhcip)); 651 default: 652 653 return (DDI_FAILURE); 654 } 655 } 656 657 658 /* 659 * uhci_rem_intrs: 660 * 661 * Unregister FIXED or MSI interrupts 662 */ 663 static void 664 uhci_rem_intrs(uhci_state_t *uhcip) 665 { 666 int i; 667 668 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 669 "uhci_rem_intrs: interrupt type 0x%x", uhcip->uhci_intr_type); 670 671 /* Disable all interrupts */ 672 if (uhcip->uhci_intr_cap & DDI_INTR_FLAG_BLOCK) { 673 (void) ddi_intr_block_disable(uhcip->uhci_htable, 674 uhcip->uhci_intr_cnt); 675 } else { 676 for (i = 0; i < uhcip->uhci_intr_cnt; i++) { 677 (void) ddi_intr_disable(uhcip->uhci_htable[i]); 678 } 679 } 680 681 /* Call ddi_intr_remove_handler() */ 682 for (i = 0; i < uhcip->uhci_intr_cnt; i++) { 683 (void) ddi_intr_remove_handler(uhcip->uhci_htable[i]); 684 (void) ddi_intr_free(uhcip->uhci_htable[i]); 685 } 686 687 kmem_free(uhcip->uhci_htable, 688 uhcip->uhci_intr_cnt * sizeof (ddi_intr_handle_t)); 689 } 690 691 692 /* 693 * Function Name: uhci_reset 694 * Description: Reset entry point - called by the Kernel 695 * on the way down. 696 * The Toshiba laptop has been observed to hang 697 * on reboot when BIOS is set to suspend/resume. 698 * The resetting uhci on the way down solves the 699 * problem. 700 * Output: DDI_SUCCESS / DDI_FAILURE 701 */ 702 /* ARGSUSED */ 703 static int 704 uhci_reset(dev_info_t *dip, ddi_reset_cmd_t cmd) 705 { 706 uhci_state_t *uhcip = uhci_obtain_state(dip); 707 708 /* Disable all HC ED list processing */ 709 Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); 710 Set_OpReg16(USBCMD, 0); 711 712 return (DDI_SUCCESS); 713 } 714 715 /* 716 * quiesce(9E) entry point. 717 * 718 * This function is called when the system is single-threaded at high 719 * PIL with preemption disabled. Therefore, this function must not be 720 * blocked. 721 * 722 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 723 * DDI_FAILURE indicates an error condition and should almost never happen. 724 */ 725 static int 726 uhci_quiesce(dev_info_t *dip) 727 { 728 uhci_state_t *uhcip = uhci_obtain_state(dip); 729 730 if (uhcip == NULL) 731 return (DDI_FAILURE); 732 733 /* Disable interrupts */ 734 Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); 735 736 /* Stop the Host Controller */ 737 Set_OpReg16(USBCMD, 0); 738 739 /* Clear all status bits */ 740 Set_OpReg16(USBSTS, Get_OpReg16(USBSTS) & UHCI_INTR_MASK); 741 742 return (DDI_SUCCESS); 743 } 744 745 746 /* 747 * uhci_info: 748 */ 749 /* ARGSUSED */ 750 static int 751 uhci_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 752 { 753 dev_t dev; 754 int instance; 755 int error = DDI_FAILURE; 756 uhci_state_t *uhcip; 757 758 switch (infocmd) { 759 case DDI_INFO_DEVT2DEVINFO: 760 dev = (dev_t)arg; 761 instance = UHCI_UNIT(dev); 762 uhcip = ddi_get_soft_state(uhci_statep, instance); 763 if (uhcip != NULL) { 764 *result = (void *)uhcip->uhci_dip; 765 if (*result != NULL) { 766 error = DDI_SUCCESS; 767 } 768 } else { 769 *result = NULL; 770 } 771 772 break; 773 case DDI_INFO_DEVT2INSTANCE: 774 dev = (dev_t)arg; 775 instance = UHCI_UNIT(dev); 776 *result = (void *)(uintptr_t)instance; 777 error = DDI_SUCCESS; 778 779 break; 780 default: 781 break; 782 } 783 784 return (error); 785 } 786 787 788 /* 789 * uhci_cleanup: 790 * Cleanup on attach failure or detach 791 */ 792 static int 793 uhci_cleanup(uhci_state_t *uhcip) 794 { 795 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, "uhci_cleanup:"); 796 797 if (usba_hubdi_unbind_root_hub(uhcip->uhci_dip) != USB_SUCCESS) { 798 799 return (USB_FAILURE); 800 } 801 802 mutex_enter(&uhcip->uhci_int_mutex); 803 804 if (uhcip->uhci_cmd_timeout_id) { 805 timeout_id_t timeout_id = uhcip->uhci_cmd_timeout_id; 806 uhcip->uhci_cmd_timeout_id = 0; 807 mutex_exit(&uhcip->uhci_int_mutex); 808 (void) untimeout(timeout_id); 809 mutex_enter(&uhcip->uhci_int_mutex); 810 } 811 812 uhci_uninit_ctlr(uhcip); 813 814 mutex_exit(&uhcip->uhci_int_mutex); 815 816 /* do interrupt cleanup */ 817 if (uhcip->uhci_htable) { 818 uhci_rem_intrs(uhcip); 819 } 820 821 mutex_enter(&uhcip->uhci_int_mutex); 822 823 usba_hcdi_unregister(uhcip->uhci_dip); 824 825 uhci_unmap_regs(uhcip); 826 827 uhci_free_pools(uhcip); 828 829 mutex_exit(&uhcip->uhci_int_mutex); 830 831 mutex_destroy(&uhcip->uhci_int_mutex); 832 cv_destroy(&uhcip->uhci_cv_SOF); 833 sema_destroy(&uhcip->uhci_ocsem); 834 835 /* cleanup kstat structures */ 836 uhci_destroy_stats(uhcip); 837 838 usba_free_hcdi_ops(uhcip->uhci_hcdi_ops); 839 usb_free_log_hdl(uhcip->uhci_log_hdl); 840 ddi_prop_remove_all(uhcip->uhci_dip); 841 ddi_soft_state_free(uhci_statep, uhcip->uhci_instance); 842 843 return (USB_SUCCESS); 844 } 845 846 847 /* 848 * uhci_cpr_suspend 849 */ 850 static int 851 uhci_cpr_suspend(uhci_state_t *uhcip) 852 { 853 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 854 "uhci_cpr_suspend:"); 855 856 /* Call into the root hub and suspend it */ 857 if (usba_hubdi_detach(uhcip->uhci_dip, DDI_SUSPEND) != DDI_SUCCESS) { 858 859 return (DDI_FAILURE); 860 } 861 862 mutex_enter(&uhcip->uhci_int_mutex); 863 864 /* Disable interrupts */ 865 Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); 866 867 mutex_exit(&uhcip->uhci_int_mutex); 868 869 /* Wait for SOF time to handle the scheduled interrupt */ 870 delay(drv_usectohz(UHCI_TIMEWAIT)); 871 872 mutex_enter(&uhcip->uhci_int_mutex); 873 /* Stop the Host Controller */ 874 Set_OpReg16(USBCMD, 0); 875 876 /* Set Global Suspend bit */ 877 Set_OpReg16(USBCMD, USBCMD_REG_ENER_GBL_SUSPEND); 878 879 /* Set host controller soft state to suspend */ 880 uhcip->uhci_hc_soft_state = UHCI_CTLR_SUSPEND_STATE; 881 882 mutex_exit(&uhcip->uhci_int_mutex); 883 884 return (USB_SUCCESS); 885 } 886 887 888 /* 889 * uhci_cpr_cleanup: 890 * 891 * Cleanup uhci specific information across resuming. 892 */ 893 static void 894 uhci_cpr_cleanup(uhci_state_t *uhcip) 895 { 896 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 897 898 /* Reset software part of usb frame number */ 899 uhcip->uhci_sw_frnum = 0; 900 } 901 902 903 /* 904 * uhci_cpr_resume 905 */ 906 static int 907 uhci_cpr_resume(uhci_state_t *uhcip) 908 { 909 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 910 "uhci_cpr_resume: Restart the controller"); 911 912 mutex_enter(&uhcip->uhci_int_mutex); 913 914 /* Cleanup uhci specific information across cpr */ 915 uhci_cpr_cleanup(uhcip); 916 917 mutex_exit(&uhcip->uhci_int_mutex); 918 919 /* Restart the controller */ 920 if (uhci_init_ctlr(uhcip) != DDI_SUCCESS) { 921 922 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 923 "uhci_cpr_resume: uhci host controller resume failed "); 924 925 return (DDI_FAILURE); 926 } 927 928 mutex_enter(&uhcip->uhci_int_mutex); 929 930 /* 931 * Set HcInterruptEnable to enable all interrupts except Root 932 * Hub Status change and SOF interrupts. 933 */ 934 Set_OpReg16(USBINTR, ENABLE_ALL_INTRS); 935 936 mutex_exit(&uhcip->uhci_int_mutex); 937 938 /* Now resume the root hub */ 939 if (usba_hubdi_attach(uhcip->uhci_dip, DDI_RESUME) != DDI_SUCCESS) { 940 941 return (DDI_FAILURE); 942 } 943 944 return (DDI_SUCCESS); 945 } 946 947 948 /* 949 * uhci_intr: 950 * uhci interrupt handling routine. 951 */ 952 static uint_t 953 uhci_intr(caddr_t arg1, caddr_t arg2) 954 { 955 ushort_t intr_status, cmd_reg, intr_reg; 956 uhci_state_t *uhcip = (uhci_state_t *)arg1; 957 958 USB_DPRINTF_L4(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 959 "uhci_intr: Interrupt occurred, arg1 0x%p arg2 0x%p", 960 (void *)arg1, (void *)arg2); 961 962 mutex_enter(&uhcip->uhci_int_mutex); 963 964 /* Any interrupt is not handled for the suspended device. */ 965 if (uhcip->uhci_hc_soft_state == UHCI_CTLR_SUSPEND_STATE) { 966 mutex_exit(&uhcip->uhci_int_mutex); 967 968 return (DDI_INTR_UNCLAIMED); 969 } 970 971 /* Get the status of the interrupts */ 972 intr_status = Get_OpReg16(USBSTS); 973 intr_reg = Get_OpReg16(USBINTR); 974 975 USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 976 "uhci_intr: intr_status = %x, intr_reg = %x", 977 intr_status, intr_reg); 978 979 /* 980 * If uhci interrupts are all disabled, the driver should return 981 * unclaimed. 982 * HC Process Error and Host System Error interrupts cannot be 983 * disabled by intr register, and need to be judged separately. 984 */ 985 if (((intr_reg & ENABLE_ALL_INTRS) == 0) && 986 ((intr_status & USBSTS_REG_HC_PROCESS_ERR) == 0) && 987 ((intr_status & USBSTS_REG_HOST_SYS_ERR) == 0)) { 988 989 USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 990 "uhci_intr: interrupts disabled, unclaim"); 991 mutex_exit(&uhcip->uhci_int_mutex); 992 993 return (DDI_INTR_UNCLAIMED); 994 } 995 996 /* 997 * If the intr is not from our controller, just return unclaimed. 998 * HCHalted status bit cannot generate interrupts and should be 999 * ignored. 1000 */ 1001 if (!(intr_status & UHCI_INTR_MASK)) { 1002 1003 USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 1004 "uhci_intr: no interrupt status set, unclaim"); 1005 mutex_exit(&uhcip->uhci_int_mutex); 1006 1007 return (DDI_INTR_UNCLAIMED); 1008 } 1009 1010 /* Update kstat values */ 1011 uhci_do_intrs_stats(uhcip, intr_status); 1012 1013 /* Acknowledge the interrupt */ 1014 Set_OpReg16(USBSTS, intr_status); 1015 1016 /* 1017 * If uhci controller has not been initialized, just clear the 1018 * interrupter status and return claimed. 1019 */ 1020 if (uhcip->uhci_hc_soft_state != UHCI_CTLR_OPERATIONAL_STATE) { 1021 1022 USB_DPRINTF_L2(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 1023 "uhci_intr: uhci controller is not in the operational " 1024 "state"); 1025 mutex_exit(&uhcip->uhci_int_mutex); 1026 1027 return (DDI_INTR_CLAIMED); 1028 } 1029 1030 /* 1031 * We configured the hw incorrectly, disable future interrupts. 1032 */ 1033 if ((intr_status & USBSTS_REG_HOST_SYS_ERR)) { 1034 USB_DPRINTF_L2(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 1035 "uhci_intr: Sys Err Disabling Interrupt"); 1036 Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); 1037 uhcip->uhci_hc_soft_state = UHCI_CTLR_ERROR_STATE; 1038 1039 mutex_exit(&uhcip->uhci_int_mutex); 1040 1041 return (DDI_INTR_CLAIMED); 1042 } 1043 1044 /* 1045 * Check whether a frame number overflow occurred. 1046 * if so, update the sw frame number. 1047 */ 1048 uhci_isoc_update_sw_frame_number(uhcip); 1049 1050 /* 1051 * Check whether any commands got completed. If so, process them. 1052 */ 1053 uhci_process_submitted_td_queue(uhcip); 1054 1055 /* 1056 * This should not occur. It occurs only if a HC controller 1057 * experiences internal problem. 1058 */ 1059 if (intr_status & USBSTS_REG_HC_HALTED) { 1060 USB_DPRINTF_L2(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 1061 "uhci_intr: Controller halted"); 1062 cmd_reg = Get_OpReg16(USBCMD); 1063 Set_OpReg16(USBCMD, (cmd_reg | USBCMD_REG_HC_RUN)); 1064 } 1065 1066 /* 1067 * Wake up all the threads which are waiting for the Start of Frame 1068 */ 1069 if (uhcip->uhci_cv_signal == B_TRUE) { 1070 cv_broadcast(&uhcip->uhci_cv_SOF); 1071 uhcip->uhci_cv_signal = B_FALSE; 1072 } 1073 1074 mutex_exit(&uhcip->uhci_int_mutex); 1075 1076 return (DDI_INTR_CLAIMED); 1077 } 1078 1079 1080 /* 1081 * uhci_process_submitted_td_queue: 1082 * Traverse thru the submitted queue and process the completed ones. 1083 */ 1084 void 1085 uhci_process_submitted_td_queue(uhci_state_t *uhcip) 1086 { 1087 uhci_td_t *head = uhcip->uhci_outst_tds_head; 1088 uhci_trans_wrapper_t *tw; 1089 1090 while (head != NULL) { 1091 if ((!(GetTD_status(uhcip, head) & UHCI_TD_ACTIVE)) && 1092 (head->tw->tw_claim == UHCI_NOT_CLAIMED)) { 1093 tw = head->tw; 1094 1095 /* 1096 * Call the corresponding handle_td routine 1097 */ 1098 (*tw->tw_handle_td)(uhcip, head); 1099 1100 /* restart at the beginning again */ 1101 head = uhcip->uhci_outst_tds_head; 1102 } else { 1103 head = head->outst_td_next; 1104 } 1105 } 1106 } 1107 1108 1109 /* 1110 * uhci_handle_intr_td: 1111 * handles the completed interrupt transfer TD's. 1112 */ 1113 void 1114 uhci_handle_intr_td(uhci_state_t *uhcip, uhci_td_t *td) 1115 { 1116 usb_req_attrs_t attrs; 1117 uint_t bytes_xfered; 1118 usb_cr_t usb_err; 1119 uhci_trans_wrapper_t *tw = td->tw; 1120 uhci_pipe_private_t *pp = tw->tw_pipe_private; 1121 usb_intr_req_t *intr_reqp = 1122 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 1123 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 1124 1125 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1126 "uhci_handle_intr_td: intr_reqp = 0x%p", (void *)intr_reqp); 1127 1128 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 1129 1130 /* set tw->tw_claim flag, so that nobody else works on this td. */ 1131 tw->tw_claim = UHCI_INTR_HDLR_CLAIMED; 1132 1133 /* Interrupt OUT */ 1134 if (UHCI_XFER_DIR(&ph->p_ep) == USB_EP_DIR_OUT) { 1135 1136 /* process errors first */ 1137 usb_err = uhci_parse_td_error(uhcip, pp, td); 1138 1139 /* get the actual xfered data size */ 1140 bytes_xfered = GetTD_alen(uhcip, td); 1141 1142 /* check data underrun error */ 1143 if ((usb_err == USB_CR_OK) && (bytes_xfered != 1144 GetTD_mlen(uhcip, td))) { 1145 1146 USB_DPRINTF_L2(PRINT_MASK_LISTS, 1147 uhcip->uhci_log_hdl, "uhci_handle_intr_td:" 1148 " Intr out pipe, data underrun occurred"); 1149 1150 usb_err = USB_CR_DATA_UNDERRUN; 1151 1152 } 1153 1154 bytes_xfered = (bytes_xfered == ZERO_LENGTH) ? 1155 0 : bytes_xfered+1; 1156 tw->tw_bytes_xfered += bytes_xfered; 1157 uhci_do_byte_stats(uhcip, tw->tw_bytes_xfered, 1158 ph->p_ep.bmAttributes, ph->p_ep.bEndpointAddress); 1159 1160 1161 /* 1162 * If error occurred or all data xfered, delete the current td, 1163 * free tw, do the callback. Otherwise wait for the next td. 1164 */ 1165 if (usb_err != USB_CR_OK) { 1166 1167 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1168 "uhci_handle_intr_td: Intr out pipe error"); 1169 1170 /* update the element pointer */ 1171 SetQH32(uhcip, pp->pp_qh->element_ptr, GetTD32( 1172 uhcip, tw->tw_hctd_tail->link_ptr)); 1173 1174 1175 } else if (tw->tw_bytes_xfered == tw->tw_length) { 1176 1177 /* all data xfered */ 1178 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1179 "uhci_handle_intr_td: Intr out pipe," 1180 " all data xfered"); 1181 1182 } else { 1183 1184 /* remove the current td and wait for the next one. */ 1185 uhci_delete_td(uhcip, td); 1186 tw->tw_claim = UHCI_NOT_CLAIMED; 1187 1188 return; 1189 } 1190 1191 uhci_delete_td(uhcip, td); 1192 uhci_hcdi_callback(uhcip, pp, ph, tw, usb_err); 1193 uhci_deallocate_tw(uhcip, tw->tw_pipe_private, tw); 1194 1195 return; 1196 } 1197 1198 /* Interrupt IN */ 1199 1200 /* Get the actual received data size */ 1201 tw->tw_bytes_xfered = GetTD_alen(uhcip, td); 1202 if (tw->tw_bytes_xfered == ZERO_LENGTH) { 1203 tw->tw_bytes_xfered = 0; 1204 } else { 1205 tw->tw_bytes_xfered++; 1206 } 1207 1208 /* process errors first */ 1209 if (GetTD_status(uhcip, td) & TD_STATUS_MASK) { 1210 SetQH32(uhcip, pp->pp_qh->element_ptr, 1211 GetTD32(uhcip, td->link_ptr)); 1212 1213 uhci_handle_intr_td_errors(uhcip, td, tw, pp); 1214 1215 return; 1216 } 1217 1218 /* 1219 * Check for data underruns. 1220 * For data underrun case, the host controller does not update 1221 * element pointer. So, we update here. 1222 */ 1223 if (GetTD_alen(uhcip, td) != GetTD_mlen(uhcip, td)) { 1224 SetQH32(uhcip, pp->pp_qh->element_ptr, 1225 GetTD32(uhcip, td->link_ptr)); 1226 } 1227 1228 /* 1229 * Call uhci_sendup_td_message to send message upstream. 1230 * The function uhci_sendup_td_message returns USB_NO_RESOURCES 1231 * if allocb fails and also sends error message to upstream by 1232 * calling USBA callback function. Under error conditions just 1233 * drop the current message. 1234 */ 1235 1236 /* Get the interrupt xfer attributes */ 1237 attrs = intr_reqp->intr_attributes; 1238 1239 /* 1240 * Check usb flag whether USB_FLAGS_ONE_XFER flag is set 1241 * and if so, free duplicate request. 1242 */ 1243 if (attrs & USB_ATTRS_ONE_XFER) { 1244 uhci_handle_one_xfer_completion(uhcip, USB_CR_OK, td); 1245 1246 return; 1247 } 1248 1249 /* save it temporarily */ 1250 if (tw->tw_bytes_xfered != 0) { 1251 uhci_sendup_td_message(uhcip, USB_CR_OK, tw); 1252 } 1253 1254 /* Clear the tw->tw_claim flag */ 1255 tw->tw_claim = UHCI_NOT_CLAIMED; 1256 1257 uhci_delete_td(uhcip, td); 1258 1259 /* allocate another interrupt periodic resource */ 1260 if (pp->pp_state == UHCI_PIPE_STATE_ACTIVE) { 1261 if (uhci_allocate_periodic_in_resource(uhcip, pp, tw, 0) != 1262 USB_SUCCESS) { 1263 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1264 "uhci_insert_intr_req: Interrupt request structure" 1265 "allocation failed"); 1266 1267 uhci_hcdi_callback(uhcip, pp, ph, 1268 tw, USB_CR_NO_RESOURCES); 1269 1270 return; 1271 } 1272 1273 /* Insert another interrupt TD */ 1274 if (uhci_insert_hc_td(uhcip, 0, 1275 tw->tw_length, pp, tw, PID_IN, attrs) != USB_SUCCESS) { 1276 1277 uhci_deallocate_periodic_in_resource(uhcip, pp, tw); 1278 1279 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1280 "uhci_handle_intr_td: TD exhausted"); 1281 1282 uhci_hcdi_callback(uhcip, pp, ph, 1283 tw, USB_CR_NO_RESOURCES); 1284 } 1285 } 1286 } 1287 1288 1289 /* 1290 * uhci_sendup_td_message: 1291 * 1292 * Get a message block and send the received message upstream. 1293 */ 1294 void 1295 uhci_sendup_td_message( 1296 uhci_state_t *uhcip, 1297 usb_cr_t usb_err, 1298 uhci_trans_wrapper_t *tw) 1299 { 1300 mblk_t *mp = NULL; 1301 size_t length = 0; 1302 size_t skip_len = 0; 1303 uchar_t *buf; 1304 usb_opaque_t curr_xfer_reqp = tw->tw_curr_xfer_reqp; 1305 uhci_pipe_private_t *pp = tw->tw_pipe_private; 1306 usb_ep_descr_t *ept = &pp->pp_pipe_handle->p_ep; 1307 1308 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 1309 1310 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1311 "uhci_sendup_td_message: bytes transferred=0x%x, " 1312 "bytes pending=0x%x", 1313 tw->tw_bytes_xfered, tw->tw_bytes_pending); 1314 1315 length = tw->tw_bytes_xfered; 1316 1317 switch (UHCI_XFER_TYPE(ept)) { 1318 case USB_EP_ATTR_CONTROL: 1319 skip_len = UHCI_CTRL_EPT_MAX_SIZE; /* length to skip */ 1320 mp = ((usb_ctrl_req_t *)curr_xfer_reqp)->ctrl_data; 1321 break; 1322 case USB_EP_ATTR_INTR: 1323 mp = ((usb_intr_req_t *)curr_xfer_reqp)->intr_data; 1324 break; 1325 case USB_EP_ATTR_BULK: 1326 mp = ((usb_bulk_req_t *)curr_xfer_reqp)->bulk_data; 1327 break; 1328 case USB_EP_ATTR_ISOCH: 1329 length = tw->tw_length; 1330 mp = ((usb_isoc_req_t *)curr_xfer_reqp)->isoc_data; 1331 break; 1332 default: 1333 break; 1334 } 1335 1336 /* Copy the data into the mblk_t */ 1337 buf = (uchar_t *)tw->tw_buf + skip_len; 1338 1339 ASSERT(mp != NULL); 1340 1341 /* 1342 * Update kstat byte counts 1343 * The control endpoints don't have direction bits so in 1344 * order for control stats to be counted correctly an IN 1345 * bit must be faked on a control read. 1346 */ 1347 uhci_do_byte_stats(uhcip, length, ept->bmAttributes, 1348 (UHCI_XFER_TYPE(ept) == USB_EP_ATTR_CONTROL) ? 1349 USB_EP_DIR_IN : ept->bEndpointAddress); 1350 1351 if (length) { 1352 int rval, i; 1353 uchar_t *p = mp->b_rptr; 1354 1355 if (UHCI_XFER_TYPE(ept) == USB_EP_ATTR_ISOCH) { 1356 /* Deal with isoc data by packets */ 1357 for (i = 0; i < tw->tw_ncookies; i++) { 1358 rval = ddi_dma_sync( 1359 tw->tw_isoc_bufs[i].dma_handle, 0, 1360 tw->tw_isoc_bufs[i].length, 1361 DDI_DMA_SYNC_FORCPU); 1362 ASSERT(rval == DDI_SUCCESS); 1363 1364 ddi_rep_get8(tw->tw_isoc_bufs[i].mem_handle, 1365 p, (uint8_t *)tw->tw_isoc_bufs[i].buf_addr, 1366 tw->tw_isoc_bufs[i].length, 1367 DDI_DEV_AUTOINCR); 1368 p += tw->tw_isoc_bufs[i].length; 1369 } 1370 } else { 1371 /* Sync the streaming buffer */ 1372 rval = ddi_dma_sync(tw->tw_dmahandle, 0, 1373 (skip_len + length), DDI_DMA_SYNC_FORCPU); 1374 ASSERT(rval == DDI_SUCCESS); 1375 1376 /* Copy the data into the message */ 1377 ddi_rep_get8(tw->tw_accesshandle, 1378 mp->b_rptr, buf, length, DDI_DEV_AUTOINCR); 1379 } 1380 1381 /* Increment the write pointer */ 1382 mp->b_wptr += length; 1383 } else { 1384 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1385 "uhci_sendup_td_message: Zero length packet"); 1386 } 1387 1388 /* Do the callback */ 1389 uhci_hcdi_callback(uhcip, pp, pp->pp_pipe_handle, tw, usb_err); 1390 } 1391 1392 1393 /* 1394 * uhci_handle_ctrl_td: 1395 * Handle a control Transfer Descriptor (TD). 1396 */ 1397 void 1398 uhci_handle_ctrl_td(uhci_state_t *uhcip, uhci_td_t *td) 1399 { 1400 ushort_t direction; 1401 ushort_t bytes_for_xfer; 1402 ushort_t bytes_xfered; 1403 ushort_t MaxPacketSize; 1404 usb_cr_t error; 1405 uhci_trans_wrapper_t *tw = td->tw; 1406 uhci_pipe_private_t *pp = tw->tw_pipe_private; 1407 usba_pipe_handle_data_t *usb_pp = pp->pp_pipe_handle; 1408 usb_ep_descr_t *eptd = &usb_pp->p_ep; 1409 usb_ctrl_req_t *reqp = (usb_ctrl_req_t *)tw->tw_curr_xfer_reqp; 1410 1411 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1412 "uhci_handle_ctrl_td: pp = 0x%p tw = 0x%p td = 0x%p " 1413 "state = 0x%x len = 0x%lx", (void *)pp, (void *)tw, 1414 (void *)td, tw->tw_ctrl_state, tw->tw_length); 1415 1416 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 1417 1418 error = uhci_parse_td_error(uhcip, pp, td); 1419 1420 /* 1421 * In case of control transfers, the device can send NAK when it 1422 * is busy. If a NAK is received, then send the status TD again. 1423 */ 1424 if (error != USB_CR_OK) { 1425 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1426 "uhci_handle_ctrl_td: Ctrl cmd failed, error = %x", error); 1427 1428 SetQH32(uhcip, pp->pp_qh->element_ptr, 1429 GetTD32(uhcip, td->link_ptr)); 1430 uhci_delete_td(uhcip, td); 1431 1432 /* Return number of bytes xfered */ 1433 if (GetTD_alen(uhcip, td) != ZERO_LENGTH) { 1434 tw->tw_bytes_xfered = GetTD_alen(uhcip, td) + 1; 1435 } 1436 1437 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1438 "uhci_handle_ctrl_td: Bytes transferred = %x", 1439 tw->tw_bytes_xfered); 1440 1441 if ((tw->tw_ctrl_state == DATA) && 1442 (tw->tw_direction == PID_IN)) { 1443 uhci_sendup_td_message(uhcip, error, tw); 1444 } else { 1445 uhci_hcdi_callback(uhcip, pp, usb_pp, tw, error); 1446 1447 uhci_deallocate_tw(uhcip, pp, tw); 1448 } 1449 1450 return; 1451 } 1452 1453 /* 1454 * A control transfer consists of three phases: 1455 * - Setup 1456 * - Data (optional) 1457 * - Status 1458 * 1459 * There is a TD per phase. A TD for a given phase isn't 1460 * enqueued until the previous phase is finished. 1461 */ 1462 switch (tw->tw_ctrl_state) { 1463 case SETUP: 1464 /* 1465 * Enqueue either the data or the status 1466 * phase depending on the length. 1467 */ 1468 pp->pp_data_toggle = 1; 1469 uhci_delete_td(uhcip, td); 1470 1471 /* 1472 * If the length is 0, move to the status. 1473 * If length is not 0, then we have some data 1474 * to move on the bus to device either IN or OUT. 1475 */ 1476 if ((tw->tw_length - SETUP_SIZE) == 0) { 1477 /* 1478 * There is no data stage, then 1479 * initiate status phase from the host. 1480 */ 1481 if ((uhci_insert_hc_td(uhcip, 0, 0, pp, tw, PID_IN, 1482 reqp->ctrl_attributes)) != USB_SUCCESS) { 1483 USB_DPRINTF_L2(PRINT_MASK_LISTS, 1484 uhcip->uhci_log_hdl, 1485 "uhci_handle_ctrl_td: No resources"); 1486 1487 uhci_hcdi_callback(uhcip, pp, usb_pp, tw, 1488 USB_CR_NO_RESOURCES); 1489 1490 return; 1491 } 1492 1493 tw->tw_ctrl_state = STATUS; 1494 } else { 1495 uint_t xx; 1496 1497 /* 1498 * Each USB device can send/receive 8/16/32/64 1499 * depending on wMaxPacketSize's implementation. 1500 * We need to insert 'N = Number of byte/ 1501 * MaxpktSize" TD's in the lattice to send/ 1502 * receive the data. Though the USB protocol 1503 * allows to insert more than one TD in the same 1504 * frame, we are inserting only one TD in one 1505 * frame. This is bcos OHCI has seen some problem 1506 * when multiple TD's are inserted at the same time. 1507 */ 1508 tw->tw_length -= UHCI_CTRL_EPT_MAX_SIZE; 1509 MaxPacketSize = eptd->wMaxPacketSize; 1510 1511 /* 1512 * We dont know the maximum packet size that 1513 * the device can handle(MaxPAcketSize=0). 1514 * In that case insert a data phase with 1515 * eight bytes or less. 1516 */ 1517 if (MaxPacketSize == 0) { 1518 xx = (tw->tw_length > 8) ? 8 : tw->tw_length; 1519 } else { 1520 xx = (tw->tw_length > MaxPacketSize) ? 1521 MaxPacketSize : tw->tw_length; 1522 } 1523 1524 tw->tw_tmp = xx; 1525 1526 /* 1527 * Create the TD. If this is an OUT 1528 * transaction, the data is already 1529 * in the buffer of the TW. 1530 * Get first 8 bytes of the command only. 1531 */ 1532 if ((uhci_insert_hc_td(uhcip, 1533 UHCI_CTRL_EPT_MAX_SIZE, xx, 1534 pp, tw, tw->tw_direction, 1535 reqp->ctrl_attributes)) != USB_SUCCESS) { 1536 1537 USB_DPRINTF_L2(PRINT_MASK_LISTS, 1538 uhcip->uhci_log_hdl, 1539 "uhci_handle_ctrl_td: No resources"); 1540 1541 uhci_hcdi_callback(uhcip, pp, usb_pp, tw, 1542 USB_CR_NO_RESOURCES); 1543 1544 return; 1545 } 1546 1547 tw->tw_ctrl_state = DATA; 1548 } 1549 1550 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1551 "Setup complete: pp 0x%p td 0x%p", (void *)pp, (void *)td); 1552 1553 break; 1554 case DATA: 1555 uhci_delete_td(uhcip, td); 1556 1557 MaxPacketSize = eptd->wMaxPacketSize; 1558 1559 /* 1560 * Decrement pending bytes and increment the total 1561 * number bytes transferred by the actual number of bytes 1562 * transferred in this TD. If the number of bytes transferred 1563 * is less than requested, that means an underrun has 1564 * occurred. Set the tw_tmp varible to indicate UNDER run. 1565 */ 1566 bytes_xfered = GetTD_alen(uhcip, td); 1567 if (bytes_xfered == ZERO_LENGTH) { 1568 bytes_xfered = 0; 1569 } else { 1570 bytes_xfered++; 1571 } 1572 1573 tw->tw_bytes_pending -= bytes_xfered; 1574 tw->tw_bytes_xfered += bytes_xfered; 1575 1576 if (bytes_xfered < tw->tw_tmp) { 1577 tw->tw_bytes_pending = 0; 1578 tw->tw_tmp = UHCI_UNDERRUN_OCCURRED; 1579 1580 /* 1581 * Controller does not update the queue head 1582 * element pointer when a data underrun occurs. 1583 */ 1584 SetQH32(uhcip, pp->pp_qh->element_ptr, 1585 GetTD32(uhcip, td->link_ptr)); 1586 } 1587 1588 if (bytes_xfered > tw->tw_tmp) { 1589 tw->tw_bytes_pending = 0; 1590 tw->tw_tmp = UHCI_OVERRUN_OCCURRED; 1591 } 1592 1593 /* 1594 * If no more bytes are pending, insert status 1595 * phase. Otherwise insert data phase. 1596 */ 1597 if (tw->tw_bytes_pending) { 1598 bytes_for_xfer = (tw->tw_bytes_pending > 1599 MaxPacketSize) ? MaxPacketSize : 1600 tw->tw_bytes_pending; 1601 1602 tw->tw_tmp = bytes_for_xfer; 1603 1604 if ((uhci_insert_hc_td(uhcip, 1605 UHCI_CTRL_EPT_MAX_SIZE + tw->tw_bytes_xfered, 1606 bytes_for_xfer, pp, tw, 1607 tw->tw_direction, 1608 reqp->ctrl_attributes)) != USB_SUCCESS) { 1609 USB_DPRINTF_L2(PRINT_MASK_LISTS, 1610 uhcip->uhci_log_hdl, 1611 "uhci_handle_ctrl_td: No TD"); 1612 1613 uhci_hcdi_callback(uhcip, pp, usb_pp, 1614 tw, USB_NO_RESOURCES); 1615 1616 return; 1617 } 1618 1619 tw->tw_ctrl_state = DATA; 1620 1621 break; 1622 } 1623 1624 pp->pp_data_toggle = 1; 1625 direction = (tw->tw_direction == PID_IN) ? PID_OUT : PID_IN; 1626 1627 if ((uhci_insert_hc_td(uhcip, 0, 0, pp, tw, direction, 1628 reqp->ctrl_attributes)) != USB_SUCCESS) { 1629 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1630 "uhci_handle_ctrl_td: TD exhausted"); 1631 1632 uhci_hcdi_callback(uhcip, pp, usb_pp, tw, 1633 USB_NO_RESOURCES); 1634 1635 return; 1636 } 1637 1638 tw->tw_ctrl_state = STATUS; 1639 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1640 "Data complete: pp 0x%p td 0x%p", (void *)pp, (void *)td); 1641 1642 break; 1643 case STATUS: 1644 /* 1645 * Send the data to the client if it is a DATA IN, 1646 * else send just return status for DATA OUT commnads. 1647 * And set the tw_claim flag. 1648 */ 1649 tw->tw_claim = UHCI_INTR_HDLR_CLAIMED; 1650 1651 if ((tw->tw_length != 0) && (tw->tw_direction == PID_IN)) { 1652 usb_req_attrs_t attrs = ((usb_ctrl_req_t *) 1653 tw->tw_curr_xfer_reqp)->ctrl_attributes; 1654 /* 1655 * Call uhci_sendup_td_message to send message 1656 * upstream. The function uhci_sendup_td_message 1657 * returns USB_NO_RESOURCES if allocb fails and 1658 * also sends error message to upstream by calling 1659 * USBA callback function. 1660 * 1661 * Under error conditions just drop the current msg. 1662 */ 1663 if ((tw->tw_tmp == UHCI_UNDERRUN_OCCURRED) && 1664 (!(attrs & USB_ATTRS_SHORT_XFER_OK))) { 1665 error = USB_CR_DATA_UNDERRUN; 1666 } else if (tw->tw_tmp == UHCI_OVERRUN_OCCURRED) { 1667 error = USB_CR_DATA_OVERRUN; 1668 } 1669 uhci_sendup_td_message(uhcip, error, tw); 1670 1671 } else { 1672 uhci_do_byte_stats(uhcip, tw->tw_length, 1673 eptd->bmAttributes, eptd->bEndpointAddress); 1674 1675 uhci_hcdi_callback(uhcip, pp, usb_pp, tw, USB_CR_OK); 1676 } 1677 1678 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1679 "Status complete: pp 0x%p td 0x%p", (void *)pp, (void *)td); 1680 1681 uhci_delete_td(uhcip, td); 1682 uhci_deallocate_tw(uhcip, pp, tw); 1683 1684 break; 1685 default: 1686 USB_DPRINTF_L2(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 1687 "uhci_handle_ctrl_td: Bad control state"); 1688 1689 uhci_hcdi_callback(uhcip, pp, usb_pp, tw, 1690 USB_CR_UNSPECIFIED_ERR); 1691 } 1692 } 1693 1694 1695 /* 1696 * uhci_handle_intr_td_errors: 1697 * Handles the errors encountered for the interrupt transfers. 1698 */ 1699 static void 1700 uhci_handle_intr_td_errors(uhci_state_t *uhcip, uhci_td_t *td, 1701 uhci_trans_wrapper_t *tw, uhci_pipe_private_t *pp) 1702 { 1703 usb_cr_t usb_err; 1704 usb_intr_req_t *intr_reqp = 1705 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 1706 1707 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1708 "uhci_handle_intr_td_errors: td = 0x%p tw = 0x%p", 1709 (void *)td, (void *)tw); 1710 1711 usb_err = uhci_parse_td_error(uhcip, pp, td); 1712 1713 if (intr_reqp->intr_attributes & USB_ATTRS_ONE_XFER) { 1714 uhci_handle_one_xfer_completion(uhcip, usb_err, td); 1715 1716 return; 1717 } 1718 1719 uhci_delete_td(uhcip, td); 1720 uhci_sendup_td_message(uhcip, usb_err, tw); 1721 uhci_deallocate_tw(uhcip, tw->tw_pipe_private, tw); 1722 } 1723 1724 1725 /* 1726 * uhci_handle_one_xfer_completion: 1727 */ 1728 static void 1729 uhci_handle_one_xfer_completion( 1730 uhci_state_t *uhcip, 1731 usb_cr_t usb_err, 1732 uhci_td_t *td) 1733 { 1734 uhci_trans_wrapper_t *tw = td->tw; 1735 uhci_pipe_private_t *pp = tw->tw_pipe_private; 1736 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 1737 usb_intr_req_t *intr_reqp = 1738 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 1739 1740 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1741 "uhci_handle_one_xfer_completion: td = 0x%p", (void *)td); 1742 1743 ASSERT(intr_reqp->intr_attributes & USB_ATTRS_ONE_XFER); 1744 1745 /* set state to idle */ 1746 pp->pp_state = UHCI_PIPE_STATE_IDLE; 1747 1748 ((usb_intr_req_t *)(pp->pp_client_periodic_in_reqp))-> 1749 intr_data = ((usb_intr_req_t *)(tw->tw_curr_xfer_reqp))->intr_data; 1750 1751 ((usb_intr_req_t *)tw->tw_curr_xfer_reqp)->intr_data = NULL; 1752 1753 /* now free duplicate current request */ 1754 usb_free_intr_req((usb_intr_req_t *)tw->tw_curr_xfer_reqp); 1755 mutex_enter(&ph->p_mutex); 1756 ph->p_req_count--; 1757 mutex_exit(&ph->p_mutex); 1758 1759 /* make client's request the current request */ 1760 tw->tw_curr_xfer_reqp = pp->pp_client_periodic_in_reqp; 1761 pp->pp_client_periodic_in_reqp = NULL; 1762 1763 uhci_sendup_td_message(uhcip, usb_err, tw); 1764 /* Clear the tw->tw_claim flag */ 1765 tw->tw_claim = UHCI_NOT_CLAIMED; 1766 1767 uhci_delete_td(uhcip, td); 1768 uhci_deallocate_tw(uhcip, pp, tw); 1769 } 1770 1771 1772 /* 1773 * uhci_parse_td_error 1774 * Parses the Transfer Descriptors error 1775 */ 1776 usb_cr_t 1777 uhci_parse_td_error(uhci_state_t *uhcip, uhci_pipe_private_t *pp, uhci_td_t *td) 1778 { 1779 uint_t status; 1780 1781 status = GetTD_status(uhcip, td) & TD_STATUS_MASK; 1782 1783 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1784 "uhci_parse_td_error: status_bits=0x%x", status); 1785 1786 if (UHCI_XFER_TYPE(&pp->pp_pipe_handle->p_ep) == USB_EP_ATTR_ISOCH) { 1787 1788 return (USB_CR_OK); 1789 } 1790 1791 if (!status) { 1792 1793 return (USB_CR_OK); 1794 } 1795 1796 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1797 "uhci_parse_td_error: status_bits=0x%x", status); 1798 1799 1800 if (status & UHCI_TD_BITSTUFF_ERR) { 1801 1802 return (USB_CR_BITSTUFFING); 1803 } 1804 1805 if (status & UHCI_TD_CRC_TIMEOUT) { 1806 pp->pp_data_toggle = GetTD_dtogg(uhcip, td); 1807 1808 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1809 "uhci_parse_td_error: timeout & data toggle reset; " 1810 "data toggle: %x", pp->pp_data_toggle); 1811 1812 return ((GetTD_PID(uhcip, td) == PID_IN) ? USB_CR_DEV_NOT_RESP : 1813 USB_CR_TIMEOUT); 1814 } 1815 1816 if (status & UHCI_TD_BABBLE_ERR) { 1817 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1818 "babble error"); 1819 1820 return (USB_CR_UNSPECIFIED_ERR); 1821 } 1822 1823 if (status & UHCI_TD_DATA_BUFFER_ERR) { 1824 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1825 "buffer error"); 1826 1827 return ((GetTD_PID(uhcip, td) == PID_IN) ? 1828 USB_CR_BUFFER_OVERRUN : USB_CR_BUFFER_UNDERRUN); 1829 } 1830 1831 if (status & UHCI_TD_STALLED) { 1832 pp->pp_data_toggle = 0; 1833 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1834 "uhci_parse_td_error: stall; data toggle reset; " 1835 "data toggle: %x", pp->pp_data_toggle); 1836 1837 return (USB_CR_STALL); 1838 } 1839 1840 if (status) { 1841 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1842 "unspecified error=0x%x", status); 1843 } 1844 1845 return (USB_CR_OK); 1846 } 1847 1848 1849 static dev_info_t * 1850 uhci_get_dip(dev_t dev) 1851 { 1852 int instance = UHCI_UNIT(dev); 1853 uhci_state_t *uhcip = ddi_get_soft_state(uhci_statep, instance); 1854 1855 return (uhcip ? uhcip->uhci_dip : NULL); 1856 } 1857 1858 1859 /* 1860 * cb_ops entry points 1861 */ 1862 static int 1863 uhci_open(dev_t *devp, int flags, int otyp, cred_t *credp) 1864 { 1865 dev_info_t *dip = uhci_get_dip(*devp); 1866 1867 return (usba_hubdi_open(dip, devp, flags, otyp, credp)); 1868 } 1869 1870 1871 static int 1872 uhci_close(dev_t dev, int flag, int otyp, cred_t *credp) 1873 { 1874 dev_info_t *dip = uhci_get_dip(dev); 1875 1876 return (usba_hubdi_close(dip, dev, flag, otyp, credp)); 1877 } 1878 1879 1880 static int 1881 uhci_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, 1882 cred_t *credp, int *rvalp) 1883 { 1884 dev_info_t *dip = uhci_get_dip(dev); 1885 1886 return (usba_hubdi_ioctl(dip, dev, cmd, arg, mode, credp, rvalp)); 1887 } 1888