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