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