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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * Open Host Controller Driver (OHCI) 31 * 32 * The USB Open Host Controller driver is a software driver which interfaces 33 * to the Universal Serial Bus layer (USBA) and the USB Open Host Controller. 34 * The interface to USB Open Host Controller is defined by the OpenHCI Host 35 * Controller Interface. 36 * 37 * NOTE: 38 * 39 * Currently OHCI driver does not support the following features 40 * 41 * - Handle request with multiple TDs under short xfer conditions except for 42 * bulk transfers. 43 */ 44 #include <sys/usb/hcd/openhci/ohcid.h> 45 46 /* Pointer to the state structure */ 47 static void *ohci_statep; 48 49 /* Number of instances */ 50 #define OHCI_INSTS 1 51 52 /* Adjustable variables for the size of the pools */ 53 int ohci_ed_pool_size = OHCI_ED_POOL_SIZE; 54 int ohci_td_pool_size = OHCI_TD_POOL_SIZE; 55 56 /* 57 * Initialize the values which are used for setting up head pointers for 58 * the 32ms scheduling lists which starts from the HCCA. 59 */ 60 static uchar_t ohci_index[NUM_INTR_ED_LISTS / 2] = {0x0, 0x8, 0x4, 0xc, 61 0x2, 0xa, 0x6, 0xe, 62 0x1, 0x9, 0x5, 0xd, 63 0x3, 0xb, 0x7, 0xf}; 64 /* Debugging information */ 65 uint_t ohci_errmask = (uint_t)PRINT_MASK_ALL; 66 uint_t ohci_errlevel = USB_LOG_L2; 67 uint_t ohci_instance_debug = (uint_t)-1; 68 69 /* 70 * OHCI MSI tunable: 71 * 72 * By default MSI is enabled on all supported platforms. 73 */ 74 boolean_t ohci_enable_msi = B_TRUE; 75 76 /* 77 * HCDI entry points 78 * 79 * The Host Controller Driver Interfaces (HCDI) are the software interfaces 80 * between the Universal Serial Bus Driver (USBA) and the Host Controller 81 * Driver (HCD). The HCDI interfaces or entry points are subject to change. 82 */ 83 static int ohci_hcdi_pipe_open( 84 usba_pipe_handle_data_t *ph, 85 usb_flags_t usb_flags); 86 static int ohci_hcdi_pipe_close( 87 usba_pipe_handle_data_t *ph, 88 usb_flags_t usb_flags); 89 static int ohci_hcdi_pipe_reset( 90 usba_pipe_handle_data_t *ph, 91 usb_flags_t usb_flags); 92 static int ohci_hcdi_pipe_ctrl_xfer( 93 usba_pipe_handle_data_t *ph, 94 usb_ctrl_req_t *ctrl_reqp, 95 usb_flags_t usb_flags); 96 static int ohci_hcdi_bulk_transfer_size( 97 usba_device_t *usba_device, 98 size_t *size); 99 static int ohci_hcdi_pipe_bulk_xfer( 100 usba_pipe_handle_data_t *ph, 101 usb_bulk_req_t *bulk_reqp, 102 usb_flags_t usb_flags); 103 static int ohci_hcdi_pipe_intr_xfer( 104 usba_pipe_handle_data_t *ph, 105 usb_intr_req_t *intr_req, 106 usb_flags_t usb_flags); 107 static int ohci_hcdi_pipe_stop_intr_polling( 108 usba_pipe_handle_data_t *ph, 109 usb_flags_t usb_flags); 110 static usb_frame_number_t ohci_hcdi_get_current_frame_number( 111 usba_device_t *usba_device); 112 static uint_t ohci_hcdi_get_max_isoc_pkts( 113 usba_device_t *usba_device); 114 static int ohci_hcdi_pipe_isoc_xfer( 115 usba_pipe_handle_data_t *ph, 116 usb_isoc_req_t *isoc_reqp, 117 usb_flags_t usb_flags); 118 static int ohci_hcdi_pipe_stop_isoc_polling( 119 usba_pipe_handle_data_t *ph, 120 usb_flags_t usb_flags); 121 122 /* 123 * Internal Function Prototypes 124 */ 125 126 /* Host Controller Driver (HCD) initialization functions */ 127 static void ohci_set_dma_attributes(ohci_state_t *ohcip); 128 static int ohci_allocate_pools(ohci_state_t *ohcip); 129 static void ohci_decode_ddi_dma_addr_bind_handle_result( 130 ohci_state_t *ohcip, 131 int result); 132 static int ohci_map_regs(ohci_state_t *ohcip); 133 static int ohci_register_intrs_and_init_mutex( 134 ohci_state_t *ohcip); 135 static int ohci_add_intrs(ohci_state_t *ohcip, 136 int intr_type); 137 static int ohci_init_ctlr(ohci_state_t *ohcip); 138 static int ohci_init_hcca(ohci_state_t *ohcip); 139 static void ohci_build_interrupt_lattice( 140 ohci_state_t *ohcip); 141 static int ohci_take_control(ohci_state_t *ohcip); 142 static usba_hcdi_ops_t *ohci_alloc_hcdi_ops( 143 ohci_state_t *ohcip); 144 145 /* Host Controller Driver (HCD) deinitialization functions */ 146 static int ohci_cleanup(ohci_state_t *ohcip); 147 static void ohci_rem_intrs(ohci_state_t *ohcip); 148 static int ohci_cpr_suspend(ohci_state_t *ohcip); 149 static int ohci_cpr_resume(ohci_state_t *ohcip); 150 151 /* Bandwidth Allocation functions */ 152 static int ohci_allocate_bandwidth(ohci_state_t *ohcip, 153 usba_pipe_handle_data_t *ph, 154 uint_t *node); 155 static void ohci_deallocate_bandwidth(ohci_state_t *ohcip, 156 usba_pipe_handle_data_t *ph); 157 static int ohci_compute_total_bandwidth( 158 usb_ep_descr_t *endpoint, 159 usb_port_status_t port_status, 160 uint_t *bandwidth); 161 static int ohci_adjust_polling_interval( 162 ohci_state_t *ohcip, 163 usb_ep_descr_t *endpoint, 164 usb_port_status_t port_status); 165 static uint_t ohci_lattice_height(uint_t interval); 166 static uint_t ohci_lattice_parent(uint_t node); 167 static uint_t ohci_leftmost_leaf(uint_t node, 168 uint_t height); 169 static uint_t ohci_hcca_intr_index( 170 uint_t node); 171 static uint_t ohci_hcca_leaf_index( 172 uint_t leaf); 173 static uint_t ohci_pow_2(uint_t x); 174 static uint_t ohci_log_2(uint_t x); 175 176 /* Endpoint Descriptor (ED) related functions */ 177 static uint_t ohci_unpack_endpoint(ohci_state_t *ohcip, 178 usba_pipe_handle_data_t *ph); 179 static void ohci_insert_ed(ohci_state_t *ohcip, 180 usba_pipe_handle_data_t *ph); 181 static void ohci_insert_ctrl_ed( 182 ohci_state_t *ohcip, 183 ohci_pipe_private_t *pp); 184 static void ohci_insert_bulk_ed( 185 ohci_state_t *ohcip, 186 ohci_pipe_private_t *pp); 187 static void ohci_insert_intr_ed( 188 ohci_state_t *ohcip, 189 ohci_pipe_private_t *pp); 190 static void ohci_insert_isoc_ed( 191 ohci_state_t *ohcip, 192 ohci_pipe_private_t *pp); 193 static void ohci_modify_sKip_bit(ohci_state_t *ohcip, 194 ohci_pipe_private_t *pp, 195 skip_bit_t action, 196 usb_flags_t flag); 197 static void ohci_remove_ed(ohci_state_t *ohcip, 198 ohci_pipe_private_t *pp); 199 static void ohci_remove_ctrl_ed( 200 ohci_state_t *ohcip, 201 ohci_pipe_private_t *pp); 202 static void ohci_remove_bulk_ed( 203 ohci_state_t *ohcip, 204 ohci_pipe_private_t *pp); 205 static void ohci_remove_periodic_ed( 206 ohci_state_t *ohcip, 207 ohci_pipe_private_t *pp); 208 static void ohci_insert_ed_on_reclaim_list( 209 ohci_state_t *ohcip, 210 ohci_pipe_private_t *pp); 211 static void ohci_detach_ed_from_list( 212 ohci_state_t *ohcip, 213 ohci_ed_t *ept, 214 uint_t ept_type); 215 static ohci_ed_t *ohci_ed_iommu_to_cpu( 216 ohci_state_t *ohcip, 217 uintptr_t addr); 218 219 /* Transfer Descriptor (TD) related functions */ 220 static int ohci_initialize_dummy(ohci_state_t *ohcip, 221 ohci_ed_t *ept); 222 static ohci_trans_wrapper_t *ohci_allocate_ctrl_resources( 223 ohci_state_t *ohcip, 224 ohci_pipe_private_t *pp, 225 usb_ctrl_req_t *ctrl_reqp, 226 usb_flags_t usb_flags); 227 static void ohci_insert_ctrl_req( 228 ohci_state_t *ohcip, 229 usba_pipe_handle_data_t *ph, 230 usb_ctrl_req_t *ctrl_reqp, 231 ohci_trans_wrapper_t *tw, 232 usb_flags_t usb_flags); 233 static ohci_trans_wrapper_t *ohci_allocate_bulk_resources( 234 ohci_state_t *ohcip, 235 ohci_pipe_private_t *pp, 236 usb_bulk_req_t *bulk_reqp, 237 usb_flags_t usb_flags); 238 static void ohci_insert_bulk_req(ohci_state_t *ohcip, 239 usba_pipe_handle_data_t *ph, 240 usb_bulk_req_t *bulk_reqp, 241 ohci_trans_wrapper_t *tw, 242 usb_flags_t flags); 243 static int ohci_start_pipe_polling(ohci_state_t *ohcip, 244 usba_pipe_handle_data_t *ph, 245 usb_flags_t flags); 246 static void ohci_set_periodic_pipe_polling( 247 ohci_state_t *ohcip, 248 usba_pipe_handle_data_t *ph); 249 static ohci_trans_wrapper_t *ohci_allocate_intr_resources( 250 ohci_state_t *ohcip, 251 usba_pipe_handle_data_t *ph, 252 usb_intr_req_t *intr_reqp, 253 usb_flags_t usb_flags); 254 static void ohci_insert_intr_req(ohci_state_t *ohcip, 255 ohci_pipe_private_t *pp, 256 ohci_trans_wrapper_t *tw, 257 usb_flags_t flags); 258 static int ohci_stop_periodic_pipe_polling( 259 ohci_state_t *ohcip, 260 usba_pipe_handle_data_t *ph, 261 usb_flags_t flags); 262 static ohci_trans_wrapper_t *ohci_allocate_isoc_resources( 263 ohci_state_t *ohcip, 264 usba_pipe_handle_data_t *ph, 265 usb_isoc_req_t *isoc_reqp, 266 usb_flags_t usb_flags); 267 static int ohci_insert_isoc_req(ohci_state_t *ohcip, 268 ohci_pipe_private_t *pp, 269 ohci_trans_wrapper_t *tw, 270 uint_t flags); 271 static int ohci_insert_hc_td(ohci_state_t *ohcip, 272 uint_t hctd_ctrl, 273 uint32_t hctd_iommu_cbp, 274 size_t hctd_length, 275 uint32_t hctd_ctrl_phase, 276 ohci_pipe_private_t *pp, 277 ohci_trans_wrapper_t *tw); 278 static ohci_td_t *ohci_allocate_td_from_pool( 279 ohci_state_t *ohcip); 280 static void ohci_fill_in_td(ohci_state_t *ohcip, 281 ohci_td_t *td, 282 ohci_td_t *new_dummy, 283 uint_t hctd_ctrl, 284 uint32_t hctd_iommu_cbp, 285 size_t hctd_length, 286 uint32_t hctd_ctrl_phase, 287 ohci_pipe_private_t *pp, 288 ohci_trans_wrapper_t *tw); 289 static void ohci_init_itd( 290 ohci_state_t *ohcip, 291 ohci_pipe_private_t *pp, 292 ohci_trans_wrapper_t *tw, 293 uint_t hctd_ctrl, 294 uint32_t hctd_iommu_cbp, 295 ohci_td_t *td); 296 static int ohci_insert_td_with_frame_number( 297 ohci_state_t *ohcip, 298 ohci_pipe_private_t *pp, 299 ohci_trans_wrapper_t *tw, 300 ohci_td_t *current_td, 301 ohci_td_t *dummy_td); 302 static void ohci_insert_td_on_tw(ohci_state_t *ohcip, 303 ohci_trans_wrapper_t *tw, 304 ohci_td_t *td); 305 static void ohci_done_list_tds(ohci_state_t *ohcip, 306 usba_pipe_handle_data_t *ph); 307 308 /* Transfer Wrapper (TW) functions */ 309 static ohci_trans_wrapper_t *ohci_create_transfer_wrapper( 310 ohci_state_t *ohcip, 311 ohci_pipe_private_t *pp, 312 size_t length, 313 uint_t usb_flags); 314 static int ohci_allocate_tds_for_tw( 315 ohci_state_t *ohcip, 316 ohci_trans_wrapper_t *tw, 317 size_t td_count); 318 static ohci_trans_wrapper_t *ohci_allocate_tw_resources( 319 ohci_state_t *ohcip, 320 ohci_pipe_private_t *pp, 321 size_t length, 322 usb_flags_t usb_flags, 323 size_t td_count); 324 static void ohci_free_tw_tds_resources( 325 ohci_state_t *ohcip, 326 ohci_trans_wrapper_t *tw); 327 static void ohci_start_xfer_timer( 328 ohci_state_t *ohcip, 329 ohci_pipe_private_t *pp, 330 ohci_trans_wrapper_t *tw); 331 static void ohci_stop_xfer_timer( 332 ohci_state_t *ohcip, 333 ohci_trans_wrapper_t *tw, 334 uint_t flag); 335 static void ohci_xfer_timeout_handler(void *arg); 336 static void ohci_remove_tw_from_timeout_list( 337 ohci_state_t *ohcip, 338 ohci_trans_wrapper_t *tw); 339 static void ohci_start_timer(ohci_state_t *ohcip); 340 static void ohci_free_dma_resources(ohci_state_t *ohcip, 341 usba_pipe_handle_data_t *ph); 342 static void ohci_free_tw(ohci_state_t *ohcip, 343 ohci_trans_wrapper_t *tw); 344 345 /* Interrupt Handling functions */ 346 static uint_t ohci_intr(caddr_t arg1, 347 caddr_t arg2); 348 static void ohci_handle_missed_intr( 349 ohci_state_t *ohcip); 350 static void ohci_handle_ue(ohci_state_t *ohcip); 351 static void ohci_handle_endpoint_reclaimation( 352 ohci_state_t *ohcip); 353 static void ohci_traverse_done_list( 354 ohci_state_t *ohcip, 355 ohci_td_t *head_done_list); 356 static ohci_td_t *ohci_reverse_done_list( 357 ohci_state_t *ohcip, 358 ohci_td_t *head_done_list); 359 static usb_cr_t ohci_parse_error(ohci_state_t *ohcip, 360 ohci_td_t *td); 361 static void ohci_parse_isoc_error( 362 ohci_state_t *ohcip, 363 ohci_pipe_private_t *pp, 364 ohci_trans_wrapper_t *tw, 365 ohci_td_t *td); 366 static usb_cr_t ohci_check_for_error( 367 ohci_state_t *ohcip, 368 ohci_pipe_private_t *pp, 369 ohci_trans_wrapper_t *tw, 370 ohci_td_t *td, 371 uint_t ctrl); 372 static void ohci_handle_error( 373 ohci_state_t *ohcip, 374 ohci_td_t *td, 375 usb_cr_t error); 376 static int ohci_cleanup_data_underrun( 377 ohci_state_t *ohcip, 378 ohci_pipe_private_t *pp, 379 ohci_trans_wrapper_t *tw, 380 ohci_td_t *td); 381 static void ohci_handle_normal_td( 382 ohci_state_t *ohcip, 383 ohci_td_t *td, 384 ohci_trans_wrapper_t *tw); 385 static void ohci_handle_ctrl_td(ohci_state_t *ohcip, 386 ohci_pipe_private_t *pp, 387 ohci_trans_wrapper_t *tw, 388 ohci_td_t *td, 389 void *); 390 static void ohci_handle_bulk_td(ohci_state_t *ohcip, 391 ohci_pipe_private_t *pp, 392 ohci_trans_wrapper_t *tw, 393 ohci_td_t *td, 394 void *); 395 static void ohci_handle_intr_td(ohci_state_t *ohcip, 396 ohci_pipe_private_t *pp, 397 ohci_trans_wrapper_t *tw, 398 ohci_td_t *td, 399 void *); 400 static void ohci_handle_one_xfer_completion( 401 ohci_state_t *ohcip, 402 ohci_trans_wrapper_t *tw); 403 static void ohci_handle_isoc_td(ohci_state_t *ohcip, 404 ohci_pipe_private_t *pp, 405 ohci_trans_wrapper_t *tw, 406 ohci_td_t *td, 407 void *); 408 static void ohci_sendup_td_message( 409 ohci_state_t *ohcip, 410 ohci_pipe_private_t *pp, 411 ohci_trans_wrapper_t *tw, 412 ohci_td_t *td, 413 usb_cr_t error); 414 415 /* Miscillaneous functions */ 416 static void ohci_cpr_cleanup( 417 ohci_state_t *ohcip); 418 static usb_req_attrs_t ohci_get_xfer_attrs(ohci_state_t *ohcip, 419 ohci_pipe_private_t *pp, 420 ohci_trans_wrapper_t *tw); 421 static int ohci_allocate_periodic_in_resource( 422 ohci_state_t *ohcip, 423 ohci_pipe_private_t *pp, 424 ohci_trans_wrapper_t *tw, 425 usb_flags_t flags); 426 static int ohci_wait_for_sof( 427 ohci_state_t *ohcip); 428 static void ohci_pipe_cleanup( 429 ohci_state_t *ohcip, 430 usba_pipe_handle_data_t *ph); 431 static void ohci_wait_for_transfers_completion( 432 ohci_state_t *ohcip, 433 ohci_pipe_private_t *pp); 434 static void ohci_check_for_transfers_completion( 435 ohci_state_t *ohcip, 436 ohci_pipe_private_t *pp); 437 static void ohci_save_data_toggle(ohci_state_t *ohcip, 438 usba_pipe_handle_data_t *ph); 439 static void ohci_restore_data_toggle(ohci_state_t *ohcip, 440 usba_pipe_handle_data_t *ph); 441 static void ohci_deallocate_periodic_in_resource( 442 ohci_state_t *ohcip, 443 ohci_pipe_private_t *pp, 444 ohci_trans_wrapper_t *tw); 445 static void ohci_do_client_periodic_in_req_callback( 446 ohci_state_t *ohcip, 447 ohci_pipe_private_t *pp, 448 usb_cr_t completion_reason); 449 static void ohci_hcdi_callback( 450 usba_pipe_handle_data_t *ph, 451 ohci_trans_wrapper_t *tw, 452 usb_cr_t completion_reason); 453 454 /* Kstat Support */ 455 static void ohci_create_stats(ohci_state_t *ohcip); 456 static void ohci_destroy_stats(ohci_state_t *ohcip); 457 static void ohci_do_byte_stats( 458 ohci_state_t *ohcip, 459 size_t len, 460 uint8_t attr, 461 uint8_t addr); 462 static void ohci_do_intrs_stats( 463 ohci_state_t *ohcip, 464 int val); 465 static void ohci_print_op_regs(ohci_state_t *ohcip); 466 static void ohci_print_ed(ohci_state_t *ohcip, 467 ohci_ed_t *ed); 468 static void ohci_print_td(ohci_state_t *ohcip, 469 ohci_td_t *td); 470 471 /* extern */ 472 int usba_hubdi_root_hub_power(dev_info_t *dip, int comp, int level); 473 474 /* 475 * Device operations (dev_ops) entries function prototypes. 476 * 477 * We use the hub cbops since all nexus ioctl operations defined so far will 478 * be executed by the root hub. The following are the Host Controller Driver 479 * (HCD) entry points. 480 * 481 * the open/close/ioctl functions call the corresponding usba_hubdi_* 482 * calls after looking up the dip thru the dev_t. 483 */ 484 static int ohci_open(dev_t *devp, int flags, int otyp, cred_t *credp); 485 static int ohci_close(dev_t dev, int flag, int otyp, cred_t *credp); 486 static int ohci_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, 487 cred_t *credp, int *rvalp); 488 489 static int ohci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 490 static int ohci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 491 static int ohci_info(dev_info_t *dip, ddi_info_cmd_t infocmd, 492 void *arg, void **result); 493 494 static struct cb_ops ohci_cb_ops = { 495 ohci_open, /* Open */ 496 ohci_close, /* Close */ 497 nodev, /* Strategy */ 498 nodev, /* Print */ 499 nodev, /* Dump */ 500 nodev, /* Read */ 501 nodev, /* Write */ 502 ohci_ioctl, /* Ioctl */ 503 nodev, /* Devmap */ 504 nodev, /* Mmap */ 505 nodev, /* Segmap */ 506 nochpoll, /* Poll */ 507 ddi_prop_op, /* cb_prop_op */ 508 NULL, /* Streamtab */ 509 D_MP /* Driver compatibility flag */ 510 }; 511 512 static struct dev_ops ohci_ops = { 513 DEVO_REV, /* Devo_rev */ 514 0, /* Refcnt */ 515 ohci_info, /* Info */ 516 nulldev, /* Identify */ 517 nulldev, /* Probe */ 518 ohci_attach, /* Attach */ 519 ohci_detach, /* Detach */ 520 nodev, /* Reset */ 521 &ohci_cb_ops, /* Driver operations */ 522 &usba_hubdi_busops, /* Bus operations */ 523 usba_hubdi_root_hub_power /* Power */ 524 }; 525 526 /* 527 * The USBA library must be loaded for this driver. 528 */ 529 static struct modldrv modldrv = { 530 &mod_driverops, /* Type of module. This one is a driver */ 531 "USB OpenHCI Driver %I%", /* Name of the module. */ 532 &ohci_ops, /* Driver ops */ 533 }; 534 535 static struct modlinkage modlinkage = { 536 MODREV_1, (void *)&modldrv, NULL 537 }; 538 539 540 int 541 _init(void) 542 { 543 int error; 544 545 /* Initialize the soft state structures */ 546 if ((error = ddi_soft_state_init(&ohci_statep, sizeof (ohci_state_t), 547 OHCI_INSTS)) != 0) { 548 return (error); 549 } 550 551 /* Install the loadable module */ 552 if ((error = mod_install(&modlinkage)) != 0) { 553 ddi_soft_state_fini(&ohci_statep); 554 } 555 556 return (error); 557 } 558 559 560 int 561 _info(struct modinfo *modinfop) 562 { 563 return (mod_info(&modlinkage, modinfop)); 564 } 565 566 567 int 568 _fini(void) 569 { 570 int error; 571 572 if ((error = mod_remove(&modlinkage)) == 0) { 573 /* Release per module resources */ 574 ddi_soft_state_fini(&ohci_statep); 575 } 576 577 return (error); 578 } 579 580 581 /* 582 * Host Controller Driver (HCD) entry points 583 */ 584 585 /* 586 * ohci_attach: 587 */ 588 static int 589 ohci_attach(dev_info_t *dip, 590 ddi_attach_cmd_t cmd) 591 { 592 int instance; 593 ohci_state_t *ohcip = NULL; 594 usba_hcdi_register_args_t hcdi_args; 595 596 switch (cmd) { 597 case DDI_ATTACH: 598 break; 599 case DDI_RESUME: 600 ohcip = ohci_obtain_state(dip); 601 602 return (ohci_cpr_resume(ohcip)); 603 default: 604 return (DDI_FAILURE); 605 } 606 607 /* Get the instance and create soft state */ 608 instance = ddi_get_instance(dip); 609 610 if (ddi_soft_state_zalloc(ohci_statep, instance) != 0) { 611 612 return (DDI_FAILURE); 613 } 614 615 ohcip = ddi_get_soft_state(ohci_statep, instance); 616 if (ohcip == NULL) { 617 618 return (DDI_FAILURE); 619 } 620 621 ohcip->ohci_flags = OHCI_ATTACH; 622 623 ohcip->ohci_log_hdl = usb_alloc_log_hdl(dip, "ohci", &ohci_errlevel, 624 &ohci_errmask, &ohci_instance_debug, 0); 625 626 ohcip->ohci_flags |= OHCI_ZALLOC; 627 628 /* Set host controller soft state to initilization */ 629 ohcip->ohci_hc_soft_state = OHCI_CTLR_INIT_STATE; 630 631 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 632 "ohcip = 0x%p", (void *)ohcip); 633 634 /* Initialize the DMA attributes */ 635 ohci_set_dma_attributes(ohcip); 636 637 /* Save the dip and instance */ 638 ohcip->ohci_dip = dip; 639 ohcip->ohci_instance = instance; 640 641 /* Initialize the kstat structures */ 642 ohci_create_stats(ohcip); 643 644 /* Create the td and ed pools */ 645 if (ohci_allocate_pools(ohcip) != DDI_SUCCESS) { 646 (void) ohci_cleanup(ohcip); 647 648 return (DDI_FAILURE); 649 } 650 651 /* Map the registers */ 652 if (ohci_map_regs(ohcip) != DDI_SUCCESS) { 653 (void) ohci_cleanup(ohcip); 654 655 return (DDI_FAILURE); 656 } 657 658 /* Register interrupts */ 659 if (ohci_register_intrs_and_init_mutex(ohcip) != DDI_SUCCESS) { 660 (void) ohci_cleanup(ohcip); 661 662 return (DDI_FAILURE); 663 } 664 665 mutex_enter(&ohcip->ohci_int_mutex); 666 667 /* Initialize the controller */ 668 if (ohci_init_ctlr(ohcip) != DDI_SUCCESS) { 669 mutex_exit(&ohcip->ohci_int_mutex); 670 (void) ohci_cleanup(ohcip); 671 672 return (DDI_FAILURE); 673 } 674 675 /* 676 * At this point, the hardware wiil be okay. 677 * Initialize the usba_hcdi structure 678 */ 679 ohcip->ohci_hcdi_ops = ohci_alloc_hcdi_ops(ohcip); 680 681 mutex_exit(&ohcip->ohci_int_mutex); 682 683 /* 684 * Make this HCD instance known to USBA 685 * (dma_attr must be passed for USBA busctl's) 686 */ 687 hcdi_args.usba_hcdi_register_version = HCDI_REGISTER_VERSION; 688 hcdi_args.usba_hcdi_register_dip = dip; 689 hcdi_args.usba_hcdi_register_ops = ohcip->ohci_hcdi_ops; 690 hcdi_args.usba_hcdi_register_dma_attr = &ohcip->ohci_dma_attr; 691 692 /* 693 * Priority and iblock_cookie are one and the same 694 * (However, retaining hcdi_soft_iblock_cookie for now 695 * assigning it w/ priority. In future all iblock_cookie 696 * could just go) 697 */ 698 hcdi_args.usba_hcdi_register_iblock_cookie = 699 (ddi_iblock_cookie_t)(uintptr_t)ohcip->ohci_intr_pri; 700 701 if (usba_hcdi_register(&hcdi_args, 0) != DDI_SUCCESS) { 702 (void) ohci_cleanup(ohcip); 703 704 return (DDI_FAILURE); 705 } 706 ohcip->ohci_flags |= OHCI_USBAREG; 707 708 mutex_enter(&ohcip->ohci_int_mutex); 709 710 if ((ohci_init_root_hub(ohcip)) != USB_SUCCESS) { 711 mutex_exit(&ohcip->ohci_int_mutex); 712 (void) ohci_cleanup(ohcip); 713 714 return (DDI_FAILURE); 715 } 716 717 mutex_exit(&ohcip->ohci_int_mutex); 718 719 /* Finally load the root hub driver */ 720 if (ohci_load_root_hub_driver(ohcip) != USB_SUCCESS) { 721 (void) ohci_cleanup(ohcip); 722 723 return (DDI_FAILURE); 724 } 725 ohcip->ohci_flags |= OHCI_RHREG; 726 727 /* Display information in the banner */ 728 ddi_report_dev(dip); 729 730 mutex_enter(&ohcip->ohci_int_mutex); 731 732 /* Reset the ohci initilization flag */ 733 ohcip->ohci_flags &= ~OHCI_ATTACH; 734 735 /* Print the Host Control's Operational registers */ 736 ohci_print_op_regs(ohcip); 737 738 /* For RIO we need to call pci_report_pmcap */ 739 if (OHCI_IS_RIO(ohcip)) { 740 741 (void) pci_report_pmcap(dip, PCI_PM_IDLESPEED, (void *)4000); 742 } 743 744 mutex_exit(&ohcip->ohci_int_mutex); 745 746 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 747 "ohci_attach: dip = 0x%p done", (void *)dip); 748 749 return (DDI_SUCCESS); 750 } 751 752 753 /* 754 * ohci_detach: 755 */ 756 int 757 ohci_detach(dev_info_t *dip, 758 ddi_detach_cmd_t cmd) 759 { 760 ohci_state_t *ohcip = ohci_obtain_state(dip); 761 762 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_detach:"); 763 764 switch (cmd) { 765 case DDI_DETACH: 766 767 return (ohci_cleanup(ohcip)); 768 769 case DDI_SUSPEND: 770 771 return (ohci_cpr_suspend(ohcip)); 772 default: 773 774 return (DDI_FAILURE); 775 } 776 } 777 778 779 /* 780 * ohci_info: 781 */ 782 /* ARGSUSED */ 783 static int 784 ohci_info(dev_info_t *dip, 785 ddi_info_cmd_t infocmd, 786 void *arg, 787 void **result) 788 { 789 dev_t dev; 790 ohci_state_t *ohcip; 791 int instance; 792 int error = DDI_FAILURE; 793 794 switch (infocmd) { 795 case DDI_INFO_DEVT2DEVINFO: 796 dev = (dev_t)arg; 797 instance = OHCI_UNIT(dev); 798 ohcip = ddi_get_soft_state(ohci_statep, instance); 799 if (ohcip != NULL) { 800 *result = (void *)ohcip->ohci_dip; 801 if (*result != NULL) { 802 error = DDI_SUCCESS; 803 } 804 } else { 805 *result = NULL; 806 } 807 808 break; 809 case DDI_INFO_DEVT2INSTANCE: 810 dev = (dev_t)arg; 811 instance = OHCI_UNIT(dev); 812 *result = (void *)(uintptr_t)instance; 813 error = DDI_SUCCESS; 814 break; 815 default: 816 break; 817 } 818 819 return (error); 820 } 821 822 823 /* 824 * cb_ops entry points 825 */ 826 static dev_info_t * 827 ohci_get_dip(dev_t dev) 828 { 829 int instance = OHCI_UNIT(dev); 830 ohci_state_t *ohcip = ddi_get_soft_state(ohci_statep, instance); 831 832 if (ohcip) { 833 834 return (ohcip->ohci_dip); 835 } else { 836 837 return (NULL); 838 } 839 } 840 841 842 static int 843 ohci_open(dev_t *devp, 844 int flags, 845 int otyp, 846 cred_t *credp) 847 { 848 dev_info_t *dip = ohci_get_dip(*devp); 849 850 return (usba_hubdi_open(dip, devp, flags, otyp, credp)); 851 } 852 853 854 static int 855 ohci_close(dev_t dev, 856 int flag, 857 int otyp, 858 cred_t *credp) 859 { 860 dev_info_t *dip = ohci_get_dip(dev); 861 862 return (usba_hubdi_close(dip, dev, flag, otyp, credp)); 863 } 864 865 866 static int 867 ohci_ioctl(dev_t dev, 868 int cmd, 869 intptr_t arg, 870 int mode, 871 cred_t *credp, 872 int *rvalp) 873 { 874 dev_info_t *dip = ohci_get_dip(dev); 875 876 return (usba_hubdi_ioctl(dip, 877 dev, cmd, arg, mode, credp, rvalp)); 878 } 879 880 881 /* 882 * Host Controller Driver (HCD) initialization functions 883 */ 884 885 /* 886 * ohci_set_dma_attributes: 887 * 888 * Set the limits in the DMA attributes structure. Most of the values used 889 * in the DMA limit structres are the default values as specified by the 890 * Writing PCI device drivers document. 891 */ 892 static void 893 ohci_set_dma_attributes(ohci_state_t *ohcip) 894 { 895 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 896 "ohci_set_dma_attributes:"); 897 898 /* Initialize the DMA attributes */ 899 ohcip->ohci_dma_attr.dma_attr_version = DMA_ATTR_V0; 900 ohcip->ohci_dma_attr.dma_attr_addr_lo = 0x00000000ull; 901 ohcip->ohci_dma_attr.dma_attr_addr_hi = 0xfffffffeull; 902 903 /* 32 bit addressing */ 904 ohcip->ohci_dma_attr.dma_attr_count_max = OHCI_DMA_ATTR_COUNT_MAX; 905 906 /* Byte alignment */ 907 ohcip->ohci_dma_attr.dma_attr_align = OHCI_DMA_ATTR_ALIGNMENT; 908 909 /* 910 * Since PCI specification is byte alignment, the 911 * burstsize field should be set to 1 for PCI devices. 912 */ 913 ohcip->ohci_dma_attr.dma_attr_burstsizes = 0x1; 914 915 ohcip->ohci_dma_attr.dma_attr_minxfer = 0x1; 916 ohcip->ohci_dma_attr.dma_attr_maxxfer = OHCI_DMA_ATTR_MAX_XFER; 917 ohcip->ohci_dma_attr.dma_attr_seg = 0xffffffffull; 918 ohcip->ohci_dma_attr.dma_attr_sgllen = 1; 919 ohcip->ohci_dma_attr.dma_attr_granular = OHCI_DMA_ATTR_GRANULAR; 920 ohcip->ohci_dma_attr.dma_attr_flags = 0; 921 } 922 923 924 /* 925 * ohci_allocate_pools: 926 * 927 * Allocate the system memory for the Endpoint Descriptor (ED) and for the 928 * Transfer Descriptor (TD) pools. Both ED and TD structures must be aligned 929 * to a 16 byte boundary. 930 */ 931 static int 932 ohci_allocate_pools(ohci_state_t *ohcip) 933 { 934 ddi_device_acc_attr_t dev_attr; 935 size_t real_length; 936 int result; 937 uint_t ccount; 938 int i; 939 940 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 941 "ohci_allocate_pools:"); 942 943 /* The host controller will be little endian */ 944 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 945 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 946 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 947 948 /* Byte alignment to TD alignment */ 949 ohcip->ohci_dma_attr.dma_attr_align = OHCI_DMA_ATTR_TD_ALIGNMENT; 950 951 /* Allocate the TD pool DMA handle */ 952 if (ddi_dma_alloc_handle(ohcip->ohci_dip, &ohcip->ohci_dma_attr, 953 DDI_DMA_SLEEP, 0, 954 &ohcip->ohci_td_pool_dma_handle) != DDI_SUCCESS) { 955 956 return (DDI_FAILURE); 957 } 958 959 /* Allocate the memory for the TD pool */ 960 if (ddi_dma_mem_alloc(ohcip->ohci_td_pool_dma_handle, 961 ohci_td_pool_size * sizeof (ohci_td_t), 962 &dev_attr, 963 DDI_DMA_CONSISTENT, 964 DDI_DMA_SLEEP, 965 0, 966 (caddr_t *)&ohcip->ohci_td_pool_addr, 967 &real_length, 968 &ohcip->ohci_td_pool_mem_handle)) { 969 970 return (DDI_FAILURE); 971 } 972 973 /* Map the TD pool into the I/O address space */ 974 result = ddi_dma_addr_bind_handle( 975 ohcip->ohci_td_pool_dma_handle, 976 NULL, 977 (caddr_t)ohcip->ohci_td_pool_addr, 978 real_length, 979 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 980 DDI_DMA_SLEEP, 981 NULL, 982 &ohcip->ohci_td_pool_cookie, 983 &ccount); 984 985 bzero((void *)ohcip->ohci_td_pool_addr, 986 ohci_td_pool_size * sizeof (ohci_td_t)); 987 988 /* Process the result */ 989 if (result == DDI_DMA_MAPPED) { 990 /* The cookie count should be 1 */ 991 if (ccount != 1) { 992 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 993 "ohci_allocate_pools: More than 1 cookie"); 994 995 return (DDI_FAILURE); 996 } 997 } else { 998 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 999 "ohci_allocate_pools: Result = %d", result); 1000 1001 ohci_decode_ddi_dma_addr_bind_handle_result(ohcip, result); 1002 1003 return (DDI_FAILURE); 1004 } 1005 1006 /* 1007 * DMA addresses for TD pools are bound 1008 */ 1009 ohcip->ohci_dma_addr_bind_flag |= OHCI_TD_POOL_BOUND; 1010 1011 /* Initialize the TD pool */ 1012 for (i = 0; i < ohci_td_pool_size; i ++) { 1013 Set_TD(ohcip->ohci_td_pool_addr[i].hctd_state, HC_TD_FREE); 1014 } 1015 1016 /* Byte alignment to ED alignment */ 1017 ohcip->ohci_dma_attr.dma_attr_align = OHCI_DMA_ATTR_ED_ALIGNMENT; 1018 1019 /* Allocate the ED pool DMA handle */ 1020 if (ddi_dma_alloc_handle(ohcip->ohci_dip, 1021 &ohcip->ohci_dma_attr, 1022 DDI_DMA_SLEEP, 1023 0, 1024 &ohcip->ohci_ed_pool_dma_handle) != DDI_SUCCESS) { 1025 1026 return (DDI_FAILURE); 1027 } 1028 1029 /* Allocate the memory for the ED pool */ 1030 if (ddi_dma_mem_alloc(ohcip->ohci_ed_pool_dma_handle, 1031 ohci_ed_pool_size * sizeof (ohci_ed_t), 1032 &dev_attr, 1033 DDI_DMA_CONSISTENT, 1034 DDI_DMA_SLEEP, 1035 0, 1036 (caddr_t *)&ohcip->ohci_ed_pool_addr, 1037 &real_length, 1038 &ohcip->ohci_ed_pool_mem_handle) != DDI_SUCCESS) { 1039 1040 return (DDI_FAILURE); 1041 } 1042 1043 result = ddi_dma_addr_bind_handle(ohcip->ohci_ed_pool_dma_handle, 1044 NULL, 1045 (caddr_t)ohcip->ohci_ed_pool_addr, 1046 real_length, 1047 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1048 DDI_DMA_SLEEP, 1049 NULL, 1050 &ohcip->ohci_ed_pool_cookie, 1051 &ccount); 1052 1053 bzero((void *)ohcip->ohci_ed_pool_addr, 1054 ohci_ed_pool_size * sizeof (ohci_ed_t)); 1055 1056 /* Process the result */ 1057 if (result == DDI_DMA_MAPPED) { 1058 /* The cookie count should be 1 */ 1059 if (ccount != 1) { 1060 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1061 "ohci_allocate_pools: More than 1 cookie"); 1062 1063 return (DDI_FAILURE); 1064 } 1065 } else { 1066 ohci_decode_ddi_dma_addr_bind_handle_result(ohcip, result); 1067 1068 return (DDI_FAILURE); 1069 } 1070 1071 /* 1072 * DMA addresses for ED pools are bound 1073 */ 1074 ohcip->ohci_dma_addr_bind_flag |= OHCI_ED_POOL_BOUND; 1075 1076 /* Initialize the ED pool */ 1077 for (i = 0; i < ohci_ed_pool_size; i ++) { 1078 Set_ED(ohcip->ohci_ed_pool_addr[i].hced_state, HC_EPT_FREE); 1079 } 1080 1081 return (DDI_SUCCESS); 1082 } 1083 1084 1085 /* 1086 * ohci_decode_ddi_dma_addr_bind_handle_result: 1087 * 1088 * Process the return values of ddi_dma_addr_bind_handle() 1089 */ 1090 static void 1091 ohci_decode_ddi_dma_addr_bind_handle_result( 1092 ohci_state_t *ohcip, 1093 int result) 1094 { 1095 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 1096 "ohci_decode_ddi_dma_addr_bind_handle_result:"); 1097 1098 switch (result) { 1099 case DDI_DMA_PARTIAL_MAP: 1100 USB_DPRINTF_L2(PRINT_MASK_ALL, ohcip->ohci_log_hdl, 1101 "Partial transfers not allowed"); 1102 break; 1103 case DDI_DMA_INUSE: 1104 USB_DPRINTF_L2(PRINT_MASK_ALL, ohcip->ohci_log_hdl, 1105 "Handle is in use"); 1106 break; 1107 case DDI_DMA_NORESOURCES: 1108 USB_DPRINTF_L2(PRINT_MASK_ALL, ohcip->ohci_log_hdl, 1109 "No resources"); 1110 break; 1111 case DDI_DMA_NOMAPPING: 1112 USB_DPRINTF_L2(PRINT_MASK_ALL, ohcip->ohci_log_hdl, 1113 "No mapping"); 1114 break; 1115 case DDI_DMA_TOOBIG: 1116 USB_DPRINTF_L2(PRINT_MASK_ALL, ohcip->ohci_log_hdl, 1117 "Object is too big"); 1118 break; 1119 default: 1120 USB_DPRINTF_L2(PRINT_MASK_ALL, ohcip->ohci_log_hdl, 1121 "Unknown dma error"); 1122 } 1123 } 1124 1125 1126 /* 1127 * ohci_map_regs: 1128 * 1129 * The Host Controller (HC) contains a set of on-chip operational registers 1130 * and which should be mapped into a non-cacheable portion of the system 1131 * addressable space. 1132 */ 1133 static int 1134 ohci_map_regs(ohci_state_t *ohcip) 1135 { 1136 ddi_device_acc_attr_t attr; 1137 uint16_t cmd_reg; 1138 1139 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_map_regs:"); 1140 1141 /* The host controller will be little endian */ 1142 attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 1143 attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 1144 attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 1145 1146 /* Map in operational registers */ 1147 if (ddi_regs_map_setup(ohcip->ohci_dip, 1, 1148 (caddr_t *)&ohcip->ohci_regsp, 0, 1149 sizeof (ohci_regs_t), &attr, 1150 &ohcip->ohci_regs_handle) != DDI_SUCCESS) { 1151 1152 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1153 "ohci_map_regs: Map setup error"); 1154 1155 return (DDI_FAILURE); 1156 } 1157 1158 if (pci_config_setup(ohcip->ohci_dip, 1159 &ohcip->ohci_config_handle) != DDI_SUCCESS) { 1160 1161 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1162 "ohci_map_regs: Config error"); 1163 1164 return (DDI_FAILURE); 1165 } 1166 1167 /* Make sure Memory Access Enable and Master Enable are set */ 1168 cmd_reg = pci_config_get16(ohcip->ohci_config_handle, PCI_CONF_COMM); 1169 1170 if (!(cmd_reg & PCI_COMM_MAE)) { 1171 1172 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1173 "ohci_map_regs: Memory base address access disabled"); 1174 1175 return (DDI_FAILURE); 1176 } 1177 1178 cmd_reg |= (PCI_COMM_MAE | PCI_COMM_ME); 1179 1180 pci_config_put16(ohcip->ohci_config_handle, PCI_CONF_COMM, cmd_reg); 1181 1182 return (DDI_SUCCESS); 1183 } 1184 1185 1186 /* 1187 * ohci_register_intrs_and_init_mutex: 1188 * 1189 * Register interrupts and initialize each mutex and condition variables 1190 */ 1191 static int 1192 ohci_register_intrs_and_init_mutex(ohci_state_t *ohcip) 1193 { 1194 int intr_types; 1195 1196 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1197 "ohci_register_intrs_and_init_mutex:"); 1198 1199 /* Get supported interrupt types */ 1200 if (ddi_intr_get_supported_types(ohcip->ohci_dip, 1201 &intr_types) != DDI_SUCCESS) { 1202 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1203 "ohci_register_intrs_and_init_mutex: " 1204 "ddi_intr_get_supported_types failed"); 1205 1206 return (DDI_FAILURE); 1207 } 1208 1209 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1210 "ohci_register_intrs_and_init_mutex: " 1211 "supported interrupt types 0x%x", intr_types); 1212 1213 if ((intr_types & DDI_INTR_TYPE_MSI) && ohci_enable_msi) { 1214 if (ohci_add_intrs(ohcip, DDI_INTR_TYPE_MSI) 1215 != DDI_SUCCESS) { 1216 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1217 "ohci_register_intrs_and_init_mutex: MSI " 1218 "registration failed, trying FIXED interrupt \n"); 1219 } else { 1220 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1221 "ohci_register_intrs_and_init_mutex: " 1222 "Using MSI interrupt type\n"); 1223 1224 ohcip->ohci_intr_type = DDI_INTR_TYPE_MSI; 1225 ohcip->ohci_flags |= OHCI_INTR; 1226 } 1227 } 1228 1229 if ((!(ohcip->ohci_flags & OHCI_INTR)) && 1230 (intr_types & DDI_INTR_TYPE_FIXED)) { 1231 if (ohci_add_intrs(ohcip, DDI_INTR_TYPE_FIXED) 1232 != DDI_SUCCESS) { 1233 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1234 "ohci_register_intrs_and_init_mutex: " 1235 "FIXED interrupt registration failed\n"); 1236 1237 return (DDI_FAILURE); 1238 } 1239 1240 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1241 "ohci_register_intrs_and_init_mutex: " 1242 "Using FIXED interrupt type\n"); 1243 1244 ohcip->ohci_intr_type = DDI_INTR_TYPE_FIXED; 1245 ohcip->ohci_flags |= OHCI_INTR; 1246 } 1247 1248 /* Create prototype for SOF condition variable */ 1249 cv_init(&ohcip->ohci_SOF_cv, NULL, CV_DRIVER, NULL); 1250 1251 /* Semaphore to serialize opens and closes */ 1252 sema_init(&ohcip->ohci_ocsem, 1, NULL, SEMA_DRIVER, NULL); 1253 1254 return (DDI_SUCCESS); 1255 } 1256 1257 1258 /* 1259 * ohci_add_intrs: 1260 * 1261 * Register FIXED or MSI interrupts. 1262 */ 1263 static int 1264 ohci_add_intrs(ohci_state_t *ohcip, 1265 int intr_type) 1266 { 1267 int actual, avail, intr_size, count = 0; 1268 int i, flag, ret; 1269 1270 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1271 "ohci_add_intrs: interrupt type 0x%x", intr_type); 1272 1273 /* Get number of interrupts */ 1274 ret = ddi_intr_get_nintrs(ohcip->ohci_dip, intr_type, &count); 1275 if ((ret != DDI_SUCCESS) || (count == 0)) { 1276 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1277 "ohci_add_intrs: ddi_intr_get_nintrs() failure, " 1278 "ret: %d, count: %d", ret, count); 1279 1280 return (DDI_FAILURE); 1281 } 1282 1283 /* Get number of available interrupts */ 1284 ret = ddi_intr_get_navail(ohcip->ohci_dip, intr_type, &avail); 1285 if ((ret != DDI_SUCCESS) || (avail == 0)) { 1286 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1287 "ohci_add_intrs: ddi_intr_get_navail() failure, " 1288 "ret: %d, count: %d", ret, count); 1289 1290 return (DDI_FAILURE); 1291 } 1292 1293 if (avail < count) { 1294 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1295 "ohci_add_intrs: ohci_add_intrs: nintrs () " 1296 "returned %d, navail returned %d\n", count, avail); 1297 } 1298 1299 /* Allocate an array of interrupt handles */ 1300 intr_size = count * sizeof (ddi_intr_handle_t); 1301 ohcip->ohci_htable = kmem_zalloc(intr_size, KM_SLEEP); 1302 1303 flag = (intr_type == DDI_INTR_TYPE_MSI) ? 1304 DDI_INTR_ALLOC_STRICT:DDI_INTR_ALLOC_NORMAL; 1305 1306 /* call ddi_intr_alloc() */ 1307 ret = ddi_intr_alloc(ohcip->ohci_dip, ohcip->ohci_htable, 1308 intr_type, 0, count, &actual, flag); 1309 1310 if ((ret != DDI_SUCCESS) || (actual == 0)) { 1311 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1312 "ohci_add_intrs: ddi_intr_alloc() failed %d", ret); 1313 1314 kmem_free(ohcip->ohci_htable, intr_size); 1315 1316 return (DDI_FAILURE); 1317 } 1318 1319 if (actual < count) { 1320 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1321 "ohci_add_intrs: Requested: %d, Received: %d\n", 1322 count, actual); 1323 1324 for (i = 0; i < actual; i++) 1325 (void) ddi_intr_free(ohcip->ohci_htable[i]); 1326 1327 kmem_free(ohcip->ohci_htable, intr_size); 1328 1329 return (DDI_FAILURE); 1330 } 1331 1332 ohcip->ohci_intr_cnt = actual; 1333 1334 if ((ret = ddi_intr_get_pri(ohcip->ohci_htable[0], 1335 &ohcip->ohci_intr_pri)) != DDI_SUCCESS) { 1336 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1337 "ohci_add_intrs: ddi_intr_get_pri() failed %d", ret); 1338 1339 for (i = 0; i < actual; i++) 1340 (void) ddi_intr_free(ohcip->ohci_htable[i]); 1341 1342 kmem_free(ohcip->ohci_htable, intr_size); 1343 1344 return (DDI_FAILURE); 1345 } 1346 1347 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1348 "ohci_add_intrs: Supported Interrupt priority 0x%x", 1349 ohcip->ohci_intr_pri); 1350 1351 /* Test for high level mutex */ 1352 if (ohcip->ohci_intr_pri >= ddi_intr_get_hilevel_pri()) { 1353 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1354 "ohci_add_intrs: Hi level interrupt not supported"); 1355 1356 for (i = 0; i < actual; i++) 1357 (void) ddi_intr_free(ohcip->ohci_htable[i]); 1358 1359 kmem_free(ohcip->ohci_htable, intr_size); 1360 1361 return (DDI_FAILURE); 1362 } 1363 1364 /* Initialize the mutex */ 1365 mutex_init(&ohcip->ohci_int_mutex, NULL, MUTEX_DRIVER, 1366 DDI_INTR_PRI(ohcip->ohci_intr_pri)); 1367 1368 /* Call ddi_intr_add_handler() */ 1369 for (i = 0; i < actual; i++) { 1370 if ((ret = ddi_intr_add_handler(ohcip->ohci_htable[i], 1371 ohci_intr, (caddr_t)ohcip, 1372 (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) { 1373 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1374 "ohci_add_intrs: ddi_intr_add_handler() " 1375 "failed %d", ret); 1376 1377 for (i = 0; i < actual; i++) 1378 (void) ddi_intr_free(ohcip->ohci_htable[i]); 1379 1380 mutex_destroy(&ohcip->ohci_int_mutex); 1381 kmem_free(ohcip->ohci_htable, intr_size); 1382 1383 return (DDI_FAILURE); 1384 } 1385 } 1386 1387 if ((ret = ddi_intr_get_cap(ohcip->ohci_htable[0], 1388 &ohcip->ohci_intr_cap)) != DDI_SUCCESS) { 1389 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1390 "ohci_add_intrs: ddi_intr_get_cap() failed %d", ret); 1391 1392 for (i = 0; i < actual; i++) { 1393 (void) ddi_intr_remove_handler(ohcip->ohci_htable[i]); 1394 (void) ddi_intr_free(ohcip->ohci_htable[i]); 1395 } 1396 1397 mutex_destroy(&ohcip->ohci_int_mutex); 1398 kmem_free(ohcip->ohci_htable, intr_size); 1399 1400 return (DDI_FAILURE); 1401 } 1402 1403 /* Enable all interrupts */ 1404 if (ohcip->ohci_intr_cap & DDI_INTR_FLAG_BLOCK) { 1405 /* Call ddi_intr_block_enable() for MSI interrupts */ 1406 (void) ddi_intr_block_enable(ohcip->ohci_htable, 1407 ohcip->ohci_intr_cnt); 1408 } else { 1409 /* Call ddi_intr_enable for MSI or FIXED interrupts */ 1410 for (i = 0; i < ohcip->ohci_intr_cnt; i++) 1411 (void) ddi_intr_enable(ohcip->ohci_htable[i]); 1412 } 1413 1414 return (DDI_SUCCESS); 1415 } 1416 1417 1418 /* 1419 * ohci_init_ctlr: 1420 * 1421 * Initialize the Host Controller (HC). 1422 */ 1423 static int 1424 ohci_init_ctlr(ohci_state_t *ohcip) 1425 { 1426 int revision, curr_control, max_packet = 0; 1427 clock_t sof_time_wait; 1428 1429 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_init_ctlr:"); 1430 1431 if (ohci_take_control(ohcip) != DDI_SUCCESS) { 1432 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1433 "ohci_init_ctlr: ohci_take_control failed\n"); 1434 1435 return (DDI_FAILURE); 1436 } 1437 1438 /* 1439 * Soft reset the host controller. 1440 * 1441 * On soft reset, the ohci host controller moves to the 1442 * USB Suspend state in which most of the ohci operational 1443 * registers are reset except stated ones. The soft reset 1444 * doesn't cause a reset to the ohci root hub and even no 1445 * subsequent reset signaling should be asserterd to its 1446 * down stream. 1447 */ 1448 Set_OpReg(hcr_cmd_status, HCR_STATUS_RESET); 1449 1450 /* Wait 10ms for reset to complete */ 1451 drv_usecwait(OHCI_RESET_TIMEWAIT); 1452 1453 /* 1454 * Do hard reset the host controller. 1455 * 1456 * Now perform USB reset in order to reset the ohci root 1457 * hub. 1458 */ 1459 Set_OpReg(hcr_control, HCR_CONTROL_RESET); 1460 1461 /* 1462 * According to Section 5.1.2.3 of the specification, the 1463 * host controller will go into suspend state immediately 1464 * after the reset. 1465 */ 1466 1467 /* Verify the version number */ 1468 revision = Get_OpReg(hcr_revision); 1469 1470 if ((revision & HCR_REVISION_MASK) != HCR_REVISION_1_0) { 1471 1472 return (DDI_FAILURE); 1473 } 1474 1475 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1476 "ohci_init_ctlr: Revision verified"); 1477 1478 /* hcca area need not be initialized on resume */ 1479 if (ohcip->ohci_hc_soft_state == OHCI_CTLR_INIT_STATE) { 1480 1481 /* Get the ohci chip vendor and device id */ 1482 ohcip->ohci_vendor_id = pci_config_get16( 1483 ohcip->ohci_config_handle, PCI_CONF_VENID); 1484 ohcip->ohci_device_id = pci_config_get16( 1485 ohcip->ohci_config_handle, PCI_CONF_DEVID); 1486 ohcip->ohci_rev_id = pci_config_get8( 1487 ohcip->ohci_config_handle, PCI_CONF_REVID); 1488 1489 /* Initialize the hcca area */ 1490 if (ohci_init_hcca(ohcip) != DDI_SUCCESS) { 1491 1492 return (DDI_FAILURE); 1493 } 1494 } 1495 1496 /* 1497 * Workaround for ULI1575 chipset. Following OHCI Operational Memory 1498 * Registers are not cleared to their default value on reset. 1499 * Explicitly set the registers to default value. 1500 */ 1501 if (ohcip->ohci_vendor_id == PCI_ULI1575_VENID && 1502 ohcip->ohci_device_id == PCI_ULI1575_DEVID) { 1503 Set_OpReg(hcr_control, HCR_CONTROL_DEFAULT); 1504 Set_OpReg(hcr_intr_enable, HCR_INT_ENABLE_DEFAULT); 1505 Set_OpReg(hcr_HCCA, HCR_HCCA_DEFAULT); 1506 Set_OpReg(hcr_ctrl_head, HCR_CONTROL_HEAD_ED_DEFAULT); 1507 Set_OpReg(hcr_bulk_head, HCR_BULK_HEAD_ED_DEFAULT); 1508 Set_OpReg(hcr_frame_interval, HCR_FRAME_INTERVAL_DEFAULT); 1509 Set_OpReg(hcr_periodic_strt, HCR_PERIODIC_START_DEFAULT); 1510 } 1511 1512 /* Set the HcHCCA to the physical address of the HCCA block */ 1513 Set_OpReg(hcr_HCCA, (uint_t)ohcip->ohci_hcca_cookie.dmac_address); 1514 1515 /* 1516 * Set HcInterruptEnable to enable all interrupts except Root 1517 * Hub Status change and SOF interrupts. 1518 */ 1519 Set_OpReg(hcr_intr_enable, HCR_INTR_SO | HCR_INTR_WDH | 1520 HCR_INTR_RD | HCR_INTR_UE | HCR_INTR_FNO | HCR_INTR_MIE); 1521 1522 /* 1523 * For non-periodic transfers, reserve atleast for one low-speed 1524 * device transaction. According to USB Bandwidth Analysis white 1525 * paper and also as per OHCI Specification 1.0a, section 7.3.5, 1526 * page 123, one low-speed transaction takes 0x628h full speed 1527 * bits (197 bytes), which comes to around 13% of USB frame time. 1528 * 1529 * The periodic transfers will get around 87% of USB frame time. 1530 */ 1531 Set_OpReg(hcr_periodic_strt, 1532 ((PERIODIC_XFER_STARTS * BITS_PER_BYTE) - 1)); 1533 1534 /* Save the contents of the Frame Interval Registers */ 1535 ohcip->ohci_frame_interval = Get_OpReg(hcr_frame_interval); 1536 1537 /* 1538 * Initialize the FSLargestDataPacket value in the frame interval 1539 * register. The controller compares the value of MaxPacketSize to 1540 * this value to see if the entire packet may be sent out before 1541 * the EOF. 1542 */ 1543 max_packet = ((((ohcip->ohci_frame_interval - 1544 MAX_OVERHEAD) * 6) / 7) << HCR_FRME_FSMPS_SHFT); 1545 1546 Set_OpReg(hcr_frame_interval, 1547 (max_packet | ohcip->ohci_frame_interval)); 1548 1549 /* Begin sending SOFs */ 1550 curr_control = Get_OpReg(hcr_control); 1551 1552 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1553 "ohci_init_ctlr: curr_control=0x%x", curr_control); 1554 1555 /* Set the state to operational */ 1556 curr_control = (curr_control & 1557 (~HCR_CONTROL_HCFS)) | HCR_CONTROL_OPERAT; 1558 1559 Set_OpReg(hcr_control, curr_control); 1560 1561 ASSERT((Get_OpReg(hcr_control) & 1562 HCR_CONTROL_HCFS) == HCR_CONTROL_OPERAT); 1563 1564 /* Set host controller soft state to operational */ 1565 ohcip->ohci_hc_soft_state = OHCI_CTLR_OPERATIONAL_STATE; 1566 1567 /* Get the number of clock ticks to wait */ 1568 sof_time_wait = drv_usectohz(OHCI_MAX_SOF_TIMEWAIT * 1000000); 1569 1570 /* Clear ohci_sof_flag indicating waiting for SOF interrupt */ 1571 ohcip->ohci_sof_flag = B_FALSE; 1572 1573 /* Enable the SOF interrupt */ 1574 Set_OpReg(hcr_intr_enable, HCR_INTR_SOF); 1575 1576 ASSERT(Get_OpReg(hcr_intr_enable) & HCR_INTR_SOF); 1577 1578 (void) cv_timedwait(&ohcip->ohci_SOF_cv, 1579 &ohcip->ohci_int_mutex, ddi_get_lbolt() + sof_time_wait); 1580 1581 /* Wait for the SOF or timeout event */ 1582 if (ohcip->ohci_sof_flag == B_FALSE) { 1583 1584 /* Set host controller soft state to error */ 1585 ohcip->ohci_hc_soft_state = OHCI_CTLR_ERROR_STATE; 1586 1587 USB_DPRINTF_L0(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1588 "No SOF interrupts have been received, this USB OHCI host" 1589 "controller is unusable"); 1590 return (DDI_FAILURE); 1591 } 1592 1593 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1594 "ohci_init_ctlr: SOF's have started"); 1595 1596 return (DDI_SUCCESS); 1597 } 1598 1599 1600 /* 1601 * ohci_init_hcca: 1602 * 1603 * Allocate the system memory and initialize Host Controller Communication 1604 * Area (HCCA). The HCCA structure must be aligned to a 256-byte boundary. 1605 */ 1606 static int 1607 ohci_init_hcca(ohci_state_t *ohcip) 1608 { 1609 ddi_device_acc_attr_t dev_attr; 1610 size_t real_length; 1611 uint_t mask, ccount; 1612 int result; 1613 uintptr_t addr; 1614 1615 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 1616 1617 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_init_hcca:"); 1618 1619 /* The host controller will be little endian */ 1620 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 1621 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 1622 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 1623 1624 /* Byte alignment to HCCA alignment */ 1625 ohcip->ohci_dma_attr.dma_attr_align = OHCI_DMA_ATTR_HCCA_ALIGNMENT; 1626 1627 /* Create space for the HCCA block */ 1628 if (ddi_dma_alloc_handle(ohcip->ohci_dip, &ohcip->ohci_dma_attr, 1629 DDI_DMA_SLEEP, 1630 0, 1631 &ohcip->ohci_hcca_dma_handle) 1632 != DDI_SUCCESS) { 1633 1634 return (DDI_FAILURE); 1635 } 1636 1637 if (ddi_dma_mem_alloc(ohcip->ohci_hcca_dma_handle, 1638 2 * sizeof (ohci_hcca_t), 1639 &dev_attr, 1640 DDI_DMA_CONSISTENT, 1641 DDI_DMA_SLEEP, 1642 0, 1643 (caddr_t *)&ohcip->ohci_hccap, 1644 &real_length, 1645 &ohcip->ohci_hcca_mem_handle)) { 1646 1647 return (DDI_FAILURE); 1648 } 1649 1650 bzero((void *)ohcip->ohci_hccap, real_length); 1651 1652 /* Figure out the alignment requirements */ 1653 Set_OpReg(hcr_HCCA, 0xFFFFFFFF); 1654 1655 /* 1656 * Read the hcr_HCCA register until 1657 * contenets are non-zero. 1658 */ 1659 mask = Get_OpReg(hcr_HCCA); 1660 1661 while (mask == 0) { 1662 drv_usecwait(OHCI_TIMEWAIT); 1663 mask = Get_OpReg(hcr_HCCA); 1664 } 1665 1666 ASSERT(mask != 0); 1667 1668 addr = (uintptr_t)ohcip->ohci_hccap; 1669 1670 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1671 "ohci_init_hcca: addr=0x%lx, mask=0x%x", addr, mask); 1672 1673 while (addr & (~mask)) { 1674 addr++; 1675 } 1676 1677 ohcip->ohci_hccap = (ohci_hcca_t *)addr; 1678 1679 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1680 "ohci_init_hcca: Real length %lu", real_length); 1681 1682 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1683 "ohci_init_hcca: virtual hcca 0x%p", (void *)ohcip->ohci_hccap); 1684 1685 /* Map the whole HCCA into the I/O address space */ 1686 result = ddi_dma_addr_bind_handle(ohcip->ohci_hcca_dma_handle, 1687 NULL, 1688 (caddr_t)ohcip->ohci_hccap, 1689 real_length, 1690 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1691 DDI_DMA_SLEEP, NULL, 1692 &ohcip->ohci_hcca_cookie, 1693 &ccount); 1694 1695 if (result == DDI_DMA_MAPPED) { 1696 /* The cookie count should be 1 */ 1697 if (ccount != 1) { 1698 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1699 "ohci_init_hcca: More than 1 cookie"); 1700 1701 return (DDI_FAILURE); 1702 } 1703 } else { 1704 ohci_decode_ddi_dma_addr_bind_handle_result(ohcip, result); 1705 1706 return (DDI_FAILURE); 1707 } 1708 1709 /* 1710 * DMA addresses for HCCA are bound 1711 */ 1712 ohcip->ohci_dma_addr_bind_flag |= OHCI_HCCA_DMA_BOUND; 1713 1714 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1715 "ohci_init_hcca: physical 0x%p", 1716 (void *)(uintptr_t)ohcip->ohci_hcca_cookie.dmac_address); 1717 1718 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1719 "ohci_init_hcca: size %lu", ohcip->ohci_hcca_cookie.dmac_size); 1720 1721 /* Initialize the interrupt lists */ 1722 ohci_build_interrupt_lattice(ohcip); 1723 1724 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1725 "ohci_init_hcca: End"); 1726 1727 return (DDI_SUCCESS); 1728 } 1729 1730 1731 /* 1732 * ohci_build_interrupt_lattice: 1733 * 1734 * Construct the interrupt lattice tree using static Endpoint Descriptors 1735 * (ED). This interrupt lattice tree will have total of 32 interrupt ED 1736 * lists and the Host Controller (HC) processes one interrupt ED list in 1737 * every frame. The lower five bits of the current frame number indexes 1738 * into an array of 32 interrupt Endpoint Descriptor lists found in the 1739 * HCCA. 1740 */ 1741 static void 1742 ohci_build_interrupt_lattice(ohci_state_t *ohcip) 1743 { 1744 ohci_ed_t *list_array = ohcip->ohci_ed_pool_addr; 1745 int half_list = NUM_INTR_ED_LISTS / 2; 1746 ohci_hcca_t *hccap = ohcip->ohci_hccap; 1747 uintptr_t addr; 1748 int i; 1749 1750 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1751 "ohci_build_interrupt_lattice:"); 1752 1753 /* 1754 * Reserve the first 31 Endpoint Descriptor (ED) structures 1755 * in the pool as static endpoints & these are required for 1756 * constructing interrupt lattice tree. 1757 */ 1758 for (i = 0; i < NUM_STATIC_NODES; i++) { 1759 Set_ED(list_array[i].hced_ctrl, HC_EPT_sKip); 1760 1761 Set_ED(list_array[i].hced_state, HC_EPT_STATIC); 1762 } 1763 1764 /* Build the interrupt lattice tree */ 1765 for (i = 0; i < half_list - 1; i++) { 1766 1767 /* 1768 * The next pointer in the host controller endpoint 1769 * descriptor must contain an iommu address. Calculate 1770 * the offset into the cpu address and add this to the 1771 * starting iommu address. 1772 */ 1773 addr = ohci_ed_cpu_to_iommu(ohcip, (ohci_ed_t *)&list_array[i]); 1774 1775 Set_ED(list_array[2*i + 1].hced_next, addr); 1776 Set_ED(list_array[2*i + 2].hced_next, addr); 1777 } 1778 1779 /* 1780 * Initialize the interrupt list in the HCCA so that it points 1781 * to the bottom of the tree. 1782 */ 1783 for (i = 0; i < half_list; i++) { 1784 addr = ohci_ed_cpu_to_iommu(ohcip, 1785 (ohci_ed_t *)&list_array[half_list - 1 + ohci_index[i]]); 1786 1787 ASSERT(Get_ED(list_array[half_list - 1 + 1788 ohci_index[i]].hced_ctrl)); 1789 1790 ASSERT(addr != 0); 1791 1792 Set_HCCA(hccap->HccaIntTble[i], addr); 1793 Set_HCCA(hccap->HccaIntTble[i + half_list], addr); 1794 } 1795 } 1796 1797 1798 /* 1799 * ohci_take_control: 1800 * 1801 * Take control of the host controller. OpenHCI allows for optional support 1802 * of legacy devices through the use of System Management Mode software and 1803 * system Management interrupt hardware. See section 5.1.1.3 of the OpenHCI 1804 * spec for more details. 1805 */ 1806 static int 1807 ohci_take_control(ohci_state_t *ohcip) 1808 { 1809 #if defined(__x86) 1810 uint32_t hcr_control_val; 1811 uint32_t hcr_cmd_status_val; 1812 int wait; 1813 #endif /* __x86 */ 1814 1815 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1816 "ohci_take_control:"); 1817 1818 #if defined(__x86) 1819 /* 1820 * On x86, we must tell the BIOS we want the controller, 1821 * and wait for it to respond that we can have it. 1822 */ 1823 hcr_control_val = Get_OpReg(hcr_control); 1824 if ((hcr_control_val & HCR_CONTROL_IR) == 0) { 1825 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1826 "ohci_take_control: InterruptRouting off\n"); 1827 1828 return (DDI_SUCCESS); 1829 } 1830 1831 /* attempt the OwnershipChange request */ 1832 hcr_cmd_status_val = Get_OpReg(hcr_cmd_status); 1833 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1834 "ohci_take_control: hcr_cmd_status: 0x%x\n", 1835 hcr_cmd_status_val); 1836 hcr_cmd_status_val |= HCR_STATUS_OCR; 1837 1838 Set_OpReg(hcr_cmd_status, hcr_cmd_status_val); 1839 1840 /* now wait for 5 seconds for InterruptRouting to go away */ 1841 for (wait = 0; wait < 5000; wait++) { 1842 if ((Get_OpReg(hcr_control) & HCR_CONTROL_IR) == 0) 1843 break; 1844 drv_usecwait(1000); 1845 } 1846 if (wait >= 5000) { 1847 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1848 "ohci_take_control: couldn't take control from BIOS\n"); 1849 1850 return (DDI_FAILURE); 1851 } 1852 #else /* __x86 */ 1853 /* 1854 * On Sparc, there won't be special System Management Mode 1855 * hardware for legacy devices, while the x86 platforms may 1856 * have to deal with this. This function may be platform 1857 * specific. 1858 * 1859 * The interrupt routing bit should not be set. 1860 */ 1861 if (Get_OpReg(hcr_control) & HCR_CONTROL_IR) { 1862 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1863 "ohci_take_control: Routing bit set"); 1864 1865 return (DDI_FAILURE); 1866 } 1867 #endif /* __x86 */ 1868 1869 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1870 "ohci_take_control: End"); 1871 1872 return (DDI_SUCCESS); 1873 } 1874 1875 /* 1876 * ohci_pm_support: 1877 * always return success since PM has been quite reliable on ohci 1878 */ 1879 /*ARGSUSED*/ 1880 int 1881 ohci_hcdi_pm_support(dev_info_t *dip) 1882 { 1883 return (USB_SUCCESS); 1884 } 1885 1886 /* 1887 * ohci_alloc_hcdi_ops: 1888 * 1889 * The HCDI interfaces or entry points are the software interfaces used by 1890 * the Universal Serial Bus Driver (USBA) to access the services of the 1891 * Host Controller Driver (HCD). During HCD initialization, inform USBA 1892 * about all available HCDI interfaces or entry points. 1893 */ 1894 static usba_hcdi_ops_t * 1895 ohci_alloc_hcdi_ops(ohci_state_t *ohcip) 1896 { 1897 usba_hcdi_ops_t *usba_hcdi_ops; 1898 1899 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 1900 "ohci_alloc_hcdi_ops:"); 1901 1902 usba_hcdi_ops = usba_alloc_hcdi_ops(); 1903 1904 usba_hcdi_ops->usba_hcdi_ops_version = HCDI_OPS_VERSION; 1905 1906 usba_hcdi_ops->usba_hcdi_pm_support = ohci_hcdi_pm_support; 1907 usba_hcdi_ops->usba_hcdi_pipe_open = ohci_hcdi_pipe_open; 1908 usba_hcdi_ops->usba_hcdi_pipe_close = ohci_hcdi_pipe_close; 1909 1910 usba_hcdi_ops->usba_hcdi_pipe_reset = ohci_hcdi_pipe_reset; 1911 1912 usba_hcdi_ops->usba_hcdi_pipe_ctrl_xfer = ohci_hcdi_pipe_ctrl_xfer; 1913 usba_hcdi_ops->usba_hcdi_pipe_bulk_xfer = ohci_hcdi_pipe_bulk_xfer; 1914 usba_hcdi_ops->usba_hcdi_pipe_intr_xfer = ohci_hcdi_pipe_intr_xfer; 1915 usba_hcdi_ops->usba_hcdi_pipe_isoc_xfer = ohci_hcdi_pipe_isoc_xfer; 1916 1917 usba_hcdi_ops->usba_hcdi_bulk_transfer_size = 1918 ohci_hcdi_bulk_transfer_size; 1919 1920 usba_hcdi_ops->usba_hcdi_pipe_stop_intr_polling = 1921 ohci_hcdi_pipe_stop_intr_polling; 1922 usba_hcdi_ops->usba_hcdi_pipe_stop_isoc_polling = 1923 ohci_hcdi_pipe_stop_isoc_polling; 1924 1925 usba_hcdi_ops->usba_hcdi_get_current_frame_number = 1926 ohci_hcdi_get_current_frame_number; 1927 usba_hcdi_ops->usba_hcdi_get_max_isoc_pkts = 1928 ohci_hcdi_get_max_isoc_pkts; 1929 usba_hcdi_ops->usba_hcdi_console_input_init = 1930 ohci_hcdi_polled_input_init; 1931 usba_hcdi_ops->usba_hcdi_console_input_enter = 1932 ohci_hcdi_polled_input_enter; 1933 usba_hcdi_ops->usba_hcdi_console_read = ohci_hcdi_polled_read; 1934 usba_hcdi_ops->usba_hcdi_console_input_exit = 1935 ohci_hcdi_polled_input_exit; 1936 usba_hcdi_ops->usba_hcdi_console_input_fini = 1937 ohci_hcdi_polled_input_fini; 1938 1939 return (usba_hcdi_ops); 1940 } 1941 1942 1943 /* 1944 * Host Controller Driver (HCD) deinitialization functions 1945 */ 1946 1947 /* 1948 * ohci_cleanup: 1949 * 1950 * Cleanup on attach failure or detach 1951 */ 1952 static int 1953 ohci_cleanup(ohci_state_t *ohcip) 1954 { 1955 ohci_trans_wrapper_t *tw; 1956 ohci_pipe_private_t *pp; 1957 ohci_td_t *td; 1958 int i, state, rval; 1959 int flags = ohcip->ohci_flags; 1960 1961 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_cleanup:"); 1962 1963 if (flags & OHCI_RHREG) { 1964 /* Unload the root hub driver */ 1965 if (ohci_unload_root_hub_driver(ohcip) != USB_SUCCESS) { 1966 1967 return (DDI_FAILURE); 1968 } 1969 } 1970 1971 if (flags & OHCI_USBAREG) { 1972 /* Unregister this HCD instance with USBA */ 1973 usba_hcdi_unregister(ohcip->ohci_dip); 1974 } 1975 1976 if (flags & OHCI_INTR) { 1977 1978 mutex_enter(&ohcip->ohci_int_mutex); 1979 1980 /* Disable all HC ED list processing */ 1981 Set_OpReg(hcr_control, 1982 (Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE | 1983 HCR_CONTROL_BLE | HCR_CONTROL_PLE | HCR_CONTROL_IE))); 1984 1985 /* Disable all HC interrupts */ 1986 Set_OpReg(hcr_intr_disable, 1987 (HCR_INTR_SO | HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE)); 1988 1989 /* Wait for the next SOF */ 1990 (void) ohci_wait_for_sof(ohcip); 1991 1992 /* Disable Master and SOF interrupts */ 1993 Set_OpReg(hcr_intr_disable, (HCR_INTR_MIE | HCR_INTR_SOF)); 1994 1995 /* Set the Host Controller Functional State to Reset */ 1996 Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) & 1997 (~HCR_CONTROL_HCFS)) | HCR_CONTROL_RESET)); 1998 1999 /* Wait for sometime */ 2000 drv_usecwait(OHCI_TIMEWAIT); 2001 2002 /* 2003 * Workaround for ULI1575 chipset. Following OHCI Operational 2004 * Memory Registers are not cleared to their default value 2005 * on reset. Explicitly set the registers to default value. 2006 */ 2007 if (ohcip->ohci_vendor_id == PCI_ULI1575_VENID && 2008 ohcip->ohci_device_id == PCI_ULI1575_DEVID) { 2009 Set_OpReg(hcr_control, HCR_CONTROL_DEFAULT); 2010 Set_OpReg(hcr_intr_enable, HCR_INT_ENABLE_DEFAULT); 2011 Set_OpReg(hcr_HCCA, HCR_HCCA_DEFAULT); 2012 Set_OpReg(hcr_ctrl_head, HCR_CONTROL_HEAD_ED_DEFAULT); 2013 Set_OpReg(hcr_bulk_head, HCR_BULK_HEAD_ED_DEFAULT); 2014 Set_OpReg(hcr_frame_interval, 2015 HCR_FRAME_INTERVAL_DEFAULT); 2016 Set_OpReg(hcr_periodic_strt, 2017 HCR_PERIODIC_START_DEFAULT); 2018 } 2019 2020 mutex_exit(&ohcip->ohci_int_mutex); 2021 2022 ohci_rem_intrs(ohcip); 2023 } 2024 2025 /* Unmap the OHCI registers */ 2026 if (ohcip->ohci_regs_handle) { 2027 /* Reset the host controller */ 2028 Set_OpReg(hcr_cmd_status, HCR_STATUS_RESET); 2029 2030 ddi_regs_map_free(&ohcip->ohci_regs_handle); 2031 } 2032 2033 if (ohcip->ohci_config_handle) { 2034 pci_config_teardown(&ohcip->ohci_config_handle); 2035 } 2036 2037 /* Free all the buffers */ 2038 if (ohcip->ohci_td_pool_addr && ohcip->ohci_td_pool_mem_handle) { 2039 for (i = 0; i < ohci_td_pool_size; i ++) { 2040 td = &ohcip->ohci_td_pool_addr[i]; 2041 state = Get_TD(ohcip->ohci_td_pool_addr[i].hctd_state); 2042 2043 if ((state != HC_TD_FREE) && (state != HC_TD_DUMMY) && 2044 (td->hctd_trans_wrapper)) { 2045 2046 mutex_enter(&ohcip->ohci_int_mutex); 2047 2048 tw = (ohci_trans_wrapper_t *) 2049 OHCI_LOOKUP_ID((uint32_t) 2050 Get_TD(td->hctd_trans_wrapper)); 2051 2052 /* Obtain the pipe private structure */ 2053 pp = tw->tw_pipe_private; 2054 2055 /* Stop the the transfer timer */ 2056 ohci_stop_xfer_timer(ohcip, tw, 2057 OHCI_REMOVE_XFER_ALWAYS); 2058 2059 ohci_deallocate_tw_resources(ohcip, pp, tw); 2060 2061 mutex_exit(&ohcip->ohci_int_mutex); 2062 } 2063 } 2064 2065 /* 2066 * If OHCI_TD_POOL_BOUND flag is set, then unbind 2067 * the handle for TD pools. 2068 */ 2069 if ((ohcip->ohci_dma_addr_bind_flag & 2070 OHCI_TD_POOL_BOUND) == OHCI_TD_POOL_BOUND) { 2071 2072 rval = ddi_dma_unbind_handle( 2073 ohcip->ohci_td_pool_dma_handle); 2074 2075 ASSERT(rval == DDI_SUCCESS); 2076 } 2077 ddi_dma_mem_free(&ohcip->ohci_td_pool_mem_handle); 2078 } 2079 2080 /* Free the TD pool */ 2081 if (ohcip->ohci_td_pool_dma_handle) { 2082 ddi_dma_free_handle(&ohcip->ohci_td_pool_dma_handle); 2083 } 2084 2085 if (ohcip->ohci_ed_pool_addr && ohcip->ohci_ed_pool_mem_handle) { 2086 /* 2087 * If OHCI_ED_POOL_BOUND flag is set, then unbind 2088 * the handle for ED pools. 2089 */ 2090 if ((ohcip->ohci_dma_addr_bind_flag & 2091 OHCI_ED_POOL_BOUND) == OHCI_ED_POOL_BOUND) { 2092 2093 rval = ddi_dma_unbind_handle( 2094 ohcip->ohci_ed_pool_dma_handle); 2095 2096 ASSERT(rval == DDI_SUCCESS); 2097 } 2098 2099 ddi_dma_mem_free(&ohcip->ohci_ed_pool_mem_handle); 2100 } 2101 2102 /* Free the ED pool */ 2103 if (ohcip->ohci_ed_pool_dma_handle) { 2104 ddi_dma_free_handle(&ohcip->ohci_ed_pool_dma_handle); 2105 } 2106 2107 /* Free the HCCA area */ 2108 if (ohcip->ohci_hccap && ohcip->ohci_hcca_mem_handle) { 2109 /* 2110 * If OHCI_HCCA_DMA_BOUND flag is set, then unbind 2111 * the handle for HCCA. 2112 */ 2113 if ((ohcip->ohci_dma_addr_bind_flag & 2114 OHCI_HCCA_DMA_BOUND) == OHCI_HCCA_DMA_BOUND) { 2115 2116 rval = ddi_dma_unbind_handle( 2117 ohcip->ohci_hcca_dma_handle); 2118 2119 ASSERT(rval == DDI_SUCCESS); 2120 } 2121 2122 ddi_dma_mem_free(&ohcip->ohci_hcca_mem_handle); 2123 } 2124 2125 if (ohcip->ohci_hcca_dma_handle) { 2126 ddi_dma_free_handle(&ohcip->ohci_hcca_dma_handle); 2127 } 2128 2129 if (flags & OHCI_INTR) { 2130 2131 /* Destroy the mutex */ 2132 mutex_destroy(&ohcip->ohci_int_mutex); 2133 2134 /* Destroy the SOF condition varibale */ 2135 cv_destroy(&ohcip->ohci_SOF_cv); 2136 2137 /* Destroy the serialize opens and closes semaphore */ 2138 sema_destroy(&ohcip->ohci_ocsem); 2139 } 2140 2141 /* clean up kstat structs */ 2142 ohci_destroy_stats(ohcip); 2143 2144 /* Free ohci hcdi ops */ 2145 if (ohcip->ohci_hcdi_ops) { 2146 usba_free_hcdi_ops(ohcip->ohci_hcdi_ops); 2147 } 2148 2149 if (flags & OHCI_ZALLOC) { 2150 2151 usb_free_log_hdl(ohcip->ohci_log_hdl); 2152 2153 /* Remove all properties that might have been created */ 2154 ddi_prop_remove_all(ohcip->ohci_dip); 2155 2156 /* Free the soft state */ 2157 ddi_soft_state_free(ohci_statep, 2158 ddi_get_instance(ohcip->ohci_dip)); 2159 } 2160 2161 return (DDI_SUCCESS); 2162 } 2163 2164 2165 /* 2166 * ohci_rem_intrs: 2167 * 2168 * Unregister FIXED or MSI interrupts 2169 */ 2170 static void 2171 ohci_rem_intrs(ohci_state_t *ohcip) 2172 { 2173 int i; 2174 2175 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 2176 "ohci_rem_intrs: interrupt type 0x%x", ohcip->ohci_intr_type); 2177 2178 /* Disable all interrupts */ 2179 if (ohcip->ohci_intr_cap & DDI_INTR_FLAG_BLOCK) { 2180 (void) ddi_intr_block_disable(ohcip->ohci_htable, 2181 ohcip->ohci_intr_cnt); 2182 } else { 2183 for (i = 0; i < ohcip->ohci_intr_cnt; i++) { 2184 (void) ddi_intr_disable(ohcip->ohci_htable[i]); 2185 } 2186 } 2187 2188 /* Call ddi_intr_remove_handler() */ 2189 for (i = 0; i < ohcip->ohci_intr_cnt; i++) { 2190 (void) ddi_intr_remove_handler(ohcip->ohci_htable[i]); 2191 (void) ddi_intr_free(ohcip->ohci_htable[i]); 2192 } 2193 2194 kmem_free(ohcip->ohci_htable, 2195 ohcip->ohci_intr_cnt * sizeof (ddi_intr_handle_t)); 2196 } 2197 2198 2199 /* 2200 * ohci_cpr_suspend 2201 */ 2202 static int 2203 ohci_cpr_suspend(ohci_state_t *ohcip) 2204 { 2205 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 2206 "ohci_cpr_suspend:"); 2207 2208 /* Call into the root hub and suspend it */ 2209 if (usba_hubdi_detach(ohcip->ohci_dip, DDI_SUSPEND) != DDI_SUCCESS) { 2210 2211 return (DDI_FAILURE); 2212 } 2213 2214 /* Only root hub's intr pipe should be open at this time */ 2215 mutex_enter(&ohcip->ohci_int_mutex); 2216 2217 if (ohcip->ohci_open_pipe_count > 1) { 2218 2219 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 2220 "ohci_cpr_suspend: fails as open pipe count = %d", 2221 ohcip->ohci_open_pipe_count); 2222 2223 mutex_exit(&ohcip->ohci_int_mutex); 2224 2225 return (DDI_FAILURE); 2226 } 2227 2228 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 2229 "ohci_cpr_suspend: Disable HC ED list processing"); 2230 2231 /* Disable all HC ED list processing */ 2232 Set_OpReg(hcr_control, (Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE | 2233 HCR_CONTROL_BLE | HCR_CONTROL_PLE | HCR_CONTROL_IE))); 2234 2235 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 2236 "ohci_cpr_suspend: Disable HC interrupts"); 2237 2238 /* Disable all HC interrupts */ 2239 Set_OpReg(hcr_intr_disable, ~(HCR_INTR_MIE|HCR_INTR_SOF)); 2240 2241 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 2242 "ohci_cpr_suspend: Wait for the next SOF"); 2243 2244 /* Wait for the next SOF */ 2245 if (ohci_wait_for_sof(ohcip) != USB_SUCCESS) { 2246 2247 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 2248 "ohci_cpr_suspend: ohci host controller suspend failed"); 2249 2250 mutex_exit(&ohcip->ohci_int_mutex); 2251 return (DDI_FAILURE); 2252 } 2253 2254 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 2255 "ohci_cpr_suspend: Disable Master interrupt"); 2256 2257 /* 2258 * Disable Master interrupt so that ohci driver don't 2259 * get any ohci interrupts. 2260 */ 2261 Set_OpReg(hcr_intr_disable, HCR_INTR_MIE); 2262 2263 /* 2264 * Suspend the ohci host controller 2265 * if usb keyboard is not connected. 2266 */ 2267 if (ohcip->ohci_polled_kbd_count == 0) { 2268 Set_OpReg(hcr_control, HCR_CONTROL_SUSPD); 2269 } 2270 2271 /* Set host controller soft state to suspend */ 2272 ohcip->ohci_hc_soft_state = OHCI_CTLR_SUSPEND_STATE; 2273 2274 mutex_exit(&ohcip->ohci_int_mutex); 2275 2276 return (DDI_SUCCESS); 2277 } 2278 2279 2280 /* 2281 * ohci_cpr_resume 2282 */ 2283 static int 2284 ohci_cpr_resume(ohci_state_t *ohcip) 2285 { 2286 mutex_enter(&ohcip->ohci_int_mutex); 2287 2288 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 2289 "ohci_cpr_resume: Restart the controller"); 2290 2291 /* Cleanup ohci specific information across cpr */ 2292 ohci_cpr_cleanup(ohcip); 2293 2294 /* Restart the controller */ 2295 if (ohci_init_ctlr(ohcip) != DDI_SUCCESS) { 2296 2297 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 2298 "ohci_cpr_resume: ohci host controller resume failed "); 2299 2300 mutex_exit(&ohcip->ohci_int_mutex); 2301 2302 return (DDI_FAILURE); 2303 } 2304 2305 mutex_exit(&ohcip->ohci_int_mutex); 2306 2307 /* Now resume the root hub */ 2308 if (usba_hubdi_attach(ohcip->ohci_dip, DDI_RESUME) != DDI_SUCCESS) { 2309 2310 return (DDI_FAILURE); 2311 } 2312 2313 return (DDI_SUCCESS); 2314 } 2315 2316 2317 /* 2318 * HCDI entry points 2319 * 2320 * The Host Controller Driver Interfaces (HCDI) are the software interfaces 2321 * between the Universal Serial Bus Layer (USBA) and the Host Controller 2322 * Driver (HCD). The HCDI interfaces or entry points are subject to change. 2323 */ 2324 2325 /* 2326 * ohci_hcdi_pipe_open: 2327 * 2328 * Member of HCD Ops structure and called during client specific pipe open 2329 * Add the pipe to the data structure representing the device and allocate 2330 * bandwidth for the pipe if it is a interrupt or isochronous endpoint. 2331 */ 2332 static int 2333 ohci_hcdi_pipe_open( 2334 usba_pipe_handle_data_t *ph, 2335 usb_flags_t flags) 2336 { 2337 ohci_state_t *ohcip = ohci_obtain_state( 2338 ph->p_usba_device->usb_root_hub_dip); 2339 usb_ep_descr_t *epdt = &ph->p_ep; 2340 int rval, error = USB_SUCCESS; 2341 int kmflag = (flags & USB_FLAGS_SLEEP) ? 2342 KM_SLEEP : KM_NOSLEEP; 2343 uint_t node = 0; 2344 ohci_pipe_private_t *pp; 2345 2346 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2347 "ohci_hcdi_pipe_open: addr = 0x%x, ep%d", 2348 ph->p_usba_device->usb_addr, 2349 epdt->bEndpointAddress & USB_EP_NUM_MASK); 2350 2351 sema_p(&ohcip->ohci_ocsem); 2352 2353 mutex_enter(&ohcip->ohci_int_mutex); 2354 rval = ohci_state_is_operational(ohcip); 2355 mutex_exit(&ohcip->ohci_int_mutex); 2356 2357 if (rval != USB_SUCCESS) { 2358 sema_v(&ohcip->ohci_ocsem); 2359 2360 return (rval); 2361 } 2362 2363 /* 2364 * Check and handle root hub pipe open. 2365 */ 2366 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) { 2367 2368 mutex_enter(&ohcip->ohci_int_mutex); 2369 error = ohci_handle_root_hub_pipe_open(ph, flags); 2370 mutex_exit(&ohcip->ohci_int_mutex); 2371 sema_v(&ohcip->ohci_ocsem); 2372 2373 return (error); 2374 } 2375 2376 /* 2377 * Opening of other pipes excluding root hub pipe are 2378 * handled below. Check whether pipe is already opened. 2379 */ 2380 if (ph->p_hcd_private) { 2381 USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2382 "ohci_hcdi_pipe_open: Pipe is already opened"); 2383 2384 sema_v(&ohcip->ohci_ocsem); 2385 2386 return (USB_FAILURE); 2387 } 2388 2389 /* 2390 * A portion of the bandwidth is reserved for the non-periodic 2391 * transfers, i.e control and bulk transfers in each of one 2392 * millisecond frame period & usually it will be 10% of frame 2393 * period. Hence there is no need to check for the available 2394 * bandwidth before adding the control or bulk endpoints. 2395 * 2396 * There is a need to check for the available bandwidth before 2397 * adding the periodic transfers, i.e interrupt & isochronous, 2398 * since all these periodic transfers are guaranteed transfers. 2399 * Usually 90% of the total frame time is reserved for periodic 2400 * transfers. 2401 */ 2402 if (OHCI_PERIODIC_ENDPOINT(epdt)) { 2403 2404 mutex_enter(&ohcip->ohci_int_mutex); 2405 mutex_enter(&ph->p_mutex); 2406 2407 error = ohci_allocate_bandwidth(ohcip, ph, &node); 2408 2409 if (error != USB_SUCCESS) { 2410 2411 USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2412 "ohci_hcdi_pipe_open: Bandwidth allocation failed"); 2413 2414 mutex_exit(&ph->p_mutex); 2415 mutex_exit(&ohcip->ohci_int_mutex); 2416 sema_v(&ohcip->ohci_ocsem); 2417 2418 return (error); 2419 } 2420 2421 mutex_exit(&ph->p_mutex); 2422 mutex_exit(&ohcip->ohci_int_mutex); 2423 } 2424 2425 /* Create the HCD pipe private structure */ 2426 pp = kmem_zalloc(sizeof (ohci_pipe_private_t), kmflag); 2427 2428 /* 2429 * Return failure if ohci pipe private 2430 * structure allocation fails. 2431 */ 2432 if (pp == NULL) { 2433 2434 mutex_enter(&ohcip->ohci_int_mutex); 2435 2436 /* Deallocate bandwidth */ 2437 if (OHCI_PERIODIC_ENDPOINT(epdt)) { 2438 2439 mutex_enter(&ph->p_mutex); 2440 ohci_deallocate_bandwidth(ohcip, ph); 2441 mutex_exit(&ph->p_mutex); 2442 } 2443 2444 mutex_exit(&ohcip->ohci_int_mutex); 2445 sema_v(&ohcip->ohci_ocsem); 2446 2447 return (USB_NO_RESOURCES); 2448 } 2449 2450 mutex_enter(&ohcip->ohci_int_mutex); 2451 2452 /* Store the node in the interrupt lattice */ 2453 pp->pp_node = node; 2454 2455 /* Create prototype for xfer completion condition variable */ 2456 cv_init(&pp->pp_xfer_cmpl_cv, NULL, CV_DRIVER, NULL); 2457 2458 /* Set the state of pipe as idle */ 2459 pp->pp_state = OHCI_PIPE_STATE_IDLE; 2460 2461 /* Store a pointer to the pipe handle */ 2462 pp->pp_pipe_handle = ph; 2463 2464 mutex_enter(&ph->p_mutex); 2465 2466 /* Store the pointer in the pipe handle */ 2467 ph->p_hcd_private = (usb_opaque_t)pp; 2468 2469 /* Store a copy of the pipe policy */ 2470 bcopy(&ph->p_policy, &pp->pp_policy, sizeof (usb_pipe_policy_t)); 2471 2472 mutex_exit(&ph->p_mutex); 2473 2474 /* Allocate the host controller endpoint descriptor */ 2475 pp->pp_ept = ohci_alloc_hc_ed(ohcip, ph); 2476 2477 if (pp->pp_ept == NULL) { 2478 USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2479 "ohci_hcdi_pipe_open: ED allocation failed"); 2480 2481 mutex_enter(&ph->p_mutex); 2482 2483 /* Deallocate bandwidth */ 2484 if (OHCI_PERIODIC_ENDPOINT(epdt)) { 2485 2486 ohci_deallocate_bandwidth(ohcip, ph); 2487 } 2488 2489 /* Destroy the xfer completion condition varibale */ 2490 cv_destroy(&pp->pp_xfer_cmpl_cv); 2491 2492 /* 2493 * Deallocate the hcd private portion 2494 * of the pipe handle. 2495 */ 2496 kmem_free(ph->p_hcd_private, sizeof (ohci_pipe_private_t)); 2497 2498 /* 2499 * Set the private structure in the 2500 * pipe handle equal to NULL. 2501 */ 2502 ph->p_hcd_private = NULL; 2503 mutex_exit(&ph->p_mutex); 2504 2505 mutex_exit(&ohcip->ohci_int_mutex); 2506 sema_v(&ohcip->ohci_ocsem); 2507 2508 return (USB_NO_RESOURCES); 2509 } 2510 2511 /* Restore the data toggle information */ 2512 ohci_restore_data_toggle(ohcip, ph); 2513 2514 /* 2515 * Insert the endpoint onto the host controller's 2516 * appropriate endpoint list. The host controller 2517 * will not schedule this endpoint and will not have 2518 * any TD's to process. 2519 */ 2520 ohci_insert_ed(ohcip, ph); 2521 2522 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2523 "ohci_hcdi_pipe_open: ph = 0x%p", (void *)ph); 2524 2525 ohcip->ohci_open_pipe_count++; 2526 2527 mutex_exit(&ohcip->ohci_int_mutex); 2528 2529 sema_v(&ohcip->ohci_ocsem); 2530 2531 return (USB_SUCCESS); 2532 } 2533 2534 2535 /* 2536 * ohci_hcdi_pipe_close: 2537 * 2538 * Member of HCD Ops structure and called during the client specific pipe 2539 * close. Remove the pipe and the data structure representing the device. 2540 * Deallocate bandwidth for the pipe if it is a interrupt or isochronous 2541 * endpoint. 2542 */ 2543 /* ARGSUSED */ 2544 static int 2545 ohci_hcdi_pipe_close( 2546 usba_pipe_handle_data_t *ph, 2547 usb_flags_t flags) 2548 { 2549 ohci_state_t *ohcip = ohci_obtain_state( 2550 ph->p_usba_device->usb_root_hub_dip); 2551 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 2552 usb_ep_descr_t *eptd = &ph->p_ep; 2553 int error = USB_SUCCESS; 2554 2555 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2556 "ohci_hcdi_pipe_close: addr = 0x%x, ep%d", 2557 ph->p_usba_device->usb_addr, 2558 eptd->bEndpointAddress & USB_EP_NUM_MASK); 2559 2560 sema_p(&ohcip->ohci_ocsem); 2561 2562 /* Check and handle root hub pipe close */ 2563 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) { 2564 2565 mutex_enter(&ohcip->ohci_int_mutex); 2566 error = ohci_handle_root_hub_pipe_close(ph); 2567 mutex_exit(&ohcip->ohci_int_mutex); 2568 sema_v(&ohcip->ohci_ocsem); 2569 2570 return (error); 2571 } 2572 2573 ASSERT(ph->p_hcd_private != NULL); 2574 2575 mutex_enter(&ohcip->ohci_int_mutex); 2576 2577 /* Set pipe state to pipe close */ 2578 pp->pp_state = OHCI_PIPE_STATE_CLOSE; 2579 2580 ohci_pipe_cleanup(ohcip, ph); 2581 2582 /* 2583 * Remove the endoint descriptor from Host 2584 * Controller's appropriate endpoint list. 2585 */ 2586 ohci_remove_ed(ohcip, pp); 2587 2588 /* Deallocate bandwidth */ 2589 if (OHCI_PERIODIC_ENDPOINT(eptd)) { 2590 2591 mutex_enter(&ph->p_mutex); 2592 ohci_deallocate_bandwidth(ohcip, ph); 2593 mutex_exit(&ph->p_mutex); 2594 } 2595 2596 mutex_enter(&ph->p_mutex); 2597 2598 /* Destroy the xfer completion condition varibale */ 2599 cv_destroy(&pp->pp_xfer_cmpl_cv); 2600 2601 /* 2602 * Deallocate the hcd private portion 2603 * of the pipe handle. 2604 */ 2605 kmem_free(ph->p_hcd_private, sizeof (ohci_pipe_private_t)); 2606 ph->p_hcd_private = NULL; 2607 2608 mutex_exit(&ph->p_mutex); 2609 2610 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2611 "ohci_hcdi_pipe_close: ph = 0x%p", (void *)ph); 2612 2613 ohcip->ohci_open_pipe_count--; 2614 2615 mutex_exit(&ohcip->ohci_int_mutex); 2616 sema_v(&ohcip->ohci_ocsem); 2617 2618 return (error); 2619 } 2620 2621 2622 /* 2623 * ohci_hcdi_pipe_reset: 2624 */ 2625 /* ARGSUSED */ 2626 static int 2627 ohci_hcdi_pipe_reset( 2628 usba_pipe_handle_data_t *ph, 2629 usb_flags_t usb_flags) 2630 { 2631 ohci_state_t *ohcip = ohci_obtain_state( 2632 ph->p_usba_device->usb_root_hub_dip); 2633 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 2634 int error = USB_SUCCESS; 2635 2636 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2637 "ohci_hcdi_pipe_reset: ph = 0x%p ", (void *)ph); 2638 2639 /* 2640 * Check and handle root hub pipe reset. 2641 */ 2642 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) { 2643 2644 error = ohci_handle_root_hub_pipe_reset(ph, usb_flags); 2645 return (error); 2646 } 2647 2648 mutex_enter(&ohcip->ohci_int_mutex); 2649 2650 /* Set pipe state to pipe reset */ 2651 pp->pp_state = OHCI_PIPE_STATE_RESET; 2652 2653 ohci_pipe_cleanup(ohcip, ph); 2654 2655 mutex_exit(&ohcip->ohci_int_mutex); 2656 2657 return (error); 2658 } 2659 2660 2661 /* 2662 * ohci_hcdi_pipe_ctrl_xfer: 2663 */ 2664 static int 2665 ohci_hcdi_pipe_ctrl_xfer( 2666 usba_pipe_handle_data_t *ph, 2667 usb_ctrl_req_t *ctrl_reqp, 2668 usb_flags_t usb_flags) 2669 { 2670 ohci_state_t *ohcip = ohci_obtain_state( 2671 ph->p_usba_device->usb_root_hub_dip); 2672 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 2673 int rval; 2674 int error = USB_SUCCESS; 2675 ohci_trans_wrapper_t *tw; 2676 2677 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2678 "ohci_hcdi_pipe_ctrl_xfer: ph = 0x%p reqp = 0x%p flags = 0x%x", 2679 (void *)ph, ctrl_reqp, usb_flags); 2680 2681 mutex_enter(&ohcip->ohci_int_mutex); 2682 rval = ohci_state_is_operational(ohcip); 2683 mutex_exit(&ohcip->ohci_int_mutex); 2684 2685 if (rval != USB_SUCCESS) { 2686 2687 return (rval); 2688 } 2689 2690 /* 2691 * Check and handle root hub control request. 2692 */ 2693 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) { 2694 2695 error = ohci_handle_root_hub_request(ohcip, ph, ctrl_reqp); 2696 2697 return (error); 2698 } 2699 2700 mutex_enter(&ohcip->ohci_int_mutex); 2701 2702 /* 2703 * Check whether pipe is in halted state. 2704 */ 2705 if (pp->pp_state == OHCI_PIPE_STATE_ERROR) { 2706 2707 USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2708 "ohci_hcdi_pipe_ctrl_xfer:" 2709 "Pipe is in error state, need pipe reset to continue"); 2710 2711 mutex_exit(&ohcip->ohci_int_mutex); 2712 2713 return (USB_FAILURE); 2714 } 2715 2716 /* Allocate a transfer wrapper */ 2717 if ((tw = ohci_allocate_ctrl_resources(ohcip, pp, ctrl_reqp, 2718 usb_flags)) == NULL) { 2719 2720 error = USB_NO_RESOURCES; 2721 } else { 2722 /* Insert the td's on the endpoint */ 2723 ohci_insert_ctrl_req(ohcip, ph, ctrl_reqp, tw, usb_flags); 2724 } 2725 2726 mutex_exit(&ohcip->ohci_int_mutex); 2727 2728 return (error); 2729 } 2730 2731 2732 /* 2733 * ohci_hcdi_bulk_transfer_size: 2734 * 2735 * Return maximum bulk transfer size 2736 */ 2737 2738 /* ARGSUSED */ 2739 static int 2740 ohci_hcdi_bulk_transfer_size( 2741 usba_device_t *usba_device, 2742 size_t *size) 2743 { 2744 ohci_state_t *ohcip = ohci_obtain_state( 2745 usba_device->usb_root_hub_dip); 2746 int rval; 2747 2748 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2749 "ohci_hcdi_bulk_transfer_size:"); 2750 2751 mutex_enter(&ohcip->ohci_int_mutex); 2752 rval = ohci_state_is_operational(ohcip); 2753 mutex_exit(&ohcip->ohci_int_mutex); 2754 2755 if (rval != USB_SUCCESS) { 2756 2757 return (rval); 2758 } 2759 2760 *size = OHCI_MAX_BULK_XFER_SIZE; 2761 2762 return (USB_SUCCESS); 2763 } 2764 2765 2766 /* 2767 * ohci_hcdi_pipe_bulk_xfer: 2768 */ 2769 static int 2770 ohci_hcdi_pipe_bulk_xfer( 2771 usba_pipe_handle_data_t *ph, 2772 usb_bulk_req_t *bulk_reqp, 2773 usb_flags_t usb_flags) 2774 { 2775 ohci_state_t *ohcip = ohci_obtain_state( 2776 ph->p_usba_device->usb_root_hub_dip); 2777 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 2778 int rval, error = USB_SUCCESS; 2779 ohci_trans_wrapper_t *tw; 2780 2781 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2782 "ohci_hcdi_pipe_bulk_xfer: ph = 0x%p reqp = 0x%p flags = 0x%x", 2783 (void *)ph, bulk_reqp, usb_flags); 2784 2785 mutex_enter(&ohcip->ohci_int_mutex); 2786 rval = ohci_state_is_operational(ohcip); 2787 2788 if (rval != USB_SUCCESS) { 2789 mutex_exit(&ohcip->ohci_int_mutex); 2790 2791 return (rval); 2792 } 2793 2794 /* 2795 * Check whether pipe is in halted state. 2796 */ 2797 if (pp->pp_state == OHCI_PIPE_STATE_ERROR) { 2798 2799 USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2800 "ohci_hcdi_pipe_bulk_xfer:" 2801 "Pipe is in error state, need pipe reset to continue"); 2802 2803 mutex_exit(&ohcip->ohci_int_mutex); 2804 2805 return (USB_FAILURE); 2806 } 2807 2808 /* Allocate a transfer wrapper */ 2809 if ((tw = ohci_allocate_bulk_resources(ohcip, pp, bulk_reqp, 2810 usb_flags)) == NULL) { 2811 2812 error = USB_NO_RESOURCES; 2813 } else { 2814 /* Add the TD into the Host Controller's bulk list */ 2815 ohci_insert_bulk_req(ohcip, ph, bulk_reqp, tw, usb_flags); 2816 } 2817 2818 mutex_exit(&ohcip->ohci_int_mutex); 2819 2820 return (error); 2821 } 2822 2823 2824 /* 2825 * ohci_hcdi_pipe_intr_xfer: 2826 */ 2827 static int 2828 ohci_hcdi_pipe_intr_xfer( 2829 usba_pipe_handle_data_t *ph, 2830 usb_intr_req_t *intr_reqp, 2831 usb_flags_t usb_flags) 2832 { 2833 ohci_state_t *ohcip = ohci_obtain_state( 2834 ph->p_usba_device->usb_root_hub_dip); 2835 int pipe_dir, rval, error = USB_SUCCESS; 2836 ohci_trans_wrapper_t *tw; 2837 2838 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2839 "ohci_hcdi_pipe_intr_xfer: ph = 0x%p reqp = 0x%p flags = 0x%x", 2840 (void *)ph, intr_reqp, usb_flags); 2841 2842 mutex_enter(&ohcip->ohci_int_mutex); 2843 rval = ohci_state_is_operational(ohcip); 2844 2845 if (rval != USB_SUCCESS) { 2846 mutex_exit(&ohcip->ohci_int_mutex); 2847 2848 return (rval); 2849 } 2850 2851 /* Get the pipe direction */ 2852 pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK; 2853 2854 if (pipe_dir == USB_EP_DIR_IN) { 2855 error = ohci_start_periodic_pipe_polling(ohcip, ph, 2856 (usb_opaque_t)intr_reqp, usb_flags); 2857 } else { 2858 /* Allocate transaction resources */ 2859 if ((tw = ohci_allocate_intr_resources(ohcip, ph, 2860 intr_reqp, usb_flags)) == NULL) { 2861 error = USB_NO_RESOURCES; 2862 } else { 2863 ohci_insert_intr_req(ohcip, 2864 (ohci_pipe_private_t *)ph->p_hcd_private, 2865 tw, usb_flags); 2866 } 2867 } 2868 2869 mutex_exit(&ohcip->ohci_int_mutex); 2870 2871 return (error); 2872 } 2873 2874 2875 /* 2876 * ohci_hcdi_pipe_stop_intr_polling() 2877 */ 2878 static int 2879 ohci_hcdi_pipe_stop_intr_polling( 2880 usba_pipe_handle_data_t *ph, 2881 usb_flags_t flags) 2882 { 2883 ohci_state_t *ohcip = ohci_obtain_state( 2884 ph->p_usba_device->usb_root_hub_dip); 2885 int error = USB_SUCCESS; 2886 2887 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2888 "ohci_hcdi_pipe_stop_intr_polling: ph = 0x%p fl = 0x%x", 2889 ph, flags); 2890 2891 mutex_enter(&ohcip->ohci_int_mutex); 2892 2893 error = ohci_stop_periodic_pipe_polling(ohcip, ph, flags); 2894 2895 mutex_exit(&ohcip->ohci_int_mutex); 2896 2897 return (error); 2898 } 2899 2900 2901 /* 2902 * ohci_hcdi_get_current_frame_number: 2903 * 2904 * Return the current usb frame number 2905 */ 2906 static usb_frame_number_t 2907 ohci_hcdi_get_current_frame_number(usba_device_t *usba_device) 2908 { 2909 ohci_state_t *ohcip = ohci_obtain_state( 2910 usba_device->usb_root_hub_dip); 2911 usb_frame_number_t frame_number; 2912 int rval; 2913 2914 ohcip = ohci_obtain_state(usba_device->usb_root_hub_dip); 2915 2916 mutex_enter(&ohcip->ohci_int_mutex); 2917 rval = ohci_state_is_operational(ohcip); 2918 2919 if (rval != USB_SUCCESS) { 2920 mutex_exit(&ohcip->ohci_int_mutex); 2921 2922 return (rval); 2923 } 2924 2925 frame_number = ohci_get_current_frame_number(ohcip); 2926 2927 mutex_exit(&ohcip->ohci_int_mutex); 2928 2929 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2930 "ohci_hcdi_get_current_frame_number:" 2931 "Current frame number 0x%llx", frame_number); 2932 2933 return (frame_number); 2934 } 2935 2936 2937 /* 2938 * ohci_hcdi_get_max_isoc_pkts: 2939 * 2940 * Return maximum isochronous packets per usb isochronous request 2941 */ 2942 static uint_t 2943 ohci_hcdi_get_max_isoc_pkts(usba_device_t *usba_device) 2944 { 2945 ohci_state_t *ohcip = ohci_obtain_state( 2946 usba_device->usb_root_hub_dip); 2947 uint_t max_isoc_pkts_per_request; 2948 int rval; 2949 2950 mutex_enter(&ohcip->ohci_int_mutex); 2951 rval = ohci_state_is_operational(ohcip); 2952 mutex_exit(&ohcip->ohci_int_mutex); 2953 2954 if (rval != USB_SUCCESS) { 2955 2956 return (rval); 2957 } 2958 2959 max_isoc_pkts_per_request = OHCI_MAX_ISOC_PKTS_PER_XFER; 2960 2961 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2962 "ohci_hcdi_get_max_isoc_pkts: maximum isochronous" 2963 "packets per usb isochronous request = 0x%x", 2964 max_isoc_pkts_per_request); 2965 2966 return (max_isoc_pkts_per_request); 2967 } 2968 2969 2970 /* 2971 * ohci_hcdi_pipe_isoc_xfer: 2972 */ 2973 static int 2974 ohci_hcdi_pipe_isoc_xfer( 2975 usba_pipe_handle_data_t *ph, 2976 usb_isoc_req_t *isoc_reqp, 2977 usb_flags_t usb_flags) 2978 { 2979 ohci_state_t *ohcip = ohci_obtain_state( 2980 ph->p_usba_device->usb_root_hub_dip); 2981 int error = USB_SUCCESS; 2982 int pipe_dir, rval; 2983 ohci_trans_wrapper_t *tw; 2984 2985 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 2986 "ohci_hcdi_pipe_isoc_xfer: ph = 0x%p reqp = 0x%p flags = 0x%x", 2987 (void *)ph, isoc_reqp, usb_flags); 2988 2989 mutex_enter(&ohcip->ohci_int_mutex); 2990 rval = ohci_state_is_operational(ohcip); 2991 2992 if (rval != USB_SUCCESS) { 2993 mutex_exit(&ohcip->ohci_int_mutex); 2994 2995 return (rval); 2996 } 2997 2998 /* Get the isochronous pipe direction */ 2999 pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK; 3000 3001 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 3002 "ohci_hcdi_pipe_isoc_xfer: isoc_reqp = 0x%p, uf = 0x%x", 3003 isoc_reqp, usb_flags); 3004 3005 if (pipe_dir == USB_EP_DIR_IN) { 3006 error = ohci_start_periodic_pipe_polling(ohcip, ph, 3007 (usb_opaque_t)isoc_reqp, usb_flags); 3008 } else { 3009 /* Allocate transaction resources */ 3010 if ((tw = ohci_allocate_isoc_resources(ohcip, ph, 3011 isoc_reqp, usb_flags)) == NULL) { 3012 error = USB_NO_RESOURCES; 3013 } else { 3014 error = ohci_insert_isoc_req(ohcip, 3015 (ohci_pipe_private_t *)ph->p_hcd_private, 3016 tw, usb_flags); 3017 } 3018 } 3019 3020 mutex_exit(&ohcip->ohci_int_mutex); 3021 3022 return (error); 3023 } 3024 3025 3026 /* 3027 * ohci_hcdi_pipe_stop_isoc_polling() 3028 */ 3029 static int 3030 ohci_hcdi_pipe_stop_isoc_polling( 3031 usba_pipe_handle_data_t *ph, 3032 usb_flags_t flags) 3033 { 3034 ohci_state_t *ohcip = ohci_obtain_state( 3035 ph->p_usba_device->usb_root_hub_dip); 3036 int rval, error = USB_SUCCESS; 3037 3038 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl, 3039 "ohci_hcdi_pipe_stop_isoc_polling: ph = 0x%p fl = 0x%x", 3040 (void *)ph, flags); 3041 3042 mutex_enter(&ohcip->ohci_int_mutex); 3043 rval = ohci_state_is_operational(ohcip); 3044 3045 if (rval != USB_SUCCESS) { 3046 mutex_exit(&ohcip->ohci_int_mutex); 3047 return (rval); 3048 } 3049 3050 error = ohci_stop_periodic_pipe_polling(ohcip, ph, flags); 3051 3052 mutex_exit(&ohcip->ohci_int_mutex); 3053 return (error); 3054 } 3055 3056 3057 /* 3058 * Bandwidth Allocation functions 3059 */ 3060 3061 /* 3062 * ohci_allocate_bandwidth: 3063 * 3064 * Figure out whether or not this interval may be supported. Return the index 3065 * into the lattice if it can be supported. Return allocation failure if it 3066 * can not be supported. 3067 * 3068 * The lattice structure looks like this with the bottom leaf actually 3069 * being an array. There is a total of 63 nodes in this tree. The lattice tree 3070 * itself is 0 based, while the bottom leaf array is 0 based. The 0 bucket in 3071 * the bottom leaf array is used to store the smalled allocated bandwidth of all 3072 * the leaves. 3073 * 3074 * 0 3075 * 1 2 3076 * 3 4 5 6 3077 * ... 3078 * (32 33 ... 62 63) <-- last row does not exist in lattice, but an array 3079 * 0 1 2 3 ... 30 31 3080 * 3081 * We keep track of the bandwidth that each leaf uses. First we search for the 3082 * first leaf with the smallest used bandwidth. Based on that leaf we find the 3083 * parent node of that leaf based on the interval time. 3084 * 3085 * From the parent node, we find all the leafs of that subtree and update the 3086 * additional bandwidth needed. In order to balance the load the leaves are not 3087 * executed directly from left to right, but scattered. For a better picture 3088 * refer to Section 3.3.2 in the OpenHCI 1.0 spec, there should be a figure 3089 * showing the Interrupt ED Structure. 3090 */ 3091 static int 3092 ohci_allocate_bandwidth( 3093 ohci_state_t *ohcip, 3094 usba_pipe_handle_data_t *ph, 3095 uint_t *node) 3096 { 3097 int interval, error, i; 3098 uint_t min, min_index, height; 3099 uint_t leftmost, list, bandwidth; 3100 usb_ep_descr_t *endpoint = &ph->p_ep; 3101 3102 /* This routine is protected by the ohci_int_mutex */ 3103 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 3104 3105 /* 3106 * Calculate the length in bytes of a transaction on this 3107 * periodic endpoint. 3108 */ 3109 mutex_enter(&ph->p_usba_device->usb_mutex); 3110 error = ohci_compute_total_bandwidth( 3111 endpoint, ph->p_usba_device->usb_port_status, &bandwidth); 3112 mutex_exit(&ph->p_usba_device->usb_mutex); 3113 3114 /* 3115 * If length is zero, then, it means endpoint maximum packet 3116 * supported is zero. In that case, return failure without 3117 * allocating any bandwidth. 3118 */ 3119 if (error != USB_SUCCESS) { 3120 USB_DPRINTF_L2(PRINT_MASK_BW, ohcip->ohci_log_hdl, 3121 "ohci_allocate_bandwidth: Periodic endpoint with " 3122 "zero endpoint maximum packet size is not supported"); 3123 3124 return (USB_NOT_SUPPORTED); 3125 } 3126 3127 /* 3128 * If the length in bytes plus the allocated bandwidth exceeds 3129 * the maximum, return bandwidth allocation failure. 3130 */ 3131 if ((ohcip->ohci_periodic_minimum_bandwidth + bandwidth) > 3132 (MAX_PERIODIC_BANDWIDTH)) { 3133 3134 USB_DPRINTF_L2(PRINT_MASK_BW, ohcip->ohci_log_hdl, 3135 "ohci_allocate_bandwidth: Reached maximum " 3136 "bandwidth value and cannot allocate bandwidth " 3137 "for a given periodic endpoint"); 3138 3139 return (USB_NO_BANDWIDTH); 3140 } 3141 3142 /* Adjust polling interval to be a power of 2 */ 3143 mutex_enter(&ph->p_usba_device->usb_mutex); 3144 interval = ohci_adjust_polling_interval(ohcip, 3145 endpoint, ph->p_usba_device->usb_port_status); 3146 mutex_exit(&ph->p_usba_device->usb_mutex); 3147 3148 /* 3149 * If this interval can't be supported, 3150 * return allocation failure. 3151 */ 3152 if (interval == USB_FAILURE) { 3153 3154 return (USB_FAILURE); 3155 } 3156 3157 USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl, 3158 "The new interval is %d", interval); 3159 3160 /* Find the leaf with the smallest allocated bandwidth */ 3161 min_index = 0; 3162 min = ohcip->ohci_periodic_bandwidth[0]; 3163 3164 for (i = 1; i < NUM_INTR_ED_LISTS; i++) { 3165 if (ohcip->ohci_periodic_bandwidth[i] < min) { 3166 min_index = i; 3167 min = ohcip->ohci_periodic_bandwidth[i]; 3168 } 3169 } 3170 3171 USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl, 3172 "The leaf %d for minimal bandwidth %d", min_index, min); 3173 3174 /* Adjust min for the lattice */ 3175 min_index = min_index + NUM_INTR_ED_LISTS - 1; 3176 3177 /* 3178 * Find the index into the lattice given the 3179 * leaf with the smallest allocated bandwidth. 3180 */ 3181 height = ohci_lattice_height(interval); 3182 3183 USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl, 3184 "The height is %d", height); 3185 3186 *node = min_index; 3187 3188 for (i = 0; i < height; i++) { 3189 *node = ohci_lattice_parent(*node); 3190 } 3191 3192 USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl, 3193 "Real node is %d", *node); 3194 3195 /* 3196 * Find the leftmost leaf in the subtree 3197 * specified by the node. 3198 */ 3199 leftmost = ohci_leftmost_leaf(*node, height); 3200 3201 USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl, 3202 "Leftmost %d", leftmost); 3203 3204 for (i = 0; i < (NUM_INTR_ED_LISTS/interval); i++) { 3205 list = ohci_hcca_leaf_index(leftmost + i); 3206 if ((ohcip->ohci_periodic_bandwidth[list] + 3207 bandwidth) > MAX_PERIODIC_BANDWIDTH) { 3208 3209 USB_DPRINTF_L2(PRINT_MASK_BW, ohcip->ohci_log_hdl, 3210 "ohci_allocate_bandwidth: Reached maximum " 3211 "bandwidth value and cannot allocate bandwidth " 3212 "for periodic endpoint"); 3213 3214 return (USB_NO_BANDWIDTH); 3215 } 3216 } 3217 3218 /* 3219 * All the leaves for this node must be updated with the bandwidth. 3220 */ 3221 for (i = 0; i < (NUM_INTR_ED_LISTS/interval); i++) { 3222 list = ohci_hcca_leaf_index(leftmost + i); 3223 ohcip->ohci_periodic_bandwidth[list] += bandwidth; 3224 } 3225 3226 /* Find the leaf with the smallest allocated bandwidth */ 3227 min_index = 0; 3228 min = ohcip->ohci_periodic_bandwidth[0]; 3229 3230 for (i = 1; i < NUM_INTR_ED_LISTS; i++) { 3231 if (ohcip->ohci_periodic_bandwidth[i] < min) { 3232 min_index = i; 3233 min = ohcip->ohci_periodic_bandwidth[i]; 3234 } 3235 } 3236 3237 /* Save the minimum for later use */ 3238 ohcip->ohci_periodic_minimum_bandwidth = min; 3239 3240 return (USB_SUCCESS); 3241 } 3242 3243 3244 /* 3245 * ohci_deallocate_bandwidth: 3246 * 3247 * Deallocate bandwidth for the given node in the lattice and the length 3248 * of transfer. 3249 */ 3250 static void 3251 ohci_deallocate_bandwidth( 3252 ohci_state_t *ohcip, 3253 usba_pipe_handle_data_t *ph) 3254 { 3255 uint_t min, node, bandwidth; 3256 uint_t height, leftmost, list; 3257 int i, interval; 3258 usb_ep_descr_t *endpoint = &ph->p_ep; 3259 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 3260 3261 /* This routine is protected by the ohci_int_mutex */ 3262 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 3263 3264 /* Obtain the length */ 3265 mutex_enter(&ph->p_usba_device->usb_mutex); 3266 (void) ohci_compute_total_bandwidth( 3267 endpoint, ph->p_usba_device->usb_port_status, &bandwidth); 3268 mutex_exit(&ph->p_usba_device->usb_mutex); 3269 3270 /* Obtain the node */ 3271 node = pp->pp_node; 3272 3273 /* Adjust polling interval to be a power of 2 */ 3274 mutex_enter(&ph->p_usba_device->usb_mutex); 3275 interval = ohci_adjust_polling_interval(ohcip, 3276 endpoint, ph->p_usba_device->usb_port_status); 3277 mutex_exit(&ph->p_usba_device->usb_mutex); 3278 3279 /* Find the height in the tree */ 3280 height = ohci_lattice_height(interval); 3281 3282 /* 3283 * Find the leftmost leaf in the subtree specified by the node 3284 */ 3285 leftmost = ohci_leftmost_leaf(node, height); 3286 3287 /* Delete the bandwith from the appropriate lists */ 3288 for (i = 0; i < (NUM_INTR_ED_LISTS/interval); i++) { 3289 list = ohci_hcca_leaf_index(leftmost + i); 3290 ohcip->ohci_periodic_bandwidth[list] -= bandwidth; 3291 } 3292 3293 min = ohcip->ohci_periodic_bandwidth[0]; 3294 3295 /* Recompute the minimum */ 3296 for (i = 1; i < NUM_INTR_ED_LISTS; i++) { 3297 if (ohcip->ohci_periodic_bandwidth[i] < min) { 3298 min = ohcip->ohci_periodic_bandwidth[i]; 3299 } 3300 } 3301 3302 /* Save the minimum for later use */ 3303 ohcip->ohci_periodic_minimum_bandwidth = min; 3304 } 3305 3306 3307 /* 3308 * ohci_compute_total_bandwidth: 3309 * 3310 * Given a periodic endpoint (interrupt or isochronous) determine the total 3311 * bandwidth for one transaction. The OpenHCI host controller traverses the 3312 * endpoint descriptor lists on a first-come-first-serve basis. When the HC 3313 * services an endpoint, only a single transaction attempt is made. The HC 3314 * moves to the next Endpoint Descriptor after the first transaction attempt 3315 * rather than finishing the entire Transfer Descriptor. Therefore, when a 3316 * Transfer Descriptor is inserted into the lattice, we will only count the 3317 * number of bytes for one transaction. 3318 * 3319 * The following are the formulas used for calculating bandwidth in terms 3320 * bytes and it is for the single USB full speed and low speed transaction 3321 * respectively. The protocol overheads will be different for each of type 3322 * of USB transfer and all these formulas & protocol overheads are derived 3323 * from the 5.9.3 section of USB Specification & with the help of Bandwidth 3324 * Analysis white paper which is posted on the USB developer forum. 3325 * 3326 * Full-Speed: 3327 * Protocol overhead + ((MaxPacketSize * 7)/6 ) + Host_Delay 3328 * 3329 * Low-Speed: 3330 * Protocol overhead + Hub LS overhead + 3331 * (Low-Speed clock * ((MaxPacketSize * 7)/6 )) + Host_Delay 3332 */ 3333 static int 3334 ohci_compute_total_bandwidth( 3335 usb_ep_descr_t *endpoint, 3336 usb_port_status_t port_status, 3337 uint_t *bandwidth) 3338 { 3339 ushort_t maxpacketsize = endpoint->wMaxPacketSize; 3340 3341 /* 3342 * If endpoint maximum packet is zero, then return immediately. 3343 */ 3344 if (maxpacketsize == 0) { 3345 3346 return (USB_NOT_SUPPORTED); 3347 } 3348 3349 /* Add Host Controller specific delay to required bandwidth */ 3350 *bandwidth = HOST_CONTROLLER_DELAY; 3351 3352 /* Add bit-stuffing overhead */ 3353 maxpacketsize = (ushort_t)((maxpacketsize * 7) / 6); 3354 3355 /* Low Speed interrupt transaction */ 3356 if (port_status == USBA_LOW_SPEED_DEV) { 3357 /* Low Speed interrupt transaction */ 3358 *bandwidth += (LOW_SPEED_PROTO_OVERHEAD + 3359 HUB_LOW_SPEED_PROTO_OVERHEAD + 3360 (LOW_SPEED_CLOCK * maxpacketsize)); 3361 } else { 3362 /* Full Speed transaction */ 3363 *bandwidth += maxpacketsize; 3364 3365 if ((endpoint->bmAttributes & 3366 USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) { 3367 /* Full Speed interrupt transaction */ 3368 *bandwidth += FS_NON_ISOC_PROTO_OVERHEAD; 3369 } else { 3370 /* Isochronous and input transaction */ 3371 if ((endpoint->bEndpointAddress & 3372 USB_EP_DIR_MASK) == USB_EP_DIR_IN) { 3373 *bandwidth += FS_ISOC_INPUT_PROTO_OVERHEAD; 3374 } else { 3375 /* Isochronous and output transaction */ 3376 *bandwidth += FS_ISOC_OUTPUT_PROTO_OVERHEAD; 3377 } 3378 } 3379 } 3380 3381 return (USB_SUCCESS); 3382 } 3383 3384 3385 /* 3386 * ohci_adjust_polling_interval: 3387 */ 3388 static int 3389 ohci_adjust_polling_interval( 3390 ohci_state_t *ohcip, 3391 usb_ep_descr_t *endpoint, 3392 usb_port_status_t port_status) 3393 { 3394 uint_t interval; 3395 int i = 0; 3396 3397 /* 3398 * Get the polling interval from the endpoint descriptor 3399 */ 3400 interval = endpoint->bInterval; 3401 3402 /* 3403 * The bInterval value in the endpoint descriptor can range 3404 * from 1 to 255ms. The interrupt lattice has 32 leaf nodes, 3405 * and the host controller cycles through these nodes every 3406 * 32ms. The longest polling interval that the controller 3407 * supports is 32ms. 3408 */ 3409 3410 /* 3411 * Return an error if the polling interval is less than 1ms 3412 * and greater than 255ms 3413 */ 3414 if ((interval < MIN_POLL_INTERVAL) || 3415 (interval > MAX_POLL_INTERVAL)) { 3416 3417 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 3418 "ohci_adjust_polling_interval: " 3419 "Endpoint's poll interval must be between %d and %d ms", 3420 MIN_POLL_INTERVAL, MAX_POLL_INTERVAL); 3421 3422 return (USB_FAILURE); 3423 } 3424 3425 /* 3426 * According USB Specifications, a full-speed endpoint can 3427 * specify a desired polling interval 1ms to 255ms and a low 3428 * speed endpoints are limited to specifying only 10ms to 3429 * 255ms. But some old keyboards & mice uses polling interval 3430 * of 8ms. For compatibility purpose, we are using polling 3431 * interval between 8ms & 255ms for low speed endpoints. But 3432 * ohci driver will reject the any low speed endpoints which 3433 * request polling interval less than 8ms. 3434 */ 3435 if ((port_status == USBA_LOW_SPEED_DEV) && 3436 (interval < MIN_LOW_SPEED_POLL_INTERVAL)) { 3437 3438 USB_DPRINTF_L2(PRINT_MASK_BW, ohcip->ohci_log_hdl, 3439 "ohci_adjust_polling_interval: " 3440 "Low speed endpoint's poll interval of %d ms " 3441 "is below threshold. Rounding up to %d ms", 3442 interval, MIN_LOW_SPEED_POLL_INTERVAL); 3443 3444 interval = MIN_LOW_SPEED_POLL_INTERVAL; 3445 } 3446 3447 /* 3448 * If polling interval is greater than 32ms, 3449 * adjust polling interval equal to 32ms. 3450 */ 3451 if (interval > NUM_INTR_ED_LISTS) { 3452 interval = NUM_INTR_ED_LISTS; 3453 } 3454 3455 /* 3456 * Find the nearest power of 2 that'sless 3457 * than interval. 3458 */ 3459 while ((ohci_pow_2(i)) <= interval) { 3460 i++; 3461 } 3462 3463 return (ohci_pow_2((i - 1))); 3464 } 3465 3466 3467 /* 3468 * ohci_lattice_height: 3469 * 3470 * Given the requested bandwidth, find the height in the tree at which the 3471 * nodes for this bandwidth fall. The height is measured as the number of 3472 * nodes from the leaf to the level specified by bandwidth The root of the 3473 * tree is at height TREE_HEIGHT. 3474 */ 3475 static uint_t 3476 ohci_lattice_height(uint_t interval) 3477 { 3478 return (TREE_HEIGHT - (ohci_log_2(interval))); 3479 } 3480 3481 3482 /* 3483 * ohci_lattice_parent: 3484 */ 3485 static uint_t 3486 ohci_lattice_parent(uint_t node) 3487 { 3488 if ((node % 2) == 0) { 3489 return ((node/2) - 1); 3490 } else { 3491 return ((node + 1)/2 - 1); 3492 } 3493 } 3494 3495 3496 /* 3497 * ohci_leftmost_leaf: 3498 * 3499 * Find the leftmost leaf in the subtree specified by the node. Height refers 3500 * to number of nodes from the bottom of the tree to the node, including the 3501 * node. 3502 * 3503 * The formula for a zero based tree is: 3504 * 2^H * Node + 2^H - 1 3505 * The leaf of the tree is an array, convert the number for the array. 3506 * Subtract the size of nodes not in the array 3507 * 2^H * Node + 2^H - 1 - (NUM_INTR_ED_LIST - 1) = 3508 * 2^H * Node + 2^H - NUM_INTR_ED_LIST = 3509 * 2^H * (Node + 1) - NUM_INTR_ED_LIST 3510 * 0 3511 * 1 2 3512 * 0 1 2 3 3513 */ 3514 static uint_t 3515 ohci_leftmost_leaf( 3516 uint_t node, 3517 uint_t height) 3518 { 3519 return ((ohci_pow_2(height) * (node + 1)) - NUM_INTR_ED_LISTS); 3520 } 3521 3522 /* 3523 * ohci_hcca_intr_index: 3524 * 3525 * Given a node in the lattice, find the index for the hcca interrupt table 3526 */ 3527 static uint_t 3528 ohci_hcca_intr_index(uint_t node) 3529 { 3530 /* 3531 * Adjust the node to the array representing 3532 * the bottom of the tree. 3533 */ 3534 node = node - NUM_STATIC_NODES; 3535 3536 if ((node % 2) == 0) { 3537 return (ohci_index[node / 2]); 3538 } else { 3539 return (ohci_index[node / 2] + (NUM_INTR_ED_LISTS / 2)); 3540 } 3541 } 3542 3543 /* 3544 * ohci_hcca_leaf_index: 3545 * 3546 * Given a node in the bottom leaf array of the lattice, find the index 3547 * for the hcca interrupt table 3548 */ 3549 static uint_t 3550 ohci_hcca_leaf_index(uint_t leaf) 3551 { 3552 if ((leaf % 2) == 0) { 3553 return (ohci_index[leaf / 2]); 3554 } else { 3555 return (ohci_index[leaf / 2] + (NUM_INTR_ED_LISTS / 2)); 3556 } 3557 } 3558 3559 /* 3560 * ohci_pow_2: 3561 * 3562 * Compute 2 to the power 3563 */ 3564 static uint_t 3565 ohci_pow_2(uint_t x) 3566 { 3567 if (x == 0) { 3568 return (1); 3569 } else { 3570 return (2 << (x - 1)); 3571 } 3572 } 3573 3574 3575 /* 3576 * ohci_log_2: 3577 * 3578 * Compute log base 2 of x 3579 */ 3580 static uint_t 3581 ohci_log_2(uint_t x) 3582 { 3583 int i = 0; 3584 3585 while (x != 1) { 3586 x = x >> 1; 3587 i++; 3588 } 3589 3590 return (i); 3591 } 3592 3593 3594 /* 3595 * Endpoint Descriptor (ED) manipulations functions 3596 */ 3597 3598 /* 3599 * ohci_alloc_hc_ed: 3600 * NOTE: This function is also called from POLLED MODE. 3601 * 3602 * Allocate an endpoint descriptor (ED) 3603 */ 3604 ohci_ed_t * 3605 ohci_alloc_hc_ed( 3606 ohci_state_t *ohcip, 3607 usba_pipe_handle_data_t *ph) 3608 { 3609 int i, state; 3610 ohci_ed_t *hc_ed; 3611 3612 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 3613 "ohci_alloc_hc_ed: ph = 0x%p", (void *)ph); 3614 3615 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 3616 3617 /* 3618 * The first 31 endpoints in the Endpoint Descriptor (ED) 3619 * buffer pool are reserved for building interrupt lattice 3620 * tree. Search for a blank endpoint descriptor in the ED 3621 * buffer pool. 3622 */ 3623 for (i = NUM_STATIC_NODES; i < ohci_ed_pool_size; i ++) { 3624 state = Get_ED(ohcip->ohci_ed_pool_addr[i].hced_state); 3625 3626 if (state == HC_EPT_FREE) { 3627 break; 3628 } 3629 } 3630 3631 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 3632 "ohci_alloc_hc_ed: Allocated %d", i); 3633 3634 if (i == ohci_ed_pool_size) { 3635 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 3636 "ohci_alloc_hc_ed: ED exhausted"); 3637 3638 return (NULL); 3639 } else { 3640 3641 hc_ed = &ohcip->ohci_ed_pool_addr[i]; 3642 3643 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 3644 "ohci_alloc_hc_ed: Allocated address 0x%p", (void *)hc_ed); 3645 3646 ohci_print_ed(ohcip, hc_ed); 3647 3648 /* Unpack the endpoint descriptor into a control field */ 3649 if (ph) { 3650 if ((ohci_initialize_dummy(ohcip, 3651 hc_ed)) == USB_NO_RESOURCES) { 3652 bzero((void *)hc_ed, sizeof (ohci_ed_t)); 3653 Set_ED(hc_ed->hced_state, HC_EPT_FREE); 3654 return (NULL); 3655 } 3656 3657 Set_ED(hc_ed->hced_prev, NULL); 3658 Set_ED(hc_ed->hced_next, NULL); 3659 3660 /* Change ED's state Active */ 3661 Set_ED(hc_ed->hced_state, HC_EPT_ACTIVE); 3662 3663 Set_ED(hc_ed->hced_ctrl, 3664 ohci_unpack_endpoint(ohcip, ph)); 3665 } else { 3666 Set_ED(hc_ed->hced_ctrl, HC_EPT_sKip); 3667 3668 /* Change ED's state Static */ 3669 Set_ED(hc_ed->hced_state, HC_EPT_STATIC); 3670 } 3671 3672 return (hc_ed); 3673 } 3674 } 3675 3676 3677 /* 3678 * ohci_unpack_endpoint: 3679 * 3680 * Unpack the information in the pipe handle and create the first byte 3681 * of the Host Controller's (HC) Endpoint Descriptor (ED). 3682 */ 3683 static uint_t 3684 ohci_unpack_endpoint( 3685 ohci_state_t *ohcip, 3686 usba_pipe_handle_data_t *ph) 3687 { 3688 usb_ep_descr_t *endpoint = &ph->p_ep; 3689 uint_t maxpacketsize, addr, ctrl = 0; 3690 3691 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 3692 "ohci_unpack_endpoint:"); 3693 3694 ctrl = ph->p_usba_device->usb_addr; 3695 3696 addr = endpoint->bEndpointAddress; 3697 3698 /* Assign the endpoint's address */ 3699 ctrl = ctrl | ((addr & USB_EP_NUM_MASK) << HC_EPT_EP_SHFT); 3700 3701 /* 3702 * Assign the direction. If the endpoint is a control endpoint, 3703 * the direction is assigned by the Transfer Descriptor (TD). 3704 */ 3705 if ((endpoint->bmAttributes & 3706 USB_EP_ATTR_MASK) != USB_EP_ATTR_CONTROL) { 3707 if (addr & USB_EP_DIR_MASK) { 3708 /* The direction is IN */ 3709 ctrl = ctrl | HC_EPT_DF_IN; 3710 } else { 3711 /* The direction is OUT */ 3712 ctrl = ctrl | HC_EPT_DF_OUT; 3713 } 3714 } 3715 3716 /* Assign the speed */ 3717 mutex_enter(&ph->p_usba_device->usb_mutex); 3718 if (ph->p_usba_device->usb_port_status == USBA_LOW_SPEED_DEV) { 3719 ctrl = ctrl | HC_EPT_Speed; 3720 } 3721 mutex_exit(&ph->p_usba_device->usb_mutex); 3722 3723 /* Assign the format */ 3724 if ((endpoint->bmAttributes & 3725 USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH) { 3726 ctrl = ctrl | HC_EPT_Format; 3727 } 3728 3729 maxpacketsize = endpoint->wMaxPacketSize; 3730 maxpacketsize = maxpacketsize << HC_EPT_MAXPKTSZ; 3731 ctrl = ctrl | (maxpacketsize & HC_EPT_MPS); 3732 3733 return (ctrl); 3734 } 3735 3736 3737 /* 3738 * ohci_insert_ed: 3739 * 3740 * Add the Endpoint Descriptor (ED) into the Host Controller's 3741 * (HC) appropriate endpoint list. 3742 */ 3743 static void 3744 ohci_insert_ed( 3745 ohci_state_t *ohcip, 3746 usba_pipe_handle_data_t *ph) 3747 { 3748 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 3749 3750 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 3751 "ohci_insert_ed:"); 3752 3753 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 3754 3755 switch (ph->p_ep.bmAttributes & USB_EP_ATTR_MASK) { 3756 case USB_EP_ATTR_CONTROL: 3757 ohci_insert_ctrl_ed(ohcip, pp); 3758 break; 3759 case USB_EP_ATTR_BULK: 3760 ohci_insert_bulk_ed(ohcip, pp); 3761 break; 3762 case USB_EP_ATTR_INTR: 3763 ohci_insert_intr_ed(ohcip, pp); 3764 break; 3765 case USB_EP_ATTR_ISOCH: 3766 ohci_insert_isoc_ed(ohcip, pp); 3767 break; 3768 } 3769 } 3770 3771 3772 /* 3773 * ohci_insert_ctrl_ed: 3774 * 3775 * Insert a control endpoint into the Host Controller's (HC) 3776 * control endpoint list. 3777 */ 3778 static void 3779 ohci_insert_ctrl_ed( 3780 ohci_state_t *ohcip, 3781 ohci_pipe_private_t *pp) 3782 { 3783 ohci_ed_t *ept = pp->pp_ept; 3784 ohci_ed_t *prev_ept; 3785 3786 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 3787 "ohci_insert_ctrl_ed:"); 3788 3789 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 3790 3791 /* Obtain a ptr to the head of the list */ 3792 if (Get_OpReg(hcr_ctrl_head)) { 3793 prev_ept = ohci_ed_iommu_to_cpu(ohcip, 3794 Get_OpReg(hcr_ctrl_head)); 3795 3796 /* Set up the backwards pointer */ 3797 Set_ED(prev_ept->hced_prev, ohci_ed_cpu_to_iommu(ohcip, ept)); 3798 } 3799 3800 /* The new endpoint points to the head of the list */ 3801 Set_ED(ept->hced_next, Get_OpReg(hcr_ctrl_head)); 3802 3803 /* Set the head ptr to the new endpoint */ 3804 Set_OpReg(hcr_ctrl_head, ohci_ed_cpu_to_iommu(ohcip, ept)); 3805 3806 /* 3807 * Enable Control list processing if control open 3808 * pipe count is zero. 3809 */ 3810 if (!ohcip->ohci_open_ctrl_pipe_count) { 3811 /* Start Control list processing */ 3812 Set_OpReg(hcr_control, 3813 (Get_OpReg(hcr_control) | HCR_CONTROL_CLE)); 3814 } 3815 3816 ohcip->ohci_open_ctrl_pipe_count++; 3817 } 3818 3819 3820 /* 3821 * ohci_insert_bulk_ed: 3822 * 3823 * Insert a bulk endpoint into the Host Controller's (HC) bulk endpoint list. 3824 */ 3825 static void 3826 ohci_insert_bulk_ed( 3827 ohci_state_t *ohcip, 3828 ohci_pipe_private_t *pp) 3829 { 3830 ohci_ed_t *ept = pp->pp_ept; 3831 ohci_ed_t *prev_ept; 3832 3833 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 3834 "ohci_insert_bulk_ed:"); 3835 3836 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 3837 3838 /* Obtain a ptr to the head of the Bulk list */ 3839 if (Get_OpReg(hcr_bulk_head)) { 3840 prev_ept = ohci_ed_iommu_to_cpu(ohcip, 3841 Get_OpReg(hcr_bulk_head)); 3842 3843 /* Set up the backwards pointer */ 3844 Set_ED(prev_ept->hced_prev, ohci_ed_cpu_to_iommu(ohcip, ept)); 3845 } 3846 3847 /* The new endpoint points to the head of the Bulk list */ 3848 Set_ED(ept->hced_next, Get_OpReg(hcr_bulk_head)); 3849 3850 /* Set the Bulk head ptr to the new endpoint */ 3851 Set_OpReg(hcr_bulk_head, ohci_ed_cpu_to_iommu(ohcip, ept)); 3852 3853 /* 3854 * Enable Bulk list processing if bulk open pipe 3855 * count is zero. 3856 */ 3857 if (!ohcip->ohci_open_bulk_pipe_count) { 3858 /* Start Bulk list processing */ 3859 Set_OpReg(hcr_control, 3860 (Get_OpReg(hcr_control) | HCR_CONTROL_BLE)); 3861 } 3862 3863 ohcip->ohci_open_bulk_pipe_count++; 3864 } 3865 3866 3867 /* 3868 * ohci_insert_intr_ed: 3869 * 3870 * Insert a interrupt endpoint into the Host Controller's (HC) interrupt 3871 * lattice tree. 3872 */ 3873 static void 3874 ohci_insert_intr_ed( 3875 ohci_state_t *ohcip, 3876 ohci_pipe_private_t *pp) 3877 { 3878 ohci_ed_t *ept = pp->pp_ept; 3879 ohci_ed_t *next_lattice_ept, *lattice_ept; 3880 uint_t node; 3881 3882 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 3883 3884 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 3885 "ohci_insert_intr_ed:"); 3886 3887 /* 3888 * The appropriate node was found 3889 * during the opening of the pipe. 3890 */ 3891 node = pp->pp_node; 3892 3893 if (node >= NUM_STATIC_NODES) { 3894 /* Get the hcca interrupt table index */ 3895 node = ohci_hcca_intr_index(node); 3896 3897 /* Get the first endpoint on the list */ 3898 next_lattice_ept = ohci_ed_iommu_to_cpu(ohcip, 3899 Get_HCCA(ohcip->ohci_hccap->HccaIntTble[node])); 3900 3901 /* Update this endpoint to point to it */ 3902 Set_ED(ept->hced_next, 3903 ohci_ed_cpu_to_iommu(ohcip, next_lattice_ept)); 3904 3905 /* Put this endpoint at the head of the list */ 3906 Set_HCCA(ohcip->ohci_hccap->HccaIntTble[node], 3907 ohci_ed_cpu_to_iommu(ohcip, ept)); 3908 3909 /* The previous pointer is NULL */ 3910 Set_ED(ept->hced_prev, NULL); 3911 3912 /* Update the previous pointer of ept->hced_next */ 3913 if (Get_ED(next_lattice_ept->hced_state) != HC_EPT_STATIC) { 3914 Set_ED(next_lattice_ept->hced_prev, 3915 ohci_ed_cpu_to_iommu(ohcip, ept)); 3916 } 3917 } else { 3918 /* Find the lattice endpoint */ 3919 lattice_ept = &ohcip->ohci_ed_pool_addr[node]; 3920 3921 /* Find the next lattice endpoint */ 3922 next_lattice_ept = ohci_ed_iommu_to_cpu( 3923 ohcip, Get_ED(lattice_ept->hced_next)); 3924 3925 /* 3926 * Update this endpoint to point to the next one in the 3927 * lattice. 3928 */ 3929 Set_ED(ept->hced_next, Get_ED(lattice_ept->hced_next)); 3930 3931 /* Insert this endpoint into the lattice */ 3932 Set_ED(lattice_ept->hced_next, 3933 ohci_ed_cpu_to_iommu(ohcip, ept)); 3934 3935 /* Update the previous pointer */ 3936 Set_ED(ept->hced_prev, 3937 ohci_ed_cpu_to_iommu(ohcip, lattice_ept)); 3938 3939 /* Update the previous pointer of ept->hced_next */ 3940 if ((next_lattice_ept) && 3941 (Get_ED(next_lattice_ept->hced_state) != HC_EPT_STATIC)) { 3942 3943 Set_ED(next_lattice_ept->hced_prev, 3944 ohci_ed_cpu_to_iommu(ohcip, ept)); 3945 } 3946 } 3947 3948 /* 3949 * Enable periodic list processing if periodic (interrupt 3950 * and isochronous) open pipe count is zero. 3951 */ 3952 if (!ohcip->ohci_open_periodic_pipe_count) { 3953 ASSERT(!ohcip->ohci_open_isoch_pipe_count); 3954 3955 Set_OpReg(hcr_control, 3956 (Get_OpReg(hcr_control) | HCR_CONTROL_PLE)); 3957 } 3958 3959 ohcip->ohci_open_periodic_pipe_count++; 3960 } 3961 3962 3963 /* 3964 * ohci_insert_isoc_ed: 3965 * 3966 * Insert a isochronous endpoint into the Host Controller's (HC) interrupt 3967 * lattice tree. A isochronous endpoint will be inserted at the end of the 3968 * 1ms interrupt endpoint list. 3969 */ 3970 static void 3971 ohci_insert_isoc_ed( 3972 ohci_state_t *ohcip, 3973 ohci_pipe_private_t *pp) 3974 { 3975 ohci_ed_t *next_lattice_ept, *lattice_ept; 3976 ohci_ed_t *ept = pp->pp_ept; 3977 uint_t node; 3978 3979 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 3980 3981 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 3982 "ohci_insert_isoc_ed:"); 3983 3984 /* 3985 * The appropriate node was found during the opening of the pipe. 3986 * This node must be root of the interrupt lattice tree. 3987 */ 3988 node = pp->pp_node; 3989 3990 ASSERT(node == 0); 3991 3992 /* Find the 1ms interrupt lattice endpoint */ 3993 lattice_ept = &ohcip->ohci_ed_pool_addr[node]; 3994 3995 /* Find the next lattice endpoint */ 3996 next_lattice_ept = ohci_ed_iommu_to_cpu( 3997 ohcip, Get_ED(lattice_ept->hced_next)); 3998 3999 while (next_lattice_ept) { 4000 lattice_ept = next_lattice_ept; 4001 4002 /* Find the next lattice endpoint */ 4003 next_lattice_ept = ohci_ed_iommu_to_cpu( 4004 ohcip, Get_ED(lattice_ept->hced_next)); 4005 } 4006 4007 /* The next pointer is NULL */ 4008 Set_ED(ept->hced_next, NULL); 4009 4010 /* Update the previous pointer */ 4011 Set_ED(ept->hced_prev, ohci_ed_cpu_to_iommu(ohcip, lattice_ept)); 4012 4013 /* Insert this endpoint into the lattice */ 4014 Set_ED(lattice_ept->hced_next, ohci_ed_cpu_to_iommu(ohcip, ept)); 4015 4016 /* 4017 * Enable periodic and isoch lists processing if isoch 4018 * open pipe count is zero. 4019 */ 4020 if (!ohcip->ohci_open_isoch_pipe_count) { 4021 4022 Set_OpReg(hcr_control, (Get_OpReg(hcr_control) | 4023 HCR_CONTROL_PLE | HCR_CONTROL_IE)); 4024 } 4025 4026 ohcip->ohci_open_periodic_pipe_count++; 4027 ohcip->ohci_open_isoch_pipe_count++; 4028 } 4029 4030 4031 /* 4032 * ohci_modify_sKip_bit: 4033 * 4034 * Modify the sKip bit on the Host Controller (HC) Endpoint Descriptor (ED). 4035 */ 4036 static void 4037 ohci_modify_sKip_bit( 4038 ohci_state_t *ohcip, 4039 ohci_pipe_private_t *pp, 4040 skip_bit_t action, 4041 usb_flags_t flag) 4042 { 4043 ohci_ed_t *ept = pp->pp_ept; 4044 4045 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4046 "ohci_modify_sKip_bit: action = 0x%x flag = 0x%x", 4047 action, flag); 4048 4049 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 4050 4051 if (action == CLEAR_sKip) { 4052 /* 4053 * If the skip bit is to be cleared, just clear it. 4054 * there shouldn't be any race condition problems. 4055 * If the host controller reads the bit before the 4056 * driver has a chance to set the bit, the bit will 4057 * be reread on the next frame. 4058 */ 4059 Set_ED(ept->hced_ctrl, (Get_ED(ept->hced_ctrl) & ~HC_EPT_sKip)); 4060 } else { 4061 /* Sync ED and TD pool */ 4062 if (flag & OHCI_FLAGS_DMA_SYNC) { 4063 Sync_ED_TD_Pool(ohcip); 4064 } 4065 4066 /* Check Halt or Skip bit is already set */ 4067 if ((Get_ED(ept->hced_headp) & HC_EPT_Halt) || 4068 (Get_ED(ept->hced_ctrl) & HC_EPT_sKip)) { 4069 4070 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4071 "ohci_modify_sKip_bit: " 4072 "Halt or Skip bit is already set"); 4073 } else { 4074 /* 4075 * The action is to set the skip bit. In order to 4076 * be sure that the HCD has seen the sKip bit, wait 4077 * for the next start of frame. 4078 */ 4079 Set_ED(ept->hced_ctrl, 4080 (Get_ED(ept->hced_ctrl) | HC_EPT_sKip)); 4081 4082 if (flag & OHCI_FLAGS_SLEEP) { 4083 /* Wait for the next SOF */ 4084 (void) ohci_wait_for_sof(ohcip); 4085 4086 /* Sync ED and TD pool */ 4087 if (flag & OHCI_FLAGS_DMA_SYNC) { 4088 Sync_ED_TD_Pool(ohcip); 4089 } 4090 } 4091 } 4092 } 4093 } 4094 4095 4096 /* 4097 * ohci_remove_ed: 4098 * 4099 * Remove the Endpoint Descriptor (ED) from the Host Controller's appropriate 4100 * endpoint list. 4101 */ 4102 static void 4103 ohci_remove_ed( 4104 ohci_state_t *ohcip, 4105 ohci_pipe_private_t *pp) 4106 { 4107 uchar_t attributes; 4108 4109 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 4110 4111 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4112 "ohci_remove_ed:"); 4113 4114 attributes = pp->pp_pipe_handle->p_ep.bmAttributes & USB_EP_ATTR_MASK; 4115 4116 switch (attributes) { 4117 case USB_EP_ATTR_CONTROL: 4118 ohci_remove_ctrl_ed(ohcip, pp); 4119 break; 4120 case USB_EP_ATTR_BULK: 4121 ohci_remove_bulk_ed(ohcip, pp); 4122 break; 4123 case USB_EP_ATTR_INTR: 4124 case USB_EP_ATTR_ISOCH: 4125 ohci_remove_periodic_ed(ohcip, pp); 4126 break; 4127 } 4128 } 4129 4130 4131 /* 4132 * ohci_remove_ctrl_ed: 4133 * 4134 * Remove a control Endpoint Descriptor (ED) from the Host Controller's (HC) 4135 * control endpoint list. 4136 */ 4137 static void 4138 ohci_remove_ctrl_ed( 4139 ohci_state_t *ohcip, 4140 ohci_pipe_private_t *pp) 4141 { 4142 ohci_ed_t *ept = pp->pp_ept; /* ept to be removed */ 4143 4144 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4145 "ohci_remove_ctrl_ed:"); 4146 4147 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 4148 4149 /* The control list should already be stopped */ 4150 ASSERT(!(Get_OpReg(hcr_control) & HCR_CONTROL_CLE)); 4151 4152 ohcip->ohci_open_ctrl_pipe_count--; 4153 4154 /* Detach the endpoint from the list that it's on */ 4155 ohci_detach_ed_from_list(ohcip, ept, USB_EP_ATTR_CONTROL); 4156 4157 /* 4158 * If next endpoint pointed by endpoint to be removed is not NULL 4159 * then set current control pointer to the next endpoint pointed by 4160 * endpoint to be removed. Otherwise set current control pointer to 4161 * the beginning of the control list. 4162 */ 4163 if (Get_ED(ept->hced_next)) { 4164 Set_OpReg(hcr_ctrl_curr, Get_ED(ept->hced_next)); 4165 } else { 4166 Set_OpReg(hcr_ctrl_curr, Get_OpReg(hcr_ctrl_head)); 4167 } 4168 4169 if (ohcip->ohci_open_ctrl_pipe_count) { 4170 ASSERT(Get_OpReg(hcr_ctrl_head)); 4171 4172 /* Reenable the control list */ 4173 Set_OpReg(hcr_control, 4174 (Get_OpReg(hcr_control) | HCR_CONTROL_CLE)); 4175 } 4176 4177 ohci_insert_ed_on_reclaim_list(ohcip, pp); 4178 } 4179 4180 4181 /* 4182 * ohci_remove_bulk_ed: 4183 * 4184 * Remove free the bulk Endpoint Descriptor (ED) from the Host Controller's 4185 * (HC) bulk endpoint list. 4186 */ 4187 static void 4188 ohci_remove_bulk_ed( 4189 ohci_state_t *ohcip, 4190 ohci_pipe_private_t *pp) 4191 { 4192 ohci_ed_t *ept = pp->pp_ept; /* ept to be removed */ 4193 4194 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4195 "ohci_remove_bulk_ed:"); 4196 4197 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 4198 4199 /* The bulk list should already be stopped */ 4200 ASSERT(!(Get_OpReg(hcr_control) & HCR_CONTROL_BLE)); 4201 4202 ohcip->ohci_open_bulk_pipe_count--; 4203 4204 /* Detach the endpoint from the bulk list */ 4205 ohci_detach_ed_from_list(ohcip, ept, USB_EP_ATTR_BULK); 4206 4207 /* 4208 * If next endpoint pointed by endpoint to be removed is not NULL 4209 * then set current bulk pointer to the next endpoint pointed by 4210 * endpoint to be removed. Otherwise set current bulk pointer to 4211 * the beginning of the bulk list. 4212 */ 4213 if (Get_ED(ept->hced_next)) { 4214 Set_OpReg(hcr_bulk_curr, Get_ED(ept->hced_next)); 4215 } else { 4216 Set_OpReg(hcr_bulk_curr, Get_OpReg(hcr_bulk_head)); 4217 } 4218 4219 if (ohcip->ohci_open_bulk_pipe_count) { 4220 ASSERT(Get_OpReg(hcr_bulk_head)); 4221 4222 /* Re-enable the bulk list */ 4223 Set_OpReg(hcr_control, 4224 (Get_OpReg(hcr_control) | HCR_CONTROL_BLE)); 4225 } 4226 4227 ohci_insert_ed_on_reclaim_list(ohcip, pp); 4228 } 4229 4230 4231 /* 4232 * ohci_remove_periodic_ed: 4233 * 4234 * Set up an periodic endpoint to be removed from the Host Controller's (HC) 4235 * interrupt lattice tree. The Endpoint Descriptor (ED) will be freed in the 4236 * interrupt handler. 4237 */ 4238 static void 4239 ohci_remove_periodic_ed( 4240 ohci_state_t *ohcip, 4241 ohci_pipe_private_t *pp) 4242 { 4243 ohci_ed_t *ept = pp->pp_ept; /* ept to be removed */ 4244 uint_t ept_type; 4245 4246 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4247 "ohci_remove_periodic_ed:"); 4248 4249 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 4250 4251 ASSERT((Get_ED(ept->hced_tailp) & HC_EPT_TD_TAIL) == 4252 (Get_ED(ept->hced_headp) & HC_EPT_TD_HEAD)); 4253 4254 ohcip->ohci_open_periodic_pipe_count--; 4255 4256 ept_type = pp->pp_pipe_handle-> 4257 p_ep.bmAttributes & USB_EP_ATTR_MASK; 4258 4259 if (ept_type == USB_EP_ATTR_ISOCH) { 4260 ohcip->ohci_open_isoch_pipe_count--; 4261 } 4262 4263 /* Store the node number */ 4264 Set_ED(ept->hced_node, pp->pp_node); 4265 4266 /* Remove the endpoint from interrupt lattice tree */ 4267 ohci_detach_ed_from_list(ohcip, ept, ept_type); 4268 4269 /* 4270 * Disable isoch list processing if isoch open pipe count 4271 * is zero. 4272 */ 4273 if (!ohcip->ohci_open_isoch_pipe_count) { 4274 Set_OpReg(hcr_control, 4275 (Get_OpReg(hcr_control) & ~(HCR_CONTROL_IE))); 4276 } 4277 4278 /* 4279 * Disable periodic list processing if periodic (interrupt 4280 * and isochrous) open pipe count is zero. 4281 */ 4282 if (!ohcip->ohci_open_periodic_pipe_count) { 4283 ASSERT(!ohcip->ohci_open_isoch_pipe_count); 4284 4285 Set_OpReg(hcr_control, 4286 (Get_OpReg(hcr_control) & ~(HCR_CONTROL_PLE))); 4287 } 4288 4289 ohci_insert_ed_on_reclaim_list(ohcip, pp); 4290 } 4291 4292 4293 /* 4294 * ohci_detach_ed_from_list: 4295 * 4296 * Remove the Endpoint Descriptor (ED) from the appropriate Host Controller's 4297 * (HC) endpoint list. 4298 */ 4299 static void 4300 ohci_detach_ed_from_list( 4301 ohci_state_t *ohcip, 4302 ohci_ed_t *ept, 4303 uint_t ept_type) 4304 { 4305 ohci_ed_t *prev_ept; /* Previous endpoint */ 4306 ohci_ed_t *next_ept; /* Endpoint after one to be removed */ 4307 uint_t node; 4308 4309 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4310 "ohci_detach_ed_from_list:"); 4311 4312 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 4313 4314 prev_ept = ohci_ed_iommu_to_cpu(ohcip, Get_ED(ept->hced_prev)); 4315 next_ept = ohci_ed_iommu_to_cpu(ohcip, Get_ED(ept->hced_next)); 4316 4317 /* 4318 * If there is no previous endpoint, then this 4319 * endpoint is at the head of the endpoint list. 4320 */ 4321 if (prev_ept == NULL) { 4322 if (next_ept) { 4323 /* 4324 * If this endpoint is the first element of the 4325 * list and there is more than one endpoint on 4326 * the list then perform specific actions based 4327 * on the type of endpoint list. 4328 */ 4329 switch (ept_type) { 4330 case USB_EP_ATTR_CONTROL: 4331 /* Set the head of list to next ept */ 4332 Set_OpReg(hcr_ctrl_head, 4333 Get_ED(ept->hced_next)); 4334 4335 /* Clear prev ptr of next endpoint */ 4336 Set_ED(next_ept->hced_prev, NULL); 4337 break; 4338 case USB_EP_ATTR_BULK: 4339 /* Set the head of list to next ept */ 4340 Set_OpReg(hcr_bulk_head, 4341 Get_ED(ept->hced_next)); 4342 4343 /* Clear prev ptr of next endpoint */ 4344 Set_ED(next_ept->hced_prev, NULL); 4345 break; 4346 case USB_EP_ATTR_INTR: 4347 /* 4348 * HCCA area should point 4349 * directly to this ept. 4350 */ 4351 ASSERT(Get_ED(ept->hced_node) >= 4352 NUM_STATIC_NODES); 4353 4354 /* Get the hcca interrupt table index */ 4355 node = ohci_hcca_intr_index( 4356 Get_ED(ept->hced_node)); 4357 4358 /* 4359 * Delete the ept from the 4360 * bottom of the tree. 4361 */ 4362 Set_HCCA(ohcip->ohci_hccap-> 4363 HccaIntTble[node], Get_ED(ept->hced_next)); 4364 4365 /* 4366 * Update the previous pointer 4367 * of ept->hced_next 4368 */ 4369 if (Get_ED(next_ept->hced_state) != 4370 HC_EPT_STATIC) { 4371 4372 Set_ED(next_ept->hced_prev, NULL); 4373 } 4374 4375 break; 4376 case USB_EP_ATTR_ISOCH: 4377 default: 4378 break; 4379 } 4380 } else { 4381 /* 4382 * If there was only one element on the list 4383 * perform specific actions based on the type 4384 * of the list. 4385 */ 4386 switch (ept_type) { 4387 case USB_EP_ATTR_CONTROL: 4388 /* Set the head to NULL */ 4389 Set_OpReg(hcr_ctrl_head, NULL); 4390 break; 4391 case USB_EP_ATTR_BULK: 4392 /* Set the head to NULL */ 4393 Set_OpReg(hcr_bulk_head, NULL); 4394 break; 4395 case USB_EP_ATTR_INTR: 4396 case USB_EP_ATTR_ISOCH: 4397 default: 4398 break; 4399 } 4400 } 4401 } else { 4402 /* The previous ept points to the next one */ 4403 Set_ED(prev_ept->hced_next, Get_ED(ept->hced_next)); 4404 4405 /* 4406 * Set the previous ptr of the next_ept to prev_ept 4407 * if this isn't the last endpoint on the list 4408 */ 4409 if ((next_ept) && 4410 (Get_ED(next_ept->hced_state) != HC_EPT_STATIC)) { 4411 4412 /* Set the previous ptr of the next one */ 4413 Set_ED(next_ept->hced_prev, Get_ED(ept->hced_prev)); 4414 } 4415 } 4416 } 4417 4418 4419 /* 4420 * ohci_insert_ed_on_reclaim_list: 4421 * 4422 * Insert Endpoint onto the reclaim list 4423 */ 4424 static void 4425 ohci_insert_ed_on_reclaim_list( 4426 ohci_state_t *ohcip, 4427 ohci_pipe_private_t *pp) 4428 { 4429 ohci_ed_t *ept = pp->pp_ept; /* ept to be removed */ 4430 ohci_ed_t *next_ept, *prev_ept; 4431 usb_frame_number_t frame_number; 4432 4433 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 4434 4435 /* 4436 * Read current usb frame number and add appropriate number of 4437 * usb frames needs to wait before reclaiming current endpoint. 4438 */ 4439 frame_number = 4440 ohci_get_current_frame_number(ohcip) + MAX_SOF_WAIT_COUNT; 4441 4442 /* Store 32bit ID */ 4443 Set_ED(ept->hced_reclaim_frame, 4444 ((uint32_t)(OHCI_GET_ID((void *)(uintptr_t)frame_number)))); 4445 4446 /* Insert the endpoint onto the reclaimation list */ 4447 if (ohcip->ohci_reclaim_list) { 4448 next_ept = ohcip->ohci_reclaim_list; 4449 4450 while (next_ept) { 4451 prev_ept = next_ept; 4452 next_ept = ohci_ed_iommu_to_cpu(ohcip, 4453 Get_ED(next_ept->hced_reclaim_next)); 4454 } 4455 4456 Set_ED(prev_ept->hced_reclaim_next, 4457 ohci_ed_cpu_to_iommu(ohcip, ept)); 4458 } else { 4459 ohcip->ohci_reclaim_list = ept; 4460 } 4461 4462 ASSERT(Get_ED(ept->hced_reclaim_next) == NULL); 4463 4464 /* Enable the SOF interrupt */ 4465 Set_OpReg(hcr_intr_enable, HCR_INTR_SOF); 4466 } 4467 4468 4469 /* 4470 * ohci_deallocate_ed: 4471 * NOTE: This function is also called from POLLED MODE. 4472 * 4473 * Deallocate a Host Controller's (HC) Endpoint Descriptor (ED). 4474 */ 4475 void 4476 ohci_deallocate_ed( 4477 ohci_state_t *ohcip, 4478 ohci_ed_t *old_ed) 4479 { 4480 ohci_td_t *dummy_td; 4481 4482 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 4483 "ohci_deallocate_ed:"); 4484 4485 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 4486 4487 dummy_td = ohci_td_iommu_to_cpu(ohcip, Get_ED(old_ed->hced_headp)); 4488 4489 if (dummy_td) { 4490 4491 ASSERT(Get_TD(dummy_td->hctd_state) == HC_TD_DUMMY); 4492 ohci_deallocate_td(ohcip, dummy_td); 4493 } 4494 4495 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 4496 "ohci_deallocate_ed: Deallocated 0x%p", (void *)old_ed); 4497 4498 bzero((void *)old_ed, sizeof (ohci_ed_t)); 4499 Set_ED(old_ed->hced_state, HC_EPT_FREE); 4500 } 4501 4502 4503 /* 4504 * ohci_ed_cpu_to_iommu: 4505 * NOTE: This function is also called from POLLED MODE. 4506 * 4507 * This function converts for the given Endpoint Descriptor (ED) CPU address 4508 * to IO address. 4509 */ 4510 uint32_t 4511 ohci_ed_cpu_to_iommu( 4512 ohci_state_t *ohcip, 4513 ohci_ed_t *addr) 4514 { 4515 uint32_t ed; 4516 4517 ed = (uint32_t)ohcip->ohci_ed_pool_cookie.dmac_address + 4518 (uint32_t)((uintptr_t)addr - (uintptr_t)(ohcip->ohci_ed_pool_addr)); 4519 4520 ASSERT(ed >= ohcip->ohci_ed_pool_cookie.dmac_address); 4521 ASSERT(ed <= ohcip->ohci_ed_pool_cookie.dmac_address + 4522 sizeof (ohci_ed_t) * ohci_ed_pool_size); 4523 4524 return (ed); 4525 } 4526 4527 4528 /* 4529 * ohci_ed_iommu_to_cpu: 4530 * 4531 * This function converts for the given Endpoint Descriptor (ED) IO address 4532 * to CPU address. 4533 */ 4534 static ohci_ed_t * 4535 ohci_ed_iommu_to_cpu( 4536 ohci_state_t *ohcip, 4537 uintptr_t addr) 4538 { 4539 ohci_ed_t *ed; 4540 4541 if (addr == NULL) { 4542 4543 return (NULL); 4544 } 4545 4546 ed = (ohci_ed_t *)((uintptr_t) 4547 (addr - ohcip->ohci_ed_pool_cookie.dmac_address) + 4548 (uintptr_t)ohcip->ohci_ed_pool_addr); 4549 4550 ASSERT(ed >= ohcip->ohci_ed_pool_addr); 4551 ASSERT((uintptr_t)ed <= (uintptr_t)ohcip->ohci_ed_pool_addr + 4552 (uintptr_t)(sizeof (ohci_ed_t) * ohci_ed_pool_size)); 4553 4554 return (ed); 4555 } 4556 4557 4558 /* 4559 * Transfer Descriptor manipulations functions 4560 */ 4561 4562 /* 4563 * ohci_initialize_dummy: 4564 * 4565 * An Endpoint Descriptor (ED) has a dummy Transfer Descriptor (TD) on the 4566 * end of its TD list. Initially, both the head and tail pointers of the ED 4567 * point to the dummy TD. 4568 */ 4569 static int 4570 ohci_initialize_dummy( 4571 ohci_state_t *ohcip, 4572 ohci_ed_t *ept) 4573 { 4574 ohci_td_t *dummy; 4575 4576 /* Obtain a dummy TD */ 4577 dummy = ohci_allocate_td_from_pool(ohcip); 4578 4579 if (dummy == NULL) { 4580 return (USB_NO_RESOURCES); 4581 } 4582 4583 /* 4584 * Both the head and tail pointers of an ED point 4585 * to this new dummy TD. 4586 */ 4587 Set_ED(ept->hced_headp, (ohci_td_cpu_to_iommu(ohcip, dummy))); 4588 Set_ED(ept->hced_tailp, (ohci_td_cpu_to_iommu(ohcip, dummy))); 4589 4590 return (USB_SUCCESS); 4591 } 4592 4593 /* 4594 * ohci_allocate_ctrl_resources: 4595 * 4596 * Calculates the number of tds necessary for a ctrl transfer, and allocates 4597 * all the resources necessary. 4598 * 4599 * Returns NULL if there is insufficient resources otherwise TW. 4600 */ 4601 static ohci_trans_wrapper_t * 4602 ohci_allocate_ctrl_resources( 4603 ohci_state_t *ohcip, 4604 ohci_pipe_private_t *pp, 4605 usb_ctrl_req_t *ctrl_reqp, 4606 usb_flags_t usb_flags) 4607 { 4608 size_t td_count = 2; 4609 ohci_trans_wrapper_t *tw; 4610 4611 /* Add one more td for data phase */ 4612 if (ctrl_reqp->ctrl_wLength) { 4613 td_count++; 4614 } 4615 4616 tw = ohci_allocate_tw_resources(ohcip, pp, 4617 ctrl_reqp->ctrl_wLength + SETUP_SIZE, 4618 usb_flags, td_count); 4619 4620 return (tw); 4621 } 4622 4623 /* 4624 * ohci_insert_ctrl_req: 4625 * 4626 * Create a Transfer Descriptor (TD) and a data buffer for a control endpoint. 4627 */ 4628 /* ARGSUSED */ 4629 static void 4630 ohci_insert_ctrl_req( 4631 ohci_state_t *ohcip, 4632 usba_pipe_handle_data_t *ph, 4633 usb_ctrl_req_t *ctrl_reqp, 4634 ohci_trans_wrapper_t *tw, 4635 usb_flags_t usb_flags) 4636 { 4637 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 4638 uchar_t bmRequestType = ctrl_reqp->ctrl_bmRequestType; 4639 uchar_t bRequest = ctrl_reqp->ctrl_bRequest; 4640 uint16_t wValue = ctrl_reqp->ctrl_wValue; 4641 uint16_t wIndex = ctrl_reqp->ctrl_wIndex; 4642 uint16_t wLength = ctrl_reqp->ctrl_wLength; 4643 mblk_t *data = ctrl_reqp->ctrl_data; 4644 uint32_t ctrl = 0; 4645 int sdata; 4646 4647 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4648 "ohci_insert_ctrl_req:"); 4649 4650 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 4651 4652 /* 4653 * Save current control request pointer and timeout values 4654 * in transfer wrapper. 4655 */ 4656 tw->tw_curr_xfer_reqp = (usb_opaque_t)ctrl_reqp; 4657 tw->tw_timeout = ctrl_reqp->ctrl_timeout ? 4658 ctrl_reqp->ctrl_timeout : OHCI_DEFAULT_XFER_TIMEOUT; 4659 4660 /* 4661 * Initialize the callback and any callback data for when 4662 * the td completes. 4663 */ 4664 tw->tw_handle_td = ohci_handle_ctrl_td; 4665 tw->tw_handle_callback_value = NULL; 4666 4667 /* Create the first four bytes of the setup packet */ 4668 sdata = (bmRequestType << 24) | (bRequest << 16) | 4669 (((wValue >> 8) | (wValue << 8)) & 0x0000FFFF); 4670 4671 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4672 "ohci_create_setup_pkt: sdata = 0x%x", sdata); 4673 4674 ddi_put32(tw->tw_accesshandle, (uint_t *)tw->tw_buf, sdata); 4675 4676 /* Create the second four bytes */ 4677 sdata = (uint32_t)(((((wIndex >> 8) | 4678 (wIndex << 8)) << 16) & 0xFFFF0000) | 4679 (((wLength >> 8) | (wLength << 8)) & 0x0000FFFF)); 4680 4681 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 4682 "ohci_create_setup_pkt: sdata = 0x%x", sdata); 4683 4684 ddi_put32(tw->tw_accesshandle, 4685 (uint_t *)(tw->tw_buf + sizeof (uint_t)), sdata); 4686 4687 ctrl = HC_TD_SETUP|HC_TD_MS_DT|HC_TD_DT_0|HC_TD_6I; 4688 4689 /* 4690 * The TD's are placed on the ED one at a time. 4691 * Once this TD is placed on the done list, the 4692 * data or status phase TD will be enqueued. 4693 */ 4694 (void) ohci_insert_hc_td(ohcip, ctrl, 4695 tw->tw_cookie.dmac_address, SETUP_SIZE, 4696 OHCI_CTRL_SETUP_PHASE, pp, tw); 4697 4698 USB_DPRINTF_L3(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 4699 "Create_setup: pp 0x%p", (void *)pp); 4700 4701 /* 4702 * If this control transfer has a data phase, record the 4703 * direction. If the data phase is an OUT transaction, 4704 * copy the data into the buffer of the transfer wrapper. 4705 */ 4706 if (wLength != 0) { 4707 /* There is a data stage. Find the direction */ 4708 if (bmRequestType & USB_DEV_REQ_DEV_TO_HOST) { 4709 tw->tw_direction = HC_TD_IN; 4710 } else { 4711 tw->tw_direction = HC_TD_OUT; 4712 4713 /* Copy the data into the message */ 4714 ddi_rep_put8(tw->tw_accesshandle, data->b_rptr, 4715 (uint8_t *)(tw->tw_buf + SETUP_SIZE), 4716 wLength, DDI_DEV_AUTOINCR); 4717 4718 } 4719 4720 ctrl = (ctrl_reqp->ctrl_attributes & USB_ATTRS_SHORT_XFER_OK) ? 4721 HC_TD_R : 0; 4722 4723 /* 4724 * There is a data stage. 4725 * Find the direction. 4726 */ 4727 if (tw->tw_direction == HC_TD_IN) { 4728 ctrl = ctrl|HC_TD_IN|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_6I; 4729 } else { 4730 ctrl = ctrl|HC_TD_OUT|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_6I; 4731 } 4732 4733 /* 4734 * Create the TD. If this is an OUT transaction, 4735 * the data is already in the buffer of the TW. 4736 */ 4737 (void) ohci_insert_hc_td(ohcip, ctrl, 4738 tw->tw_cookie.dmac_address + SETUP_SIZE, 4739 tw->tw_length - SETUP_SIZE, OHCI_CTRL_DATA_PHASE, 4740 pp, tw); 4741 4742 /* 4743 * The direction of the STATUS TD depends on 4744 * the direction of the transfer. 4745 */ 4746 if (tw->tw_direction == HC_TD_IN) { 4747 ctrl = HC_TD_OUT|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_1I; 4748 } else { 4749 ctrl = HC_TD_IN|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_1I; 4750 } 4751 } else { 4752 ctrl = HC_TD_IN|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_1I; 4753 } 4754 4755 /* Status stage */ 4756 (void) ohci_insert_hc_td(ohcip, ctrl, NULL, 4757 0, OHCI_CTRL_STATUS_PHASE, pp, tw); 4758 4759 /* Indicate that the control list is filled */ 4760 Set_OpReg(hcr_cmd_status, HCR_STATUS_CLF); 4761 4762 /* Start the timer for this control transfer */ 4763 ohci_start_xfer_timer(ohcip, pp, tw); 4764 } 4765 4766 /* 4767 * ohci_allocate_bulk_resources: 4768 * 4769 * Calculates the number of tds necessary for a ctrl transfer, and allocates 4770 * all the resources necessary. 4771 * 4772 * Returns NULL if there is insufficient resources otherwise TW. 4773 */ 4774 static ohci_trans_wrapper_t * 4775 ohci_allocate_bulk_resources( 4776 ohci_state_t *ohcip, 4777 ohci_pipe_private_t *pp, 4778 usb_bulk_req_t *bulk_reqp, 4779 usb_flags_t usb_flags) 4780 { 4781 size_t td_count = 0; 4782 ohci_trans_wrapper_t *tw; 4783 4784 /* Check the size of bulk request */ 4785 if (bulk_reqp->bulk_len > OHCI_MAX_BULK_XFER_SIZE) { 4786 4787 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4788 "ohci_allocate_bulk_resources: Bulk request size 0x%x is " 4789 "more than 0x%x", bulk_reqp->bulk_len, 4790 OHCI_MAX_BULK_XFER_SIZE); 4791 4792 return (NULL); 4793 } 4794 4795 /* Get the required bulk packet size */ 4796 td_count = bulk_reqp->bulk_len / OHCI_MAX_TD_XFER_SIZE; 4797 if (bulk_reqp->bulk_len % OHCI_MAX_TD_XFER_SIZE) { 4798 td_count++; 4799 } 4800 4801 tw = ohci_allocate_tw_resources(ohcip, pp, bulk_reqp->bulk_len, 4802 usb_flags, td_count); 4803 4804 return (tw); 4805 } 4806 4807 /* 4808 * ohci_insert_bulk_req: 4809 * 4810 * Create a Transfer Descriptor (TD) and a data buffer for a bulk 4811 * endpoint. 4812 */ 4813 /* ARGSUSED */ 4814 static void 4815 ohci_insert_bulk_req( 4816 ohci_state_t *ohcip, 4817 usba_pipe_handle_data_t *ph, 4818 usb_bulk_req_t *bulk_reqp, 4819 ohci_trans_wrapper_t *tw, 4820 usb_flags_t flags) 4821 { 4822 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 4823 uint_t bulk_pkt_size, count; 4824 size_t residue = 0, len = 0; 4825 uint32_t ctrl = 0; 4826 int pipe_dir; 4827 4828 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4829 "ohci_insert_bulk_req: bulk_reqp = 0x%p flags = 0x%x", 4830 bulk_reqp, flags); 4831 4832 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 4833 4834 /* Get the bulk pipe direction */ 4835 pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK; 4836 4837 /* Get the required bulk packet size */ 4838 bulk_pkt_size = min(bulk_reqp->bulk_len, OHCI_MAX_TD_XFER_SIZE); 4839 4840 residue = tw->tw_length % bulk_pkt_size; 4841 4842 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4843 "ohci_insert_bulk_req: bulk_pkt_size = %d", bulk_pkt_size); 4844 4845 /* 4846 * Save current bulk request pointer and timeout values 4847 * in transfer wrapper. 4848 */ 4849 tw->tw_curr_xfer_reqp = (usb_opaque_t)bulk_reqp; 4850 tw->tw_timeout = bulk_reqp->bulk_timeout; 4851 4852 /* 4853 * Initialize the callback and any callback 4854 * data required when the td completes. 4855 */ 4856 tw->tw_handle_td = ohci_handle_bulk_td; 4857 tw->tw_handle_callback_value = NULL; 4858 4859 tw->tw_direction = 4860 (pipe_dir == USB_EP_DIR_OUT) ? HC_TD_OUT : HC_TD_IN; 4861 4862 if (tw->tw_direction == HC_TD_OUT) { 4863 4864 ASSERT(bulk_reqp->bulk_data != NULL); 4865 4866 /* Copy the data into the message */ 4867 ddi_rep_put8(tw->tw_accesshandle, 4868 bulk_reqp->bulk_data->b_rptr, (uint8_t *)tw->tw_buf, 4869 bulk_reqp->bulk_len, DDI_DEV_AUTOINCR); 4870 } 4871 4872 ctrl = tw->tw_direction|HC_TD_DT_0|HC_TD_6I; 4873 4874 /* Insert all the bulk TDs */ 4875 for (count = 0; count < tw->tw_num_tds; count++) { 4876 4877 /* Check for last td */ 4878 if (count == (tw->tw_num_tds - 1)) { 4879 4880 ctrl = ((ctrl & ~HC_TD_DI) | HC_TD_1I); 4881 4882 /* Check for inserting residue data */ 4883 if (residue) { 4884 bulk_pkt_size = residue; 4885 } 4886 4887 /* 4888 * Only set the round bit on the last TD, to ensure 4889 * the controller will always HALT the ED in case of 4890 * a short transfer. 4891 */ 4892 if (bulk_reqp->bulk_attributes & 4893 USB_ATTRS_SHORT_XFER_OK) { 4894 ctrl |= HC_TD_R; 4895 } 4896 } 4897 4898 /* Insert the TD onto the endpoint */ 4899 (void) ohci_insert_hc_td(ohcip, ctrl, 4900 tw->tw_cookie.dmac_address + len, 4901 bulk_pkt_size, 0, pp, tw); 4902 4903 len = len + bulk_pkt_size; 4904 } 4905 4906 /* Indicate that the bulk list is filled */ 4907 Set_OpReg(hcr_cmd_status, HCR_STATUS_BLF); 4908 4909 /* Start the timer for this bulk transfer */ 4910 ohci_start_xfer_timer(ohcip, pp, tw); 4911 } 4912 4913 4914 /* 4915 * ohci_start_periodic_pipe_polling: 4916 * NOTE: This function is also called from POLLED MODE. 4917 */ 4918 int 4919 ohci_start_periodic_pipe_polling( 4920 ohci_state_t *ohcip, 4921 usba_pipe_handle_data_t *ph, 4922 usb_opaque_t periodic_in_reqp, 4923 usb_flags_t flags) 4924 { 4925 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 4926 usb_ep_descr_t *eptd = &ph->p_ep; 4927 int error = USB_SUCCESS; 4928 4929 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4930 "ohci_start_periodic_pipe_polling: ep%d", 4931 ph->p_ep.bEndpointAddress & USB_EP_NUM_MASK); 4932 4933 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 4934 4935 /* 4936 * Check and handle start polling on root hub interrupt pipe. 4937 */ 4938 if ((ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) && 4939 ((eptd->bmAttributes & USB_EP_ATTR_MASK) == 4940 USB_EP_ATTR_INTR)) { 4941 4942 error = ohci_handle_root_hub_pipe_start_intr_polling(ph, 4943 (usb_intr_req_t *)periodic_in_reqp, flags); 4944 4945 return (error); 4946 } 4947 4948 switch (pp->pp_state) { 4949 case OHCI_PIPE_STATE_IDLE: 4950 /* Save the Original client's Periodic IN request */ 4951 pp->pp_client_periodic_in_reqp = periodic_in_reqp; 4952 4953 /* 4954 * This pipe is uninitialized or if a valid TD is 4955 * not found then insert a TD on the interrupt or 4956 * isochronous IN endpoint. 4957 */ 4958 error = ohci_start_pipe_polling(ohcip, ph, flags); 4959 4960 if (error != USB_SUCCESS) { 4961 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4962 "ohci_start_periodic_pipe_polling: " 4963 "Start polling failed"); 4964 4965 pp->pp_client_periodic_in_reqp = NULL; 4966 4967 return (error); 4968 } 4969 4970 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 4971 "ohci_start_periodic_pipe_polling: PP = 0x%p", pp); 4972 4973 ASSERT((pp->pp_tw_head != NULL) && (pp->pp_tw_tail != NULL)); 4974 4975 break; 4976 case OHCI_PIPE_STATE_ACTIVE: 4977 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4978 "ohci_start_periodic_pipe_polling: " 4979 "Polling is already in progress"); 4980 4981 error = USB_FAILURE; 4982 break; 4983 case OHCI_PIPE_STATE_ERROR: 4984 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4985 "ohci_start_periodic_pipe_polling: " 4986 "Pipe is halted and perform reset before restart polling"); 4987 4988 error = USB_FAILURE; 4989 break; 4990 default: 4991 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 4992 "ohci_start_periodic_pipe_polling: Undefined state"); 4993 4994 error = USB_FAILURE; 4995 break; 4996 } 4997 4998 return (error); 4999 } 5000 5001 5002 /* 5003 * ohci_start_pipe_polling: 5004 * 5005 * Insert the number of periodic requests corresponding to polling 5006 * interval as calculated during pipe open. 5007 */ 5008 static int 5009 ohci_start_pipe_polling( 5010 ohci_state_t *ohcip, 5011 usba_pipe_handle_data_t *ph, 5012 usb_flags_t flags) 5013 { 5014 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 5015 usb_ep_descr_t *eptd = &ph->p_ep; 5016 ohci_trans_wrapper_t *tw_list, *tw; 5017 int i, total_tws; 5018 int error = USB_SUCCESS; 5019 5020 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5021 "ohci_start_pipe_polling:"); 5022 5023 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 5024 5025 /* 5026 * For the start polling, pp_max_periodic_req_cnt will be zero 5027 * and for the restart polling request, it will be non zero. 5028 * 5029 * In case of start polling request, find out number of requests 5030 * required for the Interrupt IN endpoints corresponding to the 5031 * endpoint polling interval. For Isochronous IN endpoints, it is 5032 * always fixed since its polling interval will be one ms. 5033 */ 5034 if (pp->pp_max_periodic_req_cnt == 0) { 5035 5036 ohci_set_periodic_pipe_polling(ohcip, ph); 5037 } 5038 5039 ASSERT(pp->pp_max_periodic_req_cnt != 0); 5040 5041 /* Allocate all the necessary resources for the IN transfer */ 5042 tw_list = NULL; 5043 total_tws = pp->pp_max_periodic_req_cnt - pp->pp_cur_periodic_req_cnt; 5044 for (i = 0; i < total_tws; i++) { 5045 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) { 5046 case USB_EP_ATTR_INTR: 5047 tw = ohci_allocate_intr_resources( 5048 ohcip, ph, NULL, flags); 5049 break; 5050 case USB_EP_ATTR_ISOCH: 5051 tw = ohci_allocate_isoc_resources( 5052 ohcip, ph, NULL, flags); 5053 break; 5054 } 5055 if (tw == NULL) { 5056 error = USB_NO_RESOURCES; 5057 /* There are not enough resources, deallocate the TWs */ 5058 tw = tw_list; 5059 while (tw != NULL) { 5060 tw_list = tw->tw_next; 5061 ohci_deallocate_periodic_in_resource( 5062 ohcip, pp, tw); 5063 ohci_deallocate_tw_resources(ohcip, pp, tw); 5064 tw = tw_list; 5065 } 5066 return (error); 5067 } else { 5068 if (tw_list == NULL) { 5069 tw_list = tw; 5070 } 5071 } 5072 } 5073 5074 i = 0; 5075 while (pp->pp_cur_periodic_req_cnt < pp->pp_max_periodic_req_cnt) { 5076 5077 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5078 "ohci_start_pipe_polling: max = %d curr = %d tw = %p:", 5079 pp->pp_max_periodic_req_cnt, pp->pp_cur_periodic_req_cnt, 5080 tw_list); 5081 5082 tw = tw_list; 5083 tw_list = tw->tw_next; 5084 5085 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) { 5086 case USB_EP_ATTR_INTR: 5087 ohci_insert_intr_req(ohcip, pp, tw, flags); 5088 break; 5089 case USB_EP_ATTR_ISOCH: 5090 error = ohci_insert_isoc_req(ohcip, pp, tw, flags); 5091 break; 5092 } 5093 if (error == USB_SUCCESS) { 5094 pp->pp_cur_periodic_req_cnt++; 5095 } else { 5096 /* 5097 * Deallocate the remaining tw 5098 * The current tw should have already been deallocated 5099 */ 5100 tw = tw_list; 5101 while (tw != NULL) { 5102 tw_list = tw->tw_next; 5103 ohci_deallocate_periodic_in_resource( 5104 ohcip, pp, tw); 5105 ohci_deallocate_tw_resources(ohcip, pp, tw); 5106 tw = tw_list; 5107 } 5108 /* 5109 * If this is the first req return an error. 5110 * Otherwise return success. 5111 */ 5112 if (i != 0) { 5113 error = USB_SUCCESS; 5114 } 5115 5116 break; 5117 } 5118 i++; 5119 } 5120 5121 return (error); 5122 } 5123 5124 5125 /* 5126 * ohci_set_periodic_pipe_polling: 5127 * 5128 * Calculate the number of periodic requests needed corresponding to the 5129 * interrupt/isochronous IN endpoints polling interval. Table below gives 5130 * the number of periodic requests needed for the interrupt/isochronous 5131 * IN endpoints according to endpoint polling interval. 5132 * 5133 * Polling interval Number of periodic requests 5134 * 5135 * 1ms 4 5136 * 2ms 2 5137 * 4ms to 32ms 1 5138 */ 5139 static void 5140 ohci_set_periodic_pipe_polling( 5141 ohci_state_t *ohcip, 5142 usba_pipe_handle_data_t *ph) 5143 { 5144 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 5145 usb_ep_descr_t *endpoint = &ph->p_ep; 5146 uchar_t ep_attr = endpoint->bmAttributes; 5147 uint_t interval; 5148 5149 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5150 "ohci_set_periodic_pipe_polling:"); 5151 5152 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 5153 5154 pp->pp_cur_periodic_req_cnt = 0; 5155 5156 /* 5157 * Check usb flag whether USB_FLAGS_ONE_TIME_POLL flag is 5158 * set and if so, set pp->pp_max_periodic_req_cnt to one. 5159 */ 5160 if (((ep_attr & USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) && 5161 (pp->pp_client_periodic_in_reqp)) { 5162 usb_intr_req_t *intr_reqp = 5163 (usb_intr_req_t *)pp->pp_client_periodic_in_reqp; 5164 5165 if (intr_reqp->intr_attributes & 5166 USB_ATTRS_ONE_XFER) { 5167 5168 pp->pp_max_periodic_req_cnt = INTR_XMS_REQS; 5169 5170 return; 5171 } 5172 } 5173 5174 mutex_enter(&ph->p_usba_device->usb_mutex); 5175 5176 /* 5177 * The ohci_adjust_polling_interval function will not fail 5178 * at this instance since bandwidth allocation is already 5179 * done. Here we are getting only the periodic interval. 5180 */ 5181 interval = ohci_adjust_polling_interval(ohcip, endpoint, 5182 ph->p_usba_device->usb_port_status); 5183 5184 mutex_exit(&ph->p_usba_device->usb_mutex); 5185 5186 switch (interval) { 5187 case INTR_1MS_POLL: 5188 pp->pp_max_periodic_req_cnt = INTR_1MS_REQS; 5189 break; 5190 case INTR_2MS_POLL: 5191 pp->pp_max_periodic_req_cnt = INTR_2MS_REQS; 5192 break; 5193 default: 5194 pp->pp_max_periodic_req_cnt = INTR_XMS_REQS; 5195 break; 5196 } 5197 5198 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5199 "ohci_set_periodic_pipe_polling: Max periodic requests = %d", 5200 pp->pp_max_periodic_req_cnt); 5201 } 5202 5203 /* 5204 * ohci_allocate_intr_resources: 5205 * 5206 * Calculates the number of tds necessary for a intr transfer, and allocates 5207 * all the necessary resources. 5208 * 5209 * Returns NULL if there is insufficient resources otherwise TW. 5210 */ 5211 static ohci_trans_wrapper_t * 5212 ohci_allocate_intr_resources( 5213 ohci_state_t *ohcip, 5214 usba_pipe_handle_data_t *ph, 5215 usb_intr_req_t *intr_reqp, 5216 usb_flags_t flags) 5217 { 5218 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 5219 int pipe_dir; 5220 size_t td_count = 1; 5221 size_t tw_length; 5222 ohci_trans_wrapper_t *tw; 5223 5224 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5225 "ohci_allocate_intr_resources:"); 5226 5227 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 5228 5229 pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK; 5230 5231 /* Get the length of interrupt transfer & alloc data */ 5232 if (intr_reqp) { 5233 tw_length = intr_reqp->intr_len; 5234 } else { 5235 ASSERT(pipe_dir == USB_EP_DIR_IN); 5236 tw_length = (pp->pp_client_periodic_in_reqp) ? 5237 (((usb_intr_req_t *)pp-> 5238 pp_client_periodic_in_reqp)->intr_len) : 5239 ph->p_ep.wMaxPacketSize; 5240 } 5241 5242 /* Check the size of interrupt request */ 5243 if (tw_length > OHCI_MAX_TD_XFER_SIZE) { 5244 5245 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5246 "ohci_allocate_intr_resources: Intr request size 0x%lx is " 5247 "more than 0x%x", tw_length, OHCI_MAX_TD_XFER_SIZE); 5248 5249 return (NULL); 5250 } 5251 5252 if ((tw = ohci_allocate_tw_resources(ohcip, pp, tw_length, 5253 flags, td_count)) == NULL) { 5254 5255 return (NULL); 5256 } 5257 5258 if (pipe_dir == USB_EP_DIR_IN) { 5259 if (ohci_allocate_periodic_in_resource(ohcip, pp, tw, flags) != 5260 USB_SUCCESS) { 5261 5262 ohci_deallocate_tw_resources(ohcip, pp, tw); 5263 return (NULL); 5264 } 5265 tw->tw_direction = HC_TD_IN; 5266 } else { 5267 ASSERT(intr_reqp->intr_data != NULL); 5268 5269 /* Copy the data into the message */ 5270 ddi_rep_put8(tw->tw_accesshandle, 5271 intr_reqp->intr_data->b_rptr, (uint8_t *)tw->tw_buf, 5272 intr_reqp->intr_len, DDI_DEV_AUTOINCR); 5273 5274 tw->tw_curr_xfer_reqp = (usb_opaque_t)intr_reqp; 5275 tw->tw_direction = HC_TD_OUT; 5276 } 5277 5278 if (intr_reqp) { 5279 tw->tw_timeout = intr_reqp->intr_timeout; 5280 } 5281 5282 /* 5283 * Initialize the callback and any callback 5284 * data required when the td completes. 5285 */ 5286 tw->tw_handle_td = ohci_handle_intr_td; 5287 tw->tw_handle_callback_value = NULL; 5288 5289 return (tw); 5290 } 5291 5292 /* 5293 * ohci_insert_intr_req: 5294 * 5295 * Insert an Interrupt request into the Host Controller's periodic list. 5296 */ 5297 /* ARGSUSED */ 5298 static void 5299 ohci_insert_intr_req( 5300 ohci_state_t *ohcip, 5301 ohci_pipe_private_t *pp, 5302 ohci_trans_wrapper_t *tw, 5303 usb_flags_t flags) 5304 { 5305 usb_intr_req_t *curr_intr_reqp = NULL; 5306 uint_t ctrl = 0; 5307 5308 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 5309 5310 ASSERT(tw->tw_curr_xfer_reqp != NULL); 5311 5312 /* Get the current interrupt request pointer */ 5313 curr_intr_reqp = (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 5314 5315 ctrl = tw->tw_direction | HC_TD_DT_0 | HC_TD_1I; 5316 5317 if (curr_intr_reqp->intr_attributes & USB_ATTRS_SHORT_XFER_OK) { 5318 ctrl |= HC_TD_R; 5319 } 5320 5321 /* Insert another interrupt TD */ 5322 (void) ohci_insert_hc_td(ohcip, ctrl, 5323 tw->tw_cookie.dmac_address, tw->tw_length, 0, pp, tw); 5324 5325 /* Start the timer for this Interrupt transfer */ 5326 ohci_start_xfer_timer(ohcip, pp, tw); 5327 } 5328 5329 5330 /* 5331 * ohci_stop_periodic_pipe_polling: 5332 */ 5333 /* ARGSUSED */ 5334 static int 5335 ohci_stop_periodic_pipe_polling( 5336 ohci_state_t *ohcip, 5337 usba_pipe_handle_data_t *ph, 5338 usb_flags_t flags) 5339 { 5340 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 5341 usb_ep_descr_t *eptd = &ph->p_ep; 5342 5343 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5344 "ohci_stop_periodic_pipe_polling: Flags = 0x%x", flags); 5345 5346 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 5347 5348 /* 5349 * Check and handle stop polling on root hub interrupt pipe. 5350 */ 5351 if ((ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) && 5352 ((eptd->bmAttributes & USB_EP_ATTR_MASK) == 5353 USB_EP_ATTR_INTR)) { 5354 5355 ohci_handle_root_hub_pipe_stop_intr_polling( 5356 ph, flags); 5357 return (USB_SUCCESS); 5358 } 5359 5360 if (pp->pp_state != OHCI_PIPE_STATE_ACTIVE) { 5361 5362 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5363 "ohci_stop_periodic_pipe_polling: Polling already stopped"); 5364 5365 return (USB_SUCCESS); 5366 } 5367 5368 /* Set pipe state to pipe stop polling */ 5369 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING; 5370 5371 ohci_pipe_cleanup(ohcip, ph); 5372 5373 return (USB_SUCCESS); 5374 } 5375 5376 /* 5377 * ohci_allocate_isoc_resources: 5378 * 5379 * Calculates the number of tds necessary for a intr transfer, and allocates 5380 * all the necessary resources. 5381 * 5382 * Returns NULL if there is insufficient resources otherwise TW. 5383 */ 5384 static ohci_trans_wrapper_t * 5385 ohci_allocate_isoc_resources( 5386 ohci_state_t *ohcip, 5387 usba_pipe_handle_data_t *ph, 5388 usb_isoc_req_t *isoc_reqp, 5389 usb_flags_t flags) 5390 { 5391 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 5392 int pipe_dir; 5393 uint_t max_pkt_size = ph->p_ep.wMaxPacketSize; 5394 uint_t max_isoc_xfer_size; 5395 usb_isoc_pkt_descr_t *isoc_pkt_descr; 5396 ushort_t isoc_pkt_count; 5397 size_t count, td_count; 5398 size_t tw_length; 5399 ohci_trans_wrapper_t *tw; 5400 5401 5402 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5403 "ohci_allocate_isoc_resources: flags = ox%x", flags); 5404 5405 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 5406 5407 /* 5408 * Check whether pipe is in halted state. 5409 */ 5410 if (pp->pp_state == OHCI_PIPE_STATE_ERROR) { 5411 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5412 "ohci_allocate_isoc_resources:" 5413 "Pipe is in error state, need pipe reset to continue"); 5414 5415 return (NULL); 5416 } 5417 5418 pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK; 5419 5420 /* Calculate the maximum isochronous transfer size */ 5421 max_isoc_xfer_size = OHCI_MAX_ISOC_PKTS_PER_XFER * max_pkt_size; 5422 5423 if (isoc_reqp) { 5424 isoc_pkt_descr = isoc_reqp->isoc_pkt_descr; 5425 isoc_pkt_count = isoc_reqp->isoc_pkts_count; 5426 } else { 5427 isoc_pkt_descr = ((usb_isoc_req_t *) 5428 pp->pp_client_periodic_in_reqp)->isoc_pkt_descr; 5429 5430 isoc_pkt_count = ((usb_isoc_req_t *) 5431 pp->pp_client_periodic_in_reqp)->isoc_pkts_count; 5432 } 5433 5434 /* 5435 * For isochronous IN pipe, get value of number of isochronous 5436 * packets per usb isochronous request 5437 */ 5438 if (pipe_dir == USB_EP_DIR_IN) { 5439 for (count = 0, tw_length = 0; 5440 count < isoc_pkt_count; count++) { 5441 tw_length += isoc_pkt_descr->isoc_pkt_length; 5442 isoc_pkt_descr++; 5443 } 5444 } else { 5445 ASSERT(isoc_reqp != NULL); 5446 tw_length = isoc_reqp->isoc_data->b_wptr - 5447 isoc_reqp->isoc_data->b_rptr; 5448 } 5449 5450 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5451 "ohci_allocate_isoc_resources: length = 0x%lx", tw_length); 5452 5453 /* Check the size of isochronous request */ 5454 if (tw_length > max_isoc_xfer_size) { 5455 5456 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5457 "ohci_allocate_isoc_resources: Maximum isoc request" 5458 "size 0x%x Given isoc request size 0x%lx", 5459 max_isoc_xfer_size, tw_length); 5460 5461 return (NULL); 5462 } 5463 5464 /* 5465 * Each isochronous TD can hold data upto eight isochronous 5466 * data packets. Calculate the number of isochronous TDs needs 5467 * to be insert to complete current isochronous request. 5468 */ 5469 td_count = isoc_pkt_count / OHCI_ISOC_PKTS_PER_TD; 5470 5471 if (isoc_pkt_count % OHCI_ISOC_PKTS_PER_TD) { 5472 td_count++; 5473 } 5474 5475 if ((tw = ohci_allocate_tw_resources(ohcip, pp, tw_length, 5476 flags, td_count)) == NULL) { 5477 return (NULL); 5478 } 5479 5480 if (pipe_dir == USB_EP_DIR_IN) { 5481 if (ohci_allocate_periodic_in_resource(ohcip, pp, tw, flags) != 5482 USB_SUCCESS) { 5483 5484 ohci_deallocate_tw_resources(ohcip, pp, tw); 5485 return (NULL); 5486 } 5487 tw->tw_direction = HC_TD_IN; 5488 } else { 5489 if (tw->tw_length) { 5490 ASSERT(isoc_reqp->isoc_data != NULL); 5491 5492 /* Copy the data into the message */ 5493 ddi_rep_put8(tw->tw_accesshandle, 5494 isoc_reqp->isoc_data->b_rptr, 5495 (uint8_t *)tw->tw_buf, tw->tw_length, 5496 DDI_DEV_AUTOINCR); 5497 } 5498 tw->tw_curr_xfer_reqp = (usb_opaque_t)isoc_reqp; 5499 tw->tw_direction = HC_TD_OUT; 5500 } 5501 5502 /* 5503 * Initialize the callback and any callback 5504 * data required when the td completes. 5505 */ 5506 tw->tw_handle_td = ohci_handle_isoc_td; 5507 tw->tw_handle_callback_value = NULL; 5508 5509 return (tw); 5510 } 5511 5512 /* 5513 * ohci_insert_isoc_req: 5514 * 5515 * Insert an isochronous request into the Host Controller's 5516 * isochronous list. If there is an error is will appropriately 5517 * deallocate the unused resources. 5518 */ 5519 static int 5520 ohci_insert_isoc_req( 5521 ohci_state_t *ohcip, 5522 ohci_pipe_private_t *pp, 5523 ohci_trans_wrapper_t *tw, 5524 uint_t flags) 5525 { 5526 size_t curr_isoc_xfer_offset, curr_isoc_xfer_len; 5527 uint_t isoc_pkts, residue, count; 5528 uint_t i, ctrl, frame_count; 5529 uint_t error = USB_SUCCESS; 5530 usb_isoc_req_t *curr_isoc_reqp; 5531 usb_isoc_pkt_descr_t *curr_isoc_pkt_descr; 5532 5533 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5534 "ohci_insert_isoc_req: flags = 0x%x", flags); 5535 5536 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 5537 5538 /* 5539 * Get the current isochronous request and packet 5540 * descriptor pointers. 5541 */ 5542 curr_isoc_reqp = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp; 5543 curr_isoc_pkt_descr = curr_isoc_reqp->isoc_pkt_descr; 5544 5545 ASSERT(curr_isoc_reqp != NULL); 5546 ASSERT(curr_isoc_reqp->isoc_pkt_descr != NULL); 5547 5548 /* 5549 * Save address of first usb isochronous packet descriptor. 5550 */ 5551 tw->tw_curr_isoc_pktp = curr_isoc_reqp->isoc_pkt_descr; 5552 5553 /* Insert all the isochronous TDs */ 5554 for (count = 0, curr_isoc_xfer_offset = 0, 5555 isoc_pkts = 0; count < tw->tw_num_tds; count++) { 5556 5557 residue = curr_isoc_reqp->isoc_pkts_count - isoc_pkts; 5558 5559 /* Check for inserting residue data */ 5560 if ((count == (tw->tw_num_tds - 1)) && 5561 (residue < OHCI_ISOC_PKTS_PER_TD)) { 5562 frame_count = residue; 5563 } else { 5564 frame_count = OHCI_ISOC_PKTS_PER_TD; 5565 } 5566 5567 curr_isoc_pkt_descr = tw->tw_curr_isoc_pktp; 5568 5569 /* 5570 * Calculate length of isochronous transfer 5571 * for the current TD. 5572 */ 5573 for (i = 0, curr_isoc_xfer_len = 0; 5574 i < frame_count; i++, curr_isoc_pkt_descr++) { 5575 curr_isoc_xfer_len += 5576 curr_isoc_pkt_descr->isoc_pkt_length; 5577 } 5578 5579 /* 5580 * Programm td control field by checking whether this 5581 * is last td. 5582 */ 5583 if (count == (tw->tw_num_tds - 1)) { 5584 ctrl = ((((frame_count - 1) << HC_ITD_FC_SHIFT) & 5585 HC_ITD_FC) | HC_TD_DT_0 | HC_TD_0I); 5586 } else { 5587 ctrl = ((((frame_count - 1) << HC_ITD_FC_SHIFT) & 5588 HC_ITD_FC) | HC_TD_DT_0 | HC_TD_6I); 5589 } 5590 5591 /* Insert the TD into the endpoint */ 5592 if ((error = ohci_insert_hc_td(ohcip, ctrl, 5593 tw->tw_cookie.dmac_address + curr_isoc_xfer_offset, 5594 curr_isoc_xfer_len, 0, pp, tw)) != 5595 USB_SUCCESS) { 5596 tw->tw_num_tds = count; 5597 tw->tw_length = curr_isoc_xfer_offset; 5598 break; 5599 } 5600 5601 isoc_pkts += frame_count; 5602 tw->tw_curr_isoc_pktp += frame_count; 5603 curr_isoc_xfer_offset += curr_isoc_xfer_len; 5604 } 5605 5606 if (error != USB_SUCCESS) { 5607 /* Free periodic in resources */ 5608 if (tw->tw_direction == USB_EP_DIR_IN) { 5609 ohci_deallocate_periodic_in_resource(ohcip, pp, tw); 5610 } 5611 5612 /* Free all resources if IN or if count == 0(for both IN/OUT) */ 5613 if (tw->tw_direction == USB_EP_DIR_IN || count == 0) { 5614 5615 ohci_deallocate_tw_resources(ohcip, pp, tw); 5616 5617 if (pp->pp_cur_periodic_req_cnt) { 5618 /* 5619 * Set pipe state to stop polling and 5620 * error to no resource. Don't insert 5621 * any more isochronous polling requests. 5622 */ 5623 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING; 5624 pp->pp_error = error; 5625 } else { 5626 /* Set periodic in pipe state to idle */ 5627 pp->pp_state = OHCI_PIPE_STATE_IDLE; 5628 } 5629 } 5630 } else { 5631 5632 /* 5633 * Reset back to the address of first usb isochronous 5634 * packet descriptor. 5635 */ 5636 tw->tw_curr_isoc_pktp = curr_isoc_reqp->isoc_pkt_descr; 5637 5638 /* Reset the CONTINUE flag */ 5639 pp->pp_flag &= ~OHCI_ISOC_XFER_CONTINUE; 5640 } 5641 5642 return (error); 5643 } 5644 5645 5646 /* 5647 * ohci_insert_hc_td: 5648 * 5649 * Insert a Transfer Descriptor (TD) on an Endpoint Descriptor (ED). 5650 * Always returns USB_SUCCESS, except for ISOCH. 5651 */ 5652 static int 5653 ohci_insert_hc_td( 5654 ohci_state_t *ohcip, 5655 uint_t hctd_ctrl, 5656 uint32_t hctd_iommu_cbp, 5657 size_t hctd_length, 5658 uint32_t hctd_ctrl_phase, 5659 ohci_pipe_private_t *pp, 5660 ohci_trans_wrapper_t *tw) 5661 { 5662 ohci_td_t *new_dummy; 5663 ohci_td_t *cpu_current_dummy; 5664 ohci_ed_t *ept = pp->pp_ept; 5665 int error; 5666 5667 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 5668 5669 /* Retrieve preallocated td from the TW */ 5670 new_dummy = tw->tw_hctd_free_list; 5671 5672 ASSERT(new_dummy != NULL); 5673 5674 tw->tw_hctd_free_list = ohci_td_iommu_to_cpu(ohcip, 5675 Get_TD(new_dummy->hctd_tw_next_td)); 5676 Set_TD(new_dummy->hctd_tw_next_td, NULL); 5677 5678 /* Fill in the current dummy */ 5679 cpu_current_dummy = (ohci_td_t *) 5680 (ohci_td_iommu_to_cpu(ohcip, Get_ED(ept->hced_tailp))); 5681 5682 /* 5683 * Fill in the current dummy td and 5684 * add the new dummy to the end. 5685 */ 5686 ohci_fill_in_td(ohcip, cpu_current_dummy, new_dummy, 5687 hctd_ctrl, hctd_iommu_cbp, hctd_length, hctd_ctrl_phase, pp, tw); 5688 5689 /* 5690 * If this is an isochronous TD, first write proper 5691 * starting usb frame number in which this TD must 5692 * can be processed. After writing the frame number 5693 * insert this TD into the ED's list. 5694 */ 5695 if ((pp->pp_pipe_handle->p_ep.bmAttributes & 5696 USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH) { 5697 5698 error = ohci_insert_td_with_frame_number( 5699 ohcip, pp, tw, cpu_current_dummy, new_dummy); 5700 5701 if (error != USB_SUCCESS) { 5702 /* Reset the current dummy back to a dummy */ 5703 bzero((char *)cpu_current_dummy, sizeof (ohci_td_t)); 5704 Set_TD(cpu_current_dummy->hctd_state, HC_TD_DUMMY); 5705 5706 /* return the new dummy back to the free list */ 5707 bzero((char *)new_dummy, sizeof (ohci_td_t)); 5708 Set_TD(new_dummy->hctd_state, HC_TD_DUMMY); 5709 if (tw->tw_hctd_free_list != NULL) { 5710 Set_TD(new_dummy->hctd_tw_next_td, 5711 ohci_td_cpu_to_iommu(ohcip, 5712 tw->tw_hctd_free_list)); 5713 } 5714 tw->tw_hctd_free_list = new_dummy; 5715 5716 return (error); 5717 } 5718 } else { 5719 /* 5720 * For control, bulk and interrupt TD, just 5721 * add the new dummy to the ED's list. When 5722 * this occurs, the Host Controller ill see 5723 * the newly filled in dummy TD. 5724 */ 5725 Set_ED(ept->hced_tailp, 5726 (ohci_td_cpu_to_iommu(ohcip, new_dummy))); 5727 } 5728 5729 /* Insert this td onto the tw */ 5730 ohci_insert_td_on_tw(ohcip, tw, cpu_current_dummy); 5731 5732 return (USB_SUCCESS); 5733 } 5734 5735 5736 /* 5737 * ohci_allocate_td_from_pool: 5738 * 5739 * Allocate a Transfer Descriptor (TD) from the TD buffer pool. 5740 */ 5741 static ohci_td_t * 5742 ohci_allocate_td_from_pool(ohci_state_t *ohcip) 5743 { 5744 int i, state; 5745 ohci_td_t *td; 5746 5747 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 5748 5749 /* 5750 * Search for a blank Transfer Descriptor (TD) 5751 * in the TD buffer pool. 5752 */ 5753 for (i = 0; i < ohci_td_pool_size; i ++) { 5754 state = Get_TD(ohcip->ohci_td_pool_addr[i].hctd_state); 5755 if (state == HC_TD_FREE) { 5756 break; 5757 } 5758 } 5759 5760 if (i >= ohci_td_pool_size) { 5761 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 5762 "ohci_allocate_td_from_pool: TD exhausted"); 5763 5764 return (NULL); 5765 } 5766 5767 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 5768 "ohci_allocate_td_from_pool: Allocated %d", i); 5769 5770 /* Create a new dummy for the end of the TD list */ 5771 td = &ohcip->ohci_td_pool_addr[i]; 5772 5773 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5774 "ohci_allocate_td_from_pool: td 0x%p", (void *)td); 5775 5776 /* Mark the newly allocated TD as a dummy */ 5777 Set_TD(td->hctd_state, HC_TD_DUMMY); 5778 5779 return (td); 5780 } 5781 5782 /* 5783 * ohci_fill_in_td: 5784 * 5785 * Fill in the fields of a Transfer Descriptor (TD). 5786 */ 5787 static void 5788 ohci_fill_in_td( 5789 ohci_state_t *ohcip, 5790 ohci_td_t *td, 5791 ohci_td_t *new_dummy, 5792 uint_t hctd_ctrl, 5793 uint32_t hctd_iommu_cbp, 5794 size_t hctd_length, 5795 uint32_t hctd_ctrl_phase, 5796 ohci_pipe_private_t *pp, 5797 ohci_trans_wrapper_t *tw) 5798 { 5799 /* Assert that the td to be filled in is a dummy */ 5800 ASSERT(Get_TD(td->hctd_state) == HC_TD_DUMMY); 5801 5802 /* Change TD's state Active */ 5803 Set_TD(td->hctd_state, HC_TD_ACTIVE); 5804 5805 /* 5806 * If this is an isochronous TD, update the special itd 5807 * portions. Otherwise, just update the control field. 5808 */ 5809 if ((pp->pp_pipe_handle->p_ep.bmAttributes & 5810 USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH) { 5811 ohci_init_itd(ohcip, pp, tw, hctd_ctrl, hctd_iommu_cbp, td); 5812 } else { 5813 /* Update the dummy with control information */ 5814 Set_TD(td->hctd_ctrl, (hctd_ctrl | HC_TD_CC_NA)); 5815 5816 /* Update the beginning of the buffer */ 5817 Set_TD(td->hctd_cbp, hctd_iommu_cbp); 5818 } 5819 5820 /* The current dummy now points to the new dummy */ 5821 Set_TD(td->hctd_next_td, (ohci_td_cpu_to_iommu(ohcip, new_dummy))); 5822 5823 /* Fill in the end of the buffer */ 5824 if (hctd_length == 0) { 5825 ASSERT(Get_TD(td->hctd_cbp) == 0); 5826 ASSERT(hctd_iommu_cbp == 0); 5827 Set_TD(td->hctd_buf_end, 0); 5828 } else { 5829 Set_TD(td->hctd_buf_end, 5830 hctd_iommu_cbp + hctd_length - 1); 5831 } 5832 5833 /* 5834 * For Control transfer, hctd_ctrl_phase is a valid field. 5835 */ 5836 if (hctd_ctrl_phase) { 5837 Set_TD(td->hctd_ctrl_phase, hctd_ctrl_phase); 5838 } 5839 5840 /* Print the td */ 5841 ohci_print_td(ohcip, td); 5842 5843 /* Fill in the wrapper portion of the TD */ 5844 5845 /* Set the transfer wrapper */ 5846 ASSERT(tw != NULL); 5847 ASSERT(tw->tw_id != NULL); 5848 5849 Set_TD(td->hctd_trans_wrapper, (uint32_t)tw->tw_id); 5850 Set_TD(td->hctd_tw_next_td, NULL); 5851 } 5852 5853 5854 /* 5855 * ohci_init_itd: 5856 * 5857 * Initialize the Isochronous portion of the Transfer Descriptor (TD). 5858 */ 5859 /* ARGSUSED */ 5860 static void 5861 ohci_init_itd( 5862 ohci_state_t *ohcip, 5863 ohci_pipe_private_t *pp, 5864 ohci_trans_wrapper_t *tw, 5865 uint_t hctd_ctrl, 5866 uint32_t hctd_iommu_cbp, 5867 ohci_td_t *td) 5868 { 5869 uint32_t offset, offset_addr; 5870 uint_t buf, fc, toggle, flag; 5871 usb_isoc_pkt_descr_t *temp_pkt_descr; 5872 int i; 5873 5874 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 5875 5876 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5877 "ohci_init_itd: ctrl = 0x%x", hctd_ctrl); 5878 5879 /* 5880 * Write control information except starting 5881 * usb frame number. 5882 */ 5883 Set_TD(td->hctd_ctrl, (hctd_ctrl | HC_TD_CC_NA)); 5884 5885 /* 5886 * For an isochronous transfer, the hctd_cbp contains, 5887 * the 4k page, and not the actual start of the buffer. 5888 */ 5889 Set_TD(td->hctd_cbp, ((uint32_t)hctd_iommu_cbp & HC_ITD_PAGE_MASK)); 5890 5891 fc = (hctd_ctrl & HC_ITD_FC) >> HC_ITD_FC_SHIFT; 5892 toggle = 0; 5893 buf = hctd_iommu_cbp; 5894 5895 /* 5896 * Get the address of first isochronous data packet 5897 * for the current isochronous TD. 5898 */ 5899 temp_pkt_descr = tw->tw_curr_isoc_pktp; 5900 5901 /* The offsets are actually offsets into the page */ 5902 for (i = 0; i <= fc; i++) { 5903 offset_addr = (uint32_t)((buf & 5904 HC_ITD_OFFSET_ADDR) | (HC_TD_CC_NA >> HC_ITD_CC_SHIFT)); 5905 5906 flag = ((hctd_iommu_cbp & 5907 HC_ITD_PAGE_MASK) ^ (buf & HC_ITD_PAGE_MASK)); 5908 5909 if (flag) { 5910 offset_addr |= HC_ITD_4KBOUNDARY_CROSS; 5911 } 5912 5913 if (toggle) { 5914 offset = (uint32_t)((offset_addr << 5915 HC_ITD_OFFSET_SHIFT) & HC_ITD_ODD_OFFSET); 5916 5917 Set_TD(td->hctd_offsets[i / 2], 5918 Get_TD(td->hctd_offsets[i / 2]) | offset); 5919 toggle = 0; 5920 } else { 5921 offset = (uint32_t)(offset_addr & HC_ITD_EVEN_OFFSET); 5922 5923 Set_TD(td->hctd_offsets[i / 2], 5924 Get_TD(td->hctd_offsets[i / 2]) | offset); 5925 toggle = 1; 5926 } 5927 5928 buf = (uint32_t)(buf + temp_pkt_descr->isoc_pkt_length); 5929 temp_pkt_descr++; 5930 } 5931 } 5932 5933 5934 /* 5935 * ohci_insert_td_with_frame_number: 5936 * 5937 * Insert current isochronous TD into the ED's list. with proper 5938 * usb frame number in which this TD can be processed. 5939 */ 5940 static int 5941 ohci_insert_td_with_frame_number( 5942 ohci_state_t *ohcip, 5943 ohci_pipe_private_t *pp, 5944 ohci_trans_wrapper_t *tw, 5945 ohci_td_t *current_td, 5946 ohci_td_t *dummy_td) 5947 { 5948 usb_isoc_req_t *isoc_reqp = 5949 (usb_isoc_req_t *)tw->tw_curr_xfer_reqp; 5950 usb_frame_number_t current_frame_number, start_frame_number; 5951 uint_t ddic, ctrl, isoc_pkts; 5952 ohci_ed_t *ept = pp->pp_ept; 5953 5954 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 5955 "ohci_insert_td_with_frame_number:" 5956 "isoc flags 0x%x", isoc_reqp->isoc_attributes); 5957 5958 /* Get the TD ctrl information */ 5959 isoc_pkts = ((Get_TD(current_td->hctd_ctrl) & 5960 HC_ITD_FC) >> HC_ITD_FC_SHIFT) + 1; 5961 5962 /* 5963 * Enter critical, while programming the usb frame number 5964 * and inserting current isochronous TD into the ED's list. 5965 */ 5966 ddic = ddi_enter_critical(); 5967 5968 /* Get the current frame number */ 5969 current_frame_number = ohci_get_current_frame_number(ohcip); 5970 5971 /* Check the given isochronous flags */ 5972 switch (isoc_reqp->isoc_attributes & 5973 (USB_ATTRS_ISOC_START_FRAME | USB_ATTRS_ISOC_XFER_ASAP)) { 5974 case USB_ATTRS_ISOC_START_FRAME: 5975 /* Starting frame number is specified */ 5976 if (pp->pp_flag & OHCI_ISOC_XFER_CONTINUE) { 5977 /* Get the starting usb frame number */ 5978 start_frame_number = pp->pp_next_frame_number; 5979 } else { 5980 /* Check for the Starting usb frame number */ 5981 if ((isoc_reqp->isoc_frame_no == 0) || 5982 ((isoc_reqp->isoc_frame_no + 5983 isoc_reqp->isoc_pkts_count) < 5984 current_frame_number)) { 5985 5986 /* Exit the critical */ 5987 ddi_exit_critical(ddic); 5988 5989 USB_DPRINTF_L2(PRINT_MASK_LISTS, 5990 ohcip->ohci_log_hdl, 5991 "ohci_insert_td_with_frame_number:" 5992 "Invalid starting frame number"); 5993 5994 return (USB_INVALID_START_FRAME); 5995 } 5996 5997 /* Get the starting usb frame number */ 5998 start_frame_number = isoc_reqp->isoc_frame_no; 5999 6000 pp->pp_next_frame_number = 0; 6001 } 6002 break; 6003 case USB_ATTRS_ISOC_XFER_ASAP: 6004 /* ohci has to specify starting frame number */ 6005 if ((pp->pp_next_frame_number) && 6006 (pp->pp_next_frame_number > current_frame_number)) { 6007 /* 6008 * Get the next usb frame number. 6009 */ 6010 start_frame_number = pp->pp_next_frame_number; 6011 } else { 6012 /* 6013 * Add appropriate offset to the current usb 6014 * frame number and use it as a starting frame 6015 * number. 6016 */ 6017 start_frame_number = 6018 current_frame_number + OHCI_FRAME_OFFSET; 6019 } 6020 6021 if (!(pp->pp_flag & OHCI_ISOC_XFER_CONTINUE)) { 6022 isoc_reqp->isoc_frame_no = start_frame_number; 6023 } 6024 break; 6025 default: 6026 /* Exit the critical */ 6027 ddi_exit_critical(ddic); 6028 6029 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6030 "ohci_insert_td_with_frame_number: Either starting " 6031 "frame number or ASAP flags are not set, attrs = 0x%x", 6032 isoc_reqp->isoc_attributes); 6033 6034 return (USB_NO_FRAME_NUMBER); 6035 } 6036 6037 /* Get the TD ctrl information */ 6038 ctrl = Get_TD(current_td->hctd_ctrl) & (~(HC_ITD_SF)); 6039 6040 /* Set the frame number field */ 6041 Set_TD(current_td->hctd_ctrl, ctrl | (start_frame_number & HC_ITD_SF)); 6042 6043 /* 6044 * Add the new dummy to the ED's list. When this occurs, 6045 * the Host Controller will see newly filled in dummy TD. 6046 */ 6047 Set_ED(ept->hced_tailp, (ohci_td_cpu_to_iommu(ohcip, dummy_td))); 6048 6049 /* Exit the critical */ 6050 ddi_exit_critical(ddic); 6051 6052 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6053 "ohci_insert_td_with_frame_number:" 6054 "current frame number 0x%llx start frame number 0x%llx", 6055 current_frame_number, start_frame_number); 6056 6057 /* 6058 * Increment this saved frame number by current number 6059 * of data packets needs to be transfer. 6060 */ 6061 pp->pp_next_frame_number = start_frame_number + isoc_pkts; 6062 6063 /* 6064 * Set OHCI_ISOC_XFER_CONTINUE flag in order to send other 6065 * isochronous packets, part of the current isoch request 6066 * in the subsequent frames. 6067 */ 6068 pp->pp_flag |= OHCI_ISOC_XFER_CONTINUE; 6069 6070 return (USB_SUCCESS); 6071 } 6072 6073 6074 /* 6075 * ohci_insert_td_on_tw: 6076 * 6077 * The transfer wrapper keeps a list of all Transfer Descriptors (TD) that 6078 * are allocated for this transfer. Insert a TD onto this list. The list 6079 * of TD's does not include the dummy TD that is at the end of the list of 6080 * TD's for the endpoint. 6081 */ 6082 static void 6083 ohci_insert_td_on_tw( 6084 ohci_state_t *ohcip, 6085 ohci_trans_wrapper_t *tw, 6086 ohci_td_t *td) 6087 { 6088 /* 6089 * Set the next pointer to NULL because 6090 * this is the last TD on list. 6091 */ 6092 Set_TD(td->hctd_tw_next_td, NULL); 6093 6094 if (tw->tw_hctd_head == NULL) { 6095 ASSERT(tw->tw_hctd_tail == NULL); 6096 tw->tw_hctd_head = td; 6097 tw->tw_hctd_tail = td; 6098 } else { 6099 ohci_td_t *dummy = (ohci_td_t *)tw->tw_hctd_tail; 6100 6101 ASSERT(dummy != NULL); 6102 ASSERT(dummy != td); 6103 ASSERT(Get_TD(td->hctd_state) != HC_TD_DUMMY); 6104 6105 /* Add the td to the end of the list */ 6106 Set_TD(dummy->hctd_tw_next_td, 6107 ohci_td_cpu_to_iommu(ohcip, td)); 6108 6109 tw->tw_hctd_tail = td; 6110 6111 ASSERT(Get_TD(td->hctd_tw_next_td) == NULL); 6112 } 6113 } 6114 6115 6116 /* 6117 * ohci_traverse_tds: 6118 * NOTE: This function is also called from POLLED MODE. 6119 * 6120 * Traverse the list of TD's for an endpoint. Since the endpoint is marked 6121 * as sKipped, the Host Controller (HC) is no longer accessing these TD's. 6122 * Remove all the TD's that are attached to the endpoint. 6123 */ 6124 void 6125 ohci_traverse_tds( 6126 ohci_state_t *ohcip, 6127 usba_pipe_handle_data_t *ph) 6128 { 6129 ohci_trans_wrapper_t *tw; 6130 ohci_ed_t *ept; 6131 ohci_pipe_private_t *pp; 6132 uint32_t addr; 6133 ohci_td_t *tailp, *headp, *next; 6134 6135 pp = (ohci_pipe_private_t *)ph->p_hcd_private; 6136 ept = pp->pp_ept; 6137 6138 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6139 "ohci_traverse_tds: ph = 0x%p ept = 0x%p", 6140 (void *)ph, (void *)ept); 6141 6142 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 6143 6144 addr = Get_ED(ept->hced_headp) & (uint32_t)HC_EPT_TD_HEAD; 6145 6146 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6147 "ohci_traverse_tds: addr (head) = 0x%x", addr); 6148 6149 headp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, addr)); 6150 6151 addr = Get_ED(ept->hced_tailp) & (uint32_t)HC_EPT_TD_TAIL; 6152 6153 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6154 "ohci_traverse_tds: addr (tail) = 0x%x", addr); 6155 6156 tailp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, addr)); 6157 6158 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6159 "ohci_traverse_tds: cpu head = 0x%p cpu tail = 0x%p", 6160 (void *)headp, (void *)tailp); 6161 6162 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6163 "ohci_traverse_tds: iommu head = 0x%x iommu tail = 0x%x", 6164 ohci_td_cpu_to_iommu(ohcip, headp), 6165 ohci_td_cpu_to_iommu(ohcip, tailp)); 6166 6167 /* 6168 * Traverse the list of TD's that are currently on the endpoint. 6169 * These TD's have not been processed and will not be processed 6170 * because the endpoint processing is stopped. 6171 */ 6172 while (headp != tailp) { 6173 next = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, 6174 (Get_TD(headp->hctd_next_td) & HC_EPT_TD_TAIL))); 6175 6176 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID( 6177 (uint32_t)Get_TD(headp->hctd_trans_wrapper)); 6178 6179 /* Stop the the transfer timer */ 6180 ohci_stop_xfer_timer(ohcip, tw, OHCI_REMOVE_XFER_ALWAYS); 6181 6182 ohci_deallocate_td(ohcip, headp); 6183 headp = next; 6184 } 6185 6186 /* Both head and tail pointers must be same */ 6187 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6188 "ohci_traverse_tds: head = 0x%p tail = 0x%p", 6189 (void *)headp, (void *)tailp); 6190 6191 /* Update the pointer in the endpoint descriptor */ 6192 Set_ED(ept->hced_headp, (ohci_td_cpu_to_iommu(ohcip, headp))); 6193 6194 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6195 "ohci_traverse_tds: new head = 0x%x", 6196 (ohci_td_cpu_to_iommu(ohcip, headp))); 6197 6198 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6199 "ohci_traverse_tds: tailp = 0x%x headp = 0x%x", 6200 (Get_ED(ept->hced_tailp) & HC_EPT_TD_TAIL), 6201 (Get_ED(ept->hced_headp) & HC_EPT_TD_HEAD)); 6202 6203 ASSERT((Get_ED(ept->hced_tailp) & HC_EPT_TD_TAIL) == 6204 (Get_ED(ept->hced_headp) & HC_EPT_TD_HEAD)); 6205 } 6206 6207 6208 /* 6209 * ohci_done_list_tds: 6210 * 6211 * There may be TD's on the done list that have not been processed yet. Walk 6212 * through these TD's and mark them as RECLAIM. All the mappings for the TD 6213 * will be torn down, so the interrupt handle is alerted of this fact through 6214 * the RECLAIM flag. 6215 */ 6216 static void 6217 ohci_done_list_tds( 6218 ohci_state_t *ohcip, 6219 usba_pipe_handle_data_t *ph) 6220 { 6221 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 6222 ohci_trans_wrapper_t *head_tw = pp->pp_tw_head; 6223 ohci_trans_wrapper_t *next_tw; 6224 ohci_td_t *head_td, *next_td; 6225 6226 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 6227 6228 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6229 "ohci_done_list_tds:"); 6230 6231 /* Process the transfer wrappers for this pipe */ 6232 next_tw = head_tw; 6233 while (next_tw) { 6234 head_td = (ohci_td_t *)next_tw->tw_hctd_head; 6235 next_td = head_td; 6236 6237 if (head_td) { 6238 /* 6239 * Walk through each TD for this transfer 6240 * wrapper. If a TD still exists, then it 6241 * is currently on the done list. 6242 */ 6243 while (next_td) { 6244 6245 /* To free TD, set TD state to RECLAIM */ 6246 Set_TD(next_td->hctd_state, HC_TD_RECLAIM); 6247 6248 Set_TD(next_td->hctd_trans_wrapper, NULL); 6249 6250 next_td = ohci_td_iommu_to_cpu(ohcip, 6251 Get_TD(next_td->hctd_tw_next_td)); 6252 } 6253 } 6254 6255 /* Stop the the transfer timer */ 6256 ohci_stop_xfer_timer(ohcip, next_tw, OHCI_REMOVE_XFER_ALWAYS); 6257 6258 next_tw = next_tw->tw_next; 6259 } 6260 } 6261 6262 6263 /* 6264 * ohci_deallocate_td: 6265 * NOTE: This function is also called from POLLED MODE. 6266 * 6267 * Deallocate a Host Controller's (HC) Transfer Descriptor (TD). 6268 */ 6269 void 6270 ohci_deallocate_td( 6271 ohci_state_t *ohcip, 6272 ohci_td_t *old_td) 6273 { 6274 ohci_trans_wrapper_t *tw; 6275 6276 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6277 "ohci_deallocate_td: old_td = 0x%p", (void *)old_td); 6278 6279 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 6280 6281 /* 6282 * Obtain the transaction wrapper and tw will be 6283 * NULL for the dummy and for the reclaim TD's. 6284 */ 6285 if ((Get_TD(old_td->hctd_state) == HC_TD_DUMMY) || 6286 (Get_TD(old_td->hctd_state) == HC_TD_RECLAIM)) { 6287 tw = (ohci_trans_wrapper_t *)((uintptr_t) 6288 Get_TD(old_td->hctd_trans_wrapper)); 6289 ASSERT(tw == NULL); 6290 } else { 6291 tw = (ohci_trans_wrapper_t *) 6292 OHCI_LOOKUP_ID((uint32_t) 6293 Get_TD(old_td->hctd_trans_wrapper)); 6294 ASSERT(tw != NULL); 6295 } 6296 6297 /* 6298 * If this TD should be reclaimed, don't try to access its 6299 * transfer wrapper. 6300 */ 6301 if ((Get_TD(old_td->hctd_state) != HC_TD_RECLAIM) && tw) { 6302 ohci_td_t *td = (ohci_td_t *)tw->tw_hctd_head; 6303 ohci_td_t *test; 6304 6305 /* 6306 * Take this TD off the transfer wrapper's list since 6307 * the pipe is FIFO, this must be the first TD on the 6308 * list. 6309 */ 6310 ASSERT((ohci_td_t *)tw->tw_hctd_head == old_td); 6311 6312 tw->tw_hctd_head = 6313 ohci_td_iommu_to_cpu(ohcip, Get_TD(td->hctd_tw_next_td)); 6314 6315 if (tw->tw_hctd_head) { 6316 test = (ohci_td_t *)tw->tw_hctd_head; 6317 ASSERT(Get_TD(test->hctd_state) != HC_TD_DUMMY); 6318 } 6319 6320 /* 6321 * If the head becomes NULL, then there are no more 6322 * active TD's for this transfer wrapper. Also set 6323 * the tail to NULL. 6324 */ 6325 if (tw->tw_hctd_head == NULL) { 6326 tw->tw_hctd_tail = NULL; 6327 } else { 6328 /* 6329 * If this is the last td on the list, make 6330 * sure it doesn't point to yet another td. 6331 */ 6332 if (tw->tw_hctd_head == tw->tw_hctd_tail) { 6333 td = (ohci_td_t *)tw->tw_hctd_head; 6334 6335 ASSERT(Get_TD(td->hctd_tw_next_td) == NULL); 6336 } 6337 } 6338 } 6339 6340 bzero((void *)old_td, sizeof (ohci_td_t)); 6341 Set_TD(old_td->hctd_state, HC_TD_FREE); 6342 6343 USB_DPRINTF_L3(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6344 "ohci_deallocate_td: td 0x%p", (void *)old_td); 6345 } 6346 6347 6348 /* 6349 * ohci_td_cpu_to_iommu: 6350 * NOTE: This function is also called from POLLED MODE. 6351 * 6352 * This function converts for the given Transfer Descriptor (TD) CPU address 6353 * to IO address. 6354 */ 6355 uint32_t 6356 ohci_td_cpu_to_iommu( 6357 ohci_state_t *ohcip, 6358 ohci_td_t *addr) 6359 { 6360 uint32_t td; 6361 6362 td = (uint32_t)ohcip->ohci_td_pool_cookie.dmac_address + 6363 (uint32_t)((uintptr_t)addr - (uintptr_t)(ohcip->ohci_td_pool_addr)); 6364 6365 ASSERT((ohcip->ohci_td_pool_cookie.dmac_address + 6366 (uint32_t) (sizeof (ohci_td_t) * 6367 (addr - ohcip->ohci_td_pool_addr))) == 6368 (ohcip->ohci_td_pool_cookie.dmac_address + 6369 (uint32_t)((uintptr_t)addr - (uintptr_t) 6370 (ohcip->ohci_td_pool_addr)))); 6371 6372 ASSERT(td >= ohcip->ohci_td_pool_cookie.dmac_address); 6373 ASSERT(td <= ohcip->ohci_td_pool_cookie.dmac_address + 6374 sizeof (ohci_td_t) * ohci_td_pool_size); 6375 6376 return (td); 6377 } 6378 6379 6380 /* 6381 * ohci_td_iommu_to_cpu: 6382 * NOTE: This function is also called from POLLED MODE. 6383 * 6384 * This function converts for the given Transfer Descriptor (TD) IO address 6385 * to CPU address. 6386 */ 6387 ohci_td_t * 6388 ohci_td_iommu_to_cpu( 6389 ohci_state_t *ohcip, 6390 uintptr_t addr) 6391 { 6392 ohci_td_t *td; 6393 6394 if (addr == NULL) { 6395 6396 return (NULL); 6397 } 6398 6399 td = (ohci_td_t *)((uintptr_t) 6400 (addr - ohcip->ohci_td_pool_cookie.dmac_address) + 6401 (uintptr_t)ohcip->ohci_td_pool_addr); 6402 6403 ASSERT(td >= ohcip->ohci_td_pool_addr); 6404 ASSERT((uintptr_t)td <= (uintptr_t)ohcip->ohci_td_pool_addr + 6405 (uintptr_t)(sizeof (ohci_td_t) * ohci_td_pool_size)); 6406 6407 return (td); 6408 } 6409 6410 /* 6411 * ohci_allocate_tds_for_tw: 6412 * 6413 * Allocate n Transfer Descriptors (TD) from the TD buffer pool and places it 6414 * into the TW. 6415 * 6416 * Returns USB_NO_RESOURCES if it was not able to allocate all the requested TD 6417 * otherwise USB_SUCCESS. 6418 */ 6419 static int 6420 ohci_allocate_tds_for_tw( 6421 ohci_state_t *ohcip, 6422 ohci_trans_wrapper_t *tw, 6423 size_t td_count) 6424 { 6425 ohci_td_t *td; 6426 uint32_t td_addr; 6427 int i; 6428 int error = USB_SUCCESS; 6429 6430 for (i = 0; i < td_count; i++) { 6431 td = ohci_allocate_td_from_pool(ohcip); 6432 if (td == NULL) { 6433 error = USB_NO_RESOURCES; 6434 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6435 "ohci_allocate_tds_for_tw: " 6436 "Unable to allocate %lu TDs", 6437 td_count); 6438 break; 6439 } 6440 if (tw->tw_hctd_free_list != NULL) { 6441 td_addr = ohci_td_cpu_to_iommu(ohcip, 6442 tw->tw_hctd_free_list); 6443 Set_TD(td->hctd_tw_next_td, td_addr); 6444 } 6445 tw->tw_hctd_free_list = td; 6446 } 6447 6448 return (error); 6449 } 6450 6451 /* 6452 * ohci_allocate_tw_resources: 6453 * 6454 * Allocate a Transaction Wrapper (TW) and n Transfer Descriptors (TD) 6455 * from the TD buffer pool and places it into the TW. It does an all 6456 * or nothing transaction. 6457 * 6458 * Returns NULL if there is insufficient resources otherwise TW. 6459 */ 6460 static ohci_trans_wrapper_t * 6461 ohci_allocate_tw_resources( 6462 ohci_state_t *ohcip, 6463 ohci_pipe_private_t *pp, 6464 size_t tw_length, 6465 usb_flags_t usb_flags, 6466 size_t td_count) 6467 { 6468 ohci_trans_wrapper_t *tw; 6469 6470 tw = ohci_create_transfer_wrapper(ohcip, pp, tw_length, usb_flags); 6471 6472 if (tw == NULL) { 6473 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6474 "ohci_allocate_tw_resources: Unable to allocate TW"); 6475 } else { 6476 if (ohci_allocate_tds_for_tw(ohcip, tw, td_count) == 6477 USB_SUCCESS) { 6478 tw->tw_num_tds = td_count; 6479 } else { 6480 ohci_deallocate_tw_resources(ohcip, pp, tw); 6481 tw = NULL; 6482 } 6483 } 6484 6485 return (tw); 6486 } 6487 6488 /* 6489 * ohci_free_tw_tds_resources: 6490 * 6491 * Free all allocated resources for Transaction Wrapper (TW). 6492 * Does not free the TW itself. 6493 */ 6494 static void 6495 ohci_free_tw_tds_resources( 6496 ohci_state_t *ohcip, 6497 ohci_trans_wrapper_t *tw) 6498 { 6499 ohci_td_t *td; 6500 ohci_td_t *temp_td; 6501 6502 td = tw->tw_hctd_free_list; 6503 while (td != NULL) { 6504 /* Save the pointer to the next td before destroying it */ 6505 temp_td = ohci_td_iommu_to_cpu(ohcip, 6506 Get_TD(td->hctd_tw_next_td)); 6507 ohci_deallocate_td(ohcip, td); 6508 td = temp_td; 6509 } 6510 tw->tw_hctd_free_list = NULL; 6511 } 6512 6513 6514 /* 6515 * Transfer Wrapper functions 6516 * 6517 * ohci_create_transfer_wrapper: 6518 * 6519 * Create a Transaction Wrapper (TW) and this involves the allocating of DMA 6520 * resources. 6521 */ 6522 static ohci_trans_wrapper_t * 6523 ohci_create_transfer_wrapper( 6524 ohci_state_t *ohcip, 6525 ohci_pipe_private_t *pp, 6526 size_t length, 6527 uint_t usb_flags) 6528 { 6529 ddi_device_acc_attr_t dev_attr; 6530 int result; 6531 size_t real_length; 6532 uint_t ccount; /* Cookie count */ 6533 ohci_trans_wrapper_t *tw; 6534 6535 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6536 "ohci_create_transfer_wrapper: length = 0x%lx flags = 0x%x", 6537 length, usb_flags); 6538 6539 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 6540 6541 /* Allocate space for the transfer wrapper */ 6542 tw = kmem_zalloc(sizeof (ohci_trans_wrapper_t), KM_NOSLEEP); 6543 6544 if (tw == NULL) { 6545 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6546 "ohci_create_transfer_wrapper: kmem_zalloc failed"); 6547 6548 return (NULL); 6549 } 6550 6551 /* Force the required 4K restrictive alignment */ 6552 ohcip->ohci_dma_attr.dma_attr_align = OHCI_DMA_ATTR_ALIGNMENT; 6553 6554 /* Allocate the DMA handle */ 6555 result = ddi_dma_alloc_handle(ohcip->ohci_dip, 6556 &ohcip->ohci_dma_attr, DDI_DMA_DONTWAIT, 0, &tw->tw_dmahandle); 6557 6558 if (result != DDI_SUCCESS) { 6559 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6560 "ohci_create_transfer_wrapper: Alloc handle failed"); 6561 6562 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 6563 6564 return (NULL); 6565 } 6566 6567 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 6568 6569 /* The host controller will be little endian */ 6570 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_BE_ACC; 6571 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 6572 6573 /* Allocate the memory */ 6574 result = ddi_dma_mem_alloc(tw->tw_dmahandle, length, 6575 &dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, 6576 (caddr_t *)&tw->tw_buf, &real_length, &tw->tw_accesshandle); 6577 6578 if (result != DDI_SUCCESS) { 6579 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6580 "ohci_create_transfer_wrapper: dma_mem_alloc fail"); 6581 6582 ddi_dma_free_handle(&tw->tw_dmahandle); 6583 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 6584 6585 return (NULL); 6586 } 6587 6588 ASSERT(real_length >= length); 6589 6590 /* Bind the handle */ 6591 result = ddi_dma_addr_bind_handle(tw->tw_dmahandle, NULL, 6592 (caddr_t)tw->tw_buf, real_length, DDI_DMA_RDWR|DDI_DMA_CONSISTENT, 6593 DDI_DMA_DONTWAIT, NULL, &tw->tw_cookie, &ccount); 6594 6595 if (result == DDI_DMA_MAPPED) { 6596 /* The cookie count should be 1 */ 6597 if (ccount != 1) { 6598 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6599 "ohci_create_transfer_wrapper: More than 1 cookie"); 6600 6601 result = ddi_dma_unbind_handle(tw->tw_dmahandle); 6602 ASSERT(result == DDI_SUCCESS); 6603 6604 ddi_dma_mem_free(&tw->tw_accesshandle); 6605 ddi_dma_free_handle(&tw->tw_dmahandle); 6606 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 6607 6608 return (NULL); 6609 } 6610 } else { 6611 ohci_decode_ddi_dma_addr_bind_handle_result(ohcip, result); 6612 6613 ddi_dma_mem_free(&tw->tw_accesshandle); 6614 ddi_dma_free_handle(&tw->tw_dmahandle); 6615 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 6616 6617 return (NULL); 6618 } 6619 6620 /* 6621 * Only allow one wrapper to be added at a time. Insert the 6622 * new transaction wrapper into the list for this pipe. 6623 */ 6624 if (pp->pp_tw_head == NULL) { 6625 pp->pp_tw_head = tw; 6626 pp->pp_tw_tail = tw; 6627 } else { 6628 pp->pp_tw_tail->tw_next = tw; 6629 pp->pp_tw_tail = tw; 6630 } 6631 6632 /* Store the transfer length */ 6633 tw->tw_length = length; 6634 6635 /* Store a back pointer to the pipe private structure */ 6636 tw->tw_pipe_private = pp; 6637 6638 /* Store the transfer type - synchronous or asynchronous */ 6639 tw->tw_flags = usb_flags; 6640 6641 /* Get and Store 32bit ID */ 6642 tw->tw_id = OHCI_GET_ID((void *)tw); 6643 6644 ASSERT(tw->tw_id != NULL); 6645 6646 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6647 "ohci_create_transfer_wrapper: tw = 0x%p", tw); 6648 6649 return (tw); 6650 } 6651 6652 6653 /* 6654 * ohci_start_xfer_timer: 6655 * 6656 * Start the timer for the control, bulk and for one time interrupt 6657 * transfers. 6658 */ 6659 /* ARGSUSED */ 6660 static void 6661 ohci_start_xfer_timer( 6662 ohci_state_t *ohcip, 6663 ohci_pipe_private_t *pp, 6664 ohci_trans_wrapper_t *tw) 6665 { 6666 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6667 "ohci_start_xfer_timer: tw = 0x%p", tw); 6668 6669 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 6670 6671 /* 6672 * The timeout handling is done only for control, bulk and for 6673 * one time Interrupt transfers. 6674 * 6675 * NOTE: If timeout is zero; Assume infinite timeout and don't 6676 * insert this transfer on the timeout list. 6677 */ 6678 if (tw->tw_timeout) { 6679 /* 6680 * Increase timeout value by one second and this extra one 6681 * second is used to halt the endpoint if given transfer 6682 * times out. 6683 */ 6684 tw->tw_timeout++; 6685 6686 /* 6687 * Add this transfer wrapper into the transfer timeout list. 6688 */ 6689 if (ohcip->ohci_timeout_list) { 6690 tw->tw_timeout_next = ohcip->ohci_timeout_list; 6691 } 6692 6693 ohcip->ohci_timeout_list = tw; 6694 ohci_start_timer(ohcip); 6695 } 6696 } 6697 6698 6699 /* 6700 * ohci_stop_xfer_timer: 6701 * 6702 * Start the timer for the control, bulk and for one time interrupt 6703 * transfers. 6704 */ 6705 void 6706 ohci_stop_xfer_timer( 6707 ohci_state_t *ohcip, 6708 ohci_trans_wrapper_t *tw, 6709 uint_t flag) 6710 { 6711 timeout_id_t timer_id; 6712 6713 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6714 "ohci_stop_xfer_timer: tw = 0x%p", tw); 6715 6716 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 6717 6718 /* 6719 * The timeout handling is done only for control, bulk 6720 * and for one time Interrupt transfers. 6721 */ 6722 if (ohcip->ohci_timeout_list == NULL) { 6723 return; 6724 } 6725 6726 switch (flag) { 6727 case OHCI_REMOVE_XFER_IFLAST: 6728 if (tw->tw_hctd_head != tw->tw_hctd_tail) { 6729 break; 6730 } 6731 /* FALLTHRU */ 6732 case OHCI_REMOVE_XFER_ALWAYS: 6733 ohci_remove_tw_from_timeout_list(ohcip, tw); 6734 6735 if ((ohcip->ohci_timeout_list == NULL) && 6736 (ohcip->ohci_timer_id)) { 6737 6738 timer_id = ohcip->ohci_timer_id; 6739 6740 /* Reset the timer id to zero */ 6741 ohcip->ohci_timer_id = 0; 6742 6743 mutex_exit(&ohcip->ohci_int_mutex); 6744 6745 (void) untimeout(timer_id); 6746 6747 mutex_enter(&ohcip->ohci_int_mutex); 6748 } 6749 break; 6750 default: 6751 break; 6752 } 6753 } 6754 6755 6756 /* 6757 * ohci_xfer_timeout_handler: 6758 * 6759 * Control or bulk transfer timeout handler. 6760 */ 6761 static void 6762 ohci_xfer_timeout_handler(void *arg) 6763 { 6764 ohci_state_t *ohcip = (ohci_state_t *)arg; 6765 ohci_trans_wrapper_t *exp_xfer_list_head = NULL; 6766 ohci_trans_wrapper_t *exp_xfer_list_tail = NULL; 6767 ohci_trans_wrapper_t *tw, *next; 6768 ohci_td_t *td; 6769 usb_flags_t flags; 6770 6771 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6772 "ohci_xfer_timeout_handler: ohcip = 0x%p", ohcip); 6773 6774 mutex_enter(&ohcip->ohci_int_mutex); 6775 6776 /* Set the required flags */ 6777 flags = OHCI_FLAGS_NOSLEEP | OHCI_FLAGS_DMA_SYNC; 6778 6779 /* 6780 * Check whether still timeout handler is valid. 6781 */ 6782 if (ohcip->ohci_timer_id) { 6783 6784 /* Reset the timer id to zero */ 6785 ohcip->ohci_timer_id = 0; 6786 } else { 6787 mutex_exit(&ohcip->ohci_int_mutex); 6788 6789 return; 6790 } 6791 6792 /* Get the transfer timeout list head */ 6793 tw = ohcip->ohci_timeout_list; 6794 6795 /* 6796 * Process ohci timeout list and look whether the timer 6797 * has expired for any transfers. Create a temporary list 6798 * of expired transfers and process them later. 6799 */ 6800 while (tw) { 6801 /* Get the transfer on the timeout list */ 6802 next = tw->tw_timeout_next; 6803 6804 tw->tw_timeout--; 6805 6806 /* 6807 * Set the sKip bit to stop all transactions on 6808 * this pipe 6809 */ 6810 if (tw->tw_timeout == 1) { 6811 ohci_modify_sKip_bit(ohcip, 6812 tw->tw_pipe_private, SET_sKip, flags); 6813 6814 /* Reset dma sync flag */ 6815 flags &= ~OHCI_FLAGS_DMA_SYNC; 6816 } 6817 6818 /* Remove tw from the timeout list */ 6819 if (tw->tw_timeout <= 0) { 6820 6821 ohci_remove_tw_from_timeout_list(ohcip, tw); 6822 6823 /* Add tw to the end of expire list */ 6824 if (exp_xfer_list_head) { 6825 exp_xfer_list_tail->tw_timeout_next = tw; 6826 } else { 6827 exp_xfer_list_head = tw; 6828 } 6829 exp_xfer_list_tail = tw; 6830 tw->tw_timeout_next = NULL; 6831 } 6832 6833 tw = next; 6834 } 6835 6836 /* Get the expired transfer timeout list head */ 6837 tw = exp_xfer_list_head; 6838 6839 if (tw && (flags & OHCI_FLAGS_DMA_SYNC)) { 6840 /* Sync ED and TD pool */ 6841 Sync_ED_TD_Pool(ohcip); 6842 } 6843 6844 /* 6845 * Process the expired transfers by notifing the corrsponding 6846 * client driver through the exception callback. 6847 */ 6848 while (tw) { 6849 /* Get the transfer on the expired transfer timeout list */ 6850 next = tw->tw_timeout_next; 6851 6852 td = tw->tw_hctd_head; 6853 6854 while (td) { 6855 /* Set TD state to TIMEOUT */ 6856 Set_TD(td->hctd_state, HC_TD_TIMEOUT); 6857 6858 /* Get the next TD from the wrapper */ 6859 td = ohci_td_iommu_to_cpu(ohcip, 6860 Get_TD(td->hctd_tw_next_td)); 6861 } 6862 6863 ohci_handle_error(ohcip, tw->tw_hctd_head, USB_CR_TIMEOUT); 6864 6865 tw = next; 6866 } 6867 6868 ohci_start_timer(ohcip); 6869 mutex_exit(&ohcip->ohci_int_mutex); 6870 } 6871 6872 6873 /* 6874 * ohci_remove_tw_from_timeout_list: 6875 * 6876 * Remove Control or bulk transfer from the timeout list. 6877 */ 6878 static void 6879 ohci_remove_tw_from_timeout_list( 6880 ohci_state_t *ohcip, 6881 ohci_trans_wrapper_t *tw) 6882 { 6883 ohci_trans_wrapper_t *prev, *next; 6884 6885 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6886 "ohci_remove_tw_from_timeout_list: tw = 0x%p", tw); 6887 6888 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 6889 6890 if (ohcip->ohci_timeout_list == tw) { 6891 ohcip->ohci_timeout_list = tw->tw_timeout_next; 6892 } else { 6893 prev = ohcip->ohci_timeout_list; 6894 next = prev->tw_timeout_next; 6895 6896 while (next && (next != tw)) { 6897 prev = next; 6898 next = next->tw_timeout_next; 6899 } 6900 6901 if (next == tw) { 6902 prev->tw_timeout_next = next->tw_timeout_next; 6903 } 6904 } 6905 6906 /* Reset the xfer timeout */ 6907 tw->tw_timeout_next = NULL; 6908 } 6909 6910 6911 /* 6912 * ohci_start_timer: 6913 * 6914 * Start the ohci timer 6915 */ 6916 static void 6917 ohci_start_timer(ohci_state_t *ohcip) 6918 { 6919 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6920 "ohci_start_timer: ohcip = 0x%p", ohcip); 6921 6922 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 6923 6924 /* 6925 * Start the global timer only if currently timer is not 6926 * running and if there are any transfers on the timeout 6927 * list. This timer will be per USB Host Controller. 6928 */ 6929 if ((!ohcip->ohci_timer_id) && (ohcip->ohci_timeout_list)) { 6930 ohcip->ohci_timer_id = timeout(ohci_xfer_timeout_handler, 6931 (void *)ohcip, drv_usectohz(1000000)); 6932 } 6933 } 6934 6935 6936 /* 6937 * ohci_deallocate_tw_resources: 6938 * NOTE: This function is also called from POLLED MODE. 6939 * 6940 * Deallocate of a Transaction Wrapper (TW) and this involves the freeing of 6941 * of DMA resources. 6942 */ 6943 void 6944 ohci_deallocate_tw_resources( 6945 ohci_state_t *ohcip, 6946 ohci_pipe_private_t *pp, 6947 ohci_trans_wrapper_t *tw) 6948 { 6949 ohci_trans_wrapper_t *prev, *next; 6950 6951 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6952 "ohci_deallocate_tw_resources: tw = 0x%p", tw); 6953 6954 /* 6955 * If the transfer wrapper has no Host Controller (HC) 6956 * Transfer Descriptors (TD) associated with it, then 6957 * remove the transfer wrapper. 6958 */ 6959 if (tw->tw_hctd_head) { 6960 ASSERT(tw->tw_hctd_tail != NULL); 6961 6962 return; 6963 } 6964 6965 ASSERT(tw->tw_hctd_tail == NULL); 6966 6967 /* Make sure we return all the unused td's to the pool as well */ 6968 ohci_free_tw_tds_resources(ohcip, tw); 6969 6970 /* 6971 * If pp->pp_tw_head and pp->pp_tw_tail are pointing to 6972 * given TW then set the head and tail equal to NULL. 6973 * Otherwise search for this TW in the linked TW's list 6974 * and then remove this TW from the list. 6975 */ 6976 if (pp->pp_tw_head == tw) { 6977 if (pp->pp_tw_tail == tw) { 6978 pp->pp_tw_head = NULL; 6979 pp->pp_tw_tail = NULL; 6980 } else { 6981 pp->pp_tw_head = tw->tw_next; 6982 } 6983 } else { 6984 prev = pp->pp_tw_head; 6985 next = prev->tw_next; 6986 6987 while (next && (next != tw)) { 6988 prev = next; 6989 next = next->tw_next; 6990 } 6991 6992 if (next == tw) { 6993 prev->tw_next = next->tw_next; 6994 6995 if (pp->pp_tw_tail == tw) { 6996 pp->pp_tw_tail = prev; 6997 } 6998 } 6999 } 7000 7001 ohci_free_tw(ohcip, tw); 7002 } 7003 7004 7005 /* 7006 * ohci_free_dma_resources: 7007 * 7008 * Free dma resources of a Transfer Wrapper (TW) and also free the TW. 7009 */ 7010 static void 7011 ohci_free_dma_resources( 7012 ohci_state_t *ohcip, 7013 usba_pipe_handle_data_t *ph) 7014 { 7015 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 7016 ohci_trans_wrapper_t *head_tw = pp->pp_tw_head; 7017 ohci_trans_wrapper_t *next_tw, *tw; 7018 7019 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7020 "ohci_free_dma_resources: ph = 0x%p", (void *)ph); 7021 7022 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7023 7024 /* Process the Transfer Wrappers */ 7025 next_tw = head_tw; 7026 while (next_tw) { 7027 tw = next_tw; 7028 next_tw = tw->tw_next; 7029 7030 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7031 "ohci_free_dma_resources: Free TW = 0x%p", (void *)tw); 7032 7033 ohci_free_tw(ohcip, tw); 7034 } 7035 7036 /* Adjust the head and tail pointers */ 7037 pp->pp_tw_head = NULL; 7038 pp->pp_tw_tail = NULL; 7039 } 7040 7041 7042 /* 7043 * ohci_free_tw: 7044 * 7045 * Free the Transfer Wrapper (TW). 7046 */ 7047 static void 7048 ohci_free_tw( 7049 ohci_state_t *ohcip, 7050 ohci_trans_wrapper_t *tw) 7051 { 7052 int rval; 7053 7054 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7055 "ohci_free_tw: tw = 0x%p", tw); 7056 7057 ASSERT(tw != NULL); 7058 ASSERT(tw->tw_id != NULL); 7059 7060 /* Free 32bit ID */ 7061 OHCI_FREE_ID((uint32_t)tw->tw_id); 7062 7063 rval = ddi_dma_unbind_handle(tw->tw_dmahandle); 7064 ASSERT(rval == DDI_SUCCESS); 7065 7066 ddi_dma_mem_free(&tw->tw_accesshandle); 7067 ddi_dma_free_handle(&tw->tw_dmahandle); 7068 7069 /* Free transfer wrapper */ 7070 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 7071 } 7072 7073 7074 /* 7075 * Interrupt Handling functions 7076 */ 7077 7078 /* 7079 * ohci_intr: 7080 * 7081 * OpenHCI (OHCI) interrupt handling routine. 7082 */ 7083 static uint_t 7084 ohci_intr(caddr_t arg1, caddr_t arg2) 7085 { 7086 ohci_state_t *ohcip = (ohci_state_t *)arg1; 7087 uint_t intr; 7088 ohci_td_t *done_head = NULL; 7089 ohci_save_intr_sts_t *ohci_intr_sts = &ohcip->ohci_save_intr_sts; 7090 7091 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7092 "ohci_intr: Interrupt occurred, arg1 0x%p arg2 0x%p", arg1, arg2); 7093 7094 mutex_enter(&ohcip->ohci_int_mutex); 7095 7096 /* 7097 * Suppose if we switched to the polled mode from the normal 7098 * mode when interrupt handler is executing then we need to 7099 * save the interrupt status information in the polled mode 7100 * to avoid race conditions. The following flag will be set 7101 * and reset on entering & exiting of ohci interrupt handler 7102 * respectively. This flag will be used in the polled mode 7103 * to check whether the interrupt handler was running when we 7104 * switched to the polled mode from the normal mode. 7105 */ 7106 ohci_intr_sts->ohci_intr_flag = OHCI_INTR_HANDLING; 7107 7108 /* Temporarily turn off interrupts */ 7109 Set_OpReg(hcr_intr_disable, HCR_INTR_MIE); 7110 7111 /* 7112 * Handle any missed ohci interrupt especially WriteDoneHead 7113 * and SOF interrupts because of previous polled mode switch. 7114 */ 7115 ohci_handle_missed_intr(ohcip); 7116 7117 /* 7118 * Now process the actual ohci interrupt events that caused 7119 * invocation of this ohci interrupt handler. 7120 */ 7121 7122 /* 7123 * Updating the WriteDoneHead interrupt: 7124 * 7125 * (a) Host Controller 7126 * 7127 * - First Host controller (HC) checks whether WDH bit 7128 * in the interrupt status register is cleared. 7129 * 7130 * - If WDH bit is cleared then HC writes new done head 7131 * list information into the HCCA done head field. 7132 * 7133 * - Set WDH bit in the interrupt status register. 7134 * 7135 * (b) Host Controller Driver (HCD) 7136 * 7137 * - First read the interrupt status register. The HCCA 7138 * done head and WDH bit may be set or may not be set 7139 * while reading the interrupt status register. 7140 * 7141 * - Read the HCCA done head list. By this time may be 7142 * HC has updated HCCA done head and WDH bit in ohci 7143 * interrupt status register. 7144 * 7145 * - If done head is non-null and if WDH bit is not set 7146 * then Host Controller has updated HCCA done head & 7147 * WDH bit in the interrupt stats register in between 7148 * reading the interrupt status register & HCCA done 7149 * head. In that case, definitely WDH bit will be set 7150 * in the interrupt status register & driver can take 7151 * it for granted. 7152 * 7153 * Now read the Interrupt Status & Interrupt enable register 7154 * to determine the exact interrupt events. 7155 */ 7156 intr = ohci_intr_sts->ohci_curr_intr_sts = 7157 (Get_OpReg(hcr_intr_status) & Get_OpReg(hcr_intr_enable)); 7158 7159 if (ohcip->ohci_hccap) { 7160 /* Sync HCCA area */ 7161 Sync_HCCA(ohcip); 7162 7163 /* Read and Save the HCCA DoneHead value */ 7164 done_head = ohci_intr_sts->ohci_curr_done_lst = 7165 (ohci_td_t *)(uintptr_t) 7166 (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) & 7167 HCCA_DONE_HEAD_MASK); 7168 7169 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7170 "ohci_intr: Done head! 0x%p", (void *)done_head); 7171 } 7172 7173 /* Update kstat values */ 7174 ohci_do_intrs_stats(ohcip, intr); 7175 7176 /* 7177 * Look at the HccaDoneHead & if it is non-zero, then a done 7178 * list update interrupt is indicated. 7179 */ 7180 if (done_head) { 7181 7182 /* 7183 * Check for the WriteDoneHead interrupt bit in the 7184 * interrupt condition and set the WriteDoneHead bit 7185 * in the interrupt events if it is not set. 7186 */ 7187 if (!(intr & HCR_INTR_WDH)) { 7188 intr |= HCR_INTR_WDH; 7189 } 7190 } 7191 7192 /* 7193 * We could have gotten a spurious interrupts. If so, do not 7194 * claim it. This is quite possible on some architectures 7195 * where more than one PCI slots share the IRQs. If so, the 7196 * associated driver's interrupt routine may get called even 7197 * if the interrupt is not meant for them. 7198 * 7199 * By unclaiming the interrupt, the other driver gets chance 7200 * to service its interrupt. 7201 */ 7202 if (!intr) { 7203 7204 /* Reset the interrupt handler flag */ 7205 ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_HANDLING; 7206 7207 Set_OpReg(hcr_intr_enable, HCR_INTR_MIE); 7208 mutex_exit(&ohcip->ohci_int_mutex); 7209 return (DDI_INTR_UNCLAIMED); 7210 } 7211 7212 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7213 "Interrupt status 0x%x", intr); 7214 7215 /* 7216 * Check for Frame Number Overflow. 7217 */ 7218 if (intr & HCR_INTR_FNO) { 7219 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7220 "ohci_intr: Frame Number Overflow"); 7221 7222 ohci_handle_frame_number_overflow(ohcip); 7223 } 7224 7225 if (intr & HCR_INTR_SOF) { 7226 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7227 "ohci_intr: Start of Frame"); 7228 7229 /* Set ohci_sof_flag indicating SOF interrupt occurred */ 7230 ohcip->ohci_sof_flag = B_TRUE; 7231 7232 /* Disabel SOF interrupt */ 7233 Set_OpReg(hcr_intr_disable, HCR_INTR_SOF); 7234 7235 /* 7236 * Call cv_broadcast on every SOF interrupt to wakeup 7237 * all the threads that are waiting the SOF. Calling 7238 * cv_broadcast on every SOF has no effect even if no 7239 * threads are waiting for the SOF. 7240 */ 7241 cv_broadcast(&ohcip->ohci_SOF_cv); 7242 } 7243 7244 if (intr & HCR_INTR_SO) { 7245 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7246 "ohci_intr: Schedule overrun"); 7247 7248 ohcip->ohci_so_error++; 7249 } 7250 7251 if ((intr & HCR_INTR_WDH) && (done_head)) { 7252 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7253 "ohci_intr: Done Head"); 7254 7255 /* 7256 * Currently if we are processing one WriteDoneHead 7257 * interrupt and also if we switched to the polled 7258 * mode at least once during this time, then there 7259 * may be chance that Host Controller generates one 7260 * more Write DoneHead or Start of Frame interrupts 7261 * for the normal since the polled code clears WDH & 7262 * SOF interrupt bits before returning to the normal 7263 * mode. Under this condition, we must not clear the 7264 * HCCA done head field & also we must not clear WDH 7265 * interrupt bit in the interrupt status register. 7266 */ 7267 if (done_head == (ohci_td_t *)(uintptr_t) 7268 (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) & 7269 HCCA_DONE_HEAD_MASK)) { 7270 7271 /* Reset the done head to NULL */ 7272 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, NULL); 7273 } else { 7274 intr &= ~HCR_INTR_WDH; 7275 } 7276 7277 /* Clear the current done head field */ 7278 ohci_intr_sts->ohci_curr_done_lst = NULL; 7279 7280 ohci_traverse_done_list(ohcip, done_head); 7281 } 7282 7283 /* Process endpoint reclaimation list */ 7284 if (ohcip->ohci_reclaim_list) { 7285 ohci_handle_endpoint_reclaimation(ohcip); 7286 } 7287 7288 if (intr & HCR_INTR_RD) { 7289 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7290 "ohci_intr: Resume Detected"); 7291 } 7292 7293 if (intr & HCR_INTR_RHSC) { 7294 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7295 "ohci_intr: Root hub status change"); 7296 } 7297 7298 if (intr & HCR_INTR_OC) { 7299 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7300 "ohci_intr: Change ownership"); 7301 7302 } 7303 7304 if (intr & HCR_INTR_UE) { 7305 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7306 "ohci_intr: Unrecoverable error"); 7307 7308 ohci_handle_ue(ohcip); 7309 } 7310 7311 /* Acknowledge the interrupt */ 7312 Set_OpReg(hcr_intr_status, intr); 7313 7314 /* Clear the current interrupt event field */ 7315 ohci_intr_sts->ohci_curr_intr_sts = 0; 7316 7317 /* 7318 * Reset the following flag indicating exiting the interrupt 7319 * handler and this flag will be used in the polled mode to 7320 * do some extra processing. 7321 */ 7322 ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_HANDLING; 7323 7324 Set_OpReg(hcr_intr_enable, HCR_INTR_MIE); 7325 7326 /* 7327 * Read interrupt status register to make sure that any PIO 7328 * store to clear the ISR has made it on the PCI bus before 7329 * returning from its interrupt handler. 7330 */ 7331 (void) Get_OpReg(hcr_intr_status); 7332 7333 mutex_exit(&ohcip->ohci_int_mutex); 7334 7335 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7336 "Interrupt handling completed"); 7337 7338 return (DDI_INTR_CLAIMED); 7339 } 7340 7341 7342 /* 7343 * ohci_handle_missed_intr: 7344 * 7345 * Handle any ohci missed interrupts because of polled mode switch. 7346 */ 7347 static void 7348 ohci_handle_missed_intr(ohci_state_t *ohcip) 7349 { 7350 ohci_save_intr_sts_t *ohci_intr_sts = 7351 &ohcip->ohci_save_intr_sts; 7352 ohci_td_t *done_head; 7353 uint_t intr; 7354 7355 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7356 7357 /* 7358 * Check whether we have missed any ohci interrupts because 7359 * of the polled mode switch during previous ohci interrupt 7360 * handler execution. Only Write Done Head & SOF interrupts 7361 * saved in the polled mode. First process these interrupts 7362 * before processing actual interrupts that caused invocation 7363 * of ohci interrupt handler. 7364 */ 7365 if (!ohci_intr_sts->ohci_missed_intr_sts) { 7366 /* No interrupts are missed, simply return */ 7367 7368 return; 7369 } 7370 7371 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7372 "ohci_handle_missed_intr: Handle ohci missed interrupts"); 7373 7374 /* 7375 * The functionality and importance of critical code section 7376 * in the normal mode ohci interrupt handler & its usage in 7377 * the polled mode is explained below. 7378 * 7379 * (a) Normal mode: 7380 * 7381 * - Set the flag indicating that processing critical 7382 * code in ohci interrupt handler. 7383 * 7384 * - Process the missed ohci interrupts by copying the 7385 * miised interrupt events and done head list fields 7386 * information to the critical interrupt event & done 7387 * list fields. 7388 * 7389 * - Reset the missed ohci interrupt events & done head 7390 * list fields so that the new missed interrupt event 7391 * and done head list information can be saved. 7392 * 7393 * - All above steps will be executed with in critical 7394 * section of the interrupt handler.Then ohci missed 7395 * interrupt handler will be called to service missed 7396 * ohci interrupts. 7397 * 7398 * (b) Polled mode: 7399 * 7400 * - On entering the polled code,it checks for critical 7401 * section code execution within the normal mode ohci 7402 * interrupt handler. 7403 * 7404 * - If the critical section code is executing in normal 7405 * mode ohci interrupt handler and if copying of ohci 7406 * missed interrupt events & done head list fields to 7407 * the critical fields is finished then save the "any 7408 * missed interrupt events & done head list" because 7409 * of current polled mode switch into "critical missed 7410 * interrupt events & done list fields" instead actual 7411 * missed events and done list fields. 7412 * 7413 * - Otherwise save "any missed interrupt events & done 7414 * list" because of this current polled mode switch 7415 * in the actual missed interrupt events & done head 7416 * list fields. 7417 */ 7418 7419 /* 7420 * Set flag indicating that interrupt handler is processing 7421 * critical interrupt code, so that polled mode code checks 7422 * for this condition & will do extra processing as explained 7423 * above in order to aviod the race conditions. 7424 */ 7425 ohci_intr_sts->ohci_intr_flag |= OHCI_INTR_CRITICAL; 7426 ohci_intr_sts->ohci_critical_intr_sts |= 7427 ohci_intr_sts->ohci_missed_intr_sts; 7428 7429 if (ohci_intr_sts->ohci_missed_done_lst) { 7430 7431 ohci_intr_sts->ohci_critical_done_lst = 7432 ohci_intr_sts->ohci_missed_done_lst; 7433 } 7434 7435 ohci_intr_sts->ohci_missed_intr_sts = 0; 7436 ohci_intr_sts->ohci_missed_done_lst = NULL; 7437 ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_CRITICAL; 7438 7439 intr = ohci_intr_sts->ohci_critical_intr_sts; 7440 done_head = ohci_intr_sts->ohci_critical_done_lst; 7441 7442 if (intr & HCR_INTR_SOF) { 7443 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7444 "ohci_handle_missed_intr: Start of Frame"); 7445 7446 /* 7447 * Call cv_broadcast on every SOF interrupt to wakeup 7448 * all the threads that are waiting the SOF. Calling 7449 * cv_broadcast on every SOF has no effect even if no 7450 * threads are waiting for the SOF. 7451 */ 7452 cv_broadcast(&ohcip->ohci_SOF_cv); 7453 } 7454 7455 if ((intr & HCR_INTR_WDH) && (done_head)) { 7456 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7457 "ohci_handle_missed_intr: Done Head"); 7458 7459 /* Clear the critical done head field */ 7460 ohci_intr_sts->ohci_critical_done_lst = NULL; 7461 7462 ohci_traverse_done_list(ohcip, done_head); 7463 } 7464 7465 /* Clear the critical interrupt event field */ 7466 ohci_intr_sts->ohci_critical_intr_sts = 0; 7467 } 7468 7469 7470 /* 7471 * ohci_handle_ue: 7472 * 7473 * Handling of Unrecoverable Error interrupt (UE). 7474 */ 7475 static void 7476 ohci_handle_ue(ohci_state_t *ohcip) 7477 { 7478 usb_frame_number_t before_frame_number, after_frame_number; 7479 7480 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7481 7482 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7483 "ohci_handle_ue: Handling of UE interrupt"); 7484 7485 /* 7486 * First check whether current UE error occured due to USB or 7487 * due to some other subsystem. This can be verified by reading 7488 * usb frame numbers before & after a delay of few milliseconds. 7489 * If usb frame number read after delay is greater than the one 7490 * read before delay, then, USB subsystem is fine. In this case, 7491 * disable UE error interrupt and return without shutdowning the 7492 * USB subsystem. 7493 * 7494 * Otherwise, if usb frame number read after delay is less than 7495 * or equal to one read before the delay, then, current UE error 7496 * occured from USB susbsystem. In this case,go ahead with actual 7497 * UE error recovery procedure. 7498 * 7499 * Get the current usb frame number before waiting for few 7500 * milliseconds. 7501 */ 7502 before_frame_number = ohci_get_current_frame_number(ohcip); 7503 7504 /* Wait for few milliseconds */ 7505 drv_usecwait(OHCI_TIMEWAIT); 7506 7507 /* 7508 * Get the current usb frame number after waiting for 7509 * milliseconds. 7510 */ 7511 after_frame_number = ohci_get_current_frame_number(ohcip); 7512 7513 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7514 "ohci_handle_ue: Before Frm No 0x%llx After Frm No 0x%llx", 7515 before_frame_number, after_frame_number); 7516 7517 if (after_frame_number > before_frame_number) { 7518 7519 /* Disable UE interrupt */ 7520 Set_OpReg(hcr_intr_disable, HCR_INTR_UE); 7521 7522 return; 7523 } 7524 7525 /* 7526 * This UE is due to USB hardware error. Reset ohci controller 7527 * and reprogram to bring it back to functional state. 7528 */ 7529 if ((ohci_do_soft_reset(ohcip)) != USB_SUCCESS) { 7530 USB_DPRINTF_L0(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7531 "Unrecoverable USB Hardware Error"); 7532 7533 /* Disable UE interrupt */ 7534 Set_OpReg(hcr_intr_disable, HCR_INTR_UE); 7535 7536 /* Set host controller soft state to error */ 7537 ohcip->ohci_hc_soft_state = OHCI_CTLR_ERROR_STATE; 7538 } 7539 } 7540 7541 7542 /* 7543 * ohci_handle_frame_number_overflow: 7544 * 7545 * Update software based usb frame number part on every frame number 7546 * overflow interrupt. 7547 * 7548 * NOTE: This function is also called from POLLED MODE. 7549 * 7550 * Refer ohci spec 1.0a, section 5.3, page 81 for more details. 7551 */ 7552 void 7553 ohci_handle_frame_number_overflow(ohci_state_t *ohcip) 7554 { 7555 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7556 "ohci_handle_frame_number_overflow:"); 7557 7558 ohcip->ohci_fno += (0x10000 - 7559 (((Get_HCCA(ohcip->ohci_hccap->HccaFrameNo) & 7560 0xFFFF) ^ ohcip->ohci_fno) & 0x8000)); 7561 7562 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7563 "ohci_handle_frame_number_overflow:" 7564 "Frame Number Higher Part 0x%llx\n", ohcip->ohci_fno); 7565 } 7566 7567 7568 /* 7569 * ohci_handle_endpoint_reclaimation: 7570 * 7571 * Reclamation of Host Controller (HC) Endpoint Descriptors (ED). 7572 */ 7573 static void 7574 ohci_handle_endpoint_reclaimation(ohci_state_t *ohcip) 7575 { 7576 usb_frame_number_t current_frame_number; 7577 usb_frame_number_t endpoint_frame_number; 7578 ohci_ed_t *reclaim_ed; 7579 7580 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7581 "ohci_handle_endpoint_reclaimation:"); 7582 7583 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7584 7585 current_frame_number = ohci_get_current_frame_number(ohcip); 7586 7587 /* 7588 * Deallocate all Endpoint Descriptors (ED) which are on the 7589 * reclaimation list. These ED's are already removed from the 7590 * interrupt lattice tree. 7591 */ 7592 while (ohcip->ohci_reclaim_list) { 7593 reclaim_ed = ohcip->ohci_reclaim_list; 7594 7595 endpoint_frame_number = (usb_frame_number_t)(uintptr_t) 7596 (OHCI_LOOKUP_ID(Get_ED(reclaim_ed->hced_reclaim_frame))); 7597 7598 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7599 "ohci_handle_endpoint_reclaimation:" 7600 "current frame number 0x%llx endpoint frame number 0x%llx", 7601 current_frame_number, endpoint_frame_number); 7602 7603 /* 7604 * Deallocate current endpoint only if endpoint's usb frame 7605 * number is less than or equal to current usb frame number. 7606 * 7607 * If endpoint's usb frame number is greater than the current 7608 * usb frame number, ignore rest of the endpoints in the list 7609 * since rest of the endpoints are inserted into the reclaim 7610 * list later than the current reclaim endpoint. 7611 */ 7612 if (endpoint_frame_number > current_frame_number) { 7613 break; 7614 } 7615 7616 /* Get the next endpoint from the rec. list */ 7617 ohcip->ohci_reclaim_list = ohci_ed_iommu_to_cpu(ohcip, 7618 Get_ED(reclaim_ed->hced_reclaim_next)); 7619 7620 /* Free 32bit ID */ 7621 OHCI_FREE_ID((uint32_t)Get_ED(reclaim_ed->hced_reclaim_frame)); 7622 7623 /* Deallocate the endpoint */ 7624 ohci_deallocate_ed(ohcip, reclaim_ed); 7625 } 7626 } 7627 7628 7629 /* 7630 * ohci_traverse_done_list: 7631 */ 7632 static void 7633 ohci_traverse_done_list( 7634 ohci_state_t *ohcip, 7635 ohci_td_t *head_done_list) 7636 { 7637 uint_t state; /* TD state */ 7638 ohci_td_t *td, *old_td; /* TD pointers */ 7639 usb_cr_t error; /* Error from TD */ 7640 ohci_trans_wrapper_t *tw = NULL; /* Transfer wrapper */ 7641 ohci_pipe_private_t *pp = NULL; /* Pipe private field */ 7642 7643 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7644 "ohci_traverse_done_list:"); 7645 7646 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7647 7648 /* Sync ED and TD pool */ 7649 Sync_ED_TD_Pool(ohcip); 7650 7651 /* Reverse the done list */ 7652 td = ohci_reverse_done_list(ohcip, head_done_list); 7653 7654 /* Traverse the list of transfer descriptors */ 7655 while (td) { 7656 /* Check for TD state */ 7657 state = Get_TD(td->hctd_state); 7658 7659 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7660 "ohci_traverse_done_list:\n\t" 7661 "td = 0x%p state = 0x%x", (void *)td, state); 7662 7663 /* 7664 * Obtain the transfer wrapper only if the TD is 7665 * not marked as RECLAIM. 7666 * 7667 * A TD that is marked as RECLAIM has had its DMA 7668 * mappings, ED, TD and pipe private structure are 7669 * ripped down. Just deallocate this TD. 7670 */ 7671 if (state != HC_TD_RECLAIM) { 7672 7673 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID( 7674 (uint32_t)Get_TD(td->hctd_trans_wrapper)); 7675 7676 ASSERT(tw != NULL); 7677 7678 pp = tw->tw_pipe_private; 7679 7680 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7681 "ohci_traverse_done_list: PP = 0x%p TW = 0x%p", 7682 pp, tw); 7683 } 7684 7685 /* 7686 * Don't process the TD if its state is marked as 7687 * either RECLAIM or TIMEOUT. 7688 * 7689 * A TD that is marked as TIMEOUT has already been 7690 * processed by TD timeout handler & client driver 7691 * has been informed through exception callback. 7692 */ 7693 if ((state != HC_TD_RECLAIM) && (state != HC_TD_TIMEOUT)) { 7694 7695 /* Look at the error status */ 7696 error = ohci_parse_error(ohcip, td); 7697 7698 if (error == USB_CR_OK) { 7699 ohci_handle_normal_td(ohcip, td, tw); 7700 } else { 7701 /* handle the error condition */ 7702 ohci_handle_error(ohcip, td, error); 7703 } 7704 } else { 7705 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7706 "ohci_traverse_done_list: TD State = %d", state); 7707 } 7708 7709 /* 7710 * Save a pointer to the current transfer descriptor 7711 */ 7712 old_td = td; 7713 7714 td = ohci_td_iommu_to_cpu(ohcip, Get_TD(td->hctd_next_td)); 7715 7716 /* Deallocate this transfer descriptor */ 7717 ohci_deallocate_td(ohcip, old_td); 7718 7719 /* 7720 * Deallocate the transfer wrapper if there are no more 7721 * TD's for the transfer wrapper. ohci_deallocate_tw_resources() 7722 * will not deallocate the tw for a periodic endpoint 7723 * since it will always have a TD attached to it. 7724 * 7725 * Do not deallocate the TW if it is a isoc or intr pipe in. 7726 * The tw's are reused. 7727 * 7728 * An TD that is marked as reclaim doesn't have a pipe 7729 * or a TW associated with it anymore so don't call this 7730 * function. 7731 */ 7732 if (state != HC_TD_RECLAIM) { 7733 ASSERT(tw != NULL); 7734 ohci_deallocate_tw_resources(ohcip, pp, tw); 7735 } 7736 } 7737 } 7738 7739 7740 /* 7741 * ohci_reverse_done_list: 7742 * 7743 * Reverse the order of the Transfer Descriptor (TD) Done List. 7744 */ 7745 static ohci_td_t * 7746 ohci_reverse_done_list( 7747 ohci_state_t *ohcip, 7748 ohci_td_t *head_done_list) 7749 { 7750 ohci_td_t *cpu_new_tail, *cpu_new_head, *cpu_save; 7751 7752 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7753 "ohci_reverse_done_list:"); 7754 7755 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7756 ASSERT(head_done_list != NULL); 7757 7758 /* At first, both the tail and head pointers point to the same elem */ 7759 cpu_new_tail = cpu_new_head = 7760 ohci_td_iommu_to_cpu(ohcip, (uintptr_t)head_done_list); 7761 7762 /* See if the list has only one element */ 7763 if (Get_TD(cpu_new_head->hctd_next_td) == NULL) { 7764 7765 return (cpu_new_head); 7766 } 7767 7768 /* Advance the head pointer */ 7769 cpu_new_head = (ohci_td_t *) 7770 ohci_td_iommu_to_cpu(ohcip, Get_TD(cpu_new_head->hctd_next_td)); 7771 7772 /* The new tail now points to nothing */ 7773 Set_TD(cpu_new_tail->hctd_next_td, NULL); 7774 7775 cpu_save = (ohci_td_t *) 7776 ohci_td_iommu_to_cpu(ohcip, Get_TD(cpu_new_head->hctd_next_td)); 7777 7778 /* Reverse the list and store the pointers as CPU addresses */ 7779 while (cpu_save) { 7780 Set_TD(cpu_new_head->hctd_next_td, 7781 ohci_td_cpu_to_iommu(ohcip, cpu_new_tail)); 7782 7783 cpu_new_tail = cpu_new_head; 7784 cpu_new_head = cpu_save; 7785 7786 cpu_save = (ohci_td_t *) 7787 ohci_td_iommu_to_cpu(ohcip, 7788 Get_TD(cpu_new_head->hctd_next_td)); 7789 } 7790 7791 Set_TD(cpu_new_head->hctd_next_td, 7792 ohci_td_cpu_to_iommu(ohcip, cpu_new_tail)); 7793 7794 return (cpu_new_head); 7795 } 7796 7797 7798 /* 7799 * ohci_parse_error: 7800 * 7801 * Parse the result for any errors. 7802 */ 7803 static usb_cr_t 7804 ohci_parse_error( 7805 ohci_state_t *ohcip, 7806 ohci_td_t *td) 7807 { 7808 uint_t ctrl; 7809 usb_ep_descr_t *eptd; 7810 ohci_trans_wrapper_t *tw; 7811 ohci_pipe_private_t *pp; 7812 uint_t flag; 7813 usb_cr_t error; 7814 7815 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7816 "ohci_parse_error:"); 7817 7818 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7819 7820 ASSERT(td != NULL); 7821 7822 /* Obtain the transfer wrapper from the TD */ 7823 tw = (ohci_trans_wrapper_t *) 7824 OHCI_LOOKUP_ID((uint32_t)Get_TD(td->hctd_trans_wrapper)); 7825 7826 ASSERT(tw != NULL); 7827 7828 /* Obtain the pipe private structure */ 7829 pp = tw->tw_pipe_private; 7830 7831 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7832 "ohci_parse_error: PP 0x%p TW 0x%p", pp, tw); 7833 7834 eptd = &pp->pp_pipe_handle->p_ep; 7835 7836 ctrl = (uint_t)Get_TD(td->hctd_ctrl) & (uint32_t)HC_TD_CC; 7837 7838 /* 7839 * Check the condition code of completed TD and report errors 7840 * if any. This checking will be done both for the general and 7841 * the isochronous TDs. 7842 */ 7843 if ((error = ohci_check_for_error(ohcip, pp, tw, td, ctrl)) != 7844 USB_CR_OK) { 7845 flag = OHCI_REMOVE_XFER_ALWAYS; 7846 } else { 7847 flag = OHCI_REMOVE_XFER_IFLAST; 7848 } 7849 7850 /* Stop the the transfer timer */ 7851 ohci_stop_xfer_timer(ohcip, tw, flag); 7852 7853 /* 7854 * The isochronous endpoint needs additional error checking 7855 * and special processing. 7856 */ 7857 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) == 7858 USB_EP_ATTR_ISOCH) { 7859 7860 ohci_parse_isoc_error(ohcip, pp, tw, td); 7861 7862 /* always reset error */ 7863 error = USB_CR_OK; 7864 } 7865 7866 return (error); 7867 } 7868 7869 7870 /* 7871 * ohci_parse_isoc_error: 7872 * 7873 * Check for any errors in the isochronous data packets. Also fillup 7874 * the status for each of the isochrnous data packets. 7875 */ 7876 void 7877 ohci_parse_isoc_error( 7878 ohci_state_t *ohcip, 7879 ohci_pipe_private_t *pp, 7880 ohci_trans_wrapper_t *tw, 7881 ohci_td_t *td) 7882 { 7883 usb_isoc_req_t *isoc_reqp; 7884 usb_isoc_pkt_descr_t *isoc_pkt_descr; 7885 uint_t toggle = 0, fc, ctrl, psw; 7886 int i; 7887 7888 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7889 "ohci_parse_isoc_error: td 0x%p", td); 7890 7891 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7892 7893 fc = ((uint_t)Get_TD(td->hctd_ctrl) & 7894 HC_ITD_FC) >> HC_ITD_FC_SHIFT; 7895 7896 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 7897 "ohci_parse_isoc_error: frame count %d", fc); 7898 7899 /* 7900 * Get the address of current usb isochronous request 7901 * and array of packet descriptors. 7902 */ 7903 isoc_reqp = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp; 7904 isoc_pkt_descr = isoc_reqp->isoc_pkt_descr; 7905 7906 for (i = 0; i <= fc; i++) { 7907 7908 psw = Get_TD(td->hctd_offsets[i / 2]); 7909 7910 if (toggle) { 7911 ctrl = psw & HC_ITD_ODD_OFFSET; 7912 toggle = 0; 7913 } else { 7914 ctrl = (psw & HC_ITD_EVEN_OFFSET) << 7915 HC_ITD_OFFSET_SHIFT; 7916 toggle = 1; 7917 } 7918 7919 isoc_pkt_descr->isoc_pkt_actual_length = 7920 (ctrl >> HC_ITD_OFFSET_SHIFT) & HC_ITD_OFFSET_ADDR; 7921 7922 ctrl = (uint_t)(ctrl & (uint32_t)HC_TD_CC); 7923 7924 /* Write the status of isoc data packet */ 7925 isoc_pkt_descr->isoc_pkt_status = 7926 ohci_check_for_error(ohcip, pp, tw, td, ctrl); 7927 7928 if (isoc_pkt_descr->isoc_pkt_status) { 7929 /* Increment isoc data packet error count */ 7930 isoc_reqp->isoc_error_count++; 7931 } 7932 7933 /* 7934 * Get the address of next isoc data packet descriptor. 7935 */ 7936 isoc_pkt_descr++; 7937 } 7938 } 7939 7940 7941 /* 7942 * ohci_check_for_error: 7943 * 7944 * Check for any errors. 7945 */ 7946 static usb_cr_t 7947 ohci_check_for_error( 7948 ohci_state_t *ohcip, 7949 ohci_pipe_private_t *pp, 7950 ohci_trans_wrapper_t *tw, 7951 ohci_td_t *td, 7952 uint_t ctrl) 7953 { 7954 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 7955 uchar_t ep_attrs = ph->p_ep.bmAttributes; 7956 usb_cr_t error = USB_CR_OK; 7957 usb_req_attrs_t xfer_attrs; 7958 7959 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7960 "ohci_check_for_error: td = 0x%p ctrl = 0x%x", 7961 td, ctrl); 7962 7963 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7964 7965 switch (ctrl) { 7966 case HC_TD_CC_NO_E: 7967 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7968 "ohci_check_for_error: No Error"); 7969 error = USB_CR_OK; 7970 break; 7971 case HC_TD_CC_CRC: 7972 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7973 "ohci_check_for_error: CRC error"); 7974 error = USB_CR_CRC; 7975 break; 7976 case HC_TD_CC_BS: 7977 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7978 "ohci_check_for_error: Bit stuffing"); 7979 error = USB_CR_BITSTUFFING; 7980 break; 7981 case HC_TD_CC_DTM: 7982 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7983 "ohci_check_for_error: Data Toggle Mismatch"); 7984 error = USB_CR_DATA_TOGGLE_MM; 7985 break; 7986 case HC_TD_CC_STALL: 7987 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7988 "ohci_check_for_error: Stall"); 7989 error = USB_CR_STALL; 7990 break; 7991 case HC_TD_CC_DNR: 7992 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7993 "ohci_check_for_error: Device not responding"); 7994 error = USB_CR_DEV_NOT_RESP; 7995 break; 7996 case HC_TD_CC_PCF: 7997 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7998 "ohci_check_for_error: PID check failure"); 7999 error = USB_CR_PID_CHECKFAILURE; 8000 break; 8001 case HC_TD_CC_UPID: 8002 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8003 "ohci_check_for_error: Unexpected PID"); 8004 error = USB_CR_UNEXP_PID; 8005 break; 8006 case HC_TD_CC_DO: 8007 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8008 "ohci_check_for_error: Data overrrun"); 8009 error = USB_CR_DATA_OVERRUN; 8010 break; 8011 case HC_TD_CC_DU: 8012 /* 8013 * Check whether short packets are acceptable. 8014 * If so don't report error to client drivers 8015 * and restart the endpoint. Otherwise report 8016 * data underrun error to client driver. 8017 */ 8018 xfer_attrs = ohci_get_xfer_attrs(ohcip, pp, tw); 8019 8020 if (xfer_attrs & USB_ATTRS_SHORT_XFER_OK) { 8021 error = USB_CR_OK; 8022 if ((ep_attrs & USB_EP_ATTR_MASK) != 8023 USB_EP_ATTR_ISOCH) { 8024 /* 8025 * Cleanup the remaining resources that may have 8026 * been allocated for this transfer. 8027 */ 8028 if (ohci_cleanup_data_underrun(ohcip, pp, tw, 8029 td) == USB_SUCCESS) { 8030 /* Clear the halt bit */ 8031 Set_ED(pp->pp_ept->hced_headp, 8032 (Get_ED(pp->pp_ept->hced_headp) & 8033 ~HC_EPT_Halt)); 8034 } else { 8035 error = USB_CR_UNSPECIFIED_ERR; 8036 } 8037 } 8038 } else { 8039 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8040 "ohci_check_for_error: Data underrun"); 8041 8042 error = USB_CR_DATA_UNDERRUN; 8043 } 8044 8045 break; 8046 case HC_TD_CC_BO: 8047 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8048 "ohci_check_for_error: Buffer overrun"); 8049 error = USB_CR_BUFFER_OVERRUN; 8050 break; 8051 case HC_TD_CC_BU: 8052 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8053 "ohci_check_for_error: Buffer underrun"); 8054 error = USB_CR_BUFFER_UNDERRUN; 8055 break; 8056 case HC_TD_CC_NA: 8057 default: 8058 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8059 "ohci_check_for_error: Not accessed"); 8060 error = USB_CR_NOT_ACCESSED; 8061 break; 8062 } 8063 8064 if (error) { 8065 uint_t hced_ctrl = Get_ED(pp->pp_ept->hced_ctrl); 8066 8067 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8068 "ohci_check_for_error: Error %d Device address %d " 8069 "Endpoint number %d", error, (hced_ctrl & HC_EPT_FUNC), 8070 ((hced_ctrl & HC_EPT_EP) >> HC_EPT_EP_SHFT)); 8071 } 8072 8073 return (error); 8074 } 8075 8076 8077 /* 8078 * ohci_handle_error: 8079 * 8080 * Inform USBA about occured transaction errors by calling the USBA callback 8081 * routine. 8082 */ 8083 static void 8084 ohci_handle_error( 8085 ohci_state_t *ohcip, 8086 ohci_td_t *td, 8087 usb_cr_t error) 8088 { 8089 ohci_trans_wrapper_t *tw; 8090 usba_pipe_handle_data_t *ph; 8091 ohci_pipe_private_t *pp; 8092 mblk_t *mp = NULL; 8093 size_t length = 0; 8094 uchar_t attributes; 8095 usb_intr_req_t *curr_intr_reqp; 8096 8097 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8098 "ohci_handle_error: error = 0x%x", error); 8099 8100 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8101 8102 ASSERT(td != NULL); 8103 8104 /* Print the values in the td */ 8105 ohci_print_td(ohcip, td); 8106 8107 /* Obtain the transfer wrapper from the TD */ 8108 tw = (ohci_trans_wrapper_t *) 8109 OHCI_LOOKUP_ID((uint32_t)Get_TD(td->hctd_trans_wrapper)); 8110 8111 ASSERT(tw != NULL); 8112 8113 /* Obtain the pipe private structure */ 8114 pp = tw->tw_pipe_private; 8115 8116 ph = tw->tw_pipe_private->pp_pipe_handle; 8117 attributes = ph->p_ep.bmAttributes & USB_EP_ATTR_MASK; 8118 8119 /* 8120 * Special error handling 8121 */ 8122 if (tw->tw_direction == HC_TD_IN) { 8123 8124 switch (attributes) { 8125 case USB_EP_ATTR_CONTROL: 8126 if (((ph->p_ep.bmAttributes & 8127 USB_EP_ATTR_MASK) == 8128 USB_EP_ATTR_CONTROL) && 8129 (Get_TD(td->hctd_ctrl_phase) == 8130 OHCI_CTRL_SETUP_PHASE)) { 8131 8132 break; 8133 } 8134 /* FALLTHROUGH */ 8135 case USB_EP_ATTR_BULK: 8136 /* 8137 * Call ohci_sendup_td_message 8138 * to send message to upstream. 8139 */ 8140 ohci_sendup_td_message(ohcip, pp, tw, td, error); 8141 8142 return; 8143 case USB_EP_ATTR_INTR: 8144 curr_intr_reqp = 8145 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 8146 8147 if (curr_intr_reqp->intr_attributes & 8148 USB_ATTRS_ONE_XFER) { 8149 8150 ohci_handle_one_xfer_completion(ohcip, tw); 8151 } 8152 8153 /* Decrement periodic in request count */ 8154 pp->pp_cur_periodic_req_cnt--; 8155 break; 8156 case USB_EP_ATTR_ISOCH: 8157 default: 8158 break; 8159 } 8160 } else { 8161 switch (attributes) { 8162 case USB_EP_ATTR_BULK: 8163 case USB_EP_ATTR_INTR: 8164 /* 8165 * If "CurrentBufferPointer" of Transfer 8166 * Descriptor (TD) is not equal to zero, 8167 * then we sent less data to the device 8168 * than requested by client. In that case, 8169 * return the mblk after updating the 8170 * data->r_ptr. 8171 */ 8172 if (Get_TD(td->hctd_cbp)) { 8173 usb_opaque_t xfer_reqp = tw->tw_curr_xfer_reqp; 8174 8175 length = Get_TD(td->hctd_cbp) - 8176 tw->tw_cookie.dmac_address; 8177 8178 USB_DPRINTF_L2(PRINT_MASK_INTR, 8179 ohcip->ohci_log_hdl, 8180 "ohci_handle_error: requested data %lu " 8181 "sent data %lu", tw->tw_length, length); 8182 8183 if (attributes == USB_EP_ATTR_BULK) { 8184 mp = (mblk_t *)((usb_bulk_req_t *) 8185 (xfer_reqp))->bulk_data; 8186 } else { 8187 mp = (mblk_t *)((usb_intr_req_t *) 8188 (xfer_reqp))->intr_data; 8189 } 8190 8191 /* Increment the read pointer */ 8192 mp->b_rptr = mp->b_rptr + length; 8193 } 8194 break; 8195 default: 8196 break; 8197 } 8198 } 8199 8200 /* 8201 * Callback the client with the 8202 * failure reason. 8203 */ 8204 ohci_hcdi_callback(ph, tw, error); 8205 8206 /* Check anybody is waiting for transfers completion event */ 8207 ohci_check_for_transfers_completion(ohcip, pp); 8208 } 8209 8210 /* 8211 * ohci_cleanup_data_underrun: 8212 * 8213 * Cleans up resources when a short xfer occurs 8214 */ 8215 static int 8216 ohci_cleanup_data_underrun( 8217 ohci_state_t *ohcip, 8218 ohci_pipe_private_t *pp, 8219 ohci_trans_wrapper_t *tw, 8220 ohci_td_t *td) 8221 { 8222 ohci_td_t *next_td; 8223 ohci_td_t *last_td; 8224 ohci_td_t *temp_td; 8225 uint32_t last_td_addr; 8226 uint_t hced_head; 8227 8228 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8229 "ohci_cleanup_data_underrun: td 0x%p, tw 0x%p", td, tw); 8230 8231 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8232 ASSERT(tw->tw_hctd_head == td); 8233 8234 /* Check if this TD is the last td in the tw */ 8235 last_td = tw->tw_hctd_tail; 8236 if (td == last_td) { 8237 /* There is no need for cleanup */ 8238 return (USB_SUCCESS); 8239 } 8240 8241 /* 8242 * Make sure the ED is halted before we change any td's. 8243 * If for some reason it is not halted, return error to client 8244 * driver so they can reset the port. 8245 */ 8246 hced_head = Get_ED(pp->pp_ept->hced_headp); 8247 if (!(hced_head & HC_EPT_Halt)) { 8248 uint_t hced_ctrl = Get_ED(pp->pp_ept->hced_ctrl); 8249 8250 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8251 "ohci_cleanup_data_underrun: Unable to clean up a short " 8252 "xfer error. Client might send/receive irrelevant data." 8253 " Device address %d Endpoint number %d", 8254 (hced_ctrl & HC_EPT_FUNC), 8255 ((hced_ctrl & HC_EPT_EP) >> HC_EPT_EP_SHFT)); 8256 8257 Set_ED(pp->pp_ept->hced_headp, hced_head | HC_EPT_Halt); 8258 8259 return (USB_FAILURE); 8260 } 8261 8262 /* 8263 * Get the address of the first td of the next transfer (tw). 8264 * This td, may currently be a dummy td, but when a new request 8265 * arrives, it will be transformed into a regular td. 8266 */ 8267 last_td_addr = Get_TD(last_td->hctd_next_td); 8268 /* Set ED head to this last td */ 8269 Set_ED(pp->pp_ept->hced_headp, 8270 (last_td_addr & HC_EPT_TD_HEAD) | 8271 (hced_head & ~HC_EPT_TD_HEAD)); 8272 8273 /* 8274 * Start removing all the unused TD's from the TW, 8275 * but keep the first one. 8276 */ 8277 tw->tw_hctd_tail = td; 8278 8279 /* 8280 * Get the last_td, the next td in the tw list. 8281 * Afterwards completely disassociate the current td from other tds 8282 */ 8283 next_td = (ohci_td_t *)ohci_td_iommu_to_cpu(ohcip, 8284 Get_TD(td->hctd_tw_next_td)); 8285 Set_TD(td->hctd_tw_next_td, NULL); 8286 8287 /* 8288 * Iterate down the tw list and deallocate them 8289 */ 8290 while (next_td != NULL) { 8291 tw->tw_num_tds--; 8292 /* Disassociate this td from it's TW and set to RECLAIM */ 8293 Set_TD(next_td->hctd_trans_wrapper, NULL); 8294 Set_TD(next_td->hctd_state, HC_TD_RECLAIM); 8295 8296 temp_td = next_td; 8297 8298 next_td = (ohci_td_t *)ohci_td_iommu_to_cpu(ohcip, 8299 Get_TD(next_td->hctd_tw_next_td)); 8300 8301 ohci_deallocate_td(ohcip, temp_td); 8302 } 8303 8304 ASSERT(tw->tw_num_tds == 1); 8305 8306 return (USB_SUCCESS); 8307 } 8308 8309 /* 8310 * ohci_handle_normal_td: 8311 */ 8312 static void 8313 ohci_handle_normal_td( 8314 ohci_state_t *ohcip, 8315 ohci_td_t *td, 8316 ohci_trans_wrapper_t *tw) 8317 { 8318 ohci_pipe_private_t *pp; /* Pipe private field */ 8319 8320 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8321 "ohci_handle_normal_td:"); 8322 8323 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8324 ASSERT(tw != NULL); 8325 8326 /* Obtain the pipe private structure */ 8327 pp = tw->tw_pipe_private; 8328 8329 (*tw->tw_handle_td)(ohcip, pp, tw, 8330 td, tw->tw_handle_callback_value); 8331 8332 /* Check anybody is waiting for transfers completion event */ 8333 ohci_check_for_transfers_completion(ohcip, pp); 8334 } 8335 8336 8337 /* 8338 * ohci_handle_ctrl_td: 8339 * 8340 * Handle a control Transfer Descriptor (TD). 8341 */ 8342 /* ARGSUSED */ 8343 static void 8344 ohci_handle_ctrl_td( 8345 ohci_state_t *ohcip, 8346 ohci_pipe_private_t *pp, 8347 ohci_trans_wrapper_t *tw, 8348 ohci_td_t *td, 8349 void *tw_handle_callback_value) 8350 { 8351 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 8352 8353 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8354 "ohci_handle_ctrl_td: pp = 0x%p tw = 0x%p td = 0x%p state = 0x%x", 8355 (void *)pp, (void *)tw, (void *)td, Get_TD(td->hctd_ctrl_phase)); 8356 8357 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8358 8359 /* 8360 * Check which control transfer phase got completed. 8361 */ 8362 tw->tw_num_tds--; 8363 switch (Get_TD(td->hctd_ctrl_phase)) { 8364 case OHCI_CTRL_SETUP_PHASE: 8365 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8366 "Setup complete: pp 0x%p td 0x%p", (void *)pp, (void *)td); 8367 8368 break; 8369 case OHCI_CTRL_DATA_PHASE: 8370 /* 8371 * If "CurrentBufferPointer" of Transfer Descriptor (TD) 8372 * is not equal to zero, then we received less data from 8373 * the device than requested by us. In that case, get the 8374 * actual received data size. 8375 */ 8376 if (Get_TD(td->hctd_cbp)) { 8377 size_t length; 8378 8379 length = Get_TD(td->hctd_cbp) - 8380 tw->tw_cookie.dmac_address; 8381 8382 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8383 "ohci_handle_ctrl_qtd: requested data %lu " 8384 "received data %lu", tw->tw_length, length); 8385 8386 /* Save actual received data length */ 8387 tw->tw_length = length; 8388 } 8389 8390 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8391 "Data complete: pp 0x%p td 0x%p", 8392 (void *)pp, (void *)td); 8393 8394 break; 8395 case OHCI_CTRL_STATUS_PHASE: 8396 if ((tw->tw_length != 0) && 8397 (tw->tw_direction == HC_TD_IN)) { 8398 8399 /* 8400 * Call ohci_sendup_td_message 8401 * to send message to upstream. 8402 */ 8403 ohci_sendup_td_message(ohcip, 8404 pp, tw, td, USB_CR_OK); 8405 } else { 8406 ohci_do_byte_stats(ohcip, 8407 tw->tw_length - SETUP_SIZE, 8408 ph->p_ep.bmAttributes, 8409 ph->p_ep.bEndpointAddress); 8410 8411 ohci_hcdi_callback(ph, tw, USB_CR_OK); 8412 } 8413 8414 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8415 "Status complete: pp 0x%p td 0x%p", (void *)pp, (void *)td); 8416 8417 break; 8418 } 8419 } 8420 8421 8422 /* 8423 * ohci_handle_bulk_td: 8424 * 8425 * Handle a bulk Transfer Descriptor (TD). 8426 */ 8427 /* ARGSUSED */ 8428 static void 8429 ohci_handle_bulk_td( 8430 ohci_state_t *ohcip, 8431 ohci_pipe_private_t *pp, 8432 ohci_trans_wrapper_t *tw, 8433 ohci_td_t *td, 8434 void *tw_handle_callback_value) 8435 { 8436 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 8437 usb_ep_descr_t *eptd = &ph->p_ep; 8438 8439 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8440 "ohci_handle_bulk_td:"); 8441 8442 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8443 8444 /* 8445 * Decrement the TDs counter and check whether all the bulk 8446 * data has been send or received. If TDs counter reaches 8447 * zero then inform client driver about completion current 8448 * bulk request. Other wise wait for completion of other bulk 8449 * TDs or transactions on this pipe. 8450 */ 8451 if (--tw->tw_num_tds != 0) { 8452 8453 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8454 "ohci_handle_bulk_td: Number of TDs %d", tw->tw_num_tds); 8455 8456 return; 8457 } 8458 8459 /* 8460 * If this is a bulk in pipe, return the data to the client. 8461 * For a bulk out pipe, there is no need to do anything. 8462 */ 8463 if ((eptd->bEndpointAddress & 8464 USB_EP_DIR_MASK) == USB_EP_DIR_OUT) { 8465 8466 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8467 "ohci_handle_bulk_td: Bulk out pipe"); 8468 8469 ohci_do_byte_stats(ohcip, tw->tw_length, 8470 eptd->bmAttributes, eptd->bEndpointAddress); 8471 8472 /* Do the callback */ 8473 ohci_hcdi_callback(ph, tw, USB_CR_OK); 8474 8475 return; 8476 } 8477 8478 /* Call ohci_sendup_td_message to send message to upstream */ 8479 ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK); 8480 } 8481 8482 8483 /* 8484 * ohci_handle_intr_td: 8485 * 8486 * Handle a interrupt Transfer Descriptor (TD). 8487 */ 8488 /* ARGSUSED */ 8489 static void 8490 ohci_handle_intr_td( 8491 ohci_state_t *ohcip, 8492 ohci_pipe_private_t *pp, 8493 ohci_trans_wrapper_t *tw, 8494 ohci_td_t *td, 8495 void *tw_handle_callback_value) 8496 { 8497 usb_intr_req_t *curr_intr_reqp = 8498 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 8499 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 8500 usb_ep_descr_t *eptd = &ph->p_ep; 8501 usb_req_attrs_t attrs; 8502 int error = USB_SUCCESS; 8503 8504 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8505 "ohci_handle_intr_td: pp=0x%p tw=0x%p td=0x%p" 8506 "intr_reqp=0%p data=0x%p", pp, tw, td, curr_intr_reqp, 8507 curr_intr_reqp->intr_data); 8508 8509 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8510 8511 /* Get the interrupt xfer attributes */ 8512 attrs = curr_intr_reqp->intr_attributes; 8513 8514 /* 8515 * For a Interrupt OUT pipe, we just callback and we are done 8516 */ 8517 if ((eptd->bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_OUT) { 8518 8519 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8520 "ohci_handle_intr_td: Intr out pipe, intr_reqp=0x%p," 8521 "data=0x%p", curr_intr_reqp, curr_intr_reqp->intr_data); 8522 8523 ohci_do_byte_stats(ohcip, tw->tw_length, 8524 eptd->bmAttributes, eptd->bEndpointAddress); 8525 8526 /* Do the callback */ 8527 ohci_hcdi_callback(ph, tw, USB_CR_OK); 8528 8529 return; 8530 } 8531 8532 /* Decrement number of interrupt request count */ 8533 pp->pp_cur_periodic_req_cnt--; 8534 8535 /* 8536 * Check usb flag whether USB_FLAGS_ONE_XFER flag is set 8537 * and if so, free duplicate request. 8538 */ 8539 if (attrs & USB_ATTRS_ONE_XFER) { 8540 ohci_handle_one_xfer_completion(ohcip, tw); 8541 } 8542 8543 /* Call ohci_sendup_td_message to callback into client */ 8544 ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK); 8545 8546 /* 8547 * If interrupt pipe state is still active, insert next Interrupt 8548 * request into the Host Controller's Interrupt list. Otherwise 8549 * you are done. 8550 */ 8551 if (pp->pp_state != OHCI_PIPE_STATE_ACTIVE) { 8552 return; 8553 } 8554 8555 if ((error = ohci_allocate_periodic_in_resource(ohcip, pp, tw, 0)) == 8556 USB_SUCCESS) { 8557 curr_intr_reqp = (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 8558 8559 ASSERT(curr_intr_reqp != NULL); 8560 8561 tw->tw_num_tds = 1; 8562 8563 if (ohci_allocate_tds_for_tw(ohcip, tw, tw->tw_num_tds) != 8564 USB_SUCCESS) { 8565 ohci_deallocate_periodic_in_resource(ohcip, pp, tw); 8566 error = USB_FAILURE; 8567 } 8568 } 8569 8570 if (error != USB_SUCCESS) { 8571 /* 8572 * Set pipe state to stop polling and error to no 8573 * resource. Don't insert any more interrupt polling 8574 * requests. 8575 */ 8576 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING; 8577 pp->pp_error = USB_CR_NO_RESOURCES; 8578 } else { 8579 ohci_insert_intr_req(ohcip, pp, tw, 0); 8580 8581 /* Increment number of interrupt request count */ 8582 pp->pp_cur_periodic_req_cnt++; 8583 8584 ASSERT(pp->pp_cur_periodic_req_cnt == 8585 pp->pp_max_periodic_req_cnt); 8586 } 8587 } 8588 8589 8590 /* 8591 * ohci_handle_one_xfer_completion: 8592 */ 8593 static void 8594 ohci_handle_one_xfer_completion( 8595 ohci_state_t *ohcip, 8596 ohci_trans_wrapper_t *tw) 8597 { 8598 usba_pipe_handle_data_t *ph = tw->tw_pipe_private->pp_pipe_handle; 8599 ohci_pipe_private_t *pp = tw->tw_pipe_private; 8600 usb_intr_req_t *curr_intr_reqp = 8601 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 8602 8603 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8604 "ohci_handle_one_xfer_completion: tw = 0x%p", tw); 8605 8606 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8607 ASSERT(curr_intr_reqp->intr_attributes & USB_ATTRS_ONE_XFER); 8608 8609 pp->pp_state = OHCI_PIPE_STATE_IDLE; 8610 8611 /* 8612 * For one xfer, we need to copy back data ptr 8613 * and free current request 8614 */ 8615 ((usb_intr_req_t *)(pp->pp_client_periodic_in_reqp))-> 8616 intr_data = ((usb_intr_req_t *) 8617 (tw->tw_curr_xfer_reqp))->intr_data; 8618 8619 ((usb_intr_req_t *)tw->tw_curr_xfer_reqp)->intr_data = NULL; 8620 8621 /* Now free duplicate current request */ 8622 usb_free_intr_req((usb_intr_req_t *)tw-> tw_curr_xfer_reqp); 8623 8624 mutex_enter(&ph->p_mutex); 8625 ph->p_req_count--; 8626 mutex_exit(&ph->p_mutex); 8627 8628 /* Make client's request the current request */ 8629 tw->tw_curr_xfer_reqp = pp->pp_client_periodic_in_reqp; 8630 pp->pp_client_periodic_in_reqp = NULL; 8631 } 8632 8633 8634 /* 8635 * ohci_handle_isoc_td: 8636 * 8637 * Handle an isochronous Transfer Descriptor (TD). 8638 */ 8639 /* ARGSUSED */ 8640 static void 8641 ohci_handle_isoc_td( 8642 ohci_state_t *ohcip, 8643 ohci_pipe_private_t *pp, 8644 ohci_trans_wrapper_t *tw, 8645 ohci_td_t *td, 8646 void *tw_handle_callback_value) 8647 { 8648 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 8649 usb_ep_descr_t *eptd = &ph->p_ep; 8650 usb_isoc_req_t *curr_isoc_reqp = 8651 (usb_isoc_req_t *)tw->tw_curr_xfer_reqp; 8652 int error = USB_SUCCESS; 8653 8654 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8655 "ohci_handle_isoc_td: pp=0x%p tw=0x%p td=0x%p" 8656 "isoc_reqp=0%p data=0x%p", pp, tw, td, curr_isoc_reqp, 8657 curr_isoc_reqp->isoc_data); 8658 8659 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8660 8661 /* 8662 * Decrement the TDs counter and check whether all the isoc 8663 * data has been send or received. If TDs counter reaches 8664 * zero then inform client driver about completion current 8665 * isoc request. Otherwise wait for completion of other isoc 8666 * TDs or transactions on this pipe. 8667 */ 8668 if (--tw->tw_num_tds != 0) { 8669 8670 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8671 "ohci_handle_isoc_td: Number of TDs %d", tw->tw_num_tds); 8672 8673 return; 8674 } 8675 8676 /* 8677 * If this is a isoc in pipe, return the data to the client. 8678 * For a isoc out pipe, there is no need to do anything. 8679 */ 8680 if ((eptd->bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_OUT) { 8681 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8682 "ohci_handle_isoc_td: Isoc out pipe, isoc_reqp=0x%p," 8683 "data=0x%p", curr_isoc_reqp, curr_isoc_reqp->isoc_data); 8684 8685 ohci_do_byte_stats(ohcip, tw->tw_length, 8686 eptd->bmAttributes, eptd->bEndpointAddress); 8687 8688 /* Do the callback */ 8689 ohci_hcdi_callback(ph, tw, USB_CR_OK); 8690 8691 return; 8692 } 8693 8694 /* Decrement number of IN isochronous request count */ 8695 pp->pp_cur_periodic_req_cnt--; 8696 8697 /* Call ohci_sendup_td_message to send message to upstream */ 8698 ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK); 8699 8700 /* 8701 * If isochronous pipe state is still active, insert next isochronous 8702 * request into the Host Controller's isochronous list. 8703 */ 8704 if (pp->pp_state != OHCI_PIPE_STATE_ACTIVE) { 8705 return; 8706 } 8707 8708 if ((error = ohci_allocate_periodic_in_resource(ohcip, pp, tw, 0)) == 8709 USB_SUCCESS) { 8710 curr_isoc_reqp = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp; 8711 8712 ASSERT(curr_isoc_reqp != NULL); 8713 8714 tw->tw_num_tds = 8715 curr_isoc_reqp->isoc_pkts_count / OHCI_ISOC_PKTS_PER_TD; 8716 if (curr_isoc_reqp->isoc_pkts_count % OHCI_ISOC_PKTS_PER_TD) { 8717 tw->tw_num_tds++; 8718 } 8719 8720 if (ohci_allocate_tds_for_tw(ohcip, tw, tw->tw_num_tds) != 8721 USB_SUCCESS) { 8722 ohci_deallocate_periodic_in_resource(ohcip, pp, tw); 8723 error = USB_FAILURE; 8724 } 8725 } 8726 8727 if (error != USB_SUCCESS || 8728 ohci_insert_isoc_req(ohcip, pp, tw, 0) != USB_SUCCESS) { 8729 /* 8730 * Set pipe state to stop polling and error to no 8731 * resource. Don't insert any more isoch polling 8732 * requests. 8733 */ 8734 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING; 8735 pp->pp_error = USB_CR_NO_RESOURCES; 8736 8737 } else { 8738 /* Increment number of IN isochronous request count */ 8739 pp->pp_cur_periodic_req_cnt++; 8740 8741 ASSERT(pp->pp_cur_periodic_req_cnt == 8742 pp->pp_max_periodic_req_cnt); 8743 } 8744 } 8745 8746 8747 /* 8748 * ohci_sendup_td_message: 8749 * copy data, if necessary and do callback 8750 */ 8751 static void 8752 ohci_sendup_td_message( 8753 ohci_state_t *ohcip, 8754 ohci_pipe_private_t *pp, 8755 ohci_trans_wrapper_t *tw, 8756 ohci_td_t *td, 8757 usb_cr_t error) 8758 { 8759 usb_ep_descr_t *eptd = &pp->pp_pipe_handle->p_ep; 8760 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 8761 size_t length = 0, skip_len = 0; 8762 mblk_t *mp; 8763 uchar_t *buf; 8764 usb_opaque_t curr_xfer_reqp = tw->tw_curr_xfer_reqp; 8765 8766 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8767 8768 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8769 "ohci_sendup_td_message:"); 8770 8771 ASSERT(tw != NULL); 8772 8773 length = tw->tw_length; 8774 8775 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) { 8776 case USB_EP_ATTR_CONTROL: 8777 /* 8778 * Get the correct length, adjust it for the setup size 8779 * which is not part of the data length in control end 8780 * points. Update tw->tw_length for future references. 8781 */ 8782 tw->tw_length = length = length - SETUP_SIZE; 8783 8784 /* Set the length of the buffer to skip */ 8785 skip_len = SETUP_SIZE; 8786 8787 if (Get_TD(td->hctd_ctrl_phase) != OHCI_CTRL_DATA_PHASE) { 8788 break; 8789 } 8790 /* FALLTHRU */ 8791 case USB_EP_ATTR_BULK: 8792 case USB_EP_ATTR_INTR: 8793 /* 8794 * If error is "data overrun", do not check for the 8795 * "CurrentBufferPointer" and return whatever data 8796 * received to the client driver. 8797 */ 8798 if (error == USB_CR_DATA_OVERRUN) { 8799 break; 8800 } 8801 8802 /* 8803 * If "CurrentBufferPointer" of Transfer Descriptor 8804 * (TD) is not equal to zero, then we received less 8805 * data from the device than requested by us. In that 8806 * case, get the actual received data size. 8807 */ 8808 if (Get_TD(td->hctd_cbp)) { 8809 8810 length = Get_TD(td->hctd_cbp) - 8811 tw->tw_cookie.dmac_address - skip_len; 8812 8813 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8814 "ohci_sendup_qtd_message: requested data %lu " 8815 "received data %lu", tw->tw_length, length); 8816 } 8817 8818 break; 8819 case USB_EP_ATTR_ISOCH: 8820 default: 8821 break; 8822 } 8823 8824 /* Copy the data into the mblk_t */ 8825 buf = (uchar_t *)tw->tw_buf + skip_len; 8826 8827 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8828 "ohci_sendup_qtd_message: length %lu error %d", length, error); 8829 8830 /* Get the message block */ 8831 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) { 8832 case USB_EP_ATTR_CONTROL: 8833 mp = ((usb_ctrl_req_t *)curr_xfer_reqp)->ctrl_data; 8834 break; 8835 case USB_EP_ATTR_BULK: 8836 mp = ((usb_bulk_req_t *)curr_xfer_reqp)->bulk_data; 8837 break; 8838 case USB_EP_ATTR_INTR: 8839 mp = ((usb_intr_req_t *)curr_xfer_reqp)->intr_data; 8840 break; 8841 case USB_EP_ATTR_ISOCH: 8842 mp = ((usb_isoc_req_t *)curr_xfer_reqp)->isoc_data; 8843 break; 8844 } 8845 8846 ASSERT(mp != NULL); 8847 8848 if (length) { 8849 /* 8850 * Update kstat byte counts 8851 * The control endpoints don't have direction bits so in 8852 * order for control stats to be counted correctly an in 8853 * bit must be faked on a control read. 8854 */ 8855 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) == 8856 USB_EP_ATTR_CONTROL) { 8857 ohci_do_byte_stats(ohcip, length, 8858 eptd->bmAttributes, USB_EP_DIR_IN); 8859 } else { 8860 ohci_do_byte_stats(ohcip, length, 8861 eptd->bmAttributes, eptd->bEndpointAddress); 8862 } 8863 8864 /* Sync IO buffer */ 8865 Sync_IO_Buffer(tw->tw_dmahandle, length); 8866 8867 /* Copy the data into the message */ 8868 ddi_rep_get8(tw->tw_accesshandle, 8869 mp->b_rptr, buf, length, DDI_DEV_AUTOINCR); 8870 8871 /* Increment the write pointer */ 8872 mp->b_wptr = mp->b_wptr + length; 8873 } else { 8874 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8875 "ohci_sendup_td_message: Zero length packet"); 8876 } 8877 8878 ohci_hcdi_callback(ph, tw, error); 8879 } 8880 8881 8882 /* 8883 * Miscellaneous functions 8884 */ 8885 8886 /* 8887 * ohci_obtain_state: 8888 * NOTE: This function is also called from POLLED MODE. 8889 */ 8890 ohci_state_t * 8891 ohci_obtain_state(dev_info_t *dip) 8892 { 8893 int instance = ddi_get_instance(dip); 8894 ohci_state_t *state = ddi_get_soft_state( 8895 ohci_statep, instance); 8896 8897 ASSERT(state != NULL); 8898 8899 return (state); 8900 } 8901 8902 8903 /* 8904 * ohci_state_is_operational: 8905 * 8906 * Check the Host controller state and return proper values. 8907 */ 8908 int 8909 ohci_state_is_operational(ohci_state_t *ohcip) 8910 { 8911 int val; 8912 8913 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8914 8915 switch (ohcip->ohci_hc_soft_state) { 8916 case OHCI_CTLR_INIT_STATE: 8917 case OHCI_CTLR_SUSPEND_STATE: 8918 val = USB_FAILURE; 8919 break; 8920 case OHCI_CTLR_OPERATIONAL_STATE: 8921 val = USB_SUCCESS; 8922 break; 8923 case OHCI_CTLR_ERROR_STATE: 8924 val = USB_HC_HARDWARE_ERROR; 8925 break; 8926 default: 8927 val = USB_FAILURE; 8928 break; 8929 } 8930 8931 return (val); 8932 } 8933 8934 8935 /* 8936 * ohci_do_soft_reset 8937 * 8938 * Do soft reset of ohci host controller. 8939 */ 8940 int 8941 ohci_do_soft_reset(ohci_state_t *ohcip) 8942 { 8943 usb_frame_number_t before_frame_number, after_frame_number; 8944 timeout_id_t xfer_timer_id, rh_timer_id; 8945 ohci_regs_t *ohci_save_regs; 8946 ohci_td_t *done_head; 8947 8948 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8949 8950 /* Increment host controller error count */ 8951 ohcip->ohci_hc_error++; 8952 8953 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8954 "ohci_do_soft_reset:" 8955 "Reset ohci host controller 0x%x", ohcip->ohci_hc_error); 8956 8957 /* 8958 * Allocate space for saving current Host Controller 8959 * registers. Don't do any recovery if allocation 8960 * fails. 8961 */ 8962 ohci_save_regs = (ohci_regs_t *) 8963 kmem_zalloc(sizeof (ohci_regs_t), KM_NOSLEEP); 8964 8965 if (ohci_save_regs == NULL) { 8966 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8967 "ohci_do_soft_reset: kmem_zalloc failed"); 8968 8969 return (USB_FAILURE); 8970 } 8971 8972 /* Save current ohci registers */ 8973 ohci_save_regs->hcr_control = Get_OpReg(hcr_control); 8974 ohci_save_regs->hcr_cmd_status = Get_OpReg(hcr_cmd_status); 8975 ohci_save_regs->hcr_intr_enable = Get_OpReg(hcr_intr_enable); 8976 ohci_save_regs->hcr_periodic_strt = Get_OpReg(hcr_periodic_strt); 8977 ohci_save_regs->hcr_frame_interval = Get_OpReg(hcr_frame_interval); 8978 ohci_save_regs->hcr_HCCA = Get_OpReg(hcr_HCCA); 8979 ohci_save_regs->hcr_bulk_head = Get_OpReg(hcr_bulk_head); 8980 ohci_save_regs->hcr_ctrl_head = Get_OpReg(hcr_ctrl_head); 8981 8982 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8983 "ohci_do_soft_reset: Save reg = 0x%p", ohci_save_regs); 8984 8985 /* Disable all list processing and interrupts */ 8986 Set_OpReg(hcr_control, (Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE | 8987 HCR_CONTROL_BLE | HCR_CONTROL_PLE | HCR_CONTROL_IE))); 8988 8989 Set_OpReg(hcr_intr_disable, HCR_INTR_SO | 8990 HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE | 8991 HCR_INTR_FNO | HCR_INTR_SOF | HCR_INTR_MIE); 8992 8993 /* Wait for few milliseconds */ 8994 drv_usecwait(OHCI_TIMEWAIT); 8995 8996 /* Root hub interrupt pipe timeout id */ 8997 rh_timer_id = ohcip->ohci_root_hub.rh_intr_pipe_timer_id; 8998 8999 /* Stop the root hub interrupt timer */ 9000 if (rh_timer_id) { 9001 ohcip->ohci_root_hub.rh_intr_pipe_timer_id = 0; 9002 ohcip->ohci_root_hub.rh_intr_pipe_state = 9003 OHCI_PIPE_STATE_IDLE; 9004 9005 mutex_exit(&ohcip->ohci_int_mutex); 9006 (void) untimeout(rh_timer_id); 9007 mutex_enter(&ohcip->ohci_int_mutex); 9008 } 9009 9010 /* Transfer timeout id */ 9011 xfer_timer_id = ohcip->ohci_timer_id; 9012 9013 /* Stop the global transfer timer */ 9014 if (xfer_timer_id) { 9015 ohcip->ohci_timer_id = 0; 9016 mutex_exit(&ohcip->ohci_int_mutex); 9017 (void) untimeout(xfer_timer_id); 9018 mutex_enter(&ohcip->ohci_int_mutex); 9019 } 9020 9021 /* Process any pending HCCA DoneHead */ 9022 done_head = (ohci_td_t *)(uintptr_t) 9023 (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) & HCCA_DONE_HEAD_MASK); 9024 9025 if (done_head) { 9026 /* Reset the done head to NULL */ 9027 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, NULL); 9028 9029 ohci_traverse_done_list(ohcip, done_head); 9030 } 9031 9032 /* Process any pending hcr_done_head value */ 9033 if (Get_OpReg(hcr_done_head)) { 9034 ohci_traverse_done_list(ohcip, 9035 (ohci_td_t *)(uintptr_t)Get_OpReg(hcr_done_head)); 9036 } 9037 9038 /* Do soft reset of ohci host controller */ 9039 Set_OpReg(hcr_cmd_status, HCR_STATUS_RESET); 9040 9041 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9042 "ohci_do_soft_reset: Reset in progress"); 9043 9044 /* Wait for reset to complete */ 9045 drv_usecwait(OHCI_RESET_TIMEWAIT); 9046 9047 /* Reset HCCA HcFrameNumber */ 9048 Set_HCCA(ohcip->ohci_hccap->HccaFrameNo, 0x00000000); 9049 9050 /* 9051 * Restore previous saved HC register value 9052 * into the current HC registers. 9053 */ 9054 Set_OpReg(hcr_periodic_strt, (uint32_t) 9055 ohci_save_regs->hcr_periodic_strt); 9056 9057 Set_OpReg(hcr_frame_interval, (uint32_t) 9058 ohci_save_regs->hcr_frame_interval); 9059 9060 Set_OpReg(hcr_done_head, 0x0); 9061 9062 Set_OpReg(hcr_bulk_curr, 0x0); 9063 9064 Set_OpReg(hcr_bulk_head, (uint32_t) 9065 ohci_save_regs->hcr_bulk_head); 9066 9067 Set_OpReg(hcr_ctrl_curr, 0x0); 9068 9069 Set_OpReg(hcr_ctrl_head, (uint32_t) 9070 ohci_save_regs->hcr_ctrl_head); 9071 9072 Set_OpReg(hcr_periodic_curr, 0x0); 9073 9074 Set_OpReg(hcr_HCCA, (uint32_t) 9075 ohci_save_regs->hcr_HCCA); 9076 9077 Set_OpReg(hcr_intr_status, 0x0); 9078 9079 /* 9080 * Set HcInterruptEnable to enable all interrupts except 9081 * Root Hub Status change interrupt. 9082 */ 9083 Set_OpReg(hcr_intr_enable, 9084 HCR_INTR_SO | HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE | 9085 HCR_INTR_FNO | HCR_INTR_SOF | HCR_INTR_MIE); 9086 9087 /* Start Control and Bulk list processing */ 9088 Set_OpReg(hcr_cmd_status, (HCR_STATUS_CLF | HCR_STATUS_BLF)); 9089 9090 /* 9091 * Start up Control, Bulk, Periodic and Isochronous lists 9092 * processing. 9093 */ 9094 Set_OpReg(hcr_control, (uint32_t) 9095 (ohci_save_regs->hcr_control & (~HCR_CONTROL_HCFS))); 9096 9097 /* 9098 * Deallocate the space that allocated for saving 9099 * HC registers. 9100 */ 9101 kmem_free((void *) ohci_save_regs, sizeof (ohci_regs_t)); 9102 9103 /* Resume the host controller */ 9104 Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) & 9105 (~HCR_CONTROL_HCFS)) | HCR_CONTROL_RESUME)); 9106 9107 /* Wait for resume to complete */ 9108 drv_usecwait(OHCI_RESUME_TIMEWAIT); 9109 9110 /* Set the Host Controller Functional State to Operational */ 9111 Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) & 9112 (~HCR_CONTROL_HCFS)) | HCR_CONTROL_OPERAT)); 9113 9114 /* Wait 10ms for HC to start sending SOF */ 9115 drv_usecwait(OHCI_TIMEWAIT); 9116 9117 /* 9118 * Get the current usb frame number before waiting for few 9119 * milliseconds. 9120 */ 9121 before_frame_number = ohci_get_current_frame_number(ohcip); 9122 9123 /* Wait for few milliseconds */ 9124 drv_usecwait(OHCI_TIMEWAIT); 9125 9126 /* 9127 * Get the current usb frame number after waiting for few 9128 * milliseconds. 9129 */ 9130 after_frame_number = ohci_get_current_frame_number(ohcip); 9131 9132 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9133 "ohci_do_soft_reset: Before Frm No 0x%llx After Frm No 0x%llx", 9134 before_frame_number, after_frame_number); 9135 9136 if (after_frame_number <= before_frame_number) { 9137 9138 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9139 "ohci_do_soft_reset: Soft reset failed"); 9140 9141 return (USB_FAILURE); 9142 } 9143 9144 /* Start the timer for the root hub interrupt pipe polling */ 9145 if (rh_timer_id) { 9146 ohcip->ohci_root_hub.rh_intr_pipe_timer_id = 9147 timeout(ohci_handle_root_hub_status_change, 9148 (void *)ohcip, drv_usectohz(OHCI_RH_POLL_TIME)); 9149 9150 ohcip->ohci_root_hub. 9151 rh_intr_pipe_state = OHCI_PIPE_STATE_ACTIVE; 9152 } 9153 9154 /* Start the global timer */ 9155 if (xfer_timer_id) { 9156 ohcip->ohci_timer_id = timeout(ohci_xfer_timeout_handler, 9157 (void *)ohcip, drv_usectohz(1000000)); 9158 } 9159 9160 return (USB_SUCCESS); 9161 } 9162 9163 9164 /* 9165 * ohci_get_current_frame_number: 9166 * 9167 * Get the current software based usb frame number. 9168 */ 9169 usb_frame_number_t 9170 ohci_get_current_frame_number(ohci_state_t *ohcip) 9171 { 9172 usb_frame_number_t usb_frame_number; 9173 usb_frame_number_t ohci_fno, frame_number; 9174 ohci_save_intr_sts_t *ohci_intr_sts = 9175 &ohcip->ohci_save_intr_sts; 9176 9177 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9178 9179 /* 9180 * Sync HCCA area only if this function 9181 * is invoked in non interrupt context. 9182 */ 9183 if (!(ohci_intr_sts->ohci_intr_flag & 9184 OHCI_INTR_HANDLING)) { 9185 9186 /* Sync HCCA area */ 9187 Sync_HCCA(ohcip); 9188 } 9189 9190 ohci_fno = ohcip->ohci_fno; 9191 frame_number = Get_HCCA(ohcip->ohci_hccap->HccaFrameNo); 9192 9193 /* 9194 * Calculate current software based usb frame number. 9195 * 9196 * This code accounts for the fact that frame number is 9197 * updated by the Host Controller before the ohci driver 9198 * gets an FrameNumberOverflow (FNO) interrupt that will 9199 * adjust Frame higher part. 9200 * 9201 * Refer ohci specification 1.0a, section 5.4, page 86. 9202 */ 9203 usb_frame_number = ((frame_number & 0x7FFF) | ohci_fno) + 9204 (((frame_number & 0xFFFF) ^ ohci_fno) & 0x8000); 9205 9206 return (usb_frame_number); 9207 } 9208 9209 9210 /* 9211 * ohci_cpr_cleanup: 9212 * 9213 * Cleanup ohci state and other ohci specific informations across 9214 * Check Point Resume (CPR). 9215 */ 9216 static void 9217 ohci_cpr_cleanup(ohci_state_t *ohcip) 9218 { 9219 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9220 9221 /* Reset software part of usb frame number */ 9222 ohcip->ohci_fno = 0; 9223 9224 /* Reset Schedule Overrrun Error Counter */ 9225 ohcip->ohci_so_error = 0; 9226 9227 /* Reset HCCA HcFrameNumber */ 9228 Set_HCCA(ohcip->ohci_hccap->HccaFrameNo, 0x00000000); 9229 } 9230 9231 9232 /* 9233 * ohci_get_xfer_attrs: 9234 * 9235 * Get the attributes of a particular xfer. 9236 */ 9237 static usb_req_attrs_t 9238 ohci_get_xfer_attrs( 9239 ohci_state_t *ohcip, 9240 ohci_pipe_private_t *pp, 9241 ohci_trans_wrapper_t *tw) 9242 { 9243 usb_ep_descr_t *eptd = &pp->pp_pipe_handle->p_ep; 9244 usb_req_attrs_t attrs = 0; 9245 9246 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9247 "ohci_get_xfer_attrs:"); 9248 9249 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9250 9251 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) { 9252 case USB_EP_ATTR_CONTROL: 9253 attrs = ((usb_ctrl_req_t *) 9254 tw->tw_curr_xfer_reqp)->ctrl_attributes; 9255 break; 9256 case USB_EP_ATTR_BULK: 9257 attrs = ((usb_bulk_req_t *) 9258 tw->tw_curr_xfer_reqp)->bulk_attributes; 9259 break; 9260 case USB_EP_ATTR_INTR: 9261 attrs = ((usb_intr_req_t *) 9262 tw->tw_curr_xfer_reqp)->intr_attributes; 9263 break; 9264 case USB_EP_ATTR_ISOCH: 9265 attrs = ((usb_isoc_req_t *) 9266 tw->tw_curr_xfer_reqp)->isoc_attributes; 9267 break; 9268 } 9269 9270 return (attrs); 9271 } 9272 9273 9274 /* 9275 * ohci_allocate_periodic_in_resource 9276 * 9277 * Allocate interrupt/isochronous request structure for the 9278 * interrupt/isochronous IN transfer. 9279 */ 9280 static int 9281 ohci_allocate_periodic_in_resource( 9282 ohci_state_t *ohcip, 9283 ohci_pipe_private_t *pp, 9284 ohci_trans_wrapper_t *tw, 9285 usb_flags_t flags) 9286 { 9287 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 9288 uchar_t ep_attr = ph->p_ep.bmAttributes; 9289 usb_intr_req_t *curr_intr_reqp; 9290 usb_isoc_req_t *curr_isoc_reqp; 9291 usb_opaque_t client_periodic_in_reqp; 9292 size_t length = 0; 9293 9294 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9295 "ohci_allocate_periodic_in_resource:" 9296 "pp = 0x%p tw = 0x%p flags = 0x%x", pp, tw, flags); 9297 9298 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9299 ASSERT(tw->tw_curr_xfer_reqp == NULL); 9300 9301 /* Get the client periodic in request pointer */ 9302 client_periodic_in_reqp = pp->pp_client_periodic_in_reqp; 9303 9304 /* 9305 * If it a periodic IN request and periodic request is NULL, 9306 * allocate corresponding usb periodic IN request for the 9307 * current periodic polling request and copy the information 9308 * from the saved periodic request structure. 9309 */ 9310 if ((ep_attr & USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) { 9311 9312 if (client_periodic_in_reqp) { 9313 9314 /* Get the interrupt transfer length */ 9315 length = ((usb_intr_req_t *) 9316 client_periodic_in_reqp)->intr_len; 9317 9318 curr_intr_reqp = usba_hcdi_dup_intr_req( 9319 ph->p_dip, (usb_intr_req_t *) 9320 client_periodic_in_reqp, length, flags); 9321 } else { 9322 curr_intr_reqp = usb_alloc_intr_req( 9323 ph->p_dip, length, flags); 9324 } 9325 9326 if (curr_intr_reqp == NULL) { 9327 9328 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9329 "ohci_allocate_periodic_in_resource: Interrupt " 9330 "request structure allocation failed"); 9331 9332 return (USB_NO_RESOURCES); 9333 } 9334 9335 if (client_periodic_in_reqp == NULL) { 9336 /* For polled mode */ 9337 curr_intr_reqp-> 9338 intr_attributes = USB_ATTRS_SHORT_XFER_OK; 9339 curr_intr_reqp-> 9340 intr_len = ph->p_ep.wMaxPacketSize; 9341 } else { 9342 /* Check and save the timeout value */ 9343 tw->tw_timeout = (curr_intr_reqp->intr_attributes & 9344 USB_ATTRS_ONE_XFER) ? 9345 curr_intr_reqp->intr_timeout: 0; 9346 } 9347 9348 tw->tw_curr_xfer_reqp = (usb_opaque_t)curr_intr_reqp; 9349 tw->tw_length = curr_intr_reqp->intr_len; 9350 } else { 9351 ASSERT(client_periodic_in_reqp != NULL); 9352 9353 curr_isoc_reqp = usba_hcdi_dup_isoc_req(ph->p_dip, 9354 (usb_isoc_req_t *)client_periodic_in_reqp, flags); 9355 9356 if (curr_isoc_reqp == NULL) { 9357 9358 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9359 "ohci_allocate_periodic_in_resource: Isochronous" 9360 "request structure allocation failed"); 9361 9362 return (USB_NO_RESOURCES); 9363 } 9364 9365 /* 9366 * Save the client's isochronous request pointer and 9367 * length of isochronous transfer in transfer wrapper. 9368 * The dup'ed request is saved in pp_client_periodic_in_reqp 9369 */ 9370 tw->tw_curr_xfer_reqp = 9371 (usb_opaque_t)pp->pp_client_periodic_in_reqp; 9372 pp->pp_client_periodic_in_reqp = (usb_opaque_t)curr_isoc_reqp; 9373 tw->tw_length = curr_isoc_reqp->isoc_pkts_length; 9374 } 9375 9376 mutex_enter(&ph->p_mutex); 9377 ph->p_req_count++; 9378 mutex_exit(&ph->p_mutex); 9379 9380 pp->pp_state = OHCI_PIPE_STATE_ACTIVE; 9381 9382 return (USB_SUCCESS); 9383 } 9384 9385 9386 /* 9387 * ohci_wait_for_sof: 9388 * 9389 * Wait for couple of SOF interrupts 9390 */ 9391 static int 9392 ohci_wait_for_sof(ohci_state_t *ohcip) 9393 { 9394 usb_frame_number_t before_frame_number, after_frame_number; 9395 clock_t sof_time_wait; 9396 int rval, sof_wait_count; 9397 9398 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9399 "ohci_wait_for_sof"); 9400 9401 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9402 9403 rval = ohci_state_is_operational(ohcip); 9404 9405 if (rval != USB_SUCCESS) { 9406 9407 return (rval); 9408 } 9409 9410 /* Get the number of clock ticks to wait */ 9411 sof_time_wait = drv_usectohz(OHCI_MAX_SOF_TIMEWAIT * 1000000); 9412 9413 sof_wait_count = 0; 9414 9415 /* 9416 * Get the current usb frame number before waiting for the 9417 * SOF interrupt event. 9418 */ 9419 before_frame_number = ohci_get_current_frame_number(ohcip); 9420 9421 while (sof_wait_count < MAX_SOF_WAIT_COUNT) { 9422 /* Enable the SOF interrupt */ 9423 Set_OpReg(hcr_intr_enable, HCR_INTR_SOF); 9424 9425 ASSERT(Get_OpReg(hcr_intr_enable) & HCR_INTR_SOF); 9426 9427 /* Wait for the SOF or timeout event */ 9428 rval = cv_timedwait(&ohcip->ohci_SOF_cv, 9429 &ohcip->ohci_int_mutex, ddi_get_lbolt() + sof_time_wait); 9430 9431 /* 9432 * Get the current usb frame number after woken up either 9433 * from SOF interrupt or timer expired event. 9434 */ 9435 after_frame_number = ohci_get_current_frame_number(ohcip); 9436 9437 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9438 "ohci_wait_for_sof: before 0x%llx, after 0x%llx", 9439 before_frame_number, after_frame_number); 9440 9441 /* 9442 * Return failure, if we are woken up becuase of timer expired 9443 * event and if usb frame number has not been changed. 9444 */ 9445 if ((rval == -1) && 9446 (after_frame_number <= before_frame_number)) { 9447 9448 if ((ohci_do_soft_reset(ohcip)) != USB_SUCCESS) { 9449 9450 USB_DPRINTF_L0(PRINT_MASK_LISTS, 9451 ohcip->ohci_log_hdl, "No SOF interrupts"); 9452 9453 /* Set host controller soft state to error */ 9454 ohcip->ohci_hc_soft_state = 9455 OHCI_CTLR_ERROR_STATE; 9456 9457 return (USB_FAILURE); 9458 } 9459 9460 /* Get new usb frame number */ 9461 after_frame_number = before_frame_number = 9462 ohci_get_current_frame_number(ohcip); 9463 } 9464 9465 ASSERT(after_frame_number >= before_frame_number); 9466 9467 before_frame_number = after_frame_number; 9468 sof_wait_count++; 9469 } 9470 9471 return (USB_SUCCESS); 9472 } 9473 9474 9475 /* 9476 * ohci_pipe_cleanup 9477 * 9478 * Cleanup ohci pipe. 9479 */ 9480 static void 9481 ohci_pipe_cleanup( 9482 ohci_state_t *ohcip, 9483 usba_pipe_handle_data_t *ph) 9484 { 9485 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 9486 usb_ep_descr_t *eptd = &ph->p_ep; 9487 usb_cr_t completion_reason; 9488 uint_t pipe_state = pp->pp_state; 9489 uint_t bit = 0; 9490 9491 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9492 "ohci_pipe_cleanup: ph = 0x%p", ph); 9493 9494 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9495 9496 switch (pipe_state) { 9497 case OHCI_PIPE_STATE_CLOSE: 9498 if (OHCI_NON_PERIODIC_ENDPOINT(eptd)) { 9499 9500 bit = ((eptd->bmAttributes & 9501 USB_EP_ATTR_MASK) == USB_EP_ATTR_CONTROL) ? 9502 HCR_CONTROL_CLE: HCR_CONTROL_BLE; 9503 9504 Set_OpReg(hcr_control, 9505 (Get_OpReg(hcr_control) & ~(bit))); 9506 9507 /* Wait for the next SOF */ 9508 (void) ohci_wait_for_sof(ohcip); 9509 9510 break; 9511 } 9512 /* FALLTHROUGH */ 9513 case OHCI_PIPE_STATE_RESET: 9514 case OHCI_PIPE_STATE_STOP_POLLING: 9515 /* 9516 * Set the sKip bit to stop all transactions on 9517 * this pipe 9518 */ 9519 ohci_modify_sKip_bit(ohcip, pp, SET_sKip, 9520 OHCI_FLAGS_SLEEP | OHCI_FLAGS_DMA_SYNC); 9521 9522 break; 9523 default: 9524 return; 9525 } 9526 9527 /* 9528 * Wait for processing all completed transfers and 9529 * to send results to upstream. 9530 */ 9531 ohci_wait_for_transfers_completion(ohcip, pp); 9532 9533 /* Save the data toggle information */ 9534 ohci_save_data_toggle(ohcip, ph); 9535 9536 /* 9537 * Traverse the list of TD's on this endpoint and 9538 * these TD's have outstanding transfer requests. 9539 * Since the list processing is stopped, these tds 9540 * can be deallocated. 9541 */ 9542 ohci_traverse_tds(ohcip, ph); 9543 9544 /* 9545 * If all of the endpoint's TD's have been deallocated, 9546 * then the DMA mappings can be torn down. If not there 9547 * are some TD's on the done list that have not been 9548 * processed. Tag these TD's so that they are thrown 9549 * away when the done list is processed. 9550 */ 9551 ohci_done_list_tds(ohcip, ph); 9552 9553 /* Do callbacks for all unfinished requests */ 9554 ohci_handle_outstanding_requests(ohcip, pp); 9555 9556 /* Free DMA resources */ 9557 ohci_free_dma_resources(ohcip, ph); 9558 9559 switch (pipe_state) { 9560 case OHCI_PIPE_STATE_CLOSE: 9561 completion_reason = USB_CR_PIPE_CLOSING; 9562 break; 9563 case OHCI_PIPE_STATE_RESET: 9564 case OHCI_PIPE_STATE_STOP_POLLING: 9565 /* Set completion reason */ 9566 completion_reason = (pipe_state == 9567 OHCI_PIPE_STATE_RESET) ? 9568 USB_CR_PIPE_RESET: USB_CR_STOPPED_POLLING; 9569 9570 /* Restore the data toggle information */ 9571 ohci_restore_data_toggle(ohcip, ph); 9572 9573 /* 9574 * Clear the sKip bit to restart all the 9575 * transactions on this pipe. 9576 */ 9577 ohci_modify_sKip_bit(ohcip, pp, 9578 CLEAR_sKip, OHCI_FLAGS_NOSLEEP); 9579 9580 /* Set pipe state to idle */ 9581 pp->pp_state = OHCI_PIPE_STATE_IDLE; 9582 9583 break; 9584 } 9585 9586 ASSERT((Get_ED(pp->pp_ept->hced_tailp) & HC_EPT_TD_TAIL) == 9587 (Get_ED(pp->pp_ept->hced_headp) & HC_EPT_TD_HEAD)); 9588 9589 ASSERT((pp->pp_tw_head == NULL) && (pp->pp_tw_tail == NULL)); 9590 9591 /* 9592 * Do the callback for the original client 9593 * periodic IN request. 9594 */ 9595 if ((OHCI_PERIODIC_ENDPOINT(eptd)) && 9596 ((ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK) == 9597 USB_EP_DIR_IN)) { 9598 9599 ohci_do_client_periodic_in_req_callback( 9600 ohcip, pp, completion_reason); 9601 } 9602 } 9603 9604 9605 /* 9606 * ohci_wait_for_transfers_completion: 9607 * 9608 * Wait for processing all completed transfers and to send results 9609 * to upstream. 9610 */ 9611 static void 9612 ohci_wait_for_transfers_completion( 9613 ohci_state_t *ohcip, 9614 ohci_pipe_private_t *pp) 9615 { 9616 ohci_trans_wrapper_t *head_tw = pp->pp_tw_head; 9617 ohci_trans_wrapper_t *next_tw; 9618 clock_t xfer_cmpl_time_wait; 9619 ohci_td_t *tailp, *headp, *nextp; 9620 ohci_td_t *head_td, *next_td; 9621 ohci_ed_t *ept = pp->pp_ept; 9622 int rval; 9623 9624 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9625 "ohci_wait_for_transfers_completion: pp = 0x%p", pp); 9626 9627 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9628 9629 headp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, 9630 Get_ED(ept->hced_headp) & (uint32_t)HC_EPT_TD_HEAD)); 9631 9632 tailp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, 9633 Get_ED(ept->hced_tailp) & (uint32_t)HC_EPT_TD_TAIL)); 9634 9635 rval = ohci_state_is_operational(ohcip); 9636 9637 if (rval != USB_SUCCESS) { 9638 9639 return; 9640 } 9641 9642 pp->pp_count_done_tds = 0; 9643 9644 /* Process the transfer wrappers for this pipe */ 9645 next_tw = head_tw; 9646 while (next_tw) { 9647 head_td = (ohci_td_t *)next_tw->tw_hctd_head; 9648 next_td = head_td; 9649 9650 if (head_td) { 9651 /* 9652 * Walk through each TD for this transfer 9653 * wrapper. If a TD still exists, then it 9654 * is currently on the done list. 9655 */ 9656 while (next_td) { 9657 9658 nextp = headp; 9659 9660 while (nextp != tailp) { 9661 9662 /* TD is on the ED */ 9663 if (nextp == next_td) { 9664 break; 9665 } 9666 9667 nextp = (ohci_td_t *) 9668 (ohci_td_iommu_to_cpu(ohcip, 9669 (Get_TD(nextp->hctd_next_td) & 9670 HC_EPT_TD_TAIL))); 9671 } 9672 9673 if (nextp == tailp) { 9674 pp->pp_count_done_tds++; 9675 } 9676 9677 next_td = ohci_td_iommu_to_cpu(ohcip, 9678 Get_TD(next_td->hctd_tw_next_td)); 9679 } 9680 } 9681 9682 next_tw = next_tw->tw_next; 9683 } 9684 9685 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9686 "ohci_wait_for_transfers_completion: count_done_tds = 0x%x", 9687 pp->pp_count_done_tds); 9688 9689 if (!pp->pp_count_done_tds) { 9690 9691 return; 9692 } 9693 9694 /* Get the number of clock ticks to wait */ 9695 xfer_cmpl_time_wait = drv_usectohz(OHCI_XFER_CMPL_TIMEWAIT * 1000000); 9696 9697 (void) cv_timedwait(&pp->pp_xfer_cmpl_cv, 9698 &ohcip->ohci_int_mutex, 9699 ddi_get_lbolt() + xfer_cmpl_time_wait); 9700 9701 if (pp->pp_count_done_tds) { 9702 9703 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9704 "ohci_wait_for_transfers_completion: No transfers " 9705 "completion confirmation received for 0x%x requests", 9706 pp->pp_count_done_tds); 9707 } 9708 } 9709 9710 9711 /* 9712 * ohci_check_for_transfers_completion: 9713 * 9714 * Check whether anybody is waiting for transfers completion event. If so, send 9715 * this event and also stop initiating any new transfers on this pipe. 9716 */ 9717 static void 9718 ohci_check_for_transfers_completion( 9719 ohci_state_t *ohcip, 9720 ohci_pipe_private_t *pp) 9721 { 9722 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9723 "ohci_check_for_transfers_completion: pp = 0x%p", pp); 9724 9725 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9726 9727 if ((pp->pp_state == OHCI_PIPE_STATE_STOP_POLLING) && 9728 (pp->pp_error == USB_CR_NO_RESOURCES) && 9729 (pp->pp_cur_periodic_req_cnt == 0)) { 9730 9731 /* Reset pipe error to zero */ 9732 pp->pp_error = 0; 9733 9734 /* Do callback for original request */ 9735 ohci_do_client_periodic_in_req_callback( 9736 ohcip, pp, USB_CR_NO_RESOURCES); 9737 } 9738 9739 if (pp->pp_count_done_tds) { 9740 9741 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9742 "ohci_check_for_transfers_completion:" 9743 "count_done_tds = 0x%x", pp->pp_count_done_tds); 9744 9745 /* Decrement the done td count */ 9746 pp->pp_count_done_tds--; 9747 9748 if (!pp->pp_count_done_tds) { 9749 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9750 "ohci_check_for_transfers_completion:" 9751 "Sent transfers completion event pp = 0x%p", pp); 9752 9753 /* Send the transfer completion signal */ 9754 cv_signal(&pp->pp_xfer_cmpl_cv); 9755 } 9756 } 9757 } 9758 9759 9760 /* 9761 * ohci_save_data_toggle: 9762 * 9763 * Save the data toggle information. 9764 */ 9765 static void 9766 ohci_save_data_toggle( 9767 ohci_state_t *ohcip, 9768 usba_pipe_handle_data_t *ph) 9769 { 9770 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 9771 usb_ep_descr_t *eptd = &ph->p_ep; 9772 uint_t data_toggle; 9773 usb_cr_t error = pp->pp_error; 9774 ohci_ed_t *ed = pp->pp_ept; 9775 ohci_td_t *headp, *tailp; 9776 9777 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9778 "ohci_save_data_toggle: ph = 0x%p", ph); 9779 9780 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9781 9782 /* Reset the pipe error value */ 9783 pp->pp_error = USB_CR_OK; 9784 9785 /* Return immediately if it is a control or isoc pipe */ 9786 if (((eptd->bmAttributes & USB_EP_ATTR_MASK) == 9787 USB_EP_ATTR_CONTROL) || ((eptd->bmAttributes & 9788 USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH)) { 9789 9790 return; 9791 } 9792 9793 headp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, 9794 Get_ED(ed->hced_headp) & (uint32_t)HC_EPT_TD_HEAD)); 9795 9796 tailp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, 9797 Get_ED(ed->hced_tailp) & (uint32_t)HC_EPT_TD_TAIL)); 9798 9799 /* 9800 * Retrieve the data toggle information either from the endpoint 9801 * (ED) or from the transfer descriptor (TD) depending on the 9802 * situation. 9803 */ 9804 if ((Get_ED(ed->hced_headp) & HC_EPT_Halt) || (headp == tailp)) { 9805 9806 /* Get the data toggle information from the endpoint */ 9807 data_toggle = (Get_ED(ed->hced_headp) & 9808 HC_EPT_Carry)? DATA1:DATA0; 9809 } else { 9810 /* 9811 * Retrieve the data toggle information depending on the 9812 * master data toggle information saved in the transfer 9813 * descriptor (TD) at the head of the endpoint (ED). 9814 * 9815 * Check for master data toggle information . 9816 */ 9817 if (Get_TD(headp->hctd_ctrl) & HC_TD_MS_DT) { 9818 /* Get the data toggle information from td */ 9819 data_toggle = (Get_TD(headp->hctd_ctrl) & 9820 HC_TD_DT_1) ? DATA1:DATA0; 9821 } else { 9822 /* Get the data toggle information from the endpoint */ 9823 data_toggle = (Get_ED(ed->hced_headp) & 9824 HC_EPT_Carry)? DATA1:DATA0; 9825 } 9826 } 9827 9828 /* 9829 * If error is STALL, then, set 9830 * data toggle to zero. 9831 */ 9832 if (error == USB_CR_STALL) { 9833 data_toggle = DATA0; 9834 } 9835 9836 /* 9837 * Save the data toggle information 9838 * in the usb device structure. 9839 */ 9840 mutex_enter(&ph->p_mutex); 9841 usba_hcdi_set_data_toggle(ph->p_usba_device, ph->p_ep.bEndpointAddress, 9842 data_toggle); 9843 mutex_exit(&ph->p_mutex); 9844 } 9845 9846 9847 /* 9848 * ohci_restore_data_toggle: 9849 * 9850 * Restore the data toggle information. 9851 */ 9852 static void 9853 ohci_restore_data_toggle( 9854 ohci_state_t *ohcip, 9855 usba_pipe_handle_data_t *ph) 9856 { 9857 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 9858 usb_ep_descr_t *eptd = &ph->p_ep; 9859 uint_t data_toggle = 0; 9860 9861 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9862 "ohci_restore_data_toggle: ph = 0x%p", ph); 9863 9864 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9865 9866 /* 9867 * Return immediately if it is a control or isoc pipe. 9868 */ 9869 if (((eptd->bmAttributes & USB_EP_ATTR_MASK) == 9870 USB_EP_ATTR_CONTROL) || ((eptd->bmAttributes & 9871 USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH)) { 9872 9873 return; 9874 } 9875 9876 mutex_enter(&ph->p_mutex); 9877 9878 data_toggle = usba_hcdi_get_data_toggle(ph->p_usba_device, 9879 ph->p_ep.bEndpointAddress); 9880 usba_hcdi_set_data_toggle(ph->p_usba_device, ph->p_ep.bEndpointAddress, 9881 0); 9882 9883 mutex_exit(&ph->p_mutex); 9884 9885 /* 9886 * Restore the data toggle bit depending on the 9887 * previous data toggle information. 9888 */ 9889 if (data_toggle) { 9890 Set_ED(pp->pp_ept->hced_headp, 9891 Get_ED(pp->pp_ept->hced_headp) | HC_EPT_Carry); 9892 } else { 9893 Set_ED(pp->pp_ept->hced_headp, 9894 Get_ED(pp->pp_ept->hced_headp) & (~HC_EPT_Carry)); 9895 } 9896 } 9897 9898 9899 /* 9900 * ohci_handle_outstanding_requests 9901 * NOTE: This function is also called from POLLED MODE. 9902 * 9903 * Deallocate interrupt/isochronous request structure for the 9904 * interrupt/isochronous IN transfer. Do the callbacks for all 9905 * unfinished requests. 9906 */ 9907 void 9908 ohci_handle_outstanding_requests( 9909 ohci_state_t *ohcip, 9910 ohci_pipe_private_t *pp) 9911 { 9912 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 9913 usb_ep_descr_t *eptd = &ph->p_ep; 9914 ohci_trans_wrapper_t *curr_tw; 9915 ohci_trans_wrapper_t *next_tw; 9916 usb_opaque_t curr_xfer_reqp; 9917 9918 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9919 "ohci_handle_outstanding_requests: pp = 0x%p", pp); 9920 9921 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9922 9923 /* 9924 * Deallocate all the pre-allocated interrupt requests 9925 */ 9926 next_tw = pp->pp_tw_head; 9927 9928 while (next_tw) { 9929 curr_tw = next_tw; 9930 next_tw = curr_tw->tw_next; 9931 9932 curr_xfer_reqp = curr_tw->tw_curr_xfer_reqp; 9933 9934 /* Deallocate current interrupt request */ 9935 if (curr_xfer_reqp) { 9936 9937 if ((OHCI_PERIODIC_ENDPOINT(eptd)) && 9938 (curr_tw->tw_direction == HC_TD_IN)) { 9939 9940 /* Decrement periodic in request count */ 9941 pp->pp_cur_periodic_req_cnt--; 9942 9943 ohci_deallocate_periodic_in_resource( 9944 ohcip, pp, curr_tw); 9945 } else { 9946 ohci_hcdi_callback(ph, 9947 curr_tw, USB_CR_FLUSHED); 9948 } 9949 } 9950 } 9951 } 9952 9953 9954 /* 9955 * ohci_deallocate_periodic_in_resource 9956 * 9957 * Deallocate interrupt/isochronous request structure for the 9958 * interrupt/isochronous IN transfer. 9959 */ 9960 static void 9961 ohci_deallocate_periodic_in_resource( 9962 ohci_state_t *ohcip, 9963 ohci_pipe_private_t *pp, 9964 ohci_trans_wrapper_t *tw) 9965 { 9966 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 9967 uchar_t ep_attr = ph->p_ep.bmAttributes; 9968 usb_opaque_t curr_xfer_reqp; 9969 9970 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9971 "ohci_deallocate_periodic_in_resource: " 9972 "pp = 0x%p tw = 0x%p", pp, tw); 9973 9974 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9975 9976 curr_xfer_reqp = tw->tw_curr_xfer_reqp; 9977 9978 /* Check the current periodic in request pointer */ 9979 if (curr_xfer_reqp) { 9980 /* 9981 * Reset periodic in request usb isoch 9982 * packet request pointers to null. 9983 */ 9984 tw->tw_curr_xfer_reqp = NULL; 9985 tw->tw_curr_isoc_pktp = NULL; 9986 9987 mutex_enter(&ph->p_mutex); 9988 ph->p_req_count--; 9989 mutex_exit(&ph->p_mutex); 9990 9991 /* 9992 * Free pre-allocated interrupt 9993 * or isochronous requests. 9994 */ 9995 switch (ep_attr & USB_EP_ATTR_MASK) { 9996 case USB_EP_ATTR_INTR: 9997 usb_free_intr_req( 9998 (usb_intr_req_t *)curr_xfer_reqp); 9999 break; 10000 case USB_EP_ATTR_ISOCH: 10001 usb_free_isoc_req( 10002 (usb_isoc_req_t *)curr_xfer_reqp); 10003 break; 10004 } 10005 } 10006 } 10007 10008 10009 /* 10010 * ohci_do_client_periodic_in_req_callback 10011 * 10012 * Do callback for the original client periodic IN request. 10013 */ 10014 static void 10015 ohci_do_client_periodic_in_req_callback( 10016 ohci_state_t *ohcip, 10017 ohci_pipe_private_t *pp, 10018 usb_cr_t completion_reason) 10019 { 10020 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 10021 10022 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10023 "ohci_do_client_periodic_in_req_callback: " 10024 "pp = 0x%p cc = 0x%x", pp, completion_reason); 10025 10026 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10027 10028 /* 10029 * Check for Interrupt/Isochronous IN, whether we need to do 10030 * callback for the original client's periodic IN request. 10031 */ 10032 if (pp->pp_client_periodic_in_reqp) { 10033 ASSERT(pp->pp_cur_periodic_req_cnt == 0); 10034 ohci_hcdi_callback(ph, NULL, completion_reason); 10035 } 10036 } 10037 10038 10039 /* 10040 * ohci_hcdi_callback() 10041 * 10042 * Convenience wrapper around usba_hcdi_cb() other than root hub. 10043 */ 10044 static void 10045 ohci_hcdi_callback( 10046 usba_pipe_handle_data_t *ph, 10047 ohci_trans_wrapper_t *tw, 10048 usb_cr_t completion_reason) 10049 { 10050 ohci_state_t *ohcip = ohci_obtain_state( 10051 ph->p_usba_device->usb_root_hub_dip); 10052 uchar_t attributes = ph->p_ep.bmAttributes & 10053 USB_EP_ATTR_MASK; 10054 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 10055 usb_opaque_t curr_xfer_reqp; 10056 uint_t pipe_state = 0; 10057 10058 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10059 "ohci_hcdi_callback: ph = 0x%p, tw = 0x%p, cr = 0x%x", 10060 ph, tw, completion_reason); 10061 10062 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10063 10064 /* Set the pipe state as per completion reason */ 10065 switch (completion_reason) { 10066 case USB_CR_OK: 10067 pipe_state = pp->pp_state; 10068 break; 10069 case USB_CR_NO_RESOURCES: 10070 case USB_CR_NOT_SUPPORTED: 10071 case USB_CR_STOPPED_POLLING: 10072 case USB_CR_PIPE_RESET: 10073 pipe_state = OHCI_PIPE_STATE_IDLE; 10074 break; 10075 case USB_CR_PIPE_CLOSING: 10076 break; 10077 default: 10078 /* 10079 * Set the pipe state to error 10080 * except for the isoc pipe. 10081 */ 10082 if (attributes != USB_EP_ATTR_ISOCH) { 10083 pipe_state = OHCI_PIPE_STATE_ERROR; 10084 pp->pp_error = completion_reason; 10085 } 10086 break; 10087 10088 } 10089 10090 pp->pp_state = pipe_state; 10091 10092 if (tw && tw->tw_curr_xfer_reqp) { 10093 curr_xfer_reqp = tw->tw_curr_xfer_reqp; 10094 tw->tw_curr_xfer_reqp = NULL; 10095 tw->tw_curr_isoc_pktp = NULL; 10096 } else { 10097 ASSERT(pp->pp_client_periodic_in_reqp != NULL); 10098 10099 curr_xfer_reqp = pp->pp_client_periodic_in_reqp; 10100 pp->pp_client_periodic_in_reqp = NULL; 10101 } 10102 10103 ASSERT(curr_xfer_reqp != NULL); 10104 10105 mutex_exit(&ohcip->ohci_int_mutex); 10106 10107 usba_hcdi_cb(ph, curr_xfer_reqp, completion_reason); 10108 10109 mutex_enter(&ohcip->ohci_int_mutex); 10110 } 10111 10112 10113 /* 10114 * ohci kstat functions 10115 */ 10116 10117 /* 10118 * ohci_create_stats: 10119 * 10120 * Allocate and initialize the ohci kstat structures 10121 */ 10122 static void 10123 ohci_create_stats(ohci_state_t *ohcip) 10124 { 10125 char kstatname[KSTAT_STRLEN]; 10126 const char *dname = ddi_driver_name(ohcip->ohci_dip); 10127 char *usbtypes[USB_N_COUNT_KSTATS] = 10128 {"ctrl", "isoch", "bulk", "intr"}; 10129 uint_t instance = ohcip->ohci_instance; 10130 ohci_intrs_stats_t *isp; 10131 int i; 10132 10133 if (OHCI_INTRS_STATS(ohcip) == NULL) { 10134 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,intrs", 10135 dname, instance); 10136 OHCI_INTRS_STATS(ohcip) = kstat_create("usba", instance, 10137 kstatname, "usb_interrupts", KSTAT_TYPE_NAMED, 10138 sizeof (ohci_intrs_stats_t) / sizeof (kstat_named_t), 10139 KSTAT_FLAG_PERSISTENT); 10140 10141 if (OHCI_INTRS_STATS(ohcip)) { 10142 isp = OHCI_INTRS_STATS_DATA(ohcip); 10143 kstat_named_init(&isp->ohci_hcr_intr_total, 10144 "Interrupts Total", KSTAT_DATA_UINT64); 10145 kstat_named_init(&isp->ohci_hcr_intr_not_claimed, 10146 "Not Claimed", KSTAT_DATA_UINT64); 10147 kstat_named_init(&isp->ohci_hcr_intr_so, 10148 "Schedule Overruns", KSTAT_DATA_UINT64); 10149 kstat_named_init(&isp->ohci_hcr_intr_wdh, 10150 "Writeback Done Head", KSTAT_DATA_UINT64); 10151 kstat_named_init(&isp->ohci_hcr_intr_sof, 10152 "Start Of Frame", KSTAT_DATA_UINT64); 10153 kstat_named_init(&isp->ohci_hcr_intr_rd, 10154 "Resume Detected", KSTAT_DATA_UINT64); 10155 kstat_named_init(&isp->ohci_hcr_intr_ue, 10156 "Unrecoverable Error", KSTAT_DATA_UINT64); 10157 kstat_named_init(&isp->ohci_hcr_intr_fno, 10158 "Frame No. Overflow", KSTAT_DATA_UINT64); 10159 kstat_named_init(&isp->ohci_hcr_intr_rhsc, 10160 "Root Hub Status Change", KSTAT_DATA_UINT64); 10161 kstat_named_init(&isp->ohci_hcr_intr_oc, 10162 "Change In Ownership", KSTAT_DATA_UINT64); 10163 10164 OHCI_INTRS_STATS(ohcip)->ks_private = ohcip; 10165 OHCI_INTRS_STATS(ohcip)->ks_update = nulldev; 10166 kstat_install(OHCI_INTRS_STATS(ohcip)); 10167 } 10168 } 10169 10170 if (OHCI_TOTAL_STATS(ohcip) == NULL) { 10171 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,total", 10172 dname, instance); 10173 OHCI_TOTAL_STATS(ohcip) = kstat_create("usba", instance, 10174 kstatname, "usb_byte_count", KSTAT_TYPE_IO, 1, 10175 KSTAT_FLAG_PERSISTENT); 10176 10177 if (OHCI_TOTAL_STATS(ohcip)) { 10178 kstat_install(OHCI_TOTAL_STATS(ohcip)); 10179 } 10180 } 10181 10182 for (i = 0; i < USB_N_COUNT_KSTATS; i++) { 10183 if (ohcip->ohci_count_stats[i] == NULL) { 10184 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,%s", 10185 dname, instance, usbtypes[i]); 10186 ohcip->ohci_count_stats[i] = kstat_create("usba", 10187 instance, kstatname, "usb_byte_count", 10188 KSTAT_TYPE_IO, 1, KSTAT_FLAG_PERSISTENT); 10189 10190 if (ohcip->ohci_count_stats[i]) { 10191 kstat_install(ohcip->ohci_count_stats[i]); 10192 } 10193 } 10194 } 10195 } 10196 10197 10198 /* 10199 * ohci_destroy_stats: 10200 * 10201 * Clean up ohci kstat structures 10202 */ 10203 static void 10204 ohci_destroy_stats(ohci_state_t *ohcip) 10205 { 10206 int i; 10207 10208 if (OHCI_INTRS_STATS(ohcip)) { 10209 kstat_delete(OHCI_INTRS_STATS(ohcip)); 10210 OHCI_INTRS_STATS(ohcip) = NULL; 10211 } 10212 10213 if (OHCI_TOTAL_STATS(ohcip)) { 10214 kstat_delete(OHCI_TOTAL_STATS(ohcip)); 10215 OHCI_TOTAL_STATS(ohcip) = NULL; 10216 } 10217 10218 for (i = 0; i < USB_N_COUNT_KSTATS; i++) { 10219 if (ohcip->ohci_count_stats[i]) { 10220 kstat_delete(ohcip->ohci_count_stats[i]); 10221 ohcip->ohci_count_stats[i] = NULL; 10222 } 10223 } 10224 } 10225 10226 10227 /* 10228 * ohci_do_intrs_stats: 10229 * 10230 * ohci status information 10231 */ 10232 static void 10233 ohci_do_intrs_stats( 10234 ohci_state_t *ohcip, 10235 int val) 10236 { 10237 if (OHCI_INTRS_STATS(ohcip)) { 10238 OHCI_INTRS_STATS_DATA(ohcip)->ohci_hcr_intr_total.value.ui64++; 10239 switch (val) { 10240 case HCR_INTR_SO: 10241 OHCI_INTRS_STATS_DATA(ohcip)-> 10242 ohci_hcr_intr_so.value.ui64++; 10243 break; 10244 case HCR_INTR_WDH: 10245 OHCI_INTRS_STATS_DATA(ohcip)-> 10246 ohci_hcr_intr_wdh.value.ui64++; 10247 break; 10248 case HCR_INTR_SOF: 10249 OHCI_INTRS_STATS_DATA(ohcip)-> 10250 ohci_hcr_intr_sof.value.ui64++; 10251 break; 10252 case HCR_INTR_RD: 10253 OHCI_INTRS_STATS_DATA(ohcip)-> 10254 ohci_hcr_intr_rd.value.ui64++; 10255 break; 10256 case HCR_INTR_UE: 10257 OHCI_INTRS_STATS_DATA(ohcip)-> 10258 ohci_hcr_intr_ue.value.ui64++; 10259 break; 10260 case HCR_INTR_FNO: 10261 OHCI_INTRS_STATS_DATA(ohcip)-> 10262 ohci_hcr_intr_fno.value.ui64++; 10263 break; 10264 case HCR_INTR_RHSC: 10265 OHCI_INTRS_STATS_DATA(ohcip)-> 10266 ohci_hcr_intr_rhsc.value.ui64++; 10267 break; 10268 case HCR_INTR_OC: 10269 OHCI_INTRS_STATS_DATA(ohcip)-> 10270 ohci_hcr_intr_oc.value.ui64++; 10271 break; 10272 default: 10273 OHCI_INTRS_STATS_DATA(ohcip)-> 10274 ohci_hcr_intr_not_claimed.value.ui64++; 10275 break; 10276 } 10277 } 10278 } 10279 10280 10281 /* 10282 * ohci_do_byte_stats: 10283 * 10284 * ohci data xfer information 10285 */ 10286 static void 10287 ohci_do_byte_stats( 10288 ohci_state_t *ohcip, 10289 size_t len, 10290 uint8_t attr, 10291 uint8_t addr) 10292 { 10293 uint8_t type = attr & USB_EP_ATTR_MASK; 10294 uint8_t dir = addr & USB_EP_DIR_MASK; 10295 10296 if (dir == USB_EP_DIR_IN) { 10297 OHCI_TOTAL_STATS_DATA(ohcip)->reads++; 10298 OHCI_TOTAL_STATS_DATA(ohcip)->nread += len; 10299 switch (type) { 10300 case USB_EP_ATTR_CONTROL: 10301 OHCI_CTRL_STATS(ohcip)->reads++; 10302 OHCI_CTRL_STATS(ohcip)->nread += len; 10303 break; 10304 case USB_EP_ATTR_BULK: 10305 OHCI_BULK_STATS(ohcip)->reads++; 10306 OHCI_BULK_STATS(ohcip)->nread += len; 10307 break; 10308 case USB_EP_ATTR_INTR: 10309 OHCI_INTR_STATS(ohcip)->reads++; 10310 OHCI_INTR_STATS(ohcip)->nread += len; 10311 break; 10312 case USB_EP_ATTR_ISOCH: 10313 OHCI_ISOC_STATS(ohcip)->reads++; 10314 OHCI_ISOC_STATS(ohcip)->nread += len; 10315 break; 10316 } 10317 } else if (dir == USB_EP_DIR_OUT) { 10318 OHCI_TOTAL_STATS_DATA(ohcip)->writes++; 10319 OHCI_TOTAL_STATS_DATA(ohcip)->nwritten += len; 10320 switch (type) { 10321 case USB_EP_ATTR_CONTROL: 10322 OHCI_CTRL_STATS(ohcip)->writes++; 10323 OHCI_CTRL_STATS(ohcip)->nwritten += len; 10324 break; 10325 case USB_EP_ATTR_BULK: 10326 OHCI_BULK_STATS(ohcip)->writes++; 10327 OHCI_BULK_STATS(ohcip)->nwritten += len; 10328 break; 10329 case USB_EP_ATTR_INTR: 10330 OHCI_INTR_STATS(ohcip)->writes++; 10331 OHCI_INTR_STATS(ohcip)->nwritten += len; 10332 break; 10333 case USB_EP_ATTR_ISOCH: 10334 OHCI_ISOC_STATS(ohcip)->writes++; 10335 OHCI_ISOC_STATS(ohcip)->nwritten += len; 10336 break; 10337 } 10338 } 10339 } 10340 10341 10342 /* 10343 * ohci_print_op_regs: 10344 * 10345 * Print Host Controller's (HC) Operational registers. 10346 */ 10347 static void 10348 ohci_print_op_regs(ohci_state_t *ohcip) 10349 { 10350 uint_t i; 10351 10352 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 10353 "\n\tOHCI%d Operational Registers\n", 10354 ddi_get_instance(ohcip->ohci_dip)); 10355 10356 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 10357 "\thcr_revision: 0x%x \t\thcr_control: 0x%x", 10358 Get_OpReg(hcr_revision), Get_OpReg(hcr_control)); 10359 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 10360 "\thcr_cmd_status: 0x%x \t\thcr_intr_enable: 0x%x", 10361 Get_OpReg(hcr_cmd_status), Get_OpReg(hcr_intr_enable)); 10362 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 10363 "\thcr_intr_disable: 0x%x \thcr_HCCA: 0x%x", 10364 Get_OpReg(hcr_intr_disable), Get_OpReg(hcr_HCCA)); 10365 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 10366 "\thcr_periodic_curr: 0x%x \t\thcr_ctrl_head: 0x%x", 10367 Get_OpReg(hcr_periodic_curr), Get_OpReg(hcr_ctrl_head)); 10368 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 10369 "\thcr_ctrl_curr: 0x%x \t\thcr_bulk_head: 0x%x", 10370 Get_OpReg(hcr_ctrl_curr), Get_OpReg(hcr_bulk_head)); 10371 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 10372 "\thcr_bulk_curr: 0x%x \t\thcr_done_head: 0x%x", 10373 Get_OpReg(hcr_bulk_curr), Get_OpReg(hcr_done_head)); 10374 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 10375 "\thcr_frame_interval: 0x%x " 10376 "\thcr_frame_remaining: 0x%x", Get_OpReg(hcr_frame_interval), 10377 Get_OpReg(hcr_frame_remaining)); 10378 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 10379 "\thcr_frame_number: 0x%x \thcr_periodic_strt: 0x%x", 10380 Get_OpReg(hcr_frame_number), Get_OpReg(hcr_periodic_strt)); 10381 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 10382 "\thcr_transfer_ls: 0x%x \t\thcr_rh_descriptorA: 0x%x", 10383 Get_OpReg(hcr_transfer_ls), Get_OpReg(hcr_rh_descriptorA)); 10384 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 10385 "\thcr_rh_descriptorB: 0x%x \thcr_rh_status: 0x%x", 10386 Get_OpReg(hcr_rh_descriptorB), Get_OpReg(hcr_rh_status)); 10387 10388 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 10389 "\tRoot hub port status"); 10390 10391 for (i = 0; i < (Get_OpReg(hcr_rh_descriptorA) & HCR_RHA_NDP); i++) { 10392 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 10393 "\thcr_rh_portstatus 0x%x: 0x%x ", i, 10394 Get_OpReg(hcr_rh_portstatus[i])); 10395 } 10396 } 10397 10398 10399 /* 10400 * ohci_print_ed: 10401 */ 10402 static void 10403 ohci_print_ed( 10404 ohci_state_t *ohcip, 10405 ohci_ed_t *ed) 10406 { 10407 uint_t ctrl = Get_ED(ed->hced_ctrl); 10408 10409 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10410 "ohci_print_ed: ed = 0x%p", (void *)ed); 10411 10412 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10413 "\thced_ctrl: 0x%x %s", ctrl, 10414 ((Get_ED(ed->hced_headp) & HC_EPT_Halt) ? "halted": "")); 10415 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10416 "\ttoggle carry: 0x%x", Get_ED(ed->hced_headp) & HC_EPT_Carry); 10417 10418 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10419 "\tctrl: 0x%x", Get_ED(ed->hced_ctrl)); 10420 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10421 "\ttailp: 0x%x", Get_ED(ed->hced_tailp)); 10422 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10423 "\theadp: 0x%x", Get_ED(ed->hced_headp)); 10424 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10425 "\tnext: 0x%x", Get_ED(ed->hced_next)); 10426 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10427 "\tprev: 0x%x", Get_ED(ed->hced_prev)); 10428 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10429 "\tnode: 0x%x", Get_ED(ed->hced_node)); 10430 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10431 "\treclaim_next: 0x%x", Get_ED(ed->hced_reclaim_next)); 10432 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10433 "\treclaim_frame: 0x%x", Get_ED(ed->hced_reclaim_frame)); 10434 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10435 "\tstate: 0x%x", Get_ED(ed->hced_state)); 10436 } 10437 10438 10439 /* 10440 * ohci_print_td: 10441 */ 10442 static void 10443 ohci_print_td( 10444 ohci_state_t *ohcip, 10445 ohci_td_t *td) 10446 { 10447 uint_t i; 10448 uint_t ctrl = Get_TD(td->hctd_ctrl); 10449 10450 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10451 "ohci_print_td: td = 0x%p", (void *)td); 10452 10453 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10454 "\tPID: 0x%x ", ctrl & HC_TD_PID); 10455 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10456 "\tDelay Intr: 0x%x ", ctrl & HC_TD_DI); 10457 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10458 "\tData Toggle: 0x%x ", ctrl & HC_TD_DT); 10459 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10460 "\tError Count: 0x%x ", ctrl & HC_TD_EC); 10461 10462 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10463 "\tctrl: 0x%x ", Get_TD(td->hctd_ctrl)); 10464 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10465 "\tcbp: 0x%x ", Get_TD(td->hctd_cbp)); 10466 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10467 "\tnext_td: 0x%x ", Get_TD(td->hctd_next_td)); 10468 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10469 "\tbuf_end: 0x%x ", Get_TD(td->hctd_buf_end)); 10470 10471 for (i = 0; i < 4; i++) { 10472 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10473 "\toffset[%d]: 0x%x ", i, Get_TD(td->hctd_offsets[i])); 10474 } 10475 10476 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10477 "\ttrans_wrapper: 0x%x ", Get_TD(td->hctd_trans_wrapper)); 10478 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10479 "\tstate: 0x%x ", Get_TD(td->hctd_state)); 10480 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10481 "\ttw_next_td: 0x%x ", Get_TD(td->hctd_tw_next_td)); 10482 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10483 "\tctrl_phase: 0x%x ", Get_TD(td->hctd_ctrl_phase)); 10484 } 10485