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