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