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 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Universal Host Controller Driver (UHCI) 30 * 31 * The UHCI driver is a driver which interfaces to the Universal 32 * Serial Bus Architecture (USBA) and the Host Controller (HC). The interface to 33 * the Host Controller is defined by the Universal Host Controller Interface. 34 * This file contains code for auto-configuration entry points and interrupt 35 * handling. 36 */ 37 #include <sys/usb/hcd/uhci/uhcid.h> 38 #include <sys/usb/hcd/uhci/uhcihub.h> 39 #include <sys/usb/hcd/uhci/uhciutil.h> 40 41 /* 42 * Prototype Declarations for cb_ops and dev_ops 43 */ 44 static int uhci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 45 static int uhci_add_intrs(uhci_state_t *uhcip, int intr_type); 46 static int uhci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 47 static void uhci_rem_intrs(uhci_state_t *uhcip); 48 static int uhci_open(dev_t *devp, int flags, int otyp, cred_t *credp); 49 static int uhci_close(dev_t dev, int flag, int otyp, cred_t *credp); 50 static int uhci_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, 51 cred_t *credp, int *rvalp); 52 static int uhci_reset(dev_info_t *dip, ddi_reset_cmd_t cmd); 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 }; 90 91 static struct modldrv modldrv = { 92 &mod_driverops, /* Type of module. This one is a driver */ 93 "USB UHCI Controller Driver %I%", /* Name of the module. */ 94 &uhci_ops, /* Driver ops */ 95 }; 96 97 static struct modlinkage modlinkage = { 98 MODREV_1, (void *)&modldrv, NULL 99 }; 100 101 /* 102 * Globals 103 */ 104 void *uhci_statep; 105 uint_t uhci_errlevel = USB_LOG_L2; 106 uint_t uhci_errmask = PRINT_MASK_ALL; 107 uint_t uhci_instance_debug = (uint_t)-1; 108 109 uint_t uhci_td_pool_size = 256; /* Num TDs */ 110 uint_t uhci_qh_pool_size = 130; /* Num QHs */ 111 ushort_t uhci_tree_bottom_nodes[NUM_FRAME_LST_ENTRIES]; 112 113 114 /* 115 * UHCI MSI tunable: 116 * 117 * By default MSI is enabled on all supported platforms. 118 */ 119 boolean_t uhci_enable_msi = B_TRUE; 120 121 /* 122 * tunable, delay during attach in seconds 123 */ 124 int uhci_attach_wait = 0; 125 126 /* function prototypes */ 127 static void uhci_handle_intr_td_errors(uhci_state_t *uhcip, uhci_td_t *td, 128 uhci_trans_wrapper_t *tw, uhci_pipe_private_t *pp); 129 static void uhci_handle_one_xfer_completion(uhci_state_t *uhcip, 130 usb_cr_t usb_err, uhci_td_t *td); 131 static uint_t uhci_intr(caddr_t arg1, caddr_t arg2); 132 static int uhci_cleanup(uhci_state_t *uhcip); 133 static int uhci_cpr_suspend(uhci_state_t *uhcip); 134 static int uhci_cpr_resume(uhci_state_t *uhcip); 135 136 137 int 138 _init(void) 139 { 140 int error; 141 ushort_t i, j, k, *temp, num_of_nodes; 142 143 /* Initialize the soft state structures */ 144 if ((error = ddi_soft_state_init(&uhci_statep, sizeof (uhci_state_t), 145 UHCI_MAX_INSTS)) != 0) { 146 147 return (error); 148 } 149 150 /* Install the loadable module */ 151 if ((error = mod_install(&modlinkage)) != 0) { 152 ddi_soft_state_fini(&uhci_statep); 153 154 return (error); 155 } 156 157 /* 158 * Build the tree bottom shared by all instances 159 */ 160 temp = kmem_zalloc(NUM_FRAME_LST_ENTRIES * 2, KM_SLEEP); 161 162 num_of_nodes = 1; 163 for (i = 0; i < log_2(NUM_FRAME_LST_ENTRIES); i++) { 164 for (j = 0, k = 0; k < num_of_nodes; k++, j++) { 165 uhci_tree_bottom_nodes[j++] = temp[k]; 166 uhci_tree_bottom_nodes[j] = temp[k] + pow_2(i); 167 } 168 169 num_of_nodes *= 2; 170 for (k = 0; k < num_of_nodes; k++) 171 temp[k] = uhci_tree_bottom_nodes[k]; 172 173 } 174 kmem_free(temp, (NUM_FRAME_LST_ENTRIES*2)); 175 176 177 return (error); 178 } 179 180 181 int 182 _info(struct modinfo *modinfop) 183 { 184 return (mod_info(&modlinkage, modinfop)); 185 } 186 187 188 int 189 _fini(void) 190 { 191 int error; 192 193 error = mod_remove(&modlinkage); 194 195 if (error == 0) { 196 /* Release per module resources */ 197 ddi_soft_state_fini(&uhci_statep); 198 } 199 200 return (error); 201 } 202 203 /* 204 * The following simulated polling is for debugging purposes only. 205 * It is activated on x86 by setting usb-polling=true in GRUB or uhci.conf. 206 */ 207 static int 208 uhci_is_polled(dev_info_t *dip) 209 { 210 int ret; 211 char *propval; 212 213 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, 214 "usb-polling", &propval) != DDI_SUCCESS) 215 216 return (0); 217 218 ret = (strcmp(propval, "true") == 0); 219 ddi_prop_free(propval); 220 221 return (ret); 222 } 223 224 static void 225 uhci_poll_intr(void *arg) 226 { 227 /* poll every msec */ 228 for (;;) { 229 (void) uhci_intr(arg, NULL); 230 delay(drv_usectohz(1000)); 231 } 232 } 233 234 /* 235 * Host Controller Driver (HCD) Auto configuration entry points 236 */ 237 238 /* 239 * Function Name : uhci_attach: 240 * Description : Attach entry point - called by the Kernel. 241 * Allocates of per controller data structure. 242 * Initializes the controller. 243 * Output : DDI_SUCCESS / DDI_FAILURE 244 */ 245 static int 246 uhci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 247 { 248 int instance, polled; 249 int i, intr_types; 250 uhci_state_t *uhcip = NULL; 251 usba_hcdi_register_args_t hcdi_args; 252 253 USB_DPRINTF_L4(PRINT_MASK_ATTA, NULL, "uhci_attach:"); 254 255 switch (cmd) { 256 case DDI_ATTACH: 257 break; 258 case DDI_RESUME: 259 uhcip = uhci_obtain_state(dip); 260 261 return (uhci_cpr_resume(uhcip)); 262 default: 263 264 return (DDI_FAILURE); 265 } 266 267 /* Get the instance and create soft state */ 268 instance = ddi_get_instance(dip); 269 270 /* Allocate the soft state structure for this instance of the driver */ 271 if (ddi_soft_state_zalloc(uhci_statep, instance) != 0) { 272 273 return (DDI_FAILURE); 274 } 275 276 if ((uhcip = ddi_get_soft_state(uhci_statep, instance)) == NULL) { 277 278 return (DDI_FAILURE); 279 } 280 281 uhcip->uhci_log_hdl = usb_alloc_log_hdl(dip, "uhci", &uhci_errlevel, 282 &uhci_errmask, &uhci_instance_debug, 0); 283 284 /* Set host controller soft state to initialization */ 285 uhcip->uhci_hc_soft_state = UHCI_CTLR_INIT_STATE; 286 287 /* Save the dip and instance */ 288 uhcip->uhci_dip = dip; 289 uhcip->uhci_instance = instance; 290 291 polled = uhci_is_polled(dip); 292 if (polled) 293 294 goto skip_intr; 295 296 /* Get supported interrupt types */ 297 if (ddi_intr_get_supported_types(uhcip->uhci_dip, 298 &intr_types) != DDI_SUCCESS) { 299 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 300 "uhci_attach: ddi_intr_get_supported_types failed"); 301 302 usb_free_log_hdl(uhcip->uhci_log_hdl); 303 ddi_soft_state_free(uhci_statep, instance); 304 305 return (DDI_FAILURE); 306 } 307 308 USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 309 "uhci_attach: supported interrupt types 0x%x", intr_types); 310 311 if ((intr_types & DDI_INTR_TYPE_MSI) && uhci_enable_msi) { 312 if (uhci_add_intrs(uhcip, DDI_INTR_TYPE_MSI) 313 != DDI_SUCCESS) { 314 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 315 "uhci_attach: MSI registration failed, " 316 "trying FIXED interrupt \n"); 317 } else { 318 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 319 "uhci_attach: Using MSI interrupt type\n"); 320 321 uhcip->uhci_intr_type = DDI_INTR_TYPE_MSI; 322 } 323 } 324 325 if (!(uhcip->uhci_htable) && (intr_types & DDI_INTR_TYPE_FIXED)) { 326 if (uhci_add_intrs(uhcip, DDI_INTR_TYPE_FIXED) 327 != DDI_SUCCESS) { 328 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 329 "uhci_attach: FIXED interrupt registration " 330 "failed\n"); 331 332 usb_free_log_hdl(uhcip->uhci_log_hdl); 333 ddi_soft_state_free(uhci_statep, instance); 334 335 return (DDI_FAILURE); 336 } 337 338 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 339 "uhci_attach: Using FIXED interrupt type\n"); 340 341 uhcip->uhci_intr_type = DDI_INTR_TYPE_FIXED; 342 } 343 344 skip_intr: 345 /* Semaphore to serialize opens and closes */ 346 sema_init(&uhcip->uhci_ocsem, 1, NULL, SEMA_DRIVER, NULL); 347 348 /* Create prototype condition variable */ 349 cv_init(&uhcip->uhci_cv_SOF, NULL, CV_DRIVER, NULL); 350 351 /* Initialize the DMA attributes */ 352 uhci_set_dma_attributes(uhcip); 353 354 /* Initialize the kstat structures */ 355 uhci_create_stats(uhcip); 356 357 /* Create the td and ed pools */ 358 if (uhci_allocate_pools(uhcip) != USB_SUCCESS) { 359 360 goto fail; 361 } 362 363 /* Map the registers */ 364 if (uhci_map_regs(uhcip) != USB_SUCCESS) { 365 366 goto fail; 367 } 368 369 /* Enable all interrupts */ 370 if (polled) { 371 extern pri_t maxclsyspri; 372 373 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 374 "uhci_attach: running in simulated polled mode."); 375 376 /* create thread to poll */ 377 (void) thread_create(NULL, 0, uhci_poll_intr, uhcip, 0, &p0, 378 TS_RUN, maxclsyspri); 379 } else if (uhcip->uhci_intr_cap & DDI_INTR_FLAG_BLOCK) { 380 /* Call ddi_intr_block_enable() for MSI interrupts */ 381 (void) ddi_intr_block_enable(uhcip->uhci_htable, 382 uhcip->uhci_intr_cnt); 383 } else { 384 /* Call ddi_intr_enable for MSI or FIXED interrupts */ 385 for (i = 0; i < uhcip->uhci_intr_cnt; i++) 386 (void) ddi_intr_enable(uhcip->uhci_htable[i]); 387 } 388 389 390 /* Initialize the controller */ 391 if (uhci_init_ctlr(uhcip) != USB_SUCCESS) { 392 393 goto fail; 394 } 395 396 /* 397 * At this point, the hardware will be okay. 398 * Initialize the usba_hcdi structure 399 */ 400 uhcip->uhci_hcdi_ops = uhci_alloc_hcdi_ops(uhcip); 401 402 /* 403 * Make this HCD instance known to USBA 404 * (dma_attr must be passed for USBA busctl's) 405 */ 406 hcdi_args.usba_hcdi_register_version = HCDI_REGISTER_VERSION; 407 hcdi_args.usba_hcdi_register_dip = dip; 408 hcdi_args.usba_hcdi_register_ops = uhcip->uhci_hcdi_ops; 409 hcdi_args.usba_hcdi_register_dma_attr = &uhcip->uhci_dma_attr; 410 hcdi_args.usba_hcdi_register_iblock_cookie = 411 (ddi_iblock_cookie_t)(uintptr_t)uhcip->uhci_intr_pri; 412 413 if (usba_hcdi_register(&hcdi_args, 0) != USB_SUCCESS) { 414 415 goto fail; 416 } 417 418 #ifndef __sparc 419 /* 420 * On NCR system, the driver seen failure of some commands 421 * while booting. This delay mysteriously solved the problem. 422 */ 423 delay(drv_usectohz(uhci_attach_wait*1000000)); 424 #endif 425 426 /* 427 * Create another timeout handler to check whether any 428 * control/bulk/interrupt commands failed. 429 * This gets called every second. 430 */ 431 uhcip->uhci_cmd_timeout_id = timeout(uhci_cmd_timeout_hdlr, 432 (void *)uhcip, UHCI_ONE_SECOND); 433 434 mutex_enter(&uhcip->uhci_int_mutex); 435 436 /* 437 * Set HcInterruptEnable to enable all interrupts except Root 438 * Hub Status change and SOF interrupts. 439 */ 440 Set_OpReg16(USBINTR, ENABLE_ALL_INTRS); 441 442 /* Test the SOF interrupt */ 443 if (uhci_wait_for_sof(uhcip) != USB_SUCCESS) { 444 USB_DPRINTF_L0(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 445 "No SOF interrupts have been received, this USB UHCI host" 446 " controller is unusable"); 447 mutex_exit(&uhcip->uhci_int_mutex); 448 449 goto fail; 450 } 451 452 mutex_exit(&uhcip->uhci_int_mutex); 453 454 /* This should be the last step which might fail during attaching */ 455 if (uhci_init_root_hub(uhcip) != USB_SUCCESS) { 456 457 goto fail; 458 } 459 460 /* Display information in the banner */ 461 ddi_report_dev(dip); 462 463 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 464 "uhci_attach successful"); 465 466 return (DDI_SUCCESS); 467 468 fail: 469 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 470 "failed to attach"); 471 472 (void) uhci_cleanup(uhcip); 473 474 return (DDI_FAILURE); 475 } 476 477 478 /* 479 * uhci_add_intrs: 480 * 481 * Register FIXED or MSI interrupts. 482 */ 483 static int 484 uhci_add_intrs(uhci_state_t *uhcip, 485 int intr_type) 486 { 487 int actual, avail, intr_size, count = 0; 488 int i, flag, ret; 489 490 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 491 "uhci_add_intrs: interrupt type 0x%x", intr_type); 492 493 /* Get number of interrupts */ 494 ret = ddi_intr_get_nintrs(uhcip->uhci_dip, intr_type, &count); 495 if ((ret != DDI_SUCCESS) || (count == 0)) { 496 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 497 "uhci_add_intrs: ddi_intr_get_nintrs() failure, " 498 "ret: %d, count: %d", ret, count); 499 500 return (DDI_FAILURE); 501 } 502 503 /* Get number of available interrupts */ 504 ret = ddi_intr_get_navail(uhcip->uhci_dip, intr_type, &avail); 505 if ((ret != DDI_SUCCESS) || (avail == 0)) { 506 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 507 "uhci_add_intrs: ddi_intr_get_navail() failure, " 508 "ret: %d, count: %d", ret, count); 509 510 return (DDI_FAILURE); 511 } 512 513 if (avail < count) { 514 USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 515 "uhci_add_intrs: uhci_add_intrs: nintrs () " 516 "returned %d, navail returned %d\n", count, avail); 517 } 518 519 /* Allocate an array of interrupt handles */ 520 intr_size = count * sizeof (ddi_intr_handle_t); 521 uhcip->uhci_htable = kmem_zalloc(intr_size, KM_SLEEP); 522 523 flag = (intr_type == DDI_INTR_TYPE_MSI) ? 524 DDI_INTR_ALLOC_STRICT:DDI_INTR_ALLOC_NORMAL; 525 526 /* call ddi_intr_alloc() */ 527 ret = ddi_intr_alloc(uhcip->uhci_dip, uhcip->uhci_htable, 528 intr_type, 0, count, &actual, flag); 529 530 if ((ret != DDI_SUCCESS) || (actual == 0)) { 531 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 532 "uhci_add_intrs: ddi_intr_alloc() failed %d", ret); 533 534 kmem_free(uhcip->uhci_htable, intr_size); 535 536 return (DDI_FAILURE); 537 } 538 539 if (actual < count) { 540 USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 541 "uhci_add_intrs: Requested: %d, Received: %d\n", 542 count, actual); 543 544 for (i = 0; i < actual; i++) 545 (void) ddi_intr_free(uhcip->uhci_htable[i]); 546 547 kmem_free(uhcip->uhci_htable, intr_size); 548 549 return (DDI_FAILURE); 550 } 551 552 uhcip->uhci_intr_cnt = actual; 553 554 if ((ret = ddi_intr_get_pri(uhcip->uhci_htable[0], 555 &uhcip->uhci_intr_pri)) != DDI_SUCCESS) { 556 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 557 "uhci_add_intrs: ddi_intr_get_pri() failed %d", ret); 558 559 for (i = 0; i < actual; i++) 560 (void) ddi_intr_free(uhcip->uhci_htable[i]); 561 562 kmem_free(uhcip->uhci_htable, intr_size); 563 564 return (DDI_FAILURE); 565 } 566 567 USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 568 "uhci_add_intrs: Supported Interrupt priority 0x%x", 569 uhcip->uhci_intr_pri); 570 571 /* Test for high level mutex */ 572 if (uhcip->uhci_intr_pri >= ddi_intr_get_hilevel_pri()) { 573 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 574 "uhci_add_intrs: Hi level interrupt not supported"); 575 576 for (i = 0; i < actual; i++) 577 (void) ddi_intr_free(uhcip->uhci_htable[i]); 578 579 kmem_free(uhcip->uhci_htable, intr_size); 580 581 return (DDI_FAILURE); 582 } 583 584 /* Initialize the mutex */ 585 mutex_init(&uhcip->uhci_int_mutex, NULL, MUTEX_DRIVER, 586 DDI_INTR_PRI(uhcip->uhci_intr_pri)); 587 588 /* Call ddi_intr_add_handler() */ 589 for (i = 0; i < actual; i++) { 590 if ((ret = ddi_intr_add_handler(uhcip->uhci_htable[i], 591 uhci_intr, (caddr_t)uhcip, 592 (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) { 593 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 594 "uhci_add_intrs: ddi_intr_add_handler() " 595 "failed %d", ret); 596 597 for (i = 0; i < actual; i++) 598 (void) ddi_intr_free(uhcip->uhci_htable[i]); 599 600 mutex_destroy(&uhcip->uhci_int_mutex); 601 kmem_free(uhcip->uhci_htable, intr_size); 602 603 return (DDI_FAILURE); 604 } 605 } 606 607 if ((ret = ddi_intr_get_cap(uhcip->uhci_htable[0], 608 &uhcip->uhci_intr_cap)) != DDI_SUCCESS) { 609 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 610 "uhci_add_intrs: ddi_intr_get_cap() failed %d", ret); 611 612 for (i = 0; i < actual; i++) { 613 (void) ddi_intr_remove_handler(uhcip->uhci_htable[i]); 614 (void) ddi_intr_free(uhcip->uhci_htable[i]); 615 } 616 617 mutex_destroy(&uhcip->uhci_int_mutex); 618 kmem_free(uhcip->uhci_htable, intr_size); 619 620 return (DDI_FAILURE); 621 } 622 623 return (DDI_SUCCESS); 624 } 625 626 627 /* 628 * Function Name: uhci_detach 629 * Description: Detach entry point - called by the Kernel. 630 * Deallocates all the memory 631 * Unregisters the interrupt handle and other resources. 632 * Output: DDI_SUCCESS / DDI_FAILURE 633 */ 634 static int 635 uhci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 636 { 637 uhci_state_t *uhcip = uhci_obtain_state(dip); 638 639 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 640 "uhci_detach:"); 641 642 switch (cmd) { 643 case DDI_DETACH: 644 645 return (uhci_cleanup(uhcip) == USB_SUCCESS ? 646 DDI_SUCCESS : DDI_FAILURE); 647 case DDI_SUSPEND: 648 649 return (uhci_cpr_suspend(uhcip)); 650 default: 651 652 return (DDI_FAILURE); 653 } 654 } 655 656 657 /* 658 * uhci_rem_intrs: 659 * 660 * Unregister FIXED or MSI interrupts 661 */ 662 static void 663 uhci_rem_intrs(uhci_state_t *uhcip) 664 { 665 int i; 666 667 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 668 "uhci_rem_intrs: interrupt type 0x%x", uhcip->uhci_intr_type); 669 670 /* Disable all interrupts */ 671 if (uhcip->uhci_intr_cap & DDI_INTR_FLAG_BLOCK) { 672 (void) ddi_intr_block_disable(uhcip->uhci_htable, 673 uhcip->uhci_intr_cnt); 674 } else { 675 for (i = 0; i < uhcip->uhci_intr_cnt; i++) { 676 (void) ddi_intr_disable(uhcip->uhci_htable[i]); 677 } 678 } 679 680 /* Call ddi_intr_remove_handler() */ 681 for (i = 0; i < uhcip->uhci_intr_cnt; i++) { 682 (void) ddi_intr_remove_handler(uhcip->uhci_htable[i]); 683 (void) ddi_intr_free(uhcip->uhci_htable[i]); 684 } 685 686 kmem_free(uhcip->uhci_htable, 687 uhcip->uhci_intr_cnt * sizeof (ddi_intr_handle_t)); 688 } 689 690 691 /* 692 * Function Name: uhci_reset 693 * Description: Reset entry point - called by the Kernel 694 * on the way down. 695 * The Toshiba laptop has been observed to hang 696 * on reboot when BIOS is set to suspend/resume. 697 * The resetting uhci on the way down solves the 698 * problem. 699 * Output: DDI_SUCCESS / DDI_FAILURE 700 */ 701 /* ARGSUSED */ 702 static int 703 uhci_reset(dev_info_t *dip, ddi_reset_cmd_t cmd) 704 { 705 uhci_state_t *uhcip = uhci_obtain_state(dip); 706 707 /* Disable all HC ED list processing */ 708 Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); 709 Set_OpReg16(USBCMD, 0); 710 711 return (DDI_SUCCESS); 712 } 713 714 715 /* 716 * uhci_info: 717 */ 718 /* ARGSUSED */ 719 static int 720 uhci_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 721 { 722 dev_t dev; 723 int instance; 724 int error = DDI_FAILURE; 725 uhci_state_t *uhcip; 726 727 switch (infocmd) { 728 case DDI_INFO_DEVT2DEVINFO: 729 dev = (dev_t)arg; 730 instance = UHCI_UNIT(dev); 731 uhcip = ddi_get_soft_state(uhci_statep, instance); 732 if (uhcip != NULL) { 733 *result = (void *)uhcip->uhci_dip; 734 if (*result != NULL) { 735 error = DDI_SUCCESS; 736 } 737 } else { 738 *result = NULL; 739 } 740 741 break; 742 case DDI_INFO_DEVT2INSTANCE: 743 dev = (dev_t)arg; 744 instance = UHCI_UNIT(dev); 745 *result = (void *)(uintptr_t)instance; 746 error = DDI_SUCCESS; 747 748 break; 749 default: 750 break; 751 } 752 753 return (error); 754 } 755 756 757 /* 758 * uhci_cleanup: 759 * Cleanup on attach failure or detach 760 */ 761 static int 762 uhci_cleanup(uhci_state_t *uhcip) 763 { 764 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, "uhci_cleanup:"); 765 766 if (usba_hubdi_unbind_root_hub(uhcip->uhci_dip) != USB_SUCCESS) { 767 768 return (USB_FAILURE); 769 } 770 771 mutex_enter(&uhcip->uhci_int_mutex); 772 773 if (uhcip->uhci_cmd_timeout_id) { 774 timeout_id_t timeout_id = uhcip->uhci_cmd_timeout_id; 775 uhcip->uhci_cmd_timeout_id = 0; 776 mutex_exit(&uhcip->uhci_int_mutex); 777 (void) untimeout(timeout_id); 778 mutex_enter(&uhcip->uhci_int_mutex); 779 } 780 781 uhci_uninit_ctlr(uhcip); 782 783 mutex_exit(&uhcip->uhci_int_mutex); 784 785 /* do interrupt cleanup */ 786 if (uhcip->uhci_htable) { 787 uhci_rem_intrs(uhcip); 788 } 789 790 mutex_enter(&uhcip->uhci_int_mutex); 791 792 usba_hcdi_unregister(uhcip->uhci_dip); 793 794 uhci_unmap_regs(uhcip); 795 796 uhci_free_pools(uhcip); 797 798 mutex_exit(&uhcip->uhci_int_mutex); 799 800 mutex_destroy(&uhcip->uhci_int_mutex); 801 cv_destroy(&uhcip->uhci_cv_SOF); 802 sema_destroy(&uhcip->uhci_ocsem); 803 804 /* cleanup kstat structures */ 805 uhci_destroy_stats(uhcip); 806 807 usba_free_hcdi_ops(uhcip->uhci_hcdi_ops); 808 usb_free_log_hdl(uhcip->uhci_log_hdl); 809 ddi_prop_remove_all(uhcip->uhci_dip); 810 ddi_soft_state_free(uhci_statep, uhcip->uhci_instance); 811 812 return (USB_SUCCESS); 813 } 814 815 816 /* 817 * uhci_cpr_suspend 818 */ 819 static int 820 uhci_cpr_suspend(uhci_state_t *uhcip) 821 { 822 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 823 "uhci_cpr_suspend:"); 824 825 /* Call into the root hub and suspend it */ 826 if (usba_hubdi_detach(uhcip->uhci_dip, DDI_SUSPEND) != DDI_SUCCESS) { 827 828 return (DDI_FAILURE); 829 } 830 831 mutex_enter(&uhcip->uhci_int_mutex); 832 833 /* Disable interrupts */ 834 Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); 835 836 mutex_exit(&uhcip->uhci_int_mutex); 837 838 /* Wait for SOF time to handle the scheduled interrupt */ 839 delay(drv_usectohz(UHCI_TIMEWAIT)); 840 841 mutex_enter(&uhcip->uhci_int_mutex); 842 /* Stop the Host Controller */ 843 Set_OpReg16(USBCMD, 0); 844 845 /* Set Global Suspend bit */ 846 Set_OpReg16(USBCMD, USBCMD_REG_ENER_GBL_SUSPEND); 847 848 /* Set host controller soft state to suspend */ 849 uhcip->uhci_hc_soft_state = UHCI_CTLR_SUSPEND_STATE; 850 851 mutex_exit(&uhcip->uhci_int_mutex); 852 853 return (USB_SUCCESS); 854 } 855 856 857 /* 858 * uhci_cpr_cleanup: 859 * 860 * Cleanup uhci specific information across resuming. 861 */ 862 static void 863 uhci_cpr_cleanup(uhci_state_t *uhcip) 864 { 865 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 866 867 /* Reset software part of usb frame number */ 868 uhcip->uhci_sw_frnum = 0; 869 } 870 871 872 /* 873 * uhci_cpr_resume 874 */ 875 static int 876 uhci_cpr_resume(uhci_state_t *uhcip) 877 { 878 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 879 "uhci_cpr_resume: Restart the controller"); 880 881 mutex_enter(&uhcip->uhci_int_mutex); 882 883 /* Cleanup uhci specific information across cpr */ 884 uhci_cpr_cleanup(uhcip); 885 886 mutex_exit(&uhcip->uhci_int_mutex); 887 888 /* Restart the controller */ 889 if (uhci_init_ctlr(uhcip) != DDI_SUCCESS) { 890 891 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 892 "uhci_cpr_resume: uhci host controller resume failed "); 893 894 return (DDI_FAILURE); 895 } 896 897 mutex_enter(&uhcip->uhci_int_mutex); 898 899 /* 900 * Set HcInterruptEnable to enable all interrupts except Root 901 * Hub Status change and SOF interrupts. 902 */ 903 Set_OpReg16(USBINTR, ENABLE_ALL_INTRS); 904 905 mutex_exit(&uhcip->uhci_int_mutex); 906 907 /* Now resume the root hub */ 908 if (usba_hubdi_attach(uhcip->uhci_dip, DDI_RESUME) != DDI_SUCCESS) { 909 910 return (DDI_FAILURE); 911 } 912 913 return (DDI_SUCCESS); 914 } 915 916 917 /* 918 * uhci_intr: 919 * uhci interrupt handling routine. 920 */ 921 static uint_t 922 uhci_intr(caddr_t arg1, caddr_t arg2) 923 { 924 ushort_t intr_status, cmd_reg, intr_reg; 925 uhci_state_t *uhcip = (uhci_state_t *)arg1; 926 927 USB_DPRINTF_L4(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 928 "uhci_intr: Interrupt occurred, arg1 0x%p arg2 0x%p", arg1, 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", pp, 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", td, tw); 1677 1678 usb_err = uhci_parse_td_error(uhcip, pp, td); 1679 1680 if (intr_reqp->intr_attributes & USB_ATTRS_ONE_XFER) { 1681 uhci_handle_one_xfer_completion(uhcip, usb_err, td); 1682 1683 return; 1684 } 1685 1686 uhci_delete_td(uhcip, td); 1687 uhci_sendup_td_message(uhcip, usb_err, tw); 1688 uhci_deallocate_tw(uhcip, tw->tw_pipe_private, tw); 1689 } 1690 1691 1692 /* 1693 * uhci_handle_one_xfer_completion: 1694 */ 1695 static void 1696 uhci_handle_one_xfer_completion( 1697 uhci_state_t *uhcip, 1698 usb_cr_t usb_err, 1699 uhci_td_t *td) 1700 { 1701 uhci_trans_wrapper_t *tw = td->tw; 1702 uhci_pipe_private_t *pp = tw->tw_pipe_private; 1703 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 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_one_xfer_completion: td = 0x%p", td); 1709 1710 ASSERT(intr_reqp->intr_attributes & USB_ATTRS_ONE_XFER); 1711 1712 /* set state to idle */ 1713 pp->pp_state = UHCI_PIPE_STATE_IDLE; 1714 1715 ((usb_intr_req_t *)(pp->pp_client_periodic_in_reqp))-> 1716 intr_data = ((usb_intr_req_t *)(tw->tw_curr_xfer_reqp))->intr_data; 1717 1718 ((usb_intr_req_t *)tw->tw_curr_xfer_reqp)->intr_data = NULL; 1719 1720 /* now free duplicate current request */ 1721 usb_free_intr_req((usb_intr_req_t *)tw->tw_curr_xfer_reqp); 1722 mutex_enter(&ph->p_mutex); 1723 ph->p_req_count--; 1724 mutex_exit(&ph->p_mutex); 1725 1726 /* make client's request the current request */ 1727 tw->tw_curr_xfer_reqp = pp->pp_client_periodic_in_reqp; 1728 pp->pp_client_periodic_in_reqp = NULL; 1729 1730 uhci_sendup_td_message(uhcip, usb_err, tw); 1731 /* Clear the tw->tw_claim flag */ 1732 tw->tw_claim = UHCI_NOT_CLAIMED; 1733 1734 uhci_delete_td(uhcip, td); 1735 uhci_deallocate_tw(uhcip, pp, tw); 1736 } 1737 1738 1739 /* 1740 * uhci_parse_td_error 1741 * Parses the Transfer Descriptors error 1742 */ 1743 usb_cr_t 1744 uhci_parse_td_error(uhci_state_t *uhcip, uhci_pipe_private_t *pp, uhci_td_t *td) 1745 { 1746 uint_t status; 1747 1748 status = GetTD_status(uhcip, td) & TD_STATUS_MASK; 1749 1750 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1751 "uhci_parse_td_error: status_bits=0x%x", status); 1752 1753 if (UHCI_XFER_TYPE(&pp->pp_pipe_handle->p_ep) == USB_EP_ATTR_ISOCH) { 1754 1755 return (USB_CR_OK); 1756 } 1757 1758 if (!status) { 1759 1760 return (USB_CR_OK); 1761 } 1762 1763 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1764 "uhci_parse_td_error: status_bits=0x%x", status); 1765 1766 1767 if (status & UHCI_TD_BITSTUFF_ERR) { 1768 1769 return (USB_CR_BITSTUFFING); 1770 } 1771 1772 if (status & UHCI_TD_CRC_TIMEOUT) { 1773 pp->pp_data_toggle = GetTD_dtogg(uhcip, td); 1774 1775 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1776 "uhci_parse_td_error: timeout & data toggle reset; " 1777 "data toggle: %x", pp->pp_data_toggle); 1778 1779 return ((GetTD_PID(uhcip, td) == PID_IN) ? USB_CR_DEV_NOT_RESP : 1780 USB_CR_TIMEOUT); 1781 } 1782 1783 if (status & UHCI_TD_BABBLE_ERR) { 1784 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1785 "babble error"); 1786 1787 return (USB_CR_UNSPECIFIED_ERR); 1788 } 1789 1790 if (status & UHCI_TD_DATA_BUFFER_ERR) { 1791 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1792 "buffer error"); 1793 1794 return ((GetTD_PID(uhcip, td) == PID_IN) ? 1795 USB_CR_BUFFER_OVERRUN : USB_CR_BUFFER_UNDERRUN); 1796 } 1797 1798 if (status & UHCI_TD_STALLED) { 1799 pp->pp_data_toggle = 0; 1800 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1801 "uhci_parse_td_error: stall; data toggle reset; " 1802 "data toggle: %x", pp->pp_data_toggle); 1803 1804 return (USB_CR_STALL); 1805 } 1806 1807 if (status) { 1808 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1809 "unspecified error=0x%x", status); 1810 } 1811 1812 return (USB_CR_OK); 1813 } 1814 1815 1816 static dev_info_t * 1817 uhci_get_dip(dev_t dev) 1818 { 1819 int instance = UHCI_UNIT(dev); 1820 uhci_state_t *uhcip = ddi_get_soft_state(uhci_statep, instance); 1821 1822 return (uhcip ? uhcip->uhci_dip : NULL); 1823 } 1824 1825 1826 /* 1827 * cb_ops entry points 1828 */ 1829 static int 1830 uhci_open(dev_t *devp, int flags, int otyp, cred_t *credp) 1831 { 1832 dev_info_t *dip = uhci_get_dip(*devp); 1833 1834 return (usba_hubdi_open(dip, devp, flags, otyp, credp)); 1835 } 1836 1837 1838 static int 1839 uhci_close(dev_t dev, int flag, int otyp, cred_t *credp) 1840 { 1841 dev_info_t *dip = uhci_get_dip(dev); 1842 1843 return (usba_hubdi_close(dip, dev, flag, otyp, credp)); 1844 } 1845 1846 1847 static int 1848 uhci_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, 1849 cred_t *credp, int *rvalp) 1850 { 1851 dev_info_t *dip = uhci_get_dip(dev); 1852 1853 return (usba_hubdi_ioctl(dip, dev, cmd, arg, mode, credp, rvalp)); 1854 } 1855