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