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