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", 929 (void *)arg1, (void *)arg2); 930 931 mutex_enter(&uhcip->uhci_int_mutex); 932 933 /* Any interrupt is not handled for the suspended device. */ 934 if (uhcip->uhci_hc_soft_state == UHCI_CTLR_SUSPEND_STATE) { 935 mutex_exit(&uhcip->uhci_int_mutex); 936 937 return (DDI_INTR_UNCLAIMED); 938 } 939 940 /* Get the status of the interrupts */ 941 intr_status = Get_OpReg16(USBSTS); 942 intr_reg = Get_OpReg16(USBINTR); 943 944 USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 945 "uhci_intr: intr_status = %x, intr_reg = %x", 946 intr_status, intr_reg); 947 948 /* 949 * If uhci interrupts are all disabled, the driver should return 950 * unclaimed. 951 * HC Process Error and Host System Error interrupts cannot be 952 * disabled by intr register, and need to be judged separately. 953 */ 954 if (((intr_reg & ENABLE_ALL_INTRS) == 0) && 955 ((intr_status & USBSTS_REG_HC_PROCESS_ERR) == 0) && 956 ((intr_status & USBSTS_REG_HOST_SYS_ERR) == 0)) { 957 958 USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 959 "uhci_intr: interrupts disabled, unclaim"); 960 mutex_exit(&uhcip->uhci_int_mutex); 961 962 return (DDI_INTR_UNCLAIMED); 963 } 964 965 /* 966 * If the intr is not from our controller, just return unclaimed. 967 * HCHalted status bit cannot generate interrupts and should be 968 * ignored. 969 */ 970 if (!(intr_status & UHCI_INTR_MASK)) { 971 972 USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 973 "uhci_intr: no interrupt status set, unclaim"); 974 mutex_exit(&uhcip->uhci_int_mutex); 975 976 return (DDI_INTR_UNCLAIMED); 977 } 978 979 /* Update kstat values */ 980 uhci_do_intrs_stats(uhcip, intr_status); 981 982 /* Acknowledge the interrupt */ 983 Set_OpReg16(USBSTS, intr_status); 984 985 /* 986 * If uhci controller has not been initialized, just clear the 987 * interrupter status and return claimed. 988 */ 989 if (uhcip->uhci_hc_soft_state != UHCI_CTLR_OPERATIONAL_STATE) { 990 991 USB_DPRINTF_L2(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 992 "uhci_intr: uhci controller is not in the operational " 993 "state"); 994 mutex_exit(&uhcip->uhci_int_mutex); 995 996 return (DDI_INTR_CLAIMED); 997 } 998 999 /* 1000 * We configured the hw incorrectly, disable future interrupts. 1001 */ 1002 if ((intr_status & USBSTS_REG_HOST_SYS_ERR)) { 1003 USB_DPRINTF_L2(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 1004 "uhci_intr: Sys Err Disabling Interrupt"); 1005 Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); 1006 uhcip->uhci_hc_soft_state = UHCI_CTLR_ERROR_STATE; 1007 1008 mutex_exit(&uhcip->uhci_int_mutex); 1009 1010 return (DDI_INTR_CLAIMED); 1011 } 1012 1013 /* 1014 * Check whether a frame number overflow occurred. 1015 * if so, update the sw frame number. 1016 */ 1017 uhci_isoc_update_sw_frame_number(uhcip); 1018 1019 /* 1020 * Check whether any commands got completed. If so, process them. 1021 */ 1022 uhci_process_submitted_td_queue(uhcip); 1023 1024 /* 1025 * This should not occur. It occurs only if a HC controller 1026 * experiences internal problem. 1027 */ 1028 if (intr_status & USBSTS_REG_HC_HALTED) { 1029 USB_DPRINTF_L2(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 1030 "uhci_intr: Controller halted"); 1031 cmd_reg = Get_OpReg16(USBCMD); 1032 Set_OpReg16(USBCMD, (cmd_reg | USBCMD_REG_HC_RUN)); 1033 } 1034 1035 /* 1036 * Wake up all the threads which are waiting for the Start of Frame 1037 */ 1038 if (uhcip->uhci_cv_signal == B_TRUE) { 1039 cv_broadcast(&uhcip->uhci_cv_SOF); 1040 uhcip->uhci_cv_signal = B_FALSE; 1041 } 1042 1043 mutex_exit(&uhcip->uhci_int_mutex); 1044 1045 return (DDI_INTR_CLAIMED); 1046 } 1047 1048 1049 /* 1050 * uhci_process_submitted_td_queue: 1051 * Traverse thru the submitted queue and process the completed ones. 1052 */ 1053 void 1054 uhci_process_submitted_td_queue(uhci_state_t *uhcip) 1055 { 1056 uhci_td_t *head = uhcip->uhci_outst_tds_head; 1057 uhci_trans_wrapper_t *tw; 1058 1059 while (head != NULL) { 1060 if ((!(GetTD_status(uhcip, head) & UHCI_TD_ACTIVE)) && 1061 (head->tw->tw_claim == UHCI_NOT_CLAIMED)) { 1062 tw = head->tw; 1063 1064 /* 1065 * Call the corresponding handle_td routine 1066 */ 1067 (*tw->tw_handle_td)(uhcip, head); 1068 1069 /* restart at the beginning again */ 1070 head = uhcip->uhci_outst_tds_head; 1071 } else { 1072 head = head->outst_td_next; 1073 } 1074 } 1075 } 1076 1077 1078 /* 1079 * uhci_handle_intr_td: 1080 * handles the completed interrupt transfer TD's. 1081 */ 1082 void 1083 uhci_handle_intr_td(uhci_state_t *uhcip, uhci_td_t *td) 1084 { 1085 usb_req_attrs_t attrs; 1086 uint_t bytes_xfered; 1087 usb_cr_t usb_err; 1088 uhci_trans_wrapper_t *tw = td->tw; 1089 uhci_pipe_private_t *pp = tw->tw_pipe_private; 1090 usb_intr_req_t *intr_reqp = 1091 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 1092 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 1093 1094 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1095 "uhci_handle_intr_td: intr_reqp = 0x%p", (void *)intr_reqp); 1096 1097 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 1098 1099 /* set tw->tw_claim flag, so that nobody else works on this td. */ 1100 tw->tw_claim = UHCI_INTR_HDLR_CLAIMED; 1101 1102 /* Interrupt OUT */ 1103 if (UHCI_XFER_DIR(&ph->p_ep) == USB_EP_DIR_OUT) { 1104 1105 /* process errors first */ 1106 usb_err = uhci_parse_td_error(uhcip, pp, td); 1107 1108 /* get the actual xfered data size */ 1109 bytes_xfered = GetTD_alen(uhcip, td); 1110 1111 /* check data underrun error */ 1112 if ((usb_err == USB_CR_OK) && (bytes_xfered != 1113 GetTD_mlen(uhcip, td))) { 1114 1115 USB_DPRINTF_L2(PRINT_MASK_LISTS, 1116 uhcip->uhci_log_hdl, "uhci_handle_intr_td:" 1117 " Intr out pipe, data underrun occurred"); 1118 1119 usb_err = USB_CR_DATA_UNDERRUN; 1120 1121 } 1122 1123 bytes_xfered = (bytes_xfered == ZERO_LENGTH) ? 1124 0 : bytes_xfered+1; 1125 tw->tw_bytes_xfered += bytes_xfered; 1126 uhci_do_byte_stats(uhcip, tw->tw_bytes_xfered, 1127 ph->p_ep.bmAttributes, ph->p_ep.bEndpointAddress); 1128 1129 1130 /* 1131 * If error occurred or all data xfered, delete the current td, 1132 * free tw, do the callback. Otherwise wait for the next td. 1133 */ 1134 if (usb_err != USB_CR_OK) { 1135 1136 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1137 "uhci_handle_intr_td: Intr out pipe error"); 1138 1139 /* update the element pointer */ 1140 SetQH32(uhcip, pp->pp_qh->element_ptr, GetTD32( 1141 uhcip, tw->tw_hctd_tail->link_ptr)); 1142 1143 1144 } else if (tw->tw_bytes_xfered == tw->tw_length) { 1145 1146 /* all data xfered */ 1147 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1148 "uhci_handle_intr_td: Intr out pipe," 1149 " all data xfered"); 1150 1151 } else { 1152 1153 /* remove the current td and wait for the next one. */ 1154 uhci_delete_td(uhcip, td); 1155 tw->tw_claim = UHCI_NOT_CLAIMED; 1156 1157 return; 1158 } 1159 1160 uhci_delete_td(uhcip, td); 1161 uhci_hcdi_callback(uhcip, pp, ph, tw, usb_err); 1162 uhci_deallocate_tw(uhcip, tw->tw_pipe_private, tw); 1163 1164 return; 1165 } 1166 1167 /* Interrupt IN */ 1168 1169 /* Get the actual received data size */ 1170 tw->tw_bytes_xfered = GetTD_alen(uhcip, td); 1171 if (tw->tw_bytes_xfered == ZERO_LENGTH) { 1172 tw->tw_bytes_xfered = 0; 1173 } else { 1174 tw->tw_bytes_xfered++; 1175 } 1176 1177 /* process errors first */ 1178 if (GetTD_status(uhcip, td) & TD_STATUS_MASK) { 1179 SetQH32(uhcip, pp->pp_qh->element_ptr, 1180 GetTD32(uhcip, td->link_ptr)); 1181 1182 uhci_handle_intr_td_errors(uhcip, td, tw, pp); 1183 1184 return; 1185 } 1186 1187 /* 1188 * Check for data underruns. 1189 * For data underrun case, the host controller does not update 1190 * element pointer. So, we update here. 1191 */ 1192 if (GetTD_alen(uhcip, td) != GetTD_mlen(uhcip, td)) { 1193 SetQH32(uhcip, pp->pp_qh->element_ptr, 1194 GetTD32(uhcip, td->link_ptr)); 1195 } 1196 1197 /* 1198 * Call uhci_sendup_td_message to send message upstream. 1199 * The function uhci_sendup_td_message returns USB_NO_RESOURCES 1200 * if allocb fails and also sends error message to upstream by 1201 * calling USBA callback function. Under error conditions just 1202 * drop the current message. 1203 */ 1204 1205 /* Get the interrupt xfer attributes */ 1206 attrs = intr_reqp->intr_attributes; 1207 1208 /* 1209 * Check usb flag whether USB_FLAGS_ONE_XFER flag is set 1210 * and if so, free duplicate request. 1211 */ 1212 if (attrs & USB_ATTRS_ONE_XFER) { 1213 uhci_handle_one_xfer_completion(uhcip, USB_CR_OK, td); 1214 1215 return; 1216 } 1217 1218 /* save it temporarily */ 1219 if (tw->tw_bytes_xfered != 0) { 1220 uhci_sendup_td_message(uhcip, USB_CR_OK, tw); 1221 } 1222 1223 /* Clear the tw->tw_claim flag */ 1224 tw->tw_claim = UHCI_NOT_CLAIMED; 1225 1226 uhci_delete_td(uhcip, td); 1227 1228 /* allocate another interrupt periodic resource */ 1229 if (pp->pp_state == UHCI_PIPE_STATE_ACTIVE) { 1230 if (uhci_allocate_periodic_in_resource(uhcip, pp, tw, 0) != 1231 USB_SUCCESS) { 1232 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1233 "uhci_insert_intr_req: Interrupt request structure" 1234 "allocation failed"); 1235 1236 uhci_hcdi_callback(uhcip, pp, ph, 1237 tw, USB_CR_NO_RESOURCES); 1238 1239 return; 1240 } 1241 1242 /* Insert another interrupt TD */ 1243 if (uhci_insert_hc_td(uhcip, 0, 1244 tw->tw_length, pp, tw, PID_IN, attrs) != USB_SUCCESS) { 1245 1246 uhci_deallocate_periodic_in_resource(uhcip, pp, tw); 1247 1248 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1249 "uhci_handle_intr_td: TD exhausted"); 1250 1251 uhci_hcdi_callback(uhcip, pp, ph, 1252 tw, USB_CR_NO_RESOURCES); 1253 } 1254 } 1255 } 1256 1257 1258 /* 1259 * uhci_sendup_td_message: 1260 * 1261 * Get a message block and send the received message upstream. 1262 */ 1263 void 1264 uhci_sendup_td_message( 1265 uhci_state_t *uhcip, 1266 usb_cr_t usb_err, 1267 uhci_trans_wrapper_t *tw) 1268 { 1269 mblk_t *mp = NULL; 1270 size_t length = 0; 1271 size_t skip_len = 0; 1272 uchar_t *buf; 1273 usb_opaque_t curr_xfer_reqp = tw->tw_curr_xfer_reqp; 1274 uhci_pipe_private_t *pp = tw->tw_pipe_private; 1275 usb_ep_descr_t *ept = &pp->pp_pipe_handle->p_ep; 1276 1277 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 1278 1279 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1280 "uhci_sendup_td_message: bytes transferred=0x%x, " 1281 "bytes pending=0x%x", 1282 tw->tw_bytes_xfered, tw->tw_bytes_pending); 1283 1284 length = tw->tw_bytes_xfered; 1285 1286 switch (UHCI_XFER_TYPE(ept)) { 1287 case USB_EP_ATTR_CONTROL: 1288 skip_len = UHCI_CTRL_EPT_MAX_SIZE; /* length to skip */ 1289 mp = ((usb_ctrl_req_t *)curr_xfer_reqp)->ctrl_data; 1290 break; 1291 case USB_EP_ATTR_INTR: 1292 mp = ((usb_intr_req_t *)curr_xfer_reqp)->intr_data; 1293 break; 1294 case USB_EP_ATTR_BULK: 1295 mp = ((usb_bulk_req_t *)curr_xfer_reqp)->bulk_data; 1296 break; 1297 case USB_EP_ATTR_ISOCH: 1298 length = tw->tw_length; 1299 mp = ((usb_isoc_req_t *)curr_xfer_reqp)->isoc_data; 1300 break; 1301 default: 1302 break; 1303 } 1304 1305 /* Copy the data into the mblk_t */ 1306 buf = (uchar_t *)tw->tw_buf + skip_len; 1307 1308 ASSERT(mp != NULL); 1309 1310 /* 1311 * Update kstat byte counts 1312 * The control endpoints don't have direction bits so in 1313 * order for control stats to be counted correctly an IN 1314 * bit must be faked on a control read. 1315 */ 1316 uhci_do_byte_stats(uhcip, length, ept->bmAttributes, 1317 (UHCI_XFER_TYPE(ept) == USB_EP_ATTR_CONTROL) ? 1318 USB_EP_DIR_IN : ept->bEndpointAddress); 1319 1320 if (length) { 1321 int rval, i; 1322 uchar_t *p = mp->b_rptr; 1323 1324 if (UHCI_XFER_TYPE(ept) == USB_EP_ATTR_ISOCH) { 1325 /* Deal with isoc data by packets */ 1326 for (i = 0; i < tw->tw_ncookies; i++) { 1327 rval = ddi_dma_sync( 1328 tw->tw_isoc_bufs[i].dma_handle, 0, 1329 tw->tw_isoc_bufs[i].length, 1330 DDI_DMA_SYNC_FORCPU); 1331 ASSERT(rval == DDI_SUCCESS); 1332 1333 ddi_rep_get8(tw->tw_isoc_bufs[i].mem_handle, 1334 p, (uint8_t *)tw->tw_isoc_bufs[i].buf_addr, 1335 tw->tw_isoc_bufs[i].length, 1336 DDI_DEV_AUTOINCR); 1337 p += tw->tw_isoc_bufs[i].length; 1338 } 1339 } else { 1340 /* Sync the streaming buffer */ 1341 rval = ddi_dma_sync(tw->tw_dmahandle, 0, 1342 (skip_len + length), DDI_DMA_SYNC_FORCPU); 1343 ASSERT(rval == DDI_SUCCESS); 1344 1345 /* Copy the data into the message */ 1346 ddi_rep_get8(tw->tw_accesshandle, 1347 mp->b_rptr, buf, length, DDI_DEV_AUTOINCR); 1348 } 1349 1350 /* Increment the write pointer */ 1351 mp->b_wptr += length; 1352 } else { 1353 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1354 "uhci_sendup_td_message: Zero length packet"); 1355 } 1356 1357 /* Do the callback */ 1358 uhci_hcdi_callback(uhcip, pp, pp->pp_pipe_handle, tw, usb_err); 1359 } 1360 1361 1362 /* 1363 * uhci_handle_ctrl_td: 1364 * Handle a control Transfer Descriptor (TD). 1365 */ 1366 void 1367 uhci_handle_ctrl_td(uhci_state_t *uhcip, uhci_td_t *td) 1368 { 1369 ushort_t direction; 1370 ushort_t bytes_for_xfer; 1371 ushort_t bytes_xfered; 1372 ushort_t MaxPacketSize; 1373 usb_cr_t error; 1374 uhci_trans_wrapper_t *tw = td->tw; 1375 uhci_pipe_private_t *pp = tw->tw_pipe_private; 1376 usba_pipe_handle_data_t *usb_pp = pp->pp_pipe_handle; 1377 usb_ep_descr_t *eptd = &usb_pp->p_ep; 1378 usb_ctrl_req_t *reqp = (usb_ctrl_req_t *)tw->tw_curr_xfer_reqp; 1379 1380 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1381 "uhci_handle_ctrl_td: pp = 0x%p tw = 0x%p td = 0x%p " 1382 "state = 0x%x len = 0x%lx", (void *)pp, (void *)tw, 1383 (void *)td, tw->tw_ctrl_state, tw->tw_length); 1384 1385 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 1386 1387 error = uhci_parse_td_error(uhcip, pp, td); 1388 1389 /* 1390 * In case of control transfers, the device can send NAK when it 1391 * is busy. If a NAK is received, then send the status TD again. 1392 */ 1393 if (error != USB_CR_OK) { 1394 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1395 "uhci_handle_ctrl_td: Ctrl cmd failed, error = %x", error); 1396 1397 SetQH32(uhcip, pp->pp_qh->element_ptr, 1398 GetTD32(uhcip, td->link_ptr)); 1399 uhci_delete_td(uhcip, td); 1400 1401 /* Return number of bytes xfered */ 1402 if (GetTD_alen(uhcip, td) != ZERO_LENGTH) { 1403 tw->tw_bytes_xfered = GetTD_alen(uhcip, td) + 1; 1404 } 1405 1406 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1407 "uhci_handle_ctrl_td: Bytes transferred = %x", 1408 tw->tw_bytes_xfered); 1409 1410 if ((tw->tw_ctrl_state == DATA) && 1411 (tw->tw_direction == PID_IN)) { 1412 uhci_sendup_td_message(uhcip, error, tw); 1413 } else { 1414 uhci_hcdi_callback(uhcip, pp, usb_pp, tw, error); 1415 1416 uhci_deallocate_tw(uhcip, pp, tw); 1417 } 1418 1419 return; 1420 } 1421 1422 /* 1423 * A control transfer consists of three phases: 1424 * - Setup 1425 * - Data (optional) 1426 * - Status 1427 * 1428 * There is a TD per phase. A TD for a given phase isn't 1429 * enqueued until the previous phase is finished. 1430 */ 1431 switch (tw->tw_ctrl_state) { 1432 case SETUP: 1433 /* 1434 * Enqueue either the data or the status 1435 * phase depending on the length. 1436 */ 1437 pp->pp_data_toggle = 1; 1438 uhci_delete_td(uhcip, td); 1439 1440 /* 1441 * If the length is 0, move to the status. 1442 * If length is not 0, then we have some data 1443 * to move on the bus to device either IN or OUT. 1444 */ 1445 if ((tw->tw_length - SETUP_SIZE) == 0) { 1446 /* 1447 * There is no data stage, then 1448 * initiate status phase from the host. 1449 */ 1450 if ((uhci_insert_hc_td(uhcip, 0, 0, pp, tw, PID_IN, 1451 reqp->ctrl_attributes)) != USB_SUCCESS) { 1452 USB_DPRINTF_L2(PRINT_MASK_LISTS, 1453 uhcip->uhci_log_hdl, 1454 "uhci_handle_ctrl_td: No resources"); 1455 1456 uhci_hcdi_callback(uhcip, pp, usb_pp, tw, 1457 USB_CR_NO_RESOURCES); 1458 1459 return; 1460 } 1461 1462 tw->tw_ctrl_state = STATUS; 1463 } else { 1464 uint_t xx; 1465 1466 /* 1467 * Each USB device can send/receive 8/16/32/64 1468 * depending on wMaxPacketSize's implementation. 1469 * We need to insert 'N = Number of byte/ 1470 * MaxpktSize" TD's in the lattice to send/ 1471 * receive the data. Though the USB protocol 1472 * allows to insert more than one TD in the same 1473 * frame, we are inserting only one TD in one 1474 * frame. This is bcos OHCI has seen some problem 1475 * when multiple TD's are inserted at the same time. 1476 */ 1477 tw->tw_length -= UHCI_CTRL_EPT_MAX_SIZE; 1478 MaxPacketSize = eptd->wMaxPacketSize; 1479 1480 /* 1481 * We dont know the maximum packet size that 1482 * the device can handle(MaxPAcketSize=0). 1483 * In that case insert a data phase with 1484 * eight bytes or less. 1485 */ 1486 if (MaxPacketSize == 0) { 1487 xx = (tw->tw_length > 8) ? 8 : tw->tw_length; 1488 } else { 1489 xx = (tw->tw_length > MaxPacketSize) ? 1490 MaxPacketSize : tw->tw_length; 1491 } 1492 1493 tw->tw_tmp = xx; 1494 1495 /* 1496 * Create the TD. If this is an OUT 1497 * transaction, the data is already 1498 * in the buffer of the TW. 1499 * Get first 8 bytes of the command only. 1500 */ 1501 if ((uhci_insert_hc_td(uhcip, 1502 UHCI_CTRL_EPT_MAX_SIZE, xx, 1503 pp, tw, tw->tw_direction, 1504 reqp->ctrl_attributes)) != USB_SUCCESS) { 1505 1506 USB_DPRINTF_L2(PRINT_MASK_LISTS, 1507 uhcip->uhci_log_hdl, 1508 "uhci_handle_ctrl_td: No resources"); 1509 1510 uhci_hcdi_callback(uhcip, pp, usb_pp, tw, 1511 USB_CR_NO_RESOURCES); 1512 1513 return; 1514 } 1515 1516 tw->tw_ctrl_state = DATA; 1517 } 1518 1519 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1520 "Setup complete: pp 0x%p td 0x%p", (void *)pp, (void *)td); 1521 1522 break; 1523 case DATA: 1524 uhci_delete_td(uhcip, td); 1525 1526 MaxPacketSize = eptd->wMaxPacketSize; 1527 1528 /* 1529 * Decrement pending bytes and increment the total 1530 * number bytes transferred by the actual number of bytes 1531 * transferred in this TD. If the number of bytes transferred 1532 * is less than requested, that means an underrun has 1533 * occurred. Set the tw_tmp varible to indicate UNDER run. 1534 */ 1535 bytes_xfered = GetTD_alen(uhcip, td); 1536 if (bytes_xfered == ZERO_LENGTH) { 1537 bytes_xfered = 0; 1538 } else { 1539 bytes_xfered++; 1540 } 1541 1542 tw->tw_bytes_pending -= bytes_xfered; 1543 tw->tw_bytes_xfered += bytes_xfered; 1544 1545 if (bytes_xfered < tw->tw_tmp) { 1546 tw->tw_bytes_pending = 0; 1547 tw->tw_tmp = UHCI_UNDERRUN_OCCURRED; 1548 1549 /* 1550 * Controller does not update the queue head 1551 * element pointer when a data underrun occurs. 1552 */ 1553 SetQH32(uhcip, pp->pp_qh->element_ptr, 1554 GetTD32(uhcip, td->link_ptr)); 1555 } 1556 1557 if (bytes_xfered > tw->tw_tmp) { 1558 tw->tw_bytes_pending = 0; 1559 tw->tw_tmp = UHCI_OVERRUN_OCCURRED; 1560 } 1561 1562 /* 1563 * If no more bytes are pending, insert status 1564 * phase. Otherwise insert data phase. 1565 */ 1566 if (tw->tw_bytes_pending) { 1567 bytes_for_xfer = (tw->tw_bytes_pending > 1568 MaxPacketSize) ? MaxPacketSize : 1569 tw->tw_bytes_pending; 1570 1571 tw->tw_tmp = bytes_for_xfer; 1572 1573 if ((uhci_insert_hc_td(uhcip, 1574 UHCI_CTRL_EPT_MAX_SIZE + tw->tw_bytes_xfered, 1575 bytes_for_xfer, pp, tw, 1576 tw->tw_direction, 1577 reqp->ctrl_attributes)) != USB_SUCCESS) { 1578 USB_DPRINTF_L2(PRINT_MASK_LISTS, 1579 uhcip->uhci_log_hdl, 1580 "uhci_handle_ctrl_td: No TD"); 1581 1582 uhci_hcdi_callback(uhcip, pp, usb_pp, 1583 tw, USB_NO_RESOURCES); 1584 1585 return; 1586 } 1587 1588 tw->tw_ctrl_state = DATA; 1589 1590 break; 1591 } 1592 1593 pp->pp_data_toggle = 1; 1594 direction = (tw->tw_direction == PID_IN) ? PID_OUT : PID_IN; 1595 1596 if ((uhci_insert_hc_td(uhcip, 0, 0, pp, tw, direction, 1597 reqp->ctrl_attributes)) != USB_SUCCESS) { 1598 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1599 "uhci_handle_ctrl_td: TD exhausted"); 1600 1601 uhci_hcdi_callback(uhcip, pp, usb_pp, tw, 1602 USB_NO_RESOURCES); 1603 1604 return; 1605 } 1606 1607 tw->tw_ctrl_state = STATUS; 1608 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1609 "Data complete: pp 0x%p td 0x%p", (void *)pp, (void *)td); 1610 1611 break; 1612 case STATUS: 1613 /* 1614 * Send the data to the client if it is a DATA IN, 1615 * else send just return status for DATA OUT commnads. 1616 * And set the tw_claim flag. 1617 */ 1618 tw->tw_claim = UHCI_INTR_HDLR_CLAIMED; 1619 1620 if ((tw->tw_length != 0) && (tw->tw_direction == PID_IN)) { 1621 usb_req_attrs_t attrs = ((usb_ctrl_req_t *) 1622 tw->tw_curr_xfer_reqp)->ctrl_attributes; 1623 /* 1624 * Call uhci_sendup_td_message to send message 1625 * upstream. The function uhci_sendup_td_message 1626 * returns USB_NO_RESOURCES if allocb fails and 1627 * also sends error message to upstream by calling 1628 * USBA callback function. 1629 * 1630 * Under error conditions just drop the current msg. 1631 */ 1632 if ((tw->tw_tmp == UHCI_UNDERRUN_OCCURRED) && 1633 (!(attrs & USB_ATTRS_SHORT_XFER_OK))) { 1634 error = USB_CR_DATA_UNDERRUN; 1635 } else if (tw->tw_tmp == UHCI_OVERRUN_OCCURRED) { 1636 error = USB_CR_DATA_OVERRUN; 1637 } 1638 uhci_sendup_td_message(uhcip, error, tw); 1639 1640 } else { 1641 uhci_do_byte_stats(uhcip, tw->tw_length, 1642 eptd->bmAttributes, eptd->bEndpointAddress); 1643 1644 uhci_hcdi_callback(uhcip, pp, usb_pp, tw, USB_CR_OK); 1645 } 1646 1647 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1648 "Status complete: pp 0x%p td 0x%p", (void *)pp, (void *)td); 1649 1650 uhci_delete_td(uhcip, td); 1651 uhci_deallocate_tw(uhcip, pp, tw); 1652 1653 break; 1654 default: 1655 USB_DPRINTF_L2(PRINT_MASK_INTR, uhcip->uhci_log_hdl, 1656 "uhci_handle_ctrl_td: Bad control state"); 1657 1658 uhci_hcdi_callback(uhcip, pp, usb_pp, tw, 1659 USB_CR_UNSPECIFIED_ERR); 1660 } 1661 } 1662 1663 1664 /* 1665 * uhci_handle_intr_td_errors: 1666 * Handles the errors encountered for the interrupt transfers. 1667 */ 1668 static void 1669 uhci_handle_intr_td_errors(uhci_state_t *uhcip, uhci_td_t *td, 1670 uhci_trans_wrapper_t *tw, uhci_pipe_private_t *pp) 1671 { 1672 usb_cr_t usb_err; 1673 usb_intr_req_t *intr_reqp = 1674 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 1675 1676 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1677 "uhci_handle_intr_td_errors: td = 0x%p tw = 0x%p", 1678 (void *)td, (void *)tw); 1679 1680 usb_err = uhci_parse_td_error(uhcip, pp, td); 1681 1682 if (intr_reqp->intr_attributes & USB_ATTRS_ONE_XFER) { 1683 uhci_handle_one_xfer_completion(uhcip, usb_err, td); 1684 1685 return; 1686 } 1687 1688 uhci_delete_td(uhcip, td); 1689 uhci_sendup_td_message(uhcip, usb_err, tw); 1690 uhci_deallocate_tw(uhcip, tw->tw_pipe_private, tw); 1691 } 1692 1693 1694 /* 1695 * uhci_handle_one_xfer_completion: 1696 */ 1697 static void 1698 uhci_handle_one_xfer_completion( 1699 uhci_state_t *uhcip, 1700 usb_cr_t usb_err, 1701 uhci_td_t *td) 1702 { 1703 uhci_trans_wrapper_t *tw = td->tw; 1704 uhci_pipe_private_t *pp = tw->tw_pipe_private; 1705 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 1706 usb_intr_req_t *intr_reqp = 1707 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 1708 1709 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1710 "uhci_handle_one_xfer_completion: td = 0x%p", (void *)td); 1711 1712 ASSERT(intr_reqp->intr_attributes & USB_ATTRS_ONE_XFER); 1713 1714 /* set state to idle */ 1715 pp->pp_state = UHCI_PIPE_STATE_IDLE; 1716 1717 ((usb_intr_req_t *)(pp->pp_client_periodic_in_reqp))-> 1718 intr_data = ((usb_intr_req_t *)(tw->tw_curr_xfer_reqp))->intr_data; 1719 1720 ((usb_intr_req_t *)tw->tw_curr_xfer_reqp)->intr_data = NULL; 1721 1722 /* now free duplicate current request */ 1723 usb_free_intr_req((usb_intr_req_t *)tw->tw_curr_xfer_reqp); 1724 mutex_enter(&ph->p_mutex); 1725 ph->p_req_count--; 1726 mutex_exit(&ph->p_mutex); 1727 1728 /* make client's request the current request */ 1729 tw->tw_curr_xfer_reqp = pp->pp_client_periodic_in_reqp; 1730 pp->pp_client_periodic_in_reqp = NULL; 1731 1732 uhci_sendup_td_message(uhcip, usb_err, tw); 1733 /* Clear the tw->tw_claim flag */ 1734 tw->tw_claim = UHCI_NOT_CLAIMED; 1735 1736 uhci_delete_td(uhcip, td); 1737 uhci_deallocate_tw(uhcip, pp, tw); 1738 } 1739 1740 1741 /* 1742 * uhci_parse_td_error 1743 * Parses the Transfer Descriptors error 1744 */ 1745 usb_cr_t 1746 uhci_parse_td_error(uhci_state_t *uhcip, uhci_pipe_private_t *pp, uhci_td_t *td) 1747 { 1748 uint_t status; 1749 1750 status = GetTD_status(uhcip, td) & TD_STATUS_MASK; 1751 1752 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1753 "uhci_parse_td_error: status_bits=0x%x", status); 1754 1755 if (UHCI_XFER_TYPE(&pp->pp_pipe_handle->p_ep) == USB_EP_ATTR_ISOCH) { 1756 1757 return (USB_CR_OK); 1758 } 1759 1760 if (!status) { 1761 1762 return (USB_CR_OK); 1763 } 1764 1765 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1766 "uhci_parse_td_error: status_bits=0x%x", status); 1767 1768 1769 if (status & UHCI_TD_BITSTUFF_ERR) { 1770 1771 return (USB_CR_BITSTUFFING); 1772 } 1773 1774 if (status & UHCI_TD_CRC_TIMEOUT) { 1775 pp->pp_data_toggle = GetTD_dtogg(uhcip, td); 1776 1777 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1778 "uhci_parse_td_error: timeout & data toggle reset; " 1779 "data toggle: %x", pp->pp_data_toggle); 1780 1781 return ((GetTD_PID(uhcip, td) == PID_IN) ? USB_CR_DEV_NOT_RESP : 1782 USB_CR_TIMEOUT); 1783 } 1784 1785 if (status & UHCI_TD_BABBLE_ERR) { 1786 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1787 "babble error"); 1788 1789 return (USB_CR_UNSPECIFIED_ERR); 1790 } 1791 1792 if (status & UHCI_TD_DATA_BUFFER_ERR) { 1793 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1794 "buffer error"); 1795 1796 return ((GetTD_PID(uhcip, td) == PID_IN) ? 1797 USB_CR_BUFFER_OVERRUN : USB_CR_BUFFER_UNDERRUN); 1798 } 1799 1800 if (status & UHCI_TD_STALLED) { 1801 pp->pp_data_toggle = 0; 1802 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1803 "uhci_parse_td_error: stall; data toggle reset; " 1804 "data toggle: %x", pp->pp_data_toggle); 1805 1806 return (USB_CR_STALL); 1807 } 1808 1809 if (status) { 1810 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1811 "unspecified error=0x%x", status); 1812 } 1813 1814 return (USB_CR_OK); 1815 } 1816 1817 1818 static dev_info_t * 1819 uhci_get_dip(dev_t dev) 1820 { 1821 int instance = UHCI_UNIT(dev); 1822 uhci_state_t *uhcip = ddi_get_soft_state(uhci_statep, instance); 1823 1824 return (uhcip ? uhcip->uhci_dip : NULL); 1825 } 1826 1827 1828 /* 1829 * cb_ops entry points 1830 */ 1831 static int 1832 uhci_open(dev_t *devp, int flags, int otyp, cred_t *credp) 1833 { 1834 dev_info_t *dip = uhci_get_dip(*devp); 1835 1836 return (usba_hubdi_open(dip, devp, flags, otyp, credp)); 1837 } 1838 1839 1840 static int 1841 uhci_close(dev_t dev, int flag, int otyp, cred_t *credp) 1842 { 1843 dev_info_t *dip = uhci_get_dip(dev); 1844 1845 return (usba_hubdi_close(dip, dev, flag, otyp, credp)); 1846 } 1847 1848 1849 static int 1850 uhci_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, 1851 cred_t *credp, int *rvalp) 1852 { 1853 dev_info_t *dip = uhci_get_dip(dev); 1854 1855 return (usba_hubdi_ioctl(dip, dev, cmd, arg, mode, credp, rvalp)); 1856 } 1857