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 * Remove old_td from tw and update the links. 6506 */ 6507 void 6508 ohci_unlink_td_from_tw( 6509 ohci_state_t *ohcip, 6510 ohci_td_t *old_td, 6511 ohci_trans_wrapper_t *tw) 6512 { 6513 ohci_td_t *next, *head, *tail; 6514 6515 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6516 "ohci_unlink_td_from_tw: ohcip = 0x%p, old_td = 0x%p, tw = 0x%p", 6517 (void *)ohcip, (void *)old_td, (void *)tw); 6518 6519 if (old_td == NULL || tw == NULL) { 6520 6521 return; 6522 } 6523 6524 head = tw->tw_hctd_head; 6525 tail = tw->tw_hctd_tail; 6526 6527 if (head == NULL) { 6528 6529 return; 6530 } 6531 6532 /* if this old_td is on head */ 6533 if (old_td == head) { 6534 if (old_td == tail) { 6535 tw->tw_hctd_head = NULL; 6536 tw->tw_hctd_tail = NULL; 6537 } else { 6538 tw->tw_hctd_head = ohci_td_iommu_to_cpu(ohcip, 6539 Get_TD(head->hctd_tw_next_td)); 6540 } 6541 6542 return; 6543 } 6544 6545 /* find this old_td's position in the tw */ 6546 next = ohci_td_iommu_to_cpu(ohcip, Get_TD(head->hctd_tw_next_td)); 6547 while (next && (old_td != next)) { 6548 head = next; 6549 next = ohci_td_iommu_to_cpu(ohcip, 6550 Get_TD(next->hctd_tw_next_td)); 6551 } 6552 6553 /* unlink the found old_td from the tw */ 6554 if (old_td == next) { 6555 Set_TD(head->hctd_tw_next_td, Get_TD(next->hctd_tw_next_td)); 6556 if (old_td == tail) { 6557 tw->tw_hctd_tail = head; 6558 } 6559 } 6560 } 6561 6562 6563 /* 6564 * ohci_deallocate_td: 6565 * NOTE: This function is also called from POLLED MODE. 6566 * 6567 * Deallocate a Host Controller's (HC) Transfer Descriptor (TD). 6568 */ 6569 void 6570 ohci_deallocate_td( 6571 ohci_state_t *ohcip, 6572 ohci_td_t *old_td) 6573 { 6574 ohci_trans_wrapper_t *tw; 6575 6576 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6577 "ohci_deallocate_td: old_td = 0x%p", (void *)old_td); 6578 6579 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 6580 6581 /* 6582 * Obtain the transaction wrapper and tw will be 6583 * NULL for the dummy and for the reclaim TD's. 6584 */ 6585 if ((Get_TD(old_td->hctd_state) == HC_TD_DUMMY) || 6586 (Get_TD(old_td->hctd_state) == HC_TD_RECLAIM)) { 6587 tw = (ohci_trans_wrapper_t *)((uintptr_t) 6588 Get_TD(old_td->hctd_trans_wrapper)); 6589 ASSERT(tw == NULL); 6590 } else { 6591 tw = (ohci_trans_wrapper_t *) 6592 OHCI_LOOKUP_ID((uint32_t) 6593 Get_TD(old_td->hctd_trans_wrapper)); 6594 ASSERT(tw != NULL); 6595 } 6596 6597 /* 6598 * If this TD should be reclaimed, don't try to access its 6599 * transfer wrapper. 6600 */ 6601 if ((Get_TD(old_td->hctd_state) != HC_TD_RECLAIM) && tw) { 6602 6603 ohci_unlink_td_from_tw(ohcip, old_td, tw); 6604 } 6605 6606 bzero((void *)old_td, sizeof (ohci_td_t)); 6607 Set_TD(old_td->hctd_state, HC_TD_FREE); 6608 6609 USB_DPRINTF_L3(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6610 "ohci_deallocate_td: td 0x%p", (void *)old_td); 6611 } 6612 6613 6614 /* 6615 * ohci_td_cpu_to_iommu: 6616 * NOTE: This function is also called from POLLED MODE. 6617 * 6618 * This function converts for the given Transfer Descriptor (TD) CPU address 6619 * to IO address. 6620 */ 6621 uint32_t 6622 ohci_td_cpu_to_iommu( 6623 ohci_state_t *ohcip, 6624 ohci_td_t *addr) 6625 { 6626 uint32_t td; 6627 6628 td = (uint32_t)ohcip->ohci_td_pool_cookie.dmac_address + 6629 (uint32_t)((uintptr_t)addr - (uintptr_t)(ohcip->ohci_td_pool_addr)); 6630 6631 ASSERT((ohcip->ohci_td_pool_cookie.dmac_address + 6632 (uint32_t) (sizeof (ohci_td_t) * 6633 (addr - ohcip->ohci_td_pool_addr))) == 6634 (ohcip->ohci_td_pool_cookie.dmac_address + 6635 (uint32_t)((uintptr_t)addr - (uintptr_t) 6636 (ohcip->ohci_td_pool_addr)))); 6637 6638 ASSERT(td >= ohcip->ohci_td_pool_cookie.dmac_address); 6639 ASSERT(td <= ohcip->ohci_td_pool_cookie.dmac_address + 6640 sizeof (ohci_td_t) * ohci_td_pool_size); 6641 6642 return (td); 6643 } 6644 6645 6646 /* 6647 * ohci_td_iommu_to_cpu: 6648 * NOTE: This function is also called from POLLED MODE. 6649 * 6650 * This function converts for the given Transfer Descriptor (TD) IO address 6651 * to CPU address. 6652 */ 6653 ohci_td_t * 6654 ohci_td_iommu_to_cpu( 6655 ohci_state_t *ohcip, 6656 uintptr_t addr) 6657 { 6658 ohci_td_t *td; 6659 6660 if (addr == NULL) { 6661 6662 return (NULL); 6663 } 6664 6665 td = (ohci_td_t *)((uintptr_t) 6666 (addr - ohcip->ohci_td_pool_cookie.dmac_address) + 6667 (uintptr_t)ohcip->ohci_td_pool_addr); 6668 6669 ASSERT(td >= ohcip->ohci_td_pool_addr); 6670 ASSERT((uintptr_t)td <= (uintptr_t)ohcip->ohci_td_pool_addr + 6671 (uintptr_t)(sizeof (ohci_td_t) * ohci_td_pool_size)); 6672 6673 return (td); 6674 } 6675 6676 /* 6677 * ohci_allocate_tds_for_tw: 6678 * 6679 * Allocate n Transfer Descriptors (TD) from the TD buffer pool and places it 6680 * into the TW. 6681 * 6682 * Returns USB_NO_RESOURCES if it was not able to allocate all the requested TD 6683 * otherwise USB_SUCCESS. 6684 */ 6685 static int 6686 ohci_allocate_tds_for_tw( 6687 ohci_state_t *ohcip, 6688 ohci_trans_wrapper_t *tw, 6689 size_t td_count) 6690 { 6691 ohci_td_t *td; 6692 uint32_t td_addr; 6693 int i; 6694 int error = USB_SUCCESS; 6695 6696 for (i = 0; i < td_count; i++) { 6697 td = ohci_allocate_td_from_pool(ohcip); 6698 if (td == NULL) { 6699 error = USB_NO_RESOURCES; 6700 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6701 "ohci_allocate_tds_for_tw: " 6702 "Unable to allocate %lu TDs", 6703 td_count); 6704 break; 6705 } 6706 if (tw->tw_hctd_free_list != NULL) { 6707 td_addr = ohci_td_cpu_to_iommu(ohcip, 6708 tw->tw_hctd_free_list); 6709 Set_TD(td->hctd_tw_next_td, td_addr); 6710 } 6711 tw->tw_hctd_free_list = td; 6712 } 6713 6714 return (error); 6715 } 6716 6717 /* 6718 * ohci_allocate_tw_resources: 6719 * 6720 * Allocate a Transaction Wrapper (TW) and n Transfer Descriptors (TD) 6721 * from the TD buffer pool and places it into the TW. It does an all 6722 * or nothing transaction. 6723 * 6724 * Returns NULL if there is insufficient resources otherwise TW. 6725 */ 6726 static ohci_trans_wrapper_t * 6727 ohci_allocate_tw_resources( 6728 ohci_state_t *ohcip, 6729 ohci_pipe_private_t *pp, 6730 size_t tw_length, 6731 usb_flags_t usb_flags, 6732 size_t td_count) 6733 { 6734 ohci_trans_wrapper_t *tw; 6735 6736 tw = ohci_create_transfer_wrapper(ohcip, pp, tw_length, usb_flags); 6737 6738 if (tw == NULL) { 6739 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 6740 "ohci_allocate_tw_resources: Unable to allocate TW"); 6741 } else { 6742 if (ohci_allocate_tds_for_tw(ohcip, tw, td_count) == 6743 USB_SUCCESS) { 6744 tw->tw_num_tds = td_count; 6745 } else { 6746 ohci_deallocate_tw_resources(ohcip, pp, tw); 6747 tw = NULL; 6748 } 6749 } 6750 6751 return (tw); 6752 } 6753 6754 /* 6755 * ohci_free_tw_tds_resources: 6756 * 6757 * Free all allocated resources for Transaction Wrapper (TW). 6758 * Does not free the TW itself. 6759 */ 6760 static void 6761 ohci_free_tw_tds_resources( 6762 ohci_state_t *ohcip, 6763 ohci_trans_wrapper_t *tw) 6764 { 6765 ohci_td_t *td; 6766 ohci_td_t *temp_td; 6767 6768 td = tw->tw_hctd_free_list; 6769 while (td != NULL) { 6770 /* Save the pointer to the next td before destroying it */ 6771 temp_td = ohci_td_iommu_to_cpu(ohcip, 6772 Get_TD(td->hctd_tw_next_td)); 6773 ohci_deallocate_td(ohcip, td); 6774 td = temp_td; 6775 } 6776 tw->tw_hctd_free_list = NULL; 6777 } 6778 6779 6780 /* 6781 * Transfer Wrapper functions 6782 * 6783 * ohci_create_transfer_wrapper: 6784 * 6785 * Create a Transaction Wrapper (TW) for non-isoc transfer types 6786 * and this involves the allocating of DMA resources. 6787 */ 6788 static ohci_trans_wrapper_t * 6789 ohci_create_transfer_wrapper( 6790 ohci_state_t *ohcip, 6791 ohci_pipe_private_t *pp, 6792 size_t length, 6793 uint_t usb_flags) 6794 { 6795 ddi_device_acc_attr_t dev_attr; 6796 int result; 6797 size_t real_length; 6798 ohci_trans_wrapper_t *tw; 6799 ddi_dma_attr_t dma_attr; 6800 int kmem_flag; 6801 int (*dmamem_wait)(caddr_t); 6802 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 6803 6804 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6805 "ohci_create_transfer_wrapper: length = 0x%lx flags = 0x%x", 6806 length, usb_flags); 6807 6808 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 6809 6810 /* isochronous pipe should not call into this function */ 6811 if ((ph->p_ep.bmAttributes & USB_EP_ATTR_MASK) == 6812 USB_EP_ATTR_ISOCH) { 6813 6814 return (NULL); 6815 } 6816 6817 /* SLEEP flag should not be used in interrupt context */ 6818 if (servicing_interrupt()) { 6819 kmem_flag = KM_NOSLEEP; 6820 dmamem_wait = DDI_DMA_DONTWAIT; 6821 } else { 6822 kmem_flag = KM_SLEEP; 6823 dmamem_wait = DDI_DMA_SLEEP; 6824 } 6825 6826 /* Allocate space for the transfer wrapper */ 6827 tw = kmem_zalloc(sizeof (ohci_trans_wrapper_t), kmem_flag); 6828 6829 if (tw == NULL) { 6830 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6831 "ohci_create_transfer_wrapper: kmem_zalloc failed"); 6832 6833 return (NULL); 6834 } 6835 6836 /* zero-length packet doesn't need to allocate dma memory */ 6837 if (length == 0) { 6838 6839 goto dmadone; 6840 } 6841 6842 /* allow sg lists for transfer wrapper dma memory */ 6843 bcopy(&ohcip->ohci_dma_attr, &dma_attr, sizeof (ddi_dma_attr_t)); 6844 dma_attr.dma_attr_sgllen = OHCI_DMA_ATTR_TW_SGLLEN; 6845 dma_attr.dma_attr_align = OHCI_DMA_ATTR_ALIGNMENT; 6846 6847 /* Allocate the DMA handle */ 6848 result = ddi_dma_alloc_handle(ohcip->ohci_dip, 6849 &dma_attr, dmamem_wait, 0, &tw->tw_dmahandle); 6850 6851 if (result != DDI_SUCCESS) { 6852 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6853 "ohci_create_transfer_wrapper: Alloc handle failed"); 6854 6855 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 6856 6857 return (NULL); 6858 } 6859 6860 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 6861 6862 /* The host controller will be little endian */ 6863 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_BE_ACC; 6864 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 6865 6866 /* Allocate the memory */ 6867 result = ddi_dma_mem_alloc(tw->tw_dmahandle, length, 6868 &dev_attr, DDI_DMA_CONSISTENT, dmamem_wait, NULL, 6869 (caddr_t *)&tw->tw_buf, &real_length, &tw->tw_accesshandle); 6870 6871 if (result != DDI_SUCCESS) { 6872 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6873 "ohci_create_transfer_wrapper: dma_mem_alloc fail"); 6874 6875 ddi_dma_free_handle(&tw->tw_dmahandle); 6876 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 6877 6878 return (NULL); 6879 } 6880 6881 ASSERT(real_length >= length); 6882 6883 /* Bind the handle */ 6884 result = ddi_dma_addr_bind_handle(tw->tw_dmahandle, NULL, 6885 (caddr_t)tw->tw_buf, real_length, DDI_DMA_RDWR|DDI_DMA_CONSISTENT, 6886 dmamem_wait, NULL, &tw->tw_cookie, &tw->tw_ncookies); 6887 6888 if (result != DDI_DMA_MAPPED) { 6889 ohci_decode_ddi_dma_addr_bind_handle_result(ohcip, result); 6890 6891 ddi_dma_mem_free(&tw->tw_accesshandle); 6892 ddi_dma_free_handle(&tw->tw_dmahandle); 6893 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 6894 6895 return (NULL); 6896 } 6897 6898 tw->tw_cookie_idx = 0; 6899 tw->tw_dma_offs = 0; 6900 6901 dmadone: 6902 /* 6903 * Only allow one wrapper to be added at a time. Insert the 6904 * new transaction wrapper into the list for this pipe. 6905 */ 6906 if (pp->pp_tw_head == NULL) { 6907 pp->pp_tw_head = tw; 6908 pp->pp_tw_tail = tw; 6909 } else { 6910 pp->pp_tw_tail->tw_next = tw; 6911 pp->pp_tw_tail = tw; 6912 } 6913 6914 /* Store the transfer length */ 6915 tw->tw_length = length; 6916 6917 /* Store a back pointer to the pipe private structure */ 6918 tw->tw_pipe_private = pp; 6919 6920 /* Store the transfer type - synchronous or asynchronous */ 6921 tw->tw_flags = usb_flags; 6922 6923 /* Get and Store 32bit ID */ 6924 tw->tw_id = OHCI_GET_ID((void *)tw); 6925 6926 ASSERT(tw->tw_id != NULL); 6927 6928 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6929 "ohci_create_transfer_wrapper: tw = 0x%p, ncookies = %u", 6930 tw, tw->tw_ncookies); 6931 6932 return (tw); 6933 } 6934 6935 6936 /* 6937 * Transfer Wrapper functions 6938 * 6939 * ohci_create_isoc_transfer_wrapper: 6940 * 6941 * Create a Transaction Wrapper (TW) for isoc transfer 6942 * and this involves the allocating of DMA resources. 6943 */ 6944 static ohci_trans_wrapper_t * 6945 ohci_create_isoc_transfer_wrapper( 6946 ohci_state_t *ohcip, 6947 ohci_pipe_private_t *pp, 6948 size_t length, 6949 usb_isoc_pkt_descr_t *descr, 6950 ushort_t pkt_count, 6951 size_t td_count, 6952 uint_t usb_flags) 6953 { 6954 ddi_device_acc_attr_t dev_attr; 6955 int result; 6956 size_t real_length, xfer_size; 6957 uint_t ccount; 6958 ohci_trans_wrapper_t *tw; 6959 ddi_dma_attr_t dma_attr; 6960 int kmem_flag; 6961 uint_t i, j, frame_count, residue; 6962 int (*dmamem_wait)(caddr_t); 6963 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 6964 usb_isoc_pkt_descr_t *isoc_pkt_descr = descr; 6965 6966 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6967 "ohci_create_isoc_transfer_wrapper: length = 0x%lx flags = 0x%x", 6968 length, usb_flags); 6969 6970 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 6971 6972 /* non-isochronous pipe should not call into this function */ 6973 if ((ph->p_ep.bmAttributes & USB_EP_ATTR_MASK) != 6974 USB_EP_ATTR_ISOCH) { 6975 6976 return (NULL); 6977 } 6978 6979 /* SLEEP flag should not be used in interrupt context */ 6980 if (servicing_interrupt()) { 6981 kmem_flag = KM_NOSLEEP; 6982 dmamem_wait = DDI_DMA_DONTWAIT; 6983 } else { 6984 kmem_flag = KM_SLEEP; 6985 dmamem_wait = DDI_DMA_SLEEP; 6986 } 6987 6988 /* Allocate space for the transfer wrapper */ 6989 tw = kmem_zalloc(sizeof (ohci_trans_wrapper_t), kmem_flag); 6990 6991 if (tw == NULL) { 6992 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6993 "ohci_create_transfer_wrapper: kmem_zalloc failed"); 6994 6995 return (NULL); 6996 } 6997 6998 /* Allocate space for the isoc buffer handles */ 6999 tw->tw_isoc_strtlen = sizeof (ohci_isoc_buf_t) * td_count; 7000 if ((tw->tw_isoc_bufs = kmem_zalloc(tw->tw_isoc_strtlen, 7001 kmem_flag)) == NULL) { 7002 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 7003 "ohci_create_isoc_transfer_wrapper: kmem_alloc " 7004 "isoc buffer failed"); 7005 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 7006 7007 return (NULL); 7008 } 7009 7010 /* allow sg lists for transfer wrapper dma memory */ 7011 bcopy(&ohcip->ohci_dma_attr, &dma_attr, sizeof (ddi_dma_attr_t)); 7012 dma_attr.dma_attr_sgllen = OHCI_DMA_ATTR_TD_SGLLEN; 7013 dma_attr.dma_attr_align = OHCI_DMA_ATTR_ALIGNMENT; 7014 7015 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 7016 7017 /* The host controller will be little endian */ 7018 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_BE_ACC; 7019 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 7020 7021 residue = pkt_count % OHCI_ISOC_PKTS_PER_TD; 7022 7023 for (i = 0; i < td_count; i++) { 7024 tw->tw_isoc_bufs[i].index = i; 7025 7026 if ((i == (td_count - 1)) && (residue != 0)) { 7027 frame_count = residue; 7028 } else { 7029 frame_count = OHCI_ISOC_PKTS_PER_TD; 7030 } 7031 7032 /* Allocate the DMA handle */ 7033 result = ddi_dma_alloc_handle(ohcip->ohci_dip, &dma_attr, 7034 dmamem_wait, 0, &tw->tw_isoc_bufs[i].dma_handle); 7035 7036 if (result != DDI_SUCCESS) { 7037 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7038 "ohci_create_isoc_transfer_wrapper: " 7039 "Alloc handle failed"); 7040 7041 for (j = 0; j < i; j++) { 7042 result = ddi_dma_unbind_handle( 7043 tw->tw_isoc_bufs[j].dma_handle); 7044 ASSERT(result == USB_SUCCESS); 7045 ddi_dma_mem_free(&tw->tw_isoc_bufs[j]. 7046 mem_handle); 7047 ddi_dma_free_handle(&tw->tw_isoc_bufs[j]. 7048 dma_handle); 7049 } 7050 kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen); 7051 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 7052 7053 return (NULL); 7054 } 7055 7056 /* Compute the memory length */ 7057 for (xfer_size = 0, j = 0; j < frame_count; j++) { 7058 ASSERT(isoc_pkt_descr != NULL); 7059 xfer_size += isoc_pkt_descr->isoc_pkt_length; 7060 isoc_pkt_descr++; 7061 } 7062 7063 /* Allocate the memory */ 7064 result = ddi_dma_mem_alloc(tw->tw_isoc_bufs[i].dma_handle, 7065 xfer_size, &dev_attr, DDI_DMA_CONSISTENT, dmamem_wait, 7066 NULL, (caddr_t *)&tw->tw_isoc_bufs[i].buf_addr, 7067 &real_length, &tw->tw_isoc_bufs[i].mem_handle); 7068 7069 if (result != DDI_SUCCESS) { 7070 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7071 "ohci_create_isoc_transfer_wrapper: " 7072 "dma_mem_alloc %d fail", i); 7073 ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle); 7074 7075 for (j = 0; j < i; j++) { 7076 result = ddi_dma_unbind_handle( 7077 tw->tw_isoc_bufs[j].dma_handle); 7078 ASSERT(result == USB_SUCCESS); 7079 ddi_dma_mem_free(&tw->tw_isoc_bufs[j]. 7080 mem_handle); 7081 ddi_dma_free_handle(&tw->tw_isoc_bufs[j]. 7082 dma_handle); 7083 } 7084 kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen); 7085 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 7086 7087 return (NULL); 7088 } 7089 7090 ASSERT(real_length >= xfer_size); 7091 7092 /* Bind the handle */ 7093 result = ddi_dma_addr_bind_handle( 7094 tw->tw_isoc_bufs[i].dma_handle, NULL, 7095 (caddr_t)tw->tw_isoc_bufs[i].buf_addr, real_length, 7096 DDI_DMA_RDWR|DDI_DMA_CONSISTENT, dmamem_wait, NULL, 7097 &tw->tw_isoc_bufs[i].cookie, &ccount); 7098 7099 if ((result == DDI_DMA_MAPPED) && 7100 (ccount <= OHCI_DMA_ATTR_TD_SGLLEN)) { 7101 tw->tw_isoc_bufs[i].length = xfer_size; 7102 tw->tw_isoc_bufs[i].ncookies = ccount; 7103 7104 continue; 7105 } else { 7106 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7107 "ohci_create_isoc_transfer_wrapper: " 7108 "Bind handle %d failed", i); 7109 if (result == DDI_DMA_MAPPED) { 7110 result = ddi_dma_unbind_handle( 7111 tw->tw_isoc_bufs[i].dma_handle); 7112 ASSERT(result == USB_SUCCESS); 7113 } 7114 ddi_dma_mem_free(&tw->tw_isoc_bufs[i].mem_handle); 7115 ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle); 7116 7117 for (j = 0; j < i; j++) { 7118 result = ddi_dma_unbind_handle( 7119 tw->tw_isoc_bufs[j].dma_handle); 7120 ASSERT(result == USB_SUCCESS); 7121 ddi_dma_mem_free(&tw->tw_isoc_bufs[j]. 7122 mem_handle); 7123 ddi_dma_free_handle(&tw->tw_isoc_bufs[j]. 7124 dma_handle); 7125 } 7126 kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen); 7127 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 7128 7129 return (NULL); 7130 } 7131 } 7132 7133 /* 7134 * Only allow one wrapper to be added at a time. Insert the 7135 * new transaction wrapper into the list for this pipe. 7136 */ 7137 if (pp->pp_tw_head == NULL) { 7138 pp->pp_tw_head = tw; 7139 pp->pp_tw_tail = tw; 7140 } else { 7141 pp->pp_tw_tail->tw_next = tw; 7142 pp->pp_tw_tail = tw; 7143 } 7144 7145 /* Store the transfer length */ 7146 tw->tw_length = length; 7147 7148 /* Store the td numbers */ 7149 tw->tw_ncookies = td_count; 7150 7151 /* Store a back pointer to the pipe private structure */ 7152 tw->tw_pipe_private = pp; 7153 7154 /* Store the transfer type - synchronous or asynchronous */ 7155 tw->tw_flags = usb_flags; 7156 7157 /* Get and Store 32bit ID */ 7158 tw->tw_id = OHCI_GET_ID((void *)tw); 7159 7160 ASSERT(tw->tw_id != NULL); 7161 7162 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7163 "ohci_create_isoc_transfer_wrapper: tw = 0x%p", tw); 7164 7165 return (tw); 7166 } 7167 7168 7169 /* 7170 * ohci_start_xfer_timer: 7171 * 7172 * Start the timer for the control, bulk and for one time interrupt 7173 * transfers. 7174 */ 7175 /* ARGSUSED */ 7176 static void 7177 ohci_start_xfer_timer( 7178 ohci_state_t *ohcip, 7179 ohci_pipe_private_t *pp, 7180 ohci_trans_wrapper_t *tw) 7181 { 7182 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 7183 "ohci_start_xfer_timer: tw = 0x%p", tw); 7184 7185 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7186 7187 /* 7188 * The timeout handling is done only for control, bulk and for 7189 * one time Interrupt transfers. 7190 * 7191 * NOTE: If timeout is zero; Assume infinite timeout and don't 7192 * insert this transfer on the timeout list. 7193 */ 7194 if (tw->tw_timeout) { 7195 /* 7196 * Increase timeout value by one second and this extra one 7197 * second is used to halt the endpoint if given transfer 7198 * times out. 7199 */ 7200 tw->tw_timeout++; 7201 7202 /* 7203 * Add this transfer wrapper into the transfer timeout list. 7204 */ 7205 if (ohcip->ohci_timeout_list) { 7206 tw->tw_timeout_next = ohcip->ohci_timeout_list; 7207 } 7208 7209 ohcip->ohci_timeout_list = tw; 7210 ohci_start_timer(ohcip); 7211 } 7212 } 7213 7214 7215 /* 7216 * ohci_stop_xfer_timer: 7217 * 7218 * Start the timer for the control, bulk and for one time interrupt 7219 * transfers. 7220 */ 7221 void 7222 ohci_stop_xfer_timer( 7223 ohci_state_t *ohcip, 7224 ohci_trans_wrapper_t *tw, 7225 uint_t flag) 7226 { 7227 timeout_id_t timer_id; 7228 7229 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 7230 "ohci_stop_xfer_timer: tw = 0x%p", tw); 7231 7232 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7233 7234 /* 7235 * The timeout handling is done only for control, bulk 7236 * and for one time Interrupt transfers. 7237 */ 7238 if (ohcip->ohci_timeout_list == NULL) { 7239 return; 7240 } 7241 7242 switch (flag) { 7243 case OHCI_REMOVE_XFER_IFLAST: 7244 if (tw->tw_hctd_head != tw->tw_hctd_tail) { 7245 break; 7246 } 7247 /* FALLTHRU */ 7248 case OHCI_REMOVE_XFER_ALWAYS: 7249 ohci_remove_tw_from_timeout_list(ohcip, tw); 7250 7251 if ((ohcip->ohci_timeout_list == NULL) && 7252 (ohcip->ohci_timer_id)) { 7253 7254 timer_id = ohcip->ohci_timer_id; 7255 7256 /* Reset the timer id to zero */ 7257 ohcip->ohci_timer_id = 0; 7258 7259 mutex_exit(&ohcip->ohci_int_mutex); 7260 7261 (void) untimeout(timer_id); 7262 7263 mutex_enter(&ohcip->ohci_int_mutex); 7264 } 7265 break; 7266 default: 7267 break; 7268 } 7269 } 7270 7271 7272 /* 7273 * ohci_xfer_timeout_handler: 7274 * 7275 * Control or bulk transfer timeout handler. 7276 */ 7277 static void 7278 ohci_xfer_timeout_handler(void *arg) 7279 { 7280 ohci_state_t *ohcip = (ohci_state_t *)arg; 7281 ohci_trans_wrapper_t *exp_xfer_list_head = NULL; 7282 ohci_trans_wrapper_t *exp_xfer_list_tail = NULL; 7283 ohci_trans_wrapper_t *tw, *next; 7284 ohci_td_t *td; 7285 usb_flags_t flags; 7286 7287 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 7288 "ohci_xfer_timeout_handler: ohcip = 0x%p", ohcip); 7289 7290 mutex_enter(&ohcip->ohci_int_mutex); 7291 7292 /* Set the required flags */ 7293 flags = OHCI_FLAGS_NOSLEEP | OHCI_FLAGS_DMA_SYNC; 7294 7295 /* 7296 * Check whether still timeout handler is valid. 7297 */ 7298 if (ohcip->ohci_timer_id) { 7299 7300 /* Reset the timer id to zero */ 7301 ohcip->ohci_timer_id = 0; 7302 } else { 7303 mutex_exit(&ohcip->ohci_int_mutex); 7304 7305 return; 7306 } 7307 7308 /* Get the transfer timeout list head */ 7309 tw = ohcip->ohci_timeout_list; 7310 7311 /* 7312 * Process ohci timeout list and look whether the timer 7313 * has expired for any transfers. Create a temporary list 7314 * of expired transfers and process them later. 7315 */ 7316 while (tw) { 7317 /* Get the transfer on the timeout list */ 7318 next = tw->tw_timeout_next; 7319 7320 tw->tw_timeout--; 7321 7322 /* 7323 * Set the sKip bit to stop all transactions on 7324 * this pipe 7325 */ 7326 if (tw->tw_timeout == 1) { 7327 ohci_modify_sKip_bit(ohcip, 7328 tw->tw_pipe_private, SET_sKip, flags); 7329 7330 /* Reset dma sync flag */ 7331 flags &= ~OHCI_FLAGS_DMA_SYNC; 7332 } 7333 7334 /* Remove tw from the timeout list */ 7335 if (tw->tw_timeout <= 0) { 7336 7337 ohci_remove_tw_from_timeout_list(ohcip, tw); 7338 7339 /* Add tw to the end of expire list */ 7340 if (exp_xfer_list_head) { 7341 exp_xfer_list_tail->tw_timeout_next = tw; 7342 } else { 7343 exp_xfer_list_head = tw; 7344 } 7345 exp_xfer_list_tail = tw; 7346 tw->tw_timeout_next = NULL; 7347 } 7348 7349 tw = next; 7350 } 7351 7352 /* Get the expired transfer timeout list head */ 7353 tw = exp_xfer_list_head; 7354 7355 if (tw && (flags & OHCI_FLAGS_DMA_SYNC)) { 7356 /* Sync ED and TD pool */ 7357 Sync_ED_TD_Pool(ohcip); 7358 } 7359 7360 /* 7361 * Process the expired transfers by notifing the corrsponding 7362 * client driver through the exception callback. 7363 */ 7364 while (tw) { 7365 /* Get the transfer on the expired transfer timeout list */ 7366 next = tw->tw_timeout_next; 7367 7368 td = tw->tw_hctd_head; 7369 7370 while (td) { 7371 /* Set TD state to TIMEOUT */ 7372 Set_TD(td->hctd_state, HC_TD_TIMEOUT); 7373 7374 /* Get the next TD from the wrapper */ 7375 td = ohci_td_iommu_to_cpu(ohcip, 7376 Get_TD(td->hctd_tw_next_td)); 7377 } 7378 7379 ohci_handle_error(ohcip, tw->tw_hctd_head, USB_CR_TIMEOUT); 7380 7381 tw = next; 7382 } 7383 7384 ohci_start_timer(ohcip); 7385 mutex_exit(&ohcip->ohci_int_mutex); 7386 } 7387 7388 7389 /* 7390 * ohci_remove_tw_from_timeout_list: 7391 * 7392 * Remove Control or bulk transfer from the timeout list. 7393 */ 7394 static void 7395 ohci_remove_tw_from_timeout_list( 7396 ohci_state_t *ohcip, 7397 ohci_trans_wrapper_t *tw) 7398 { 7399 ohci_trans_wrapper_t *prev, *next; 7400 7401 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 7402 "ohci_remove_tw_from_timeout_list: tw = 0x%p", tw); 7403 7404 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7405 7406 if (ohcip->ohci_timeout_list == tw) { 7407 ohcip->ohci_timeout_list = tw->tw_timeout_next; 7408 } else { 7409 prev = ohcip->ohci_timeout_list; 7410 next = prev->tw_timeout_next; 7411 7412 while (next && (next != tw)) { 7413 prev = next; 7414 next = next->tw_timeout_next; 7415 } 7416 7417 if (next == tw) { 7418 prev->tw_timeout_next = next->tw_timeout_next; 7419 } 7420 } 7421 7422 /* Reset the xfer timeout */ 7423 tw->tw_timeout_next = NULL; 7424 } 7425 7426 7427 /* 7428 * ohci_start_timer: 7429 * 7430 * Start the ohci timer 7431 */ 7432 static void 7433 ohci_start_timer(ohci_state_t *ohcip) 7434 { 7435 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 7436 "ohci_start_timer: ohcip = 0x%p", ohcip); 7437 7438 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7439 7440 /* 7441 * Start the global timer only if currently timer is not 7442 * running and if there are any transfers on the timeout 7443 * list. This timer will be per USB Host Controller. 7444 */ 7445 if ((!ohcip->ohci_timer_id) && (ohcip->ohci_timeout_list)) { 7446 ohcip->ohci_timer_id = timeout(ohci_xfer_timeout_handler, 7447 (void *)ohcip, drv_usectohz(1000000)); 7448 } 7449 } 7450 7451 7452 /* 7453 * ohci_deallocate_tw_resources: 7454 * NOTE: This function is also called from POLLED MODE. 7455 * 7456 * Deallocate of a Transaction Wrapper (TW) and this involves the freeing of 7457 * of DMA resources. 7458 */ 7459 void 7460 ohci_deallocate_tw_resources( 7461 ohci_state_t *ohcip, 7462 ohci_pipe_private_t *pp, 7463 ohci_trans_wrapper_t *tw) 7464 { 7465 ohci_trans_wrapper_t *prev, *next; 7466 7467 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7468 "ohci_deallocate_tw_resources: tw = 0x%p", tw); 7469 7470 /* 7471 * If the transfer wrapper has no Host Controller (HC) 7472 * Transfer Descriptors (TD) associated with it, then 7473 * remove the transfer wrapper. 7474 */ 7475 if (tw->tw_hctd_head) { 7476 ASSERT(tw->tw_hctd_tail != NULL); 7477 7478 return; 7479 } 7480 7481 ASSERT(tw->tw_hctd_tail == NULL); 7482 7483 /* Make sure we return all the unused td's to the pool as well */ 7484 ohci_free_tw_tds_resources(ohcip, tw); 7485 7486 /* 7487 * If pp->pp_tw_head and pp->pp_tw_tail are pointing to 7488 * given TW then set the head and tail equal to NULL. 7489 * Otherwise search for this TW in the linked TW's list 7490 * and then remove this TW from the list. 7491 */ 7492 if (pp->pp_tw_head == tw) { 7493 if (pp->pp_tw_tail == tw) { 7494 pp->pp_tw_head = NULL; 7495 pp->pp_tw_tail = NULL; 7496 } else { 7497 pp->pp_tw_head = tw->tw_next; 7498 } 7499 } else { 7500 prev = pp->pp_tw_head; 7501 next = prev->tw_next; 7502 7503 while (next && (next != tw)) { 7504 prev = next; 7505 next = next->tw_next; 7506 } 7507 7508 if (next == tw) { 7509 prev->tw_next = next->tw_next; 7510 7511 if (pp->pp_tw_tail == tw) { 7512 pp->pp_tw_tail = prev; 7513 } 7514 } 7515 } 7516 7517 ohci_free_tw(ohcip, tw); 7518 } 7519 7520 7521 /* 7522 * ohci_free_dma_resources: 7523 * 7524 * Free dma resources of a Transfer Wrapper (TW) and also free the TW. 7525 */ 7526 static void 7527 ohci_free_dma_resources( 7528 ohci_state_t *ohcip, 7529 usba_pipe_handle_data_t *ph) 7530 { 7531 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 7532 ohci_trans_wrapper_t *head_tw = pp->pp_tw_head; 7533 ohci_trans_wrapper_t *next_tw, *tw; 7534 7535 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7536 "ohci_free_dma_resources: ph = 0x%p", (void *)ph); 7537 7538 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7539 7540 /* Process the Transfer Wrappers */ 7541 next_tw = head_tw; 7542 while (next_tw) { 7543 tw = next_tw; 7544 next_tw = tw->tw_next; 7545 7546 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7547 "ohci_free_dma_resources: Free TW = 0x%p", (void *)tw); 7548 7549 ohci_free_tw(ohcip, tw); 7550 } 7551 7552 /* Adjust the head and tail pointers */ 7553 pp->pp_tw_head = NULL; 7554 pp->pp_tw_tail = NULL; 7555 } 7556 7557 7558 /* 7559 * ohci_free_tw: 7560 * 7561 * Free the Transfer Wrapper (TW). 7562 */ 7563 static void 7564 ohci_free_tw( 7565 ohci_state_t *ohcip, 7566 ohci_trans_wrapper_t *tw) 7567 { 7568 int rval, i; 7569 7570 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7571 "ohci_free_tw: tw = 0x%p", tw); 7572 7573 ASSERT(tw != NULL); 7574 ASSERT(tw->tw_id != NULL); 7575 7576 /* Free 32bit ID */ 7577 OHCI_FREE_ID((uint32_t)tw->tw_id); 7578 7579 if (tw->tw_isoc_strtlen > 0) { 7580 ASSERT(tw->tw_isoc_bufs != NULL); 7581 for (i = 0; i < tw->tw_ncookies; i++) { 7582 if (tw->tw_isoc_bufs[i].ncookies > 0) { 7583 rval = ddi_dma_unbind_handle( 7584 tw->tw_isoc_bufs[i].dma_handle); 7585 ASSERT(rval == USB_SUCCESS); 7586 } 7587 ddi_dma_mem_free(&tw->tw_isoc_bufs[i].mem_handle); 7588 ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle); 7589 } 7590 kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen); 7591 } else if (tw->tw_dmahandle != NULL) { 7592 if (tw->tw_ncookies > 0) { 7593 rval = ddi_dma_unbind_handle(tw->tw_dmahandle); 7594 ASSERT(rval == DDI_SUCCESS); 7595 } 7596 ddi_dma_mem_free(&tw->tw_accesshandle); 7597 ddi_dma_free_handle(&tw->tw_dmahandle); 7598 } 7599 7600 /* Free transfer wrapper */ 7601 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 7602 } 7603 7604 7605 /* 7606 * Interrupt Handling functions 7607 */ 7608 7609 /* 7610 * ohci_intr: 7611 * 7612 * OpenHCI (OHCI) interrupt handling routine. 7613 */ 7614 static uint_t 7615 ohci_intr(caddr_t arg1, caddr_t arg2) 7616 { 7617 ohci_state_t *ohcip = (ohci_state_t *)arg1; 7618 uint_t intr; 7619 ohci_td_t *done_head = NULL; 7620 ohci_save_intr_sts_t *ohci_intr_sts = &ohcip->ohci_save_intr_sts; 7621 7622 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7623 "ohci_intr: Interrupt occurred, arg1 0x%p arg2 0x%p", arg1, arg2); 7624 7625 mutex_enter(&ohcip->ohci_int_mutex); 7626 7627 /* 7628 * Suppose if we switched to the polled mode from the normal 7629 * mode when interrupt handler is executing then we need to 7630 * save the interrupt status information in the polled mode 7631 * to avoid race conditions. The following flag will be set 7632 * and reset on entering & exiting of ohci interrupt handler 7633 * respectively. This flag will be used in the polled mode 7634 * to check whether the interrupt handler was running when we 7635 * switched to the polled mode from the normal mode. 7636 */ 7637 ohci_intr_sts->ohci_intr_flag = OHCI_INTR_HANDLING; 7638 7639 /* Temporarily turn off interrupts */ 7640 Set_OpReg(hcr_intr_disable, HCR_INTR_MIE); 7641 7642 /* 7643 * Handle any missed ohci interrupt especially WriteDoneHead 7644 * and SOF interrupts because of previous polled mode switch. 7645 */ 7646 ohci_handle_missed_intr(ohcip); 7647 7648 /* 7649 * Now process the actual ohci interrupt events that caused 7650 * invocation of this ohci interrupt handler. 7651 */ 7652 7653 /* 7654 * Updating the WriteDoneHead interrupt: 7655 * 7656 * (a) Host Controller 7657 * 7658 * - First Host controller (HC) checks whether WDH bit 7659 * in the interrupt status register is cleared. 7660 * 7661 * - If WDH bit is cleared then HC writes new done head 7662 * list information into the HCCA done head field. 7663 * 7664 * - Set WDH bit in the interrupt status register. 7665 * 7666 * (b) Host Controller Driver (HCD) 7667 * 7668 * - First read the interrupt status register. The HCCA 7669 * done head and WDH bit may be set or may not be set 7670 * while reading the interrupt status register. 7671 * 7672 * - Read the HCCA done head list. By this time may be 7673 * HC has updated HCCA done head and WDH bit in ohci 7674 * interrupt status register. 7675 * 7676 * - If done head is non-null and if WDH bit is not set 7677 * then Host Controller has updated HCCA done head & 7678 * WDH bit in the interrupt stats register in between 7679 * reading the interrupt status register & HCCA done 7680 * head. In that case, definitely WDH bit will be set 7681 * in the interrupt status register & driver can take 7682 * it for granted. 7683 * 7684 * Now read the Interrupt Status & Interrupt enable register 7685 * to determine the exact interrupt events. 7686 */ 7687 intr = ohci_intr_sts->ohci_curr_intr_sts = 7688 (Get_OpReg(hcr_intr_status) & Get_OpReg(hcr_intr_enable)); 7689 7690 if (ohcip->ohci_hccap) { 7691 /* Sync HCCA area */ 7692 Sync_HCCA(ohcip); 7693 7694 /* Read and Save the HCCA DoneHead value */ 7695 done_head = ohci_intr_sts->ohci_curr_done_lst = 7696 (ohci_td_t *)(uintptr_t) 7697 (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) & 7698 HCCA_DONE_HEAD_MASK); 7699 7700 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7701 "ohci_intr: Done head! 0x%p", (void *)done_head); 7702 } 7703 7704 /* Update kstat values */ 7705 ohci_do_intrs_stats(ohcip, intr); 7706 7707 /* 7708 * Look at the HccaDoneHead, if it is a non-zero valid address, 7709 * a done list update interrupt is indicated. Otherwise, this 7710 * intr bit is cleared. 7711 */ 7712 if (ohci_check_done_head(ohcip, done_head) == USB_SUCCESS) { 7713 7714 /* Set the WriteDoneHead bit in the interrupt events */ 7715 intr |= HCR_INTR_WDH; 7716 } else { 7717 7718 /* Clear the WriteDoneHead bit */ 7719 intr &= ~HCR_INTR_WDH; 7720 } 7721 7722 /* 7723 * We could have gotten a spurious interrupts. If so, do not 7724 * claim it. This is quite possible on some architectures 7725 * where more than one PCI slots share the IRQs. If so, the 7726 * associated driver's interrupt routine may get called even 7727 * if the interrupt is not meant for them. 7728 * 7729 * By unclaiming the interrupt, the other driver gets chance 7730 * to service its interrupt. 7731 */ 7732 if (!intr) { 7733 7734 /* Reset the interrupt handler flag */ 7735 ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_HANDLING; 7736 7737 Set_OpReg(hcr_intr_enable, HCR_INTR_MIE); 7738 mutex_exit(&ohcip->ohci_int_mutex); 7739 return (DDI_INTR_UNCLAIMED); 7740 } 7741 7742 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7743 "Interrupt status 0x%x", intr); 7744 7745 /* 7746 * Check for Frame Number Overflow. 7747 */ 7748 if (intr & HCR_INTR_FNO) { 7749 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7750 "ohci_intr: Frame Number Overflow"); 7751 7752 ohci_handle_frame_number_overflow(ohcip); 7753 } 7754 7755 if (intr & HCR_INTR_SOF) { 7756 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7757 "ohci_intr: Start of Frame"); 7758 7759 /* Set ohci_sof_flag indicating SOF interrupt occurred */ 7760 ohcip->ohci_sof_flag = B_TRUE; 7761 7762 /* Disabel SOF interrupt */ 7763 Set_OpReg(hcr_intr_disable, HCR_INTR_SOF); 7764 7765 /* 7766 * Call cv_broadcast on every SOF interrupt to wakeup 7767 * all the threads that are waiting the SOF. Calling 7768 * cv_broadcast on every SOF has no effect even if no 7769 * threads are waiting for the SOF. 7770 */ 7771 cv_broadcast(&ohcip->ohci_SOF_cv); 7772 } 7773 7774 if (intr & HCR_INTR_SO) { 7775 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7776 "ohci_intr: Schedule overrun"); 7777 7778 ohcip->ohci_so_error++; 7779 } 7780 7781 if ((intr & HCR_INTR_WDH) && (done_head)) { 7782 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7783 "ohci_intr: Done Head"); 7784 7785 /* 7786 * Currently if we are processing one WriteDoneHead 7787 * interrupt and also if we switched to the polled 7788 * mode at least once during this time, then there 7789 * may be chance that Host Controller generates one 7790 * more Write DoneHead or Start of Frame interrupts 7791 * for the normal since the polled code clears WDH & 7792 * SOF interrupt bits before returning to the normal 7793 * mode. Under this condition, we must not clear the 7794 * HCCA done head field & also we must not clear WDH 7795 * interrupt bit in the interrupt status register. 7796 */ 7797 if (done_head == (ohci_td_t *)(uintptr_t) 7798 (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) & 7799 HCCA_DONE_HEAD_MASK)) { 7800 7801 /* Reset the done head to NULL */ 7802 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, NULL); 7803 } else { 7804 intr &= ~HCR_INTR_WDH; 7805 } 7806 7807 /* Clear the current done head field */ 7808 ohci_intr_sts->ohci_curr_done_lst = NULL; 7809 7810 ohci_traverse_done_list(ohcip, done_head); 7811 } 7812 7813 /* Process endpoint reclaimation list */ 7814 if (ohcip->ohci_reclaim_list) { 7815 ohci_handle_endpoint_reclaimation(ohcip); 7816 } 7817 7818 if (intr & HCR_INTR_RD) { 7819 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7820 "ohci_intr: Resume Detected"); 7821 } 7822 7823 if (intr & HCR_INTR_RHSC) { 7824 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7825 "ohci_intr: Root hub status change"); 7826 } 7827 7828 if (intr & HCR_INTR_OC) { 7829 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7830 "ohci_intr: Change ownership"); 7831 7832 } 7833 7834 if (intr & HCR_INTR_UE) { 7835 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7836 "ohci_intr: Unrecoverable error"); 7837 7838 ohci_handle_ue(ohcip); 7839 } 7840 7841 /* Acknowledge the interrupt */ 7842 Set_OpReg(hcr_intr_status, intr); 7843 7844 /* Clear the current interrupt event field */ 7845 ohci_intr_sts->ohci_curr_intr_sts = 0; 7846 7847 /* 7848 * Reset the following flag indicating exiting the interrupt 7849 * handler and this flag will be used in the polled mode to 7850 * do some extra processing. 7851 */ 7852 ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_HANDLING; 7853 7854 Set_OpReg(hcr_intr_enable, HCR_INTR_MIE); 7855 7856 /* 7857 * Read interrupt status register to make sure that any PIO 7858 * store to clear the ISR has made it on the PCI bus before 7859 * returning from its interrupt handler. 7860 */ 7861 (void) Get_OpReg(hcr_intr_status); 7862 7863 mutex_exit(&ohcip->ohci_int_mutex); 7864 7865 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7866 "Interrupt handling completed"); 7867 7868 return (DDI_INTR_CLAIMED); 7869 } 7870 7871 /* 7872 * Check whether done_head is a valid td point address. 7873 * It should be non-zero, 16-byte aligned, and fall in ohci_td_pool. 7874 */ 7875 static int 7876 ohci_check_done_head(ohci_state_t *ohcip, ohci_td_t *done_head) 7877 { 7878 uintptr_t lower, upper, headp; 7879 lower = ohcip->ohci_td_pool_cookie.dmac_address; 7880 upper = lower + ohcip->ohci_td_pool_cookie.dmac_size; 7881 headp = (uintptr_t)done_head; 7882 7883 if (headp && !(headp & ~HCCA_DONE_HEAD_MASK) && 7884 (headp >= lower) && (headp < upper)) { 7885 7886 return (USB_SUCCESS); 7887 } else { 7888 7889 return (USB_FAILURE); 7890 } 7891 } 7892 7893 /* 7894 * ohci_handle_missed_intr: 7895 * 7896 * Handle any ohci missed interrupts because of polled mode switch. 7897 */ 7898 static void 7899 ohci_handle_missed_intr(ohci_state_t *ohcip) 7900 { 7901 ohci_save_intr_sts_t *ohci_intr_sts = 7902 &ohcip->ohci_save_intr_sts; 7903 ohci_td_t *done_head; 7904 uint_t intr; 7905 7906 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7907 7908 /* 7909 * Check whether we have missed any ohci interrupts because 7910 * of the polled mode switch during previous ohci interrupt 7911 * handler execution. Only Write Done Head & SOF interrupts 7912 * saved in the polled mode. First process these interrupts 7913 * before processing actual interrupts that caused invocation 7914 * of ohci interrupt handler. 7915 */ 7916 if (!ohci_intr_sts->ohci_missed_intr_sts) { 7917 /* No interrupts are missed, simply return */ 7918 7919 return; 7920 } 7921 7922 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7923 "ohci_handle_missed_intr: Handle ohci missed interrupts"); 7924 7925 /* 7926 * The functionality and importance of critical code section 7927 * in the normal mode ohci interrupt handler & its usage in 7928 * the polled mode is explained below. 7929 * 7930 * (a) Normal mode: 7931 * 7932 * - Set the flag indicating that processing critical 7933 * code in ohci interrupt handler. 7934 * 7935 * - Process the missed ohci interrupts by copying the 7936 * miised interrupt events and done head list fields 7937 * information to the critical interrupt event & done 7938 * list fields. 7939 * 7940 * - Reset the missed ohci interrupt events & done head 7941 * list fields so that the new missed interrupt event 7942 * and done head list information can be saved. 7943 * 7944 * - All above steps will be executed with in critical 7945 * section of the interrupt handler.Then ohci missed 7946 * interrupt handler will be called to service missed 7947 * ohci interrupts. 7948 * 7949 * (b) Polled mode: 7950 * 7951 * - On entering the polled code,it checks for critical 7952 * section code execution within the normal mode ohci 7953 * interrupt handler. 7954 * 7955 * - If the critical section code is executing in normal 7956 * mode ohci interrupt handler and if copying of ohci 7957 * missed interrupt events & done head list fields to 7958 * the critical fields is finished then save the "any 7959 * missed interrupt events & done head list" because 7960 * of current polled mode switch into "critical missed 7961 * interrupt events & done list fields" instead actual 7962 * missed events and done list fields. 7963 * 7964 * - Otherwise save "any missed interrupt events & done 7965 * list" because of this current polled mode switch 7966 * in the actual missed interrupt events & done head 7967 * list fields. 7968 */ 7969 7970 /* 7971 * Set flag indicating that interrupt handler is processing 7972 * critical interrupt code, so that polled mode code checks 7973 * for this condition & will do extra processing as explained 7974 * above in order to aviod the race conditions. 7975 */ 7976 ohci_intr_sts->ohci_intr_flag |= OHCI_INTR_CRITICAL; 7977 ohci_intr_sts->ohci_critical_intr_sts |= 7978 ohci_intr_sts->ohci_missed_intr_sts; 7979 7980 if (ohci_intr_sts->ohci_missed_done_lst) { 7981 7982 ohci_intr_sts->ohci_critical_done_lst = 7983 ohci_intr_sts->ohci_missed_done_lst; 7984 } 7985 7986 ohci_intr_sts->ohci_missed_intr_sts = 0; 7987 ohci_intr_sts->ohci_missed_done_lst = NULL; 7988 ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_CRITICAL; 7989 7990 intr = ohci_intr_sts->ohci_critical_intr_sts; 7991 done_head = ohci_intr_sts->ohci_critical_done_lst; 7992 7993 if (intr & HCR_INTR_SOF) { 7994 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7995 "ohci_handle_missed_intr: Start of Frame"); 7996 7997 /* 7998 * Call cv_broadcast on every SOF interrupt to wakeup 7999 * all the threads that are waiting the SOF. Calling 8000 * cv_broadcast on every SOF has no effect even if no 8001 * threads are waiting for the SOF. 8002 */ 8003 cv_broadcast(&ohcip->ohci_SOF_cv); 8004 } 8005 8006 if ((intr & HCR_INTR_WDH) && (done_head)) { 8007 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8008 "ohci_handle_missed_intr: Done Head"); 8009 8010 /* Clear the critical done head field */ 8011 ohci_intr_sts->ohci_critical_done_lst = NULL; 8012 8013 ohci_traverse_done_list(ohcip, done_head); 8014 } 8015 8016 /* Clear the critical interrupt event field */ 8017 ohci_intr_sts->ohci_critical_intr_sts = 0; 8018 } 8019 8020 8021 /* 8022 * ohci_handle_ue: 8023 * 8024 * Handling of Unrecoverable Error interrupt (UE). 8025 */ 8026 static void 8027 ohci_handle_ue(ohci_state_t *ohcip) 8028 { 8029 usb_frame_number_t before_frame_number, after_frame_number; 8030 8031 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8032 8033 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8034 "ohci_handle_ue: Handling of UE interrupt"); 8035 8036 /* 8037 * First check whether current UE error occured due to USB or 8038 * due to some other subsystem. This can be verified by reading 8039 * usb frame numbers before & after a delay of few milliseconds. 8040 * If usb frame number read after delay is greater than the one 8041 * read before delay, then, USB subsystem is fine. In this case, 8042 * disable UE error interrupt and return without shutdowning the 8043 * USB subsystem. 8044 * 8045 * Otherwise, if usb frame number read after delay is less than 8046 * or equal to one read before the delay, then, current UE error 8047 * occured from USB susbsystem. In this case,go ahead with actual 8048 * UE error recovery procedure. 8049 * 8050 * Get the current usb frame number before waiting for few 8051 * milliseconds. 8052 */ 8053 before_frame_number = ohci_get_current_frame_number(ohcip); 8054 8055 /* Wait for few milliseconds */ 8056 drv_usecwait(OHCI_TIMEWAIT); 8057 8058 /* 8059 * Get the current usb frame number after waiting for 8060 * milliseconds. 8061 */ 8062 after_frame_number = ohci_get_current_frame_number(ohcip); 8063 8064 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8065 "ohci_handle_ue: Before Frm No 0x%llx After Frm No 0x%llx", 8066 before_frame_number, after_frame_number); 8067 8068 if (after_frame_number > before_frame_number) { 8069 8070 /* Disable UE interrupt */ 8071 Set_OpReg(hcr_intr_disable, HCR_INTR_UE); 8072 8073 return; 8074 } 8075 8076 /* 8077 * This UE is due to USB hardware error. Reset ohci controller 8078 * and reprogram to bring it back to functional state. 8079 */ 8080 if ((ohci_do_soft_reset(ohcip)) != USB_SUCCESS) { 8081 USB_DPRINTF_L0(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8082 "Unrecoverable USB Hardware Error"); 8083 8084 /* Disable UE interrupt */ 8085 Set_OpReg(hcr_intr_disable, HCR_INTR_UE); 8086 8087 /* Set host controller soft state to error */ 8088 ohcip->ohci_hc_soft_state = OHCI_CTLR_ERROR_STATE; 8089 } 8090 } 8091 8092 8093 /* 8094 * ohci_handle_frame_number_overflow: 8095 * 8096 * Update software based usb frame number part on every frame number 8097 * overflow interrupt. 8098 * 8099 * NOTE: This function is also called from POLLED MODE. 8100 * 8101 * Refer ohci spec 1.0a, section 5.3, page 81 for more details. 8102 */ 8103 void 8104 ohci_handle_frame_number_overflow(ohci_state_t *ohcip) 8105 { 8106 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8107 "ohci_handle_frame_number_overflow:"); 8108 8109 ohcip->ohci_fno += (0x10000 - 8110 (((Get_HCCA(ohcip->ohci_hccap->HccaFrameNo) & 8111 0xFFFF) ^ ohcip->ohci_fno) & 0x8000)); 8112 8113 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8114 "ohci_handle_frame_number_overflow:" 8115 "Frame Number Higher Part 0x%llx\n", ohcip->ohci_fno); 8116 } 8117 8118 8119 /* 8120 * ohci_handle_endpoint_reclaimation: 8121 * 8122 * Reclamation of Host Controller (HC) Endpoint Descriptors (ED). 8123 */ 8124 static void 8125 ohci_handle_endpoint_reclaimation(ohci_state_t *ohcip) 8126 { 8127 usb_frame_number_t current_frame_number; 8128 usb_frame_number_t endpoint_frame_number; 8129 ohci_ed_t *reclaim_ed; 8130 8131 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8132 "ohci_handle_endpoint_reclaimation:"); 8133 8134 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8135 8136 current_frame_number = ohci_get_current_frame_number(ohcip); 8137 8138 /* 8139 * Deallocate all Endpoint Descriptors (ED) which are on the 8140 * reclaimation list. These ED's are already removed from the 8141 * interrupt lattice tree. 8142 */ 8143 while (ohcip->ohci_reclaim_list) { 8144 reclaim_ed = ohcip->ohci_reclaim_list; 8145 8146 endpoint_frame_number = (usb_frame_number_t)(uintptr_t) 8147 (OHCI_LOOKUP_ID(Get_ED(reclaim_ed->hced_reclaim_frame))); 8148 8149 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8150 "ohci_handle_endpoint_reclaimation:" 8151 "current frame number 0x%llx endpoint frame number 0x%llx", 8152 current_frame_number, endpoint_frame_number); 8153 8154 /* 8155 * Deallocate current endpoint only if endpoint's usb frame 8156 * number is less than or equal to current usb frame number. 8157 * 8158 * If endpoint's usb frame number is greater than the current 8159 * usb frame number, ignore rest of the endpoints in the list 8160 * since rest of the endpoints are inserted into the reclaim 8161 * list later than the current reclaim endpoint. 8162 */ 8163 if (endpoint_frame_number > current_frame_number) { 8164 break; 8165 } 8166 8167 /* Get the next endpoint from the rec. list */ 8168 ohcip->ohci_reclaim_list = ohci_ed_iommu_to_cpu(ohcip, 8169 Get_ED(reclaim_ed->hced_reclaim_next)); 8170 8171 /* Free 32bit ID */ 8172 OHCI_FREE_ID((uint32_t)Get_ED(reclaim_ed->hced_reclaim_frame)); 8173 8174 /* Deallocate the endpoint */ 8175 ohci_deallocate_ed(ohcip, reclaim_ed); 8176 } 8177 } 8178 8179 8180 /* 8181 * ohci_traverse_done_list: 8182 */ 8183 static void 8184 ohci_traverse_done_list( 8185 ohci_state_t *ohcip, 8186 ohci_td_t *head_done_list) 8187 { 8188 uint_t state; /* TD state */ 8189 ohci_td_t *td, *old_td; /* TD pointers */ 8190 usb_cr_t error; /* Error from TD */ 8191 ohci_trans_wrapper_t *tw = NULL; /* Transfer wrapper */ 8192 ohci_pipe_private_t *pp = NULL; /* Pipe private field */ 8193 8194 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8195 "ohci_traverse_done_list:"); 8196 8197 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8198 8199 /* Sync ED and TD pool */ 8200 Sync_ED_TD_Pool(ohcip); 8201 8202 /* Reverse the done list */ 8203 td = ohci_reverse_done_list(ohcip, head_done_list); 8204 8205 /* Traverse the list of transfer descriptors */ 8206 while (td) { 8207 /* Check for TD state */ 8208 state = Get_TD(td->hctd_state); 8209 8210 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8211 "ohci_traverse_done_list:\n\t" 8212 "td = 0x%p state = 0x%x", (void *)td, state); 8213 8214 /* 8215 * Obtain the transfer wrapper only if the TD is 8216 * not marked as RECLAIM. 8217 * 8218 * A TD that is marked as RECLAIM has had its DMA 8219 * mappings, ED, TD and pipe private structure are 8220 * ripped down. Just deallocate this TD. 8221 */ 8222 if (state != HC_TD_RECLAIM) { 8223 8224 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID( 8225 (uint32_t)Get_TD(td->hctd_trans_wrapper)); 8226 8227 ASSERT(tw != NULL); 8228 8229 pp = tw->tw_pipe_private; 8230 8231 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8232 "ohci_traverse_done_list: PP = 0x%p TW = 0x%p", 8233 pp, tw); 8234 } 8235 8236 /* 8237 * Don't process the TD if its state is marked as 8238 * either RECLAIM or TIMEOUT. 8239 * 8240 * A TD that is marked as TIMEOUT has already been 8241 * processed by TD timeout handler & client driver 8242 * has been informed through exception callback. 8243 */ 8244 if ((state != HC_TD_RECLAIM) && (state != HC_TD_TIMEOUT)) { 8245 8246 /* Look at the error status */ 8247 error = ohci_parse_error(ohcip, td); 8248 8249 if (error == USB_CR_OK) { 8250 ohci_handle_normal_td(ohcip, td, tw); 8251 } else { 8252 /* handle the error condition */ 8253 ohci_handle_error(ohcip, td, error); 8254 } 8255 } else { 8256 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8257 "ohci_traverse_done_list: TD State = %d", state); 8258 } 8259 8260 /* 8261 * Save a pointer to the current transfer descriptor 8262 */ 8263 old_td = td; 8264 8265 td = ohci_td_iommu_to_cpu(ohcip, Get_TD(td->hctd_next_td)); 8266 8267 /* Deallocate this transfer descriptor */ 8268 ohci_deallocate_td(ohcip, old_td); 8269 8270 /* 8271 * Deallocate the transfer wrapper if there are no more 8272 * TD's for the transfer wrapper. ohci_deallocate_tw_resources() 8273 * will not deallocate the tw for a periodic endpoint 8274 * since it will always have a TD attached to it. 8275 * 8276 * Do not deallocate the TW if it is a isoc or intr pipe in. 8277 * The tw's are reused. 8278 * 8279 * An TD that is marked as reclaim doesn't have a pipe 8280 * or a TW associated with it anymore so don't call this 8281 * function. 8282 */ 8283 if (state != HC_TD_RECLAIM) { 8284 ASSERT(tw != NULL); 8285 ohci_deallocate_tw_resources(ohcip, pp, tw); 8286 } 8287 } 8288 } 8289 8290 8291 /* 8292 * ohci_reverse_done_list: 8293 * 8294 * Reverse the order of the Transfer Descriptor (TD) Done List. 8295 */ 8296 static ohci_td_t * 8297 ohci_reverse_done_list( 8298 ohci_state_t *ohcip, 8299 ohci_td_t *head_done_list) 8300 { 8301 ohci_td_t *cpu_new_tail, *cpu_new_head, *cpu_save; 8302 8303 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8304 "ohci_reverse_done_list:"); 8305 8306 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8307 ASSERT(head_done_list != NULL); 8308 8309 /* At first, both the tail and head pointers point to the same elem */ 8310 cpu_new_tail = cpu_new_head = 8311 ohci_td_iommu_to_cpu(ohcip, (uintptr_t)head_done_list); 8312 8313 /* See if the list has only one element */ 8314 if (Get_TD(cpu_new_head->hctd_next_td) == NULL) { 8315 8316 return (cpu_new_head); 8317 } 8318 8319 /* Advance the head pointer */ 8320 cpu_new_head = (ohci_td_t *) 8321 ohci_td_iommu_to_cpu(ohcip, Get_TD(cpu_new_head->hctd_next_td)); 8322 8323 /* The new tail now points to nothing */ 8324 Set_TD(cpu_new_tail->hctd_next_td, NULL); 8325 8326 cpu_save = (ohci_td_t *) 8327 ohci_td_iommu_to_cpu(ohcip, Get_TD(cpu_new_head->hctd_next_td)); 8328 8329 /* Reverse the list and store the pointers as CPU addresses */ 8330 while (cpu_save) { 8331 Set_TD(cpu_new_head->hctd_next_td, 8332 ohci_td_cpu_to_iommu(ohcip, cpu_new_tail)); 8333 8334 cpu_new_tail = cpu_new_head; 8335 cpu_new_head = cpu_save; 8336 8337 cpu_save = (ohci_td_t *) 8338 ohci_td_iommu_to_cpu(ohcip, 8339 Get_TD(cpu_new_head->hctd_next_td)); 8340 } 8341 8342 Set_TD(cpu_new_head->hctd_next_td, 8343 ohci_td_cpu_to_iommu(ohcip, cpu_new_tail)); 8344 8345 return (cpu_new_head); 8346 } 8347 8348 8349 /* 8350 * ohci_parse_error: 8351 * 8352 * Parse the result for any errors. 8353 */ 8354 static usb_cr_t 8355 ohci_parse_error( 8356 ohci_state_t *ohcip, 8357 ohci_td_t *td) 8358 { 8359 uint_t ctrl; 8360 usb_ep_descr_t *eptd; 8361 ohci_trans_wrapper_t *tw; 8362 ohci_pipe_private_t *pp; 8363 uint_t flag; 8364 usb_cr_t error; 8365 8366 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8367 "ohci_parse_error:"); 8368 8369 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8370 8371 ASSERT(td != NULL); 8372 8373 /* Obtain the transfer wrapper from the TD */ 8374 tw = (ohci_trans_wrapper_t *) 8375 OHCI_LOOKUP_ID((uint32_t)Get_TD(td->hctd_trans_wrapper)); 8376 8377 ASSERT(tw != NULL); 8378 8379 /* Obtain the pipe private structure */ 8380 pp = tw->tw_pipe_private; 8381 8382 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8383 "ohci_parse_error: PP 0x%p TW 0x%p", pp, tw); 8384 8385 eptd = &pp->pp_pipe_handle->p_ep; 8386 8387 ctrl = (uint_t)Get_TD(td->hctd_ctrl) & (uint32_t)HC_TD_CC; 8388 8389 /* 8390 * Check the condition code of completed TD and report errors 8391 * if any. This checking will be done both for the general and 8392 * the isochronous TDs. 8393 */ 8394 if ((error = ohci_check_for_error(ohcip, pp, tw, td, ctrl)) != 8395 USB_CR_OK) { 8396 flag = OHCI_REMOVE_XFER_ALWAYS; 8397 } else { 8398 flag = OHCI_REMOVE_XFER_IFLAST; 8399 } 8400 8401 /* Stop the the transfer timer */ 8402 ohci_stop_xfer_timer(ohcip, tw, flag); 8403 8404 /* 8405 * The isochronous endpoint needs additional error checking 8406 * and special processing. 8407 */ 8408 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) == 8409 USB_EP_ATTR_ISOCH) { 8410 8411 ohci_parse_isoc_error(ohcip, pp, tw, td); 8412 8413 /* always reset error */ 8414 error = USB_CR_OK; 8415 } 8416 8417 return (error); 8418 } 8419 8420 8421 /* 8422 * ohci_parse_isoc_error: 8423 * 8424 * Check for any errors in the isochronous data packets. Also fillup 8425 * the status for each of the isochrnous data packets. 8426 */ 8427 void 8428 ohci_parse_isoc_error( 8429 ohci_state_t *ohcip, 8430 ohci_pipe_private_t *pp, 8431 ohci_trans_wrapper_t *tw, 8432 ohci_td_t *td) 8433 { 8434 usb_isoc_req_t *isoc_reqp; 8435 usb_isoc_pkt_descr_t *isoc_pkt_descr; 8436 uint_t toggle = 0, fc, ctrl, psw; 8437 int i; 8438 8439 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8440 "ohci_parse_isoc_error: td 0x%p", td); 8441 8442 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8443 8444 fc = ((uint_t)Get_TD(td->hctd_ctrl) & 8445 HC_ITD_FC) >> HC_ITD_FC_SHIFT; 8446 8447 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 8448 "ohci_parse_isoc_error: frame count %d", fc); 8449 8450 /* 8451 * Get the address of current usb isochronous request 8452 * and array of packet descriptors. 8453 */ 8454 isoc_reqp = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp; 8455 isoc_pkt_descr = isoc_reqp->isoc_pkt_descr; 8456 isoc_pkt_descr += tw->tw_pkt_idx; 8457 8458 for (i = 0; i <= fc; i++) { 8459 8460 psw = Get_TD(td->hctd_offsets[i / 2]); 8461 8462 if (toggle) { 8463 ctrl = psw & HC_ITD_ODD_OFFSET; 8464 toggle = 0; 8465 } else { 8466 ctrl = (psw & HC_ITD_EVEN_OFFSET) << 8467 HC_ITD_OFFSET_SHIFT; 8468 toggle = 1; 8469 } 8470 8471 isoc_pkt_descr->isoc_pkt_actual_length = 8472 (ctrl >> HC_ITD_OFFSET_SHIFT) & HC_ITD_OFFSET_ADDR; 8473 8474 ctrl = (uint_t)(ctrl & (uint32_t)HC_TD_CC); 8475 8476 /* Write the status of isoc data packet */ 8477 isoc_pkt_descr->isoc_pkt_status = 8478 ohci_check_for_error(ohcip, pp, tw, td, ctrl); 8479 8480 if (isoc_pkt_descr->isoc_pkt_status) { 8481 /* Increment isoc data packet error count */ 8482 isoc_reqp->isoc_error_count++; 8483 } 8484 8485 /* 8486 * Get the address of next isoc data packet descriptor. 8487 */ 8488 isoc_pkt_descr++; 8489 } 8490 tw->tw_pkt_idx = tw->tw_pkt_idx + fc + 1; 8491 8492 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 8493 "ohci_parse_isoc_error: tw_pkt_idx %d", tw->tw_pkt_idx); 8494 8495 } 8496 8497 8498 /* 8499 * ohci_check_for_error: 8500 * 8501 * Check for any errors. 8502 */ 8503 static usb_cr_t 8504 ohci_check_for_error( 8505 ohci_state_t *ohcip, 8506 ohci_pipe_private_t *pp, 8507 ohci_trans_wrapper_t *tw, 8508 ohci_td_t *td, 8509 uint_t ctrl) 8510 { 8511 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 8512 uchar_t ep_attrs = ph->p_ep.bmAttributes; 8513 usb_cr_t error = USB_CR_OK; 8514 usb_req_attrs_t xfer_attrs; 8515 8516 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8517 "ohci_check_for_error: td = 0x%p ctrl = 0x%x", 8518 td, ctrl); 8519 8520 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8521 8522 switch (ctrl) { 8523 case HC_TD_CC_NO_E: 8524 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8525 "ohci_check_for_error: No Error"); 8526 error = USB_CR_OK; 8527 break; 8528 case HC_TD_CC_CRC: 8529 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8530 "ohci_check_for_error: CRC error"); 8531 error = USB_CR_CRC; 8532 break; 8533 case HC_TD_CC_BS: 8534 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8535 "ohci_check_for_error: Bit stuffing"); 8536 error = USB_CR_BITSTUFFING; 8537 break; 8538 case HC_TD_CC_DTM: 8539 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8540 "ohci_check_for_error: Data Toggle Mismatch"); 8541 error = USB_CR_DATA_TOGGLE_MM; 8542 break; 8543 case HC_TD_CC_STALL: 8544 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8545 "ohci_check_for_error: Stall"); 8546 error = USB_CR_STALL; 8547 break; 8548 case HC_TD_CC_DNR: 8549 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8550 "ohci_check_for_error: Device not responding"); 8551 error = USB_CR_DEV_NOT_RESP; 8552 break; 8553 case HC_TD_CC_PCF: 8554 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8555 "ohci_check_for_error: PID check failure"); 8556 error = USB_CR_PID_CHECKFAILURE; 8557 break; 8558 case HC_TD_CC_UPID: 8559 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8560 "ohci_check_for_error: Unexpected PID"); 8561 error = USB_CR_UNEXP_PID; 8562 break; 8563 case HC_TD_CC_DO: 8564 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8565 "ohci_check_for_error: Data overrrun"); 8566 error = USB_CR_DATA_OVERRUN; 8567 break; 8568 case HC_TD_CC_DU: 8569 /* 8570 * Check whether short packets are acceptable. 8571 * If so don't report error to client drivers 8572 * and restart the endpoint. Otherwise report 8573 * data underrun error to client driver. 8574 */ 8575 xfer_attrs = ohci_get_xfer_attrs(ohcip, pp, tw); 8576 8577 if (xfer_attrs & USB_ATTRS_SHORT_XFER_OK) { 8578 error = USB_CR_OK; 8579 if ((ep_attrs & USB_EP_ATTR_MASK) != 8580 USB_EP_ATTR_ISOCH) { 8581 /* 8582 * Cleanup the remaining resources that may have 8583 * been allocated for this transfer. 8584 */ 8585 if (ohci_cleanup_data_underrun(ohcip, pp, tw, 8586 td) == USB_SUCCESS) { 8587 /* Clear the halt bit */ 8588 Set_ED(pp->pp_ept->hced_headp, 8589 (Get_ED(pp->pp_ept->hced_headp) & 8590 ~HC_EPT_Halt)); 8591 } else { 8592 error = USB_CR_UNSPECIFIED_ERR; 8593 } 8594 } 8595 } else { 8596 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8597 "ohci_check_for_error: Data underrun"); 8598 8599 error = USB_CR_DATA_UNDERRUN; 8600 } 8601 8602 break; 8603 case HC_TD_CC_BO: 8604 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8605 "ohci_check_for_error: Buffer overrun"); 8606 error = USB_CR_BUFFER_OVERRUN; 8607 break; 8608 case HC_TD_CC_BU: 8609 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8610 "ohci_check_for_error: Buffer underrun"); 8611 error = USB_CR_BUFFER_UNDERRUN; 8612 break; 8613 case HC_TD_CC_NA: 8614 default: 8615 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8616 "ohci_check_for_error: Not accessed"); 8617 error = USB_CR_NOT_ACCESSED; 8618 break; 8619 } 8620 8621 if (error) { 8622 uint_t hced_ctrl = Get_ED(pp->pp_ept->hced_ctrl); 8623 8624 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8625 "ohci_check_for_error: Error %d Device address %d " 8626 "Endpoint number %d", error, (hced_ctrl & HC_EPT_FUNC), 8627 ((hced_ctrl & HC_EPT_EP) >> HC_EPT_EP_SHFT)); 8628 } 8629 8630 return (error); 8631 } 8632 8633 8634 /* 8635 * ohci_handle_error: 8636 * 8637 * Inform USBA about occured transaction errors by calling the USBA callback 8638 * routine. 8639 */ 8640 static void 8641 ohci_handle_error( 8642 ohci_state_t *ohcip, 8643 ohci_td_t *td, 8644 usb_cr_t error) 8645 { 8646 ohci_trans_wrapper_t *tw; 8647 usba_pipe_handle_data_t *ph; 8648 ohci_pipe_private_t *pp; 8649 mblk_t *mp = NULL; 8650 size_t length = 0; 8651 uchar_t attributes; 8652 usb_intr_req_t *curr_intr_reqp; 8653 8654 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8655 "ohci_handle_error: error = 0x%x", error); 8656 8657 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8658 8659 ASSERT(td != NULL); 8660 8661 /* Print the values in the td */ 8662 ohci_print_td(ohcip, td); 8663 8664 /* Obtain the transfer wrapper from the TD */ 8665 tw = (ohci_trans_wrapper_t *) 8666 OHCI_LOOKUP_ID((uint32_t)Get_TD(td->hctd_trans_wrapper)); 8667 8668 ASSERT(tw != NULL); 8669 8670 /* Obtain the pipe private structure */ 8671 pp = tw->tw_pipe_private; 8672 8673 ph = tw->tw_pipe_private->pp_pipe_handle; 8674 attributes = ph->p_ep.bmAttributes & USB_EP_ATTR_MASK; 8675 8676 /* 8677 * Special error handling 8678 */ 8679 if (tw->tw_direction == HC_TD_IN) { 8680 8681 switch (attributes) { 8682 case USB_EP_ATTR_CONTROL: 8683 if (((ph->p_ep.bmAttributes & 8684 USB_EP_ATTR_MASK) == 8685 USB_EP_ATTR_CONTROL) && 8686 (Get_TD(td->hctd_ctrl_phase) == 8687 OHCI_CTRL_SETUP_PHASE)) { 8688 8689 break; 8690 } 8691 /* FALLTHROUGH */ 8692 case USB_EP_ATTR_BULK: 8693 /* 8694 * Call ohci_sendup_td_message 8695 * to send message to upstream. 8696 */ 8697 ohci_sendup_td_message(ohcip, pp, tw, td, error); 8698 8699 return; 8700 case USB_EP_ATTR_INTR: 8701 curr_intr_reqp = 8702 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 8703 8704 if (curr_intr_reqp->intr_attributes & 8705 USB_ATTRS_ONE_XFER) { 8706 8707 ohci_handle_one_xfer_completion(ohcip, tw); 8708 } 8709 8710 /* Decrement periodic in request count */ 8711 pp->pp_cur_periodic_req_cnt--; 8712 break; 8713 case USB_EP_ATTR_ISOCH: 8714 default: 8715 break; 8716 } 8717 } else { 8718 switch (attributes) { 8719 case USB_EP_ATTR_BULK: 8720 case USB_EP_ATTR_INTR: 8721 /* 8722 * If "CurrentBufferPointer" of Transfer 8723 * Descriptor (TD) is not equal to zero, 8724 * then we sent less data to the device 8725 * than requested by client. In that case, 8726 * return the mblk after updating the 8727 * data->r_ptr. 8728 */ 8729 if (Get_TD(td->hctd_cbp)) { 8730 usb_opaque_t xfer_reqp = tw->tw_curr_xfer_reqp; 8731 size_t residue; 8732 8733 residue = ohci_get_td_residue(ohcip, td); 8734 length = Get_TD(td->hctd_xfer_offs) + 8735 Get_TD(td->hctd_xfer_len) - residue; 8736 8737 USB_DPRINTF_L2(PRINT_MASK_INTR, 8738 ohcip->ohci_log_hdl, 8739 "ohci_handle_error: requested data %lu " 8740 "sent data %lu", tw->tw_length, length); 8741 8742 if (attributes == USB_EP_ATTR_BULK) { 8743 mp = (mblk_t *)((usb_bulk_req_t *) 8744 (xfer_reqp))->bulk_data; 8745 } else { 8746 mp = (mblk_t *)((usb_intr_req_t *) 8747 (xfer_reqp))->intr_data; 8748 } 8749 8750 /* Increment the read pointer */ 8751 mp->b_rptr = mp->b_rptr + length; 8752 } 8753 break; 8754 default: 8755 break; 8756 } 8757 } 8758 8759 /* 8760 * Callback the client with the 8761 * failure reason. 8762 */ 8763 ohci_hcdi_callback(ph, tw, error); 8764 8765 /* Check anybody is waiting for transfers completion event */ 8766 ohci_check_for_transfers_completion(ohcip, pp); 8767 } 8768 8769 /* 8770 * ohci_cleanup_data_underrun: 8771 * 8772 * Cleans up resources when a short xfer occurs 8773 */ 8774 static int 8775 ohci_cleanup_data_underrun( 8776 ohci_state_t *ohcip, 8777 ohci_pipe_private_t *pp, 8778 ohci_trans_wrapper_t *tw, 8779 ohci_td_t *td) 8780 { 8781 ohci_td_t *next_td; 8782 ohci_td_t *last_td; 8783 ohci_td_t *temp_td; 8784 uint32_t last_td_addr; 8785 uint_t hced_head; 8786 8787 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8788 "ohci_cleanup_data_underrun: td 0x%p, tw 0x%p", td, tw); 8789 8790 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8791 ASSERT(tw->tw_hctd_head == td); 8792 8793 /* Check if this TD is the last td in the tw */ 8794 last_td = tw->tw_hctd_tail; 8795 if (td == last_td) { 8796 /* There is no need for cleanup */ 8797 return (USB_SUCCESS); 8798 } 8799 8800 /* 8801 * Make sure the ED is halted before we change any td's. 8802 * If for some reason it is not halted, return error to client 8803 * driver so they can reset the port. 8804 */ 8805 hced_head = Get_ED(pp->pp_ept->hced_headp); 8806 if (!(hced_head & HC_EPT_Halt)) { 8807 uint_t hced_ctrl = Get_ED(pp->pp_ept->hced_ctrl); 8808 8809 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8810 "ohci_cleanup_data_underrun: Unable to clean up a short " 8811 "xfer error. Client might send/receive irrelevant data." 8812 " Device address %d Endpoint number %d", 8813 (hced_ctrl & HC_EPT_FUNC), 8814 ((hced_ctrl & HC_EPT_EP) >> HC_EPT_EP_SHFT)); 8815 8816 Set_ED(pp->pp_ept->hced_headp, hced_head | HC_EPT_Halt); 8817 8818 return (USB_FAILURE); 8819 } 8820 8821 /* 8822 * Get the address of the first td of the next transfer (tw). 8823 * This td, may currently be a dummy td, but when a new request 8824 * arrives, it will be transformed into a regular td. 8825 */ 8826 last_td_addr = Get_TD(last_td->hctd_next_td); 8827 /* Set ED head to this last td */ 8828 Set_ED(pp->pp_ept->hced_headp, 8829 (last_td_addr & HC_EPT_TD_HEAD) | 8830 (hced_head & ~HC_EPT_TD_HEAD)); 8831 8832 /* 8833 * Start removing all the unused TD's from the TW, 8834 * but keep the first one. 8835 */ 8836 tw->tw_hctd_tail = td; 8837 8838 /* 8839 * Get the last_td, the next td in the tw list. 8840 * Afterwards completely disassociate the current td from other tds 8841 */ 8842 next_td = (ohci_td_t *)ohci_td_iommu_to_cpu(ohcip, 8843 Get_TD(td->hctd_tw_next_td)); 8844 Set_TD(td->hctd_tw_next_td, NULL); 8845 8846 /* 8847 * Iterate down the tw list and deallocate them 8848 */ 8849 while (next_td != NULL) { 8850 tw->tw_num_tds--; 8851 /* Disassociate this td from it's TW and set to RECLAIM */ 8852 Set_TD(next_td->hctd_trans_wrapper, NULL); 8853 Set_TD(next_td->hctd_state, HC_TD_RECLAIM); 8854 8855 temp_td = next_td; 8856 8857 next_td = (ohci_td_t *)ohci_td_iommu_to_cpu(ohcip, 8858 Get_TD(next_td->hctd_tw_next_td)); 8859 8860 ohci_deallocate_td(ohcip, temp_td); 8861 } 8862 8863 ASSERT(tw->tw_num_tds == 1); 8864 8865 return (USB_SUCCESS); 8866 } 8867 8868 /* 8869 * ohci_handle_normal_td: 8870 */ 8871 static void 8872 ohci_handle_normal_td( 8873 ohci_state_t *ohcip, 8874 ohci_td_t *td, 8875 ohci_trans_wrapper_t *tw) 8876 { 8877 ohci_pipe_private_t *pp; /* Pipe private field */ 8878 8879 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8880 "ohci_handle_normal_td:"); 8881 8882 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8883 ASSERT(tw != NULL); 8884 8885 /* Obtain the pipe private structure */ 8886 pp = tw->tw_pipe_private; 8887 8888 (*tw->tw_handle_td)(ohcip, pp, tw, 8889 td, tw->tw_handle_callback_value); 8890 8891 /* Check anybody is waiting for transfers completion event */ 8892 ohci_check_for_transfers_completion(ohcip, pp); 8893 } 8894 8895 8896 /* 8897 * ohci_handle_ctrl_td: 8898 * 8899 * Handle a control Transfer Descriptor (TD). 8900 */ 8901 /* ARGSUSED */ 8902 static void 8903 ohci_handle_ctrl_td( 8904 ohci_state_t *ohcip, 8905 ohci_pipe_private_t *pp, 8906 ohci_trans_wrapper_t *tw, 8907 ohci_td_t *td, 8908 void *tw_handle_callback_value) 8909 { 8910 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 8911 8912 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8913 "ohci_handle_ctrl_td: pp = 0x%p tw = 0x%p td = 0x%p state = 0x%x", 8914 (void *)pp, (void *)tw, (void *)td, Get_TD(td->hctd_ctrl_phase)); 8915 8916 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8917 8918 /* 8919 * Check which control transfer phase got completed. 8920 */ 8921 tw->tw_num_tds--; 8922 switch (Get_TD(td->hctd_ctrl_phase)) { 8923 case OHCI_CTRL_SETUP_PHASE: 8924 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8925 "Setup complete: pp 0x%p td 0x%p", (void *)pp, (void *)td); 8926 8927 break; 8928 case OHCI_CTRL_DATA_PHASE: 8929 /* 8930 * If "CurrentBufferPointer" of Transfer Descriptor (TD) 8931 * is not equal to zero, then we received less data from 8932 * the device than requested by us. In that case, get the 8933 * actual received data size. 8934 */ 8935 if (Get_TD(td->hctd_cbp)) { 8936 size_t length, residue; 8937 8938 residue = ohci_get_td_residue(ohcip, td); 8939 length = Get_TD(td->hctd_xfer_offs) + 8940 Get_TD(td->hctd_xfer_len) - residue; 8941 8942 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8943 "ohci_handle_ctrl_qtd: requested data %lu " 8944 "received data %lu", tw->tw_length, length); 8945 8946 /* Save actual received data length */ 8947 tw->tw_length = length; 8948 } 8949 8950 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8951 "Data complete: pp 0x%p td 0x%p", 8952 (void *)pp, (void *)td); 8953 8954 break; 8955 case OHCI_CTRL_STATUS_PHASE: 8956 if ((tw->tw_length != 0) && 8957 (tw->tw_direction == HC_TD_IN)) { 8958 8959 /* 8960 * Call ohci_sendup_td_message 8961 * to send message to upstream. 8962 */ 8963 ohci_sendup_td_message(ohcip, 8964 pp, tw, td, USB_CR_OK); 8965 } else { 8966 ohci_do_byte_stats(ohcip, 8967 tw->tw_length - OHCI_MAX_TD_BUF_SIZE, 8968 ph->p_ep.bmAttributes, 8969 ph->p_ep.bEndpointAddress); 8970 8971 ohci_hcdi_callback(ph, tw, USB_CR_OK); 8972 } 8973 8974 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8975 "Status complete: pp 0x%p td 0x%p", (void *)pp, (void *)td); 8976 8977 break; 8978 } 8979 } 8980 8981 8982 /* 8983 * ohci_handle_bulk_td: 8984 * 8985 * Handle a bulk Transfer Descriptor (TD). 8986 */ 8987 /* ARGSUSED */ 8988 static void 8989 ohci_handle_bulk_td( 8990 ohci_state_t *ohcip, 8991 ohci_pipe_private_t *pp, 8992 ohci_trans_wrapper_t *tw, 8993 ohci_td_t *td, 8994 void *tw_handle_callback_value) 8995 { 8996 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 8997 usb_ep_descr_t *eptd = &ph->p_ep; 8998 8999 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9000 "ohci_handle_bulk_td:"); 9001 9002 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9003 9004 /* 9005 * Decrement the TDs counter and check whether all the bulk 9006 * data has been send or received. If TDs counter reaches 9007 * zero then inform client driver about completion current 9008 * bulk request. Other wise wait for completion of other bulk 9009 * TDs or transactions on this pipe. 9010 */ 9011 if (--tw->tw_num_tds != 0) { 9012 9013 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9014 "ohci_handle_bulk_td: Number of TDs %d", tw->tw_num_tds); 9015 9016 return; 9017 } 9018 9019 /* 9020 * If this is a bulk in pipe, return the data to the client. 9021 * For a bulk out pipe, there is no need to do anything. 9022 */ 9023 if ((eptd->bEndpointAddress & 9024 USB_EP_DIR_MASK) == USB_EP_DIR_OUT) { 9025 9026 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9027 "ohci_handle_bulk_td: Bulk out pipe"); 9028 9029 ohci_do_byte_stats(ohcip, tw->tw_length, 9030 eptd->bmAttributes, eptd->bEndpointAddress); 9031 9032 /* Do the callback */ 9033 ohci_hcdi_callback(ph, tw, USB_CR_OK); 9034 9035 return; 9036 } 9037 9038 /* Call ohci_sendup_td_message to send message to upstream */ 9039 ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK); 9040 } 9041 9042 9043 /* 9044 * ohci_handle_intr_td: 9045 * 9046 * Handle a interrupt Transfer Descriptor (TD). 9047 */ 9048 /* ARGSUSED */ 9049 static void 9050 ohci_handle_intr_td( 9051 ohci_state_t *ohcip, 9052 ohci_pipe_private_t *pp, 9053 ohci_trans_wrapper_t *tw, 9054 ohci_td_t *td, 9055 void *tw_handle_callback_value) 9056 { 9057 usb_intr_req_t *curr_intr_reqp = 9058 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 9059 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 9060 usb_ep_descr_t *eptd = &ph->p_ep; 9061 usb_req_attrs_t attrs; 9062 int error = USB_SUCCESS; 9063 9064 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9065 "ohci_handle_intr_td: pp=0x%p tw=0x%p td=0x%p" 9066 "intr_reqp=0%p data=0x%p", pp, tw, td, curr_intr_reqp, 9067 curr_intr_reqp->intr_data); 9068 9069 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9070 9071 /* Get the interrupt xfer attributes */ 9072 attrs = curr_intr_reqp->intr_attributes; 9073 9074 /* 9075 * For a Interrupt OUT pipe, we just callback and we are done 9076 */ 9077 if ((eptd->bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_OUT) { 9078 9079 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9080 "ohci_handle_intr_td: Intr out pipe, intr_reqp=0x%p," 9081 "data=0x%p", curr_intr_reqp, curr_intr_reqp->intr_data); 9082 9083 ohci_do_byte_stats(ohcip, tw->tw_length, 9084 eptd->bmAttributes, eptd->bEndpointAddress); 9085 9086 /* Do the callback */ 9087 ohci_hcdi_callback(ph, tw, USB_CR_OK); 9088 9089 return; 9090 } 9091 9092 /* Decrement number of interrupt request count */ 9093 pp->pp_cur_periodic_req_cnt--; 9094 9095 /* 9096 * Check usb flag whether USB_FLAGS_ONE_XFER flag is set 9097 * and if so, free duplicate request. 9098 */ 9099 if (attrs & USB_ATTRS_ONE_XFER) { 9100 ohci_handle_one_xfer_completion(ohcip, tw); 9101 } 9102 9103 /* Call ohci_sendup_td_message to callback into client */ 9104 ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK); 9105 9106 /* 9107 * If interrupt pipe state is still active, insert next Interrupt 9108 * request into the Host Controller's Interrupt list. Otherwise 9109 * you are done. 9110 */ 9111 if (pp->pp_state != OHCI_PIPE_STATE_ACTIVE) { 9112 return; 9113 } 9114 9115 if ((error = ohci_allocate_periodic_in_resource(ohcip, pp, tw, 0)) == 9116 USB_SUCCESS) { 9117 curr_intr_reqp = (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 9118 9119 ASSERT(curr_intr_reqp != NULL); 9120 9121 tw->tw_num_tds = 1; 9122 9123 if (ohci_tw_rebind_cookie(ohcip, pp, tw) != USB_SUCCESS) { 9124 ohci_deallocate_periodic_in_resource(ohcip, pp, tw); 9125 error = USB_FAILURE; 9126 } else if (ohci_allocate_tds_for_tw(ohcip, tw, 9127 tw->tw_num_tds) != USB_SUCCESS) { 9128 ohci_deallocate_periodic_in_resource(ohcip, pp, tw); 9129 error = USB_FAILURE; 9130 } 9131 } 9132 9133 if (error != USB_SUCCESS) { 9134 /* 9135 * Set pipe state to stop polling and error to no 9136 * resource. Don't insert any more interrupt polling 9137 * requests. 9138 */ 9139 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING; 9140 pp->pp_error = USB_CR_NO_RESOURCES; 9141 } else { 9142 ohci_insert_intr_req(ohcip, pp, tw, 0); 9143 9144 /* Increment number of interrupt request count */ 9145 pp->pp_cur_periodic_req_cnt++; 9146 9147 ASSERT(pp->pp_cur_periodic_req_cnt == 9148 pp->pp_max_periodic_req_cnt); 9149 } 9150 } 9151 9152 9153 /* 9154 * ohci_handle_one_xfer_completion: 9155 */ 9156 static void 9157 ohci_handle_one_xfer_completion( 9158 ohci_state_t *ohcip, 9159 ohci_trans_wrapper_t *tw) 9160 { 9161 usba_pipe_handle_data_t *ph = tw->tw_pipe_private->pp_pipe_handle; 9162 ohci_pipe_private_t *pp = tw->tw_pipe_private; 9163 usb_intr_req_t *curr_intr_reqp = 9164 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 9165 9166 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9167 "ohci_handle_one_xfer_completion: tw = 0x%p", tw); 9168 9169 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9170 ASSERT(curr_intr_reqp->intr_attributes & USB_ATTRS_ONE_XFER); 9171 9172 pp->pp_state = OHCI_PIPE_STATE_IDLE; 9173 9174 /* 9175 * For one xfer, we need to copy back data ptr 9176 * and free current request 9177 */ 9178 ((usb_intr_req_t *)(pp->pp_client_periodic_in_reqp))-> 9179 intr_data = ((usb_intr_req_t *) 9180 (tw->tw_curr_xfer_reqp))->intr_data; 9181 9182 ((usb_intr_req_t *)tw->tw_curr_xfer_reqp)->intr_data = NULL; 9183 9184 /* Now free duplicate current request */ 9185 usb_free_intr_req((usb_intr_req_t *)tw-> tw_curr_xfer_reqp); 9186 9187 mutex_enter(&ph->p_mutex); 9188 ph->p_req_count--; 9189 mutex_exit(&ph->p_mutex); 9190 9191 /* Make client's request the current request */ 9192 tw->tw_curr_xfer_reqp = pp->pp_client_periodic_in_reqp; 9193 pp->pp_client_periodic_in_reqp = NULL; 9194 } 9195 9196 9197 /* 9198 * ohci_handle_isoc_td: 9199 * 9200 * Handle an isochronous Transfer Descriptor (TD). 9201 */ 9202 /* ARGSUSED */ 9203 static void 9204 ohci_handle_isoc_td( 9205 ohci_state_t *ohcip, 9206 ohci_pipe_private_t *pp, 9207 ohci_trans_wrapper_t *tw, 9208 ohci_td_t *td, 9209 void *tw_handle_callback_value) 9210 { 9211 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 9212 usb_ep_descr_t *eptd = &ph->p_ep; 9213 usb_isoc_req_t *curr_isoc_reqp = 9214 (usb_isoc_req_t *)tw->tw_curr_xfer_reqp; 9215 int error = USB_SUCCESS; 9216 9217 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9218 "ohci_handle_isoc_td: pp=0x%p tw=0x%p td=0x%p" 9219 "isoc_reqp=0%p data=0x%p", pp, tw, td, curr_isoc_reqp, 9220 curr_isoc_reqp->isoc_data); 9221 9222 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9223 9224 /* 9225 * Decrement the TDs counter and check whether all the isoc 9226 * data has been send or received. If TDs counter reaches 9227 * zero then inform client driver about completion current 9228 * isoc request. Otherwise wait for completion of other isoc 9229 * TDs or transactions on this pipe. 9230 */ 9231 if (--tw->tw_num_tds != 0) { 9232 9233 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9234 "ohci_handle_isoc_td: Number of TDs %d", tw->tw_num_tds); 9235 9236 return; 9237 } 9238 9239 /* 9240 * If this is a isoc in pipe, return the data to the client. 9241 * For a isoc out pipe, there is no need to do anything. 9242 */ 9243 if ((eptd->bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_OUT) { 9244 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9245 "ohci_handle_isoc_td: Isoc out pipe, isoc_reqp=0x%p," 9246 "data=0x%p", curr_isoc_reqp, curr_isoc_reqp->isoc_data); 9247 9248 ohci_do_byte_stats(ohcip, tw->tw_length, 9249 eptd->bmAttributes, eptd->bEndpointAddress); 9250 9251 /* Do the callback */ 9252 ohci_hcdi_callback(ph, tw, USB_CR_OK); 9253 9254 return; 9255 } 9256 9257 /* Decrement number of IN isochronous request count */ 9258 pp->pp_cur_periodic_req_cnt--; 9259 9260 /* Call ohci_sendup_td_message to send message to upstream */ 9261 ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK); 9262 9263 /* 9264 * If isochronous pipe state is still active, insert next isochronous 9265 * request into the Host Controller's isochronous list. 9266 */ 9267 if (pp->pp_state != OHCI_PIPE_STATE_ACTIVE) { 9268 return; 9269 } 9270 9271 if ((error = ohci_allocate_periodic_in_resource(ohcip, pp, tw, 0)) == 9272 USB_SUCCESS) { 9273 curr_isoc_reqp = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp; 9274 9275 ASSERT(curr_isoc_reqp != NULL); 9276 9277 tw->tw_num_tds = 9278 curr_isoc_reqp->isoc_pkts_count / OHCI_ISOC_PKTS_PER_TD; 9279 if (curr_isoc_reqp->isoc_pkts_count % OHCI_ISOC_PKTS_PER_TD) { 9280 tw->tw_num_tds++; 9281 } 9282 9283 if (ohci_tw_rebind_cookie(ohcip, pp, tw) != USB_SUCCESS) { 9284 ohci_deallocate_periodic_in_resource(ohcip, pp, tw); 9285 error = USB_FAILURE; 9286 } else if (ohci_allocate_tds_for_tw(ohcip, tw, 9287 tw->tw_num_tds) != USB_SUCCESS) { 9288 ohci_deallocate_periodic_in_resource(ohcip, pp, tw); 9289 error = USB_FAILURE; 9290 } 9291 } 9292 9293 if (error != USB_SUCCESS || 9294 ohci_insert_isoc_req(ohcip, pp, tw, 0) != USB_SUCCESS) { 9295 /* 9296 * Set pipe state to stop polling and error to no 9297 * resource. Don't insert any more isoch polling 9298 * requests. 9299 */ 9300 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING; 9301 pp->pp_error = USB_CR_NO_RESOURCES; 9302 9303 } else { 9304 /* Increment number of IN isochronous request count */ 9305 pp->pp_cur_periodic_req_cnt++; 9306 9307 ASSERT(pp->pp_cur_periodic_req_cnt == 9308 pp->pp_max_periodic_req_cnt); 9309 } 9310 } 9311 9312 9313 /* 9314 * ohci_tw_rebind_cookie: 9315 * 9316 * If the cookie associated with a DMA buffer has been walked, the cookie 9317 * is not usable any longer. To reuse the DMA buffer, the DMA handle needs 9318 * to rebind for cookies. 9319 */ 9320 static int 9321 ohci_tw_rebind_cookie( 9322 ohci_state_t *ohcip, 9323 ohci_pipe_private_t *pp, 9324 ohci_trans_wrapper_t *tw) 9325 { 9326 usb_ep_descr_t *eptd = &pp->pp_pipe_handle->p_ep; 9327 int rval, i; 9328 uint_t ccount; 9329 9330 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9331 "ohci_tw_rebind_cookie:"); 9332 9333 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9334 9335 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH) { 9336 ASSERT(tw->tw_num_tds == tw->tw_ncookies); 9337 9338 for (i = 0; i < tw->tw_num_tds; i++) { 9339 if (tw->tw_isoc_bufs[i].ncookies == 1) { 9340 9341 /* 9342 * no need to rebind when there is 9343 * only one cookie in a buffer 9344 */ 9345 continue; 9346 } 9347 9348 /* unbind the DMA handle before rebinding */ 9349 rval = ddi_dma_unbind_handle( 9350 tw->tw_isoc_bufs[i].dma_handle); 9351 ASSERT(rval == USB_SUCCESS); 9352 tw->tw_isoc_bufs[i].ncookies = 0; 9353 9354 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9355 "rebind dma_handle %d", i); 9356 9357 /* rebind the handle to get cookies */ 9358 rval = ddi_dma_addr_bind_handle( 9359 tw->tw_isoc_bufs[i].dma_handle, NULL, 9360 (caddr_t)tw->tw_isoc_bufs[i].buf_addr, 9361 tw->tw_isoc_bufs[i].length, 9362 DDI_DMA_RDWR|DDI_DMA_CONSISTENT, 9363 DDI_DMA_DONTWAIT, NULL, 9364 &tw->tw_isoc_bufs[i].cookie, &ccount); 9365 9366 if ((rval == DDI_DMA_MAPPED) && 9367 (ccount <= OHCI_DMA_ATTR_TD_SGLLEN)) { 9368 tw->tw_isoc_bufs[i].ncookies = ccount; 9369 } else { 9370 9371 return (USB_NO_RESOURCES); 9372 } 9373 } 9374 } else { 9375 if (tw->tw_cookie_idx != 0) { 9376 /* unbind the DMA handle before rebinding */ 9377 rval = ddi_dma_unbind_handle(tw->tw_dmahandle); 9378 ASSERT(rval == DDI_SUCCESS); 9379 tw->tw_ncookies = 0; 9380 9381 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9382 "rebind dma_handle"); 9383 9384 /* rebind the handle to get cookies */ 9385 rval = ddi_dma_addr_bind_handle( 9386 tw->tw_dmahandle, NULL, 9387 (caddr_t)tw->tw_buf, tw->tw_length, 9388 DDI_DMA_RDWR|DDI_DMA_CONSISTENT, 9389 DDI_DMA_DONTWAIT, NULL, 9390 &tw->tw_cookie, &ccount); 9391 9392 if (rval == DDI_DMA_MAPPED) { 9393 tw->tw_ncookies = ccount; 9394 tw->tw_dma_offs = 0; 9395 tw->tw_cookie_idx = 0; 9396 } else { 9397 9398 return (USB_NO_RESOURCES); 9399 } 9400 } 9401 } 9402 9403 return (USB_SUCCESS); 9404 } 9405 9406 9407 /* 9408 * ohci_sendup_td_message: 9409 * copy data, if necessary and do callback 9410 */ 9411 static void 9412 ohci_sendup_td_message( 9413 ohci_state_t *ohcip, 9414 ohci_pipe_private_t *pp, 9415 ohci_trans_wrapper_t *tw, 9416 ohci_td_t *td, 9417 usb_cr_t error) 9418 { 9419 usb_ep_descr_t *eptd = &pp->pp_pipe_handle->p_ep; 9420 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 9421 size_t length = 0, skip_len = 0, residue; 9422 mblk_t *mp; 9423 uchar_t *buf; 9424 usb_opaque_t curr_xfer_reqp = tw->tw_curr_xfer_reqp; 9425 9426 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9427 9428 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9429 "ohci_sendup_td_message:"); 9430 9431 ASSERT(tw != NULL); 9432 9433 length = tw->tw_length; 9434 9435 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) { 9436 case USB_EP_ATTR_CONTROL: 9437 /* 9438 * Get the correct length, adjust it for the setup size 9439 * which is not part of the data length in control end 9440 * points. Update tw->tw_length for future references. 9441 */ 9442 if (((usb_ctrl_req_t *)curr_xfer_reqp)->ctrl_wLength) { 9443 tw->tw_length = length = length - OHCI_MAX_TD_BUF_SIZE; 9444 } else { 9445 tw->tw_length = length = length - SETUP_SIZE; 9446 } 9447 9448 /* Set the length of the buffer to skip */ 9449 skip_len = OHCI_MAX_TD_BUF_SIZE; 9450 9451 if (Get_TD(td->hctd_ctrl_phase) != OHCI_CTRL_DATA_PHASE) { 9452 break; 9453 } 9454 /* FALLTHRU */ 9455 case USB_EP_ATTR_BULK: 9456 case USB_EP_ATTR_INTR: 9457 /* 9458 * If error is "data overrun", do not check for the 9459 * "CurrentBufferPointer" and return whatever data 9460 * received to the client driver. 9461 */ 9462 if (error == USB_CR_DATA_OVERRUN) { 9463 break; 9464 } 9465 9466 /* 9467 * If "CurrentBufferPointer" of Transfer Descriptor 9468 * (TD) is not equal to zero, then we received less 9469 * data from the device than requested by us. In that 9470 * case, get the actual received data size. 9471 */ 9472 if (Get_TD(td->hctd_cbp)) { 9473 residue = ohci_get_td_residue(ohcip, td); 9474 length = Get_TD(td->hctd_xfer_offs) + 9475 Get_TD(td->hctd_xfer_len) - residue - skip_len; 9476 9477 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9478 "ohci_sendup_qtd_message: requested data %lu " 9479 "received data %lu", tw->tw_length, length); 9480 } 9481 9482 break; 9483 case USB_EP_ATTR_ISOCH: 9484 default: 9485 break; 9486 } 9487 9488 /* Copy the data into the mblk_t */ 9489 buf = (uchar_t *)tw->tw_buf + skip_len; 9490 9491 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9492 "ohci_sendup_qtd_message: length %lu error %d", length, error); 9493 9494 /* Get the message block */ 9495 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) { 9496 case USB_EP_ATTR_CONTROL: 9497 mp = ((usb_ctrl_req_t *)curr_xfer_reqp)->ctrl_data; 9498 break; 9499 case USB_EP_ATTR_BULK: 9500 mp = ((usb_bulk_req_t *)curr_xfer_reqp)->bulk_data; 9501 break; 9502 case USB_EP_ATTR_INTR: 9503 mp = ((usb_intr_req_t *)curr_xfer_reqp)->intr_data; 9504 break; 9505 case USB_EP_ATTR_ISOCH: 9506 mp = ((usb_isoc_req_t *)curr_xfer_reqp)->isoc_data; 9507 break; 9508 } 9509 9510 ASSERT(mp != NULL); 9511 9512 if (length) { 9513 int i; 9514 uchar_t *p = mp->b_rptr; 9515 9516 /* 9517 * Update kstat byte counts 9518 * The control endpoints don't have direction bits so in 9519 * order for control stats to be counted correctly an in 9520 * bit must be faked on a control read. 9521 */ 9522 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) == 9523 USB_EP_ATTR_CONTROL) { 9524 ohci_do_byte_stats(ohcip, length, 9525 eptd->bmAttributes, USB_EP_DIR_IN); 9526 } else { 9527 ohci_do_byte_stats(ohcip, length, 9528 eptd->bmAttributes, eptd->bEndpointAddress); 9529 } 9530 9531 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) == 9532 USB_EP_ATTR_ISOCH) { 9533 for (i = 0; i < tw->tw_ncookies; i++) { 9534 Sync_IO_Buffer( 9535 tw->tw_isoc_bufs[i].dma_handle, 9536 tw->tw_isoc_bufs[i].length); 9537 9538 ddi_rep_get8(tw->tw_isoc_bufs[i].mem_handle, 9539 p, (uint8_t *)tw->tw_isoc_bufs[i].buf_addr, 9540 tw->tw_isoc_bufs[i].length, 9541 DDI_DEV_AUTOINCR); 9542 p += tw->tw_isoc_bufs[i].length; 9543 } 9544 tw->tw_pkt_idx = 0; 9545 } else { 9546 /* Sync IO buffer */ 9547 Sync_IO_Buffer(tw->tw_dmahandle, (skip_len + length)); 9548 9549 /* Copy the data into the message */ 9550 ddi_rep_get8(tw->tw_accesshandle, 9551 mp->b_rptr, buf, length, DDI_DEV_AUTOINCR); 9552 } 9553 9554 /* Increment the write pointer */ 9555 mp->b_wptr = mp->b_wptr + length; 9556 } else { 9557 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9558 "ohci_sendup_td_message: Zero length packet"); 9559 } 9560 9561 ohci_hcdi_callback(ph, tw, error); 9562 } 9563 9564 9565 /* 9566 * ohci_get_td_residue: 9567 * 9568 * Calculate the bytes not transfered by the TD 9569 */ 9570 size_t 9571 ohci_get_td_residue( 9572 ohci_state_t *ohcip, 9573 ohci_td_t *td) 9574 { 9575 uint32_t buf_addr, end_addr; 9576 size_t residue; 9577 9578 buf_addr = Get_TD(td->hctd_cbp); 9579 end_addr = Get_TD(td->hctd_buf_end); 9580 9581 if ((buf_addr & 0xfffff000) == 9582 (end_addr & 0xfffff000)) { 9583 residue = end_addr - buf_addr + 1; 9584 } else { 9585 residue = OHCI_MAX_TD_BUF_SIZE - 9586 (buf_addr & 0x00000fff) + 9587 (end_addr & 0x00000fff) + 1; 9588 } 9589 9590 return (residue); 9591 } 9592 9593 9594 /* 9595 * Miscellaneous functions 9596 */ 9597 9598 /* 9599 * ohci_obtain_state: 9600 * NOTE: This function is also called from POLLED MODE. 9601 */ 9602 ohci_state_t * 9603 ohci_obtain_state(dev_info_t *dip) 9604 { 9605 int instance = ddi_get_instance(dip); 9606 ohci_state_t *state = ddi_get_soft_state( 9607 ohci_statep, instance); 9608 9609 ASSERT(state != NULL); 9610 9611 return (state); 9612 } 9613 9614 9615 /* 9616 * ohci_state_is_operational: 9617 * 9618 * Check the Host controller state and return proper values. 9619 */ 9620 int 9621 ohci_state_is_operational(ohci_state_t *ohcip) 9622 { 9623 int val; 9624 9625 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9626 9627 switch (ohcip->ohci_hc_soft_state) { 9628 case OHCI_CTLR_INIT_STATE: 9629 case OHCI_CTLR_SUSPEND_STATE: 9630 val = USB_FAILURE; 9631 break; 9632 case OHCI_CTLR_OPERATIONAL_STATE: 9633 val = USB_SUCCESS; 9634 break; 9635 case OHCI_CTLR_ERROR_STATE: 9636 val = USB_HC_HARDWARE_ERROR; 9637 break; 9638 default: 9639 val = USB_FAILURE; 9640 break; 9641 } 9642 9643 return (val); 9644 } 9645 9646 9647 /* 9648 * ohci_do_soft_reset 9649 * 9650 * Do soft reset of ohci host controller. 9651 */ 9652 int 9653 ohci_do_soft_reset(ohci_state_t *ohcip) 9654 { 9655 usb_frame_number_t before_frame_number, after_frame_number; 9656 timeout_id_t xfer_timer_id, rh_timer_id; 9657 ohci_regs_t *ohci_save_regs; 9658 ohci_td_t *done_head; 9659 9660 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9661 9662 /* Increment host controller error count */ 9663 ohcip->ohci_hc_error++; 9664 9665 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9666 "ohci_do_soft_reset:" 9667 "Reset ohci host controller 0x%x", ohcip->ohci_hc_error); 9668 9669 /* 9670 * Allocate space for saving current Host Controller 9671 * registers. Don't do any recovery if allocation 9672 * fails. 9673 */ 9674 ohci_save_regs = (ohci_regs_t *) 9675 kmem_zalloc(sizeof (ohci_regs_t), KM_NOSLEEP); 9676 9677 if (ohci_save_regs == NULL) { 9678 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9679 "ohci_do_soft_reset: kmem_zalloc failed"); 9680 9681 return (USB_FAILURE); 9682 } 9683 9684 /* Save current ohci registers */ 9685 ohci_save_regs->hcr_control = Get_OpReg(hcr_control); 9686 ohci_save_regs->hcr_cmd_status = Get_OpReg(hcr_cmd_status); 9687 ohci_save_regs->hcr_intr_enable = Get_OpReg(hcr_intr_enable); 9688 ohci_save_regs->hcr_periodic_strt = Get_OpReg(hcr_periodic_strt); 9689 ohci_save_regs->hcr_frame_interval = Get_OpReg(hcr_frame_interval); 9690 ohci_save_regs->hcr_HCCA = Get_OpReg(hcr_HCCA); 9691 ohci_save_regs->hcr_bulk_head = Get_OpReg(hcr_bulk_head); 9692 ohci_save_regs->hcr_ctrl_head = Get_OpReg(hcr_ctrl_head); 9693 9694 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9695 "ohci_do_soft_reset: Save reg = 0x%p", ohci_save_regs); 9696 9697 /* Disable all list processing and interrupts */ 9698 Set_OpReg(hcr_control, (Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE | 9699 HCR_CONTROL_BLE | HCR_CONTROL_PLE | HCR_CONTROL_IE))); 9700 9701 Set_OpReg(hcr_intr_disable, HCR_INTR_SO | 9702 HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE | 9703 HCR_INTR_FNO | HCR_INTR_SOF | HCR_INTR_MIE); 9704 9705 /* Wait for few milliseconds */ 9706 drv_usecwait(OHCI_TIMEWAIT); 9707 9708 /* Root hub interrupt pipe timeout id */ 9709 rh_timer_id = ohcip->ohci_root_hub.rh_intr_pipe_timer_id; 9710 9711 /* Stop the root hub interrupt timer */ 9712 if (rh_timer_id) { 9713 ohcip->ohci_root_hub.rh_intr_pipe_timer_id = 0; 9714 ohcip->ohci_root_hub.rh_intr_pipe_state = 9715 OHCI_PIPE_STATE_IDLE; 9716 9717 mutex_exit(&ohcip->ohci_int_mutex); 9718 (void) untimeout(rh_timer_id); 9719 mutex_enter(&ohcip->ohci_int_mutex); 9720 } 9721 9722 /* Transfer timeout id */ 9723 xfer_timer_id = ohcip->ohci_timer_id; 9724 9725 /* Stop the global transfer timer */ 9726 if (xfer_timer_id) { 9727 ohcip->ohci_timer_id = 0; 9728 mutex_exit(&ohcip->ohci_int_mutex); 9729 (void) untimeout(xfer_timer_id); 9730 mutex_enter(&ohcip->ohci_int_mutex); 9731 } 9732 9733 /* Process any pending HCCA DoneHead */ 9734 done_head = (ohci_td_t *)(uintptr_t) 9735 (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) & HCCA_DONE_HEAD_MASK); 9736 9737 if (ohci_check_done_head(ohcip, done_head) == USB_SUCCESS) { 9738 /* Reset the done head to NULL */ 9739 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, NULL); 9740 9741 ohci_traverse_done_list(ohcip, done_head); 9742 } 9743 9744 /* Process any pending hcr_done_head value */ 9745 done_head = (ohci_td_t *)(uintptr_t) 9746 (Get_OpReg(hcr_done_head) & HCCA_DONE_HEAD_MASK); 9747 if (ohci_check_done_head(ohcip, done_head) == USB_SUCCESS) { 9748 9749 ohci_traverse_done_list(ohcip, done_head); 9750 } 9751 9752 /* Do soft reset of ohci host controller */ 9753 Set_OpReg(hcr_cmd_status, HCR_STATUS_RESET); 9754 9755 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9756 "ohci_do_soft_reset: Reset in progress"); 9757 9758 /* Wait for reset to complete */ 9759 drv_usecwait(OHCI_RESET_TIMEWAIT); 9760 9761 /* Reset HCCA HcFrameNumber */ 9762 Set_HCCA(ohcip->ohci_hccap->HccaFrameNo, 0x00000000); 9763 9764 /* 9765 * Restore previous saved HC register value 9766 * into the current HC registers. 9767 */ 9768 Set_OpReg(hcr_periodic_strt, (uint32_t) 9769 ohci_save_regs->hcr_periodic_strt); 9770 9771 Set_OpReg(hcr_frame_interval, (uint32_t) 9772 ohci_save_regs->hcr_frame_interval); 9773 9774 Set_OpReg(hcr_done_head, 0x0); 9775 9776 Set_OpReg(hcr_bulk_curr, 0x0); 9777 9778 Set_OpReg(hcr_bulk_head, (uint32_t) 9779 ohci_save_regs->hcr_bulk_head); 9780 9781 Set_OpReg(hcr_ctrl_curr, 0x0); 9782 9783 Set_OpReg(hcr_ctrl_head, (uint32_t) 9784 ohci_save_regs->hcr_ctrl_head); 9785 9786 Set_OpReg(hcr_periodic_curr, 0x0); 9787 9788 Set_OpReg(hcr_HCCA, (uint32_t) 9789 ohci_save_regs->hcr_HCCA); 9790 9791 Set_OpReg(hcr_intr_status, 0x0); 9792 9793 /* 9794 * Set HcInterruptEnable to enable all interrupts except 9795 * Root Hub Status change interrupt. 9796 */ 9797 Set_OpReg(hcr_intr_enable, 9798 HCR_INTR_SO | HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE | 9799 HCR_INTR_FNO | HCR_INTR_SOF | HCR_INTR_MIE); 9800 9801 /* Start Control and Bulk list processing */ 9802 Set_OpReg(hcr_cmd_status, (HCR_STATUS_CLF | HCR_STATUS_BLF)); 9803 9804 /* 9805 * Start up Control, Bulk, Periodic and Isochronous lists 9806 * processing. 9807 */ 9808 Set_OpReg(hcr_control, (uint32_t) 9809 (ohci_save_regs->hcr_control & (~HCR_CONTROL_HCFS))); 9810 9811 /* 9812 * Deallocate the space that allocated for saving 9813 * HC registers. 9814 */ 9815 kmem_free((void *) ohci_save_regs, sizeof (ohci_regs_t)); 9816 9817 /* Resume the host controller */ 9818 Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) & 9819 (~HCR_CONTROL_HCFS)) | HCR_CONTROL_RESUME)); 9820 9821 /* Wait for resume to complete */ 9822 drv_usecwait(OHCI_RESUME_TIMEWAIT); 9823 9824 /* Set the Host Controller Functional State to Operational */ 9825 Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) & 9826 (~HCR_CONTROL_HCFS)) | HCR_CONTROL_OPERAT)); 9827 9828 /* Wait 10ms for HC to start sending SOF */ 9829 drv_usecwait(OHCI_TIMEWAIT); 9830 9831 /* 9832 * Get the current usb frame number before waiting for few 9833 * milliseconds. 9834 */ 9835 before_frame_number = ohci_get_current_frame_number(ohcip); 9836 9837 /* Wait for few milliseconds */ 9838 drv_usecwait(OHCI_TIMEWAIT); 9839 9840 /* 9841 * Get the current usb frame number after waiting for few 9842 * milliseconds. 9843 */ 9844 after_frame_number = ohci_get_current_frame_number(ohcip); 9845 9846 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9847 "ohci_do_soft_reset: Before Frm No 0x%llx After Frm No 0x%llx", 9848 before_frame_number, after_frame_number); 9849 9850 if (after_frame_number <= before_frame_number) { 9851 9852 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9853 "ohci_do_soft_reset: Soft reset failed"); 9854 9855 return (USB_FAILURE); 9856 } 9857 9858 /* Start the timer for the root hub interrupt pipe polling */ 9859 if (rh_timer_id) { 9860 ohcip->ohci_root_hub.rh_intr_pipe_timer_id = 9861 timeout(ohci_handle_root_hub_status_change, 9862 (void *)ohcip, drv_usectohz(OHCI_RH_POLL_TIME)); 9863 9864 ohcip->ohci_root_hub. 9865 rh_intr_pipe_state = OHCI_PIPE_STATE_ACTIVE; 9866 } 9867 9868 /* Start the global timer */ 9869 if (xfer_timer_id) { 9870 ohcip->ohci_timer_id = timeout(ohci_xfer_timeout_handler, 9871 (void *)ohcip, drv_usectohz(1000000)); 9872 } 9873 9874 return (USB_SUCCESS); 9875 } 9876 9877 9878 /* 9879 * ohci_get_current_frame_number: 9880 * 9881 * Get the current software based usb frame number. 9882 */ 9883 usb_frame_number_t 9884 ohci_get_current_frame_number(ohci_state_t *ohcip) 9885 { 9886 usb_frame_number_t usb_frame_number; 9887 usb_frame_number_t ohci_fno, frame_number; 9888 ohci_save_intr_sts_t *ohci_intr_sts = 9889 &ohcip->ohci_save_intr_sts; 9890 9891 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9892 9893 /* 9894 * Sync HCCA area only if this function 9895 * is invoked in non interrupt context. 9896 */ 9897 if (!(ohci_intr_sts->ohci_intr_flag & 9898 OHCI_INTR_HANDLING)) { 9899 9900 /* Sync HCCA area */ 9901 Sync_HCCA(ohcip); 9902 } 9903 9904 ohci_fno = ohcip->ohci_fno; 9905 frame_number = Get_HCCA(ohcip->ohci_hccap->HccaFrameNo); 9906 9907 /* 9908 * Calculate current software based usb frame number. 9909 * 9910 * This code accounts for the fact that frame number is 9911 * updated by the Host Controller before the ohci driver 9912 * gets an FrameNumberOverflow (FNO) interrupt that will 9913 * adjust Frame higher part. 9914 * 9915 * Refer ohci specification 1.0a, section 5.4, page 86. 9916 */ 9917 usb_frame_number = ((frame_number & 0x7FFF) | ohci_fno) + 9918 (((frame_number & 0xFFFF) ^ ohci_fno) & 0x8000); 9919 9920 return (usb_frame_number); 9921 } 9922 9923 9924 /* 9925 * ohci_cpr_cleanup: 9926 * 9927 * Cleanup ohci state and other ohci specific informations across 9928 * Check Point Resume (CPR). 9929 */ 9930 static void 9931 ohci_cpr_cleanup(ohci_state_t *ohcip) 9932 { 9933 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9934 9935 /* Reset software part of usb frame number */ 9936 ohcip->ohci_fno = 0; 9937 9938 /* Reset Schedule Overrrun Error Counter */ 9939 ohcip->ohci_so_error = 0; 9940 9941 /* Reset HCCA HcFrameNumber */ 9942 Set_HCCA(ohcip->ohci_hccap->HccaFrameNo, 0x00000000); 9943 } 9944 9945 9946 /* 9947 * ohci_get_xfer_attrs: 9948 * 9949 * Get the attributes of a particular xfer. 9950 */ 9951 static usb_req_attrs_t 9952 ohci_get_xfer_attrs( 9953 ohci_state_t *ohcip, 9954 ohci_pipe_private_t *pp, 9955 ohci_trans_wrapper_t *tw) 9956 { 9957 usb_ep_descr_t *eptd = &pp->pp_pipe_handle->p_ep; 9958 usb_req_attrs_t attrs = 0; 9959 9960 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 9961 "ohci_get_xfer_attrs:"); 9962 9963 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9964 9965 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) { 9966 case USB_EP_ATTR_CONTROL: 9967 attrs = ((usb_ctrl_req_t *) 9968 tw->tw_curr_xfer_reqp)->ctrl_attributes; 9969 break; 9970 case USB_EP_ATTR_BULK: 9971 attrs = ((usb_bulk_req_t *) 9972 tw->tw_curr_xfer_reqp)->bulk_attributes; 9973 break; 9974 case USB_EP_ATTR_INTR: 9975 attrs = ((usb_intr_req_t *) 9976 tw->tw_curr_xfer_reqp)->intr_attributes; 9977 break; 9978 case USB_EP_ATTR_ISOCH: 9979 attrs = ((usb_isoc_req_t *) 9980 tw->tw_curr_xfer_reqp)->isoc_attributes; 9981 break; 9982 } 9983 9984 return (attrs); 9985 } 9986 9987 9988 /* 9989 * ohci_allocate_periodic_in_resource 9990 * 9991 * Allocate interrupt/isochronous request structure for the 9992 * interrupt/isochronous IN transfer. 9993 */ 9994 static int 9995 ohci_allocate_periodic_in_resource( 9996 ohci_state_t *ohcip, 9997 ohci_pipe_private_t *pp, 9998 ohci_trans_wrapper_t *tw, 9999 usb_flags_t flags) 10000 { 10001 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 10002 uchar_t ep_attr = ph->p_ep.bmAttributes; 10003 usb_intr_req_t *curr_intr_reqp; 10004 usb_isoc_req_t *curr_isoc_reqp; 10005 usb_opaque_t client_periodic_in_reqp; 10006 size_t length = 0; 10007 10008 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10009 "ohci_allocate_periodic_in_resource:" 10010 "pp = 0x%p tw = 0x%p flags = 0x%x", pp, tw, flags); 10011 10012 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10013 ASSERT(tw->tw_curr_xfer_reqp == NULL); 10014 10015 /* Get the client periodic in request pointer */ 10016 client_periodic_in_reqp = pp->pp_client_periodic_in_reqp; 10017 10018 /* 10019 * If it a periodic IN request and periodic request is NULL, 10020 * allocate corresponding usb periodic IN request for the 10021 * current periodic polling request and copy the information 10022 * from the saved periodic request structure. 10023 */ 10024 if ((ep_attr & USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) { 10025 10026 if (client_periodic_in_reqp) { 10027 10028 /* Get the interrupt transfer length */ 10029 length = ((usb_intr_req_t *) 10030 client_periodic_in_reqp)->intr_len; 10031 10032 curr_intr_reqp = usba_hcdi_dup_intr_req( 10033 ph->p_dip, (usb_intr_req_t *) 10034 client_periodic_in_reqp, length, flags); 10035 } else { 10036 curr_intr_reqp = usb_alloc_intr_req( 10037 ph->p_dip, length, flags); 10038 } 10039 10040 if (curr_intr_reqp == NULL) { 10041 10042 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10043 "ohci_allocate_periodic_in_resource: Interrupt " 10044 "request structure allocation failed"); 10045 10046 return (USB_NO_RESOURCES); 10047 } 10048 10049 if (client_periodic_in_reqp == NULL) { 10050 /* For polled mode */ 10051 curr_intr_reqp-> 10052 intr_attributes = USB_ATTRS_SHORT_XFER_OK; 10053 curr_intr_reqp-> 10054 intr_len = ph->p_ep.wMaxPacketSize; 10055 } else { 10056 /* Check and save the timeout value */ 10057 tw->tw_timeout = (curr_intr_reqp->intr_attributes & 10058 USB_ATTRS_ONE_XFER) ? 10059 curr_intr_reqp->intr_timeout: 0; 10060 } 10061 10062 tw->tw_curr_xfer_reqp = (usb_opaque_t)curr_intr_reqp; 10063 tw->tw_length = curr_intr_reqp->intr_len; 10064 } else { 10065 ASSERT(client_periodic_in_reqp != NULL); 10066 10067 curr_isoc_reqp = usba_hcdi_dup_isoc_req(ph->p_dip, 10068 (usb_isoc_req_t *)client_periodic_in_reqp, flags); 10069 10070 if (curr_isoc_reqp == NULL) { 10071 10072 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10073 "ohci_allocate_periodic_in_resource: Isochronous" 10074 "request structure allocation failed"); 10075 10076 return (USB_NO_RESOURCES); 10077 } 10078 10079 /* 10080 * Save the client's isochronous request pointer and 10081 * length of isochronous transfer in transfer wrapper. 10082 * The dup'ed request is saved in pp_client_periodic_in_reqp 10083 */ 10084 tw->tw_curr_xfer_reqp = 10085 (usb_opaque_t)pp->pp_client_periodic_in_reqp; 10086 pp->pp_client_periodic_in_reqp = (usb_opaque_t)curr_isoc_reqp; 10087 } 10088 10089 mutex_enter(&ph->p_mutex); 10090 ph->p_req_count++; 10091 mutex_exit(&ph->p_mutex); 10092 10093 pp->pp_state = OHCI_PIPE_STATE_ACTIVE; 10094 10095 return (USB_SUCCESS); 10096 } 10097 10098 10099 /* 10100 * ohci_wait_for_sof: 10101 * 10102 * Wait for couple of SOF interrupts 10103 */ 10104 static int 10105 ohci_wait_for_sof(ohci_state_t *ohcip) 10106 { 10107 usb_frame_number_t before_frame_number, after_frame_number; 10108 clock_t sof_time_wait; 10109 int rval, sof_wait_count; 10110 10111 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10112 "ohci_wait_for_sof"); 10113 10114 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10115 10116 rval = ohci_state_is_operational(ohcip); 10117 10118 if (rval != USB_SUCCESS) { 10119 10120 return (rval); 10121 } 10122 10123 /* Get the number of clock ticks to wait */ 10124 sof_time_wait = drv_usectohz(OHCI_MAX_SOF_TIMEWAIT * 1000000); 10125 10126 sof_wait_count = 0; 10127 10128 /* 10129 * Get the current usb frame number before waiting for the 10130 * SOF interrupt event. 10131 */ 10132 before_frame_number = ohci_get_current_frame_number(ohcip); 10133 10134 while (sof_wait_count < MAX_SOF_WAIT_COUNT) { 10135 /* Enable the SOF interrupt */ 10136 Set_OpReg(hcr_intr_enable, HCR_INTR_SOF); 10137 10138 ASSERT(Get_OpReg(hcr_intr_enable) & HCR_INTR_SOF); 10139 10140 /* Wait for the SOF or timeout event */ 10141 rval = cv_timedwait(&ohcip->ohci_SOF_cv, 10142 &ohcip->ohci_int_mutex, ddi_get_lbolt() + sof_time_wait); 10143 10144 /* 10145 * Get the current usb frame number after woken up either 10146 * from SOF interrupt or timer expired event. 10147 */ 10148 after_frame_number = ohci_get_current_frame_number(ohcip); 10149 10150 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10151 "ohci_wait_for_sof: before 0x%llx, after 0x%llx", 10152 before_frame_number, after_frame_number); 10153 10154 /* 10155 * Return failure, if we are woken up becuase of timer expired 10156 * event and if usb frame number has not been changed. 10157 */ 10158 if ((rval == -1) && 10159 (after_frame_number <= before_frame_number)) { 10160 10161 if ((ohci_do_soft_reset(ohcip)) != USB_SUCCESS) { 10162 10163 USB_DPRINTF_L0(PRINT_MASK_LISTS, 10164 ohcip->ohci_log_hdl, "No SOF interrupts"); 10165 10166 /* Set host controller soft state to error */ 10167 ohcip->ohci_hc_soft_state = 10168 OHCI_CTLR_ERROR_STATE; 10169 10170 return (USB_FAILURE); 10171 } 10172 10173 /* Get new usb frame number */ 10174 after_frame_number = before_frame_number = 10175 ohci_get_current_frame_number(ohcip); 10176 } 10177 10178 ASSERT(after_frame_number >= before_frame_number); 10179 10180 before_frame_number = after_frame_number; 10181 sof_wait_count++; 10182 } 10183 10184 return (USB_SUCCESS); 10185 } 10186 10187 10188 /* 10189 * ohci_pipe_cleanup 10190 * 10191 * Cleanup ohci pipe. 10192 */ 10193 static void 10194 ohci_pipe_cleanup( 10195 ohci_state_t *ohcip, 10196 usba_pipe_handle_data_t *ph) 10197 { 10198 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 10199 usb_ep_descr_t *eptd = &ph->p_ep; 10200 usb_cr_t completion_reason; 10201 uint_t pipe_state = pp->pp_state; 10202 uint_t bit = 0; 10203 10204 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10205 "ohci_pipe_cleanup: ph = 0x%p", ph); 10206 10207 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10208 10209 switch (pipe_state) { 10210 case OHCI_PIPE_STATE_CLOSE: 10211 if (OHCI_NON_PERIODIC_ENDPOINT(eptd)) { 10212 10213 bit = ((eptd->bmAttributes & 10214 USB_EP_ATTR_MASK) == USB_EP_ATTR_CONTROL) ? 10215 HCR_CONTROL_CLE: HCR_CONTROL_BLE; 10216 10217 Set_OpReg(hcr_control, 10218 (Get_OpReg(hcr_control) & ~(bit))); 10219 10220 /* Wait for the next SOF */ 10221 (void) ohci_wait_for_sof(ohcip); 10222 10223 break; 10224 } 10225 /* FALLTHROUGH */ 10226 case OHCI_PIPE_STATE_RESET: 10227 case OHCI_PIPE_STATE_STOP_POLLING: 10228 /* 10229 * Set the sKip bit to stop all transactions on 10230 * this pipe 10231 */ 10232 ohci_modify_sKip_bit(ohcip, pp, SET_sKip, 10233 OHCI_FLAGS_SLEEP | OHCI_FLAGS_DMA_SYNC); 10234 10235 break; 10236 default: 10237 return; 10238 } 10239 10240 /* 10241 * Wait for processing all completed transfers and 10242 * to send results to upstream. 10243 */ 10244 ohci_wait_for_transfers_completion(ohcip, pp); 10245 10246 /* Save the data toggle information */ 10247 ohci_save_data_toggle(ohcip, ph); 10248 10249 /* 10250 * Traverse the list of TD's on this endpoint and 10251 * these TD's have outstanding transfer requests. 10252 * Since the list processing is stopped, these tds 10253 * can be deallocated. 10254 */ 10255 ohci_traverse_tds(ohcip, ph); 10256 10257 /* 10258 * If all of the endpoint's TD's have been deallocated, 10259 * then the DMA mappings can be torn down. If not there 10260 * are some TD's on the done list that have not been 10261 * processed. Tag these TD's so that they are thrown 10262 * away when the done list is processed. 10263 */ 10264 ohci_done_list_tds(ohcip, ph); 10265 10266 /* Do callbacks for all unfinished requests */ 10267 ohci_handle_outstanding_requests(ohcip, pp); 10268 10269 /* Free DMA resources */ 10270 ohci_free_dma_resources(ohcip, ph); 10271 10272 switch (pipe_state) { 10273 case OHCI_PIPE_STATE_CLOSE: 10274 completion_reason = USB_CR_PIPE_CLOSING; 10275 break; 10276 case OHCI_PIPE_STATE_RESET: 10277 case OHCI_PIPE_STATE_STOP_POLLING: 10278 /* Set completion reason */ 10279 completion_reason = (pipe_state == 10280 OHCI_PIPE_STATE_RESET) ? 10281 USB_CR_PIPE_RESET: USB_CR_STOPPED_POLLING; 10282 10283 /* Restore the data toggle information */ 10284 ohci_restore_data_toggle(ohcip, ph); 10285 10286 /* 10287 * Clear the sKip bit to restart all the 10288 * transactions on this pipe. 10289 */ 10290 ohci_modify_sKip_bit(ohcip, pp, 10291 CLEAR_sKip, OHCI_FLAGS_NOSLEEP); 10292 10293 /* Set pipe state to idle */ 10294 pp->pp_state = OHCI_PIPE_STATE_IDLE; 10295 10296 break; 10297 } 10298 10299 ASSERT((Get_ED(pp->pp_ept->hced_tailp) & HC_EPT_TD_TAIL) == 10300 (Get_ED(pp->pp_ept->hced_headp) & HC_EPT_TD_HEAD)); 10301 10302 ASSERT((pp->pp_tw_head == NULL) && (pp->pp_tw_tail == NULL)); 10303 10304 /* 10305 * Do the callback for the original client 10306 * periodic IN request. 10307 */ 10308 if ((OHCI_PERIODIC_ENDPOINT(eptd)) && 10309 ((ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK) == 10310 USB_EP_DIR_IN)) { 10311 10312 ohci_do_client_periodic_in_req_callback( 10313 ohcip, pp, completion_reason); 10314 } 10315 } 10316 10317 10318 /* 10319 * ohci_wait_for_transfers_completion: 10320 * 10321 * Wait for processing all completed transfers and to send results 10322 * to upstream. 10323 */ 10324 static void 10325 ohci_wait_for_transfers_completion( 10326 ohci_state_t *ohcip, 10327 ohci_pipe_private_t *pp) 10328 { 10329 ohci_trans_wrapper_t *head_tw = pp->pp_tw_head; 10330 ohci_trans_wrapper_t *next_tw; 10331 clock_t xfer_cmpl_time_wait; 10332 ohci_td_t *tailp, *headp, *nextp; 10333 ohci_td_t *head_td, *next_td; 10334 ohci_ed_t *ept = pp->pp_ept; 10335 int rval; 10336 10337 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10338 "ohci_wait_for_transfers_completion: pp = 0x%p", pp); 10339 10340 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10341 10342 headp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, 10343 Get_ED(ept->hced_headp) & (uint32_t)HC_EPT_TD_HEAD)); 10344 10345 tailp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, 10346 Get_ED(ept->hced_tailp) & (uint32_t)HC_EPT_TD_TAIL)); 10347 10348 rval = ohci_state_is_operational(ohcip); 10349 10350 if (rval != USB_SUCCESS) { 10351 10352 return; 10353 } 10354 10355 pp->pp_count_done_tds = 0; 10356 10357 /* Process the transfer wrappers for this pipe */ 10358 next_tw = head_tw; 10359 while (next_tw) { 10360 head_td = (ohci_td_t *)next_tw->tw_hctd_head; 10361 next_td = head_td; 10362 10363 if (head_td) { 10364 /* 10365 * Walk through each TD for this transfer 10366 * wrapper. If a TD still exists, then it 10367 * is currently on the done list. 10368 */ 10369 while (next_td) { 10370 10371 nextp = headp; 10372 10373 while (nextp != tailp) { 10374 10375 /* TD is on the ED */ 10376 if (nextp == next_td) { 10377 break; 10378 } 10379 10380 nextp = (ohci_td_t *) 10381 (ohci_td_iommu_to_cpu(ohcip, 10382 (Get_TD(nextp->hctd_next_td) & 10383 HC_EPT_TD_TAIL))); 10384 } 10385 10386 if (nextp == tailp) { 10387 pp->pp_count_done_tds++; 10388 } 10389 10390 next_td = ohci_td_iommu_to_cpu(ohcip, 10391 Get_TD(next_td->hctd_tw_next_td)); 10392 } 10393 } 10394 10395 next_tw = next_tw->tw_next; 10396 } 10397 10398 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10399 "ohci_wait_for_transfers_completion: count_done_tds = 0x%x", 10400 pp->pp_count_done_tds); 10401 10402 if (!pp->pp_count_done_tds) { 10403 10404 return; 10405 } 10406 10407 /* Get the number of clock ticks to wait */ 10408 xfer_cmpl_time_wait = drv_usectohz(OHCI_XFER_CMPL_TIMEWAIT * 1000000); 10409 10410 (void) cv_timedwait(&pp->pp_xfer_cmpl_cv, 10411 &ohcip->ohci_int_mutex, 10412 ddi_get_lbolt() + xfer_cmpl_time_wait); 10413 10414 if (pp->pp_count_done_tds) { 10415 10416 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10417 "ohci_wait_for_transfers_completion: No transfers " 10418 "completion confirmation received for 0x%x requests", 10419 pp->pp_count_done_tds); 10420 } 10421 } 10422 10423 10424 /* 10425 * ohci_check_for_transfers_completion: 10426 * 10427 * Check whether anybody is waiting for transfers completion event. If so, send 10428 * this event and also stop initiating any new transfers on this pipe. 10429 */ 10430 static void 10431 ohci_check_for_transfers_completion( 10432 ohci_state_t *ohcip, 10433 ohci_pipe_private_t *pp) 10434 { 10435 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10436 "ohci_check_for_transfers_completion: pp = 0x%p", pp); 10437 10438 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10439 10440 if ((pp->pp_state == OHCI_PIPE_STATE_STOP_POLLING) && 10441 (pp->pp_error == USB_CR_NO_RESOURCES) && 10442 (pp->pp_cur_periodic_req_cnt == 0)) { 10443 10444 /* Reset pipe error to zero */ 10445 pp->pp_error = 0; 10446 10447 /* Do callback for original request */ 10448 ohci_do_client_periodic_in_req_callback( 10449 ohcip, pp, USB_CR_NO_RESOURCES); 10450 } 10451 10452 if (pp->pp_count_done_tds) { 10453 10454 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10455 "ohci_check_for_transfers_completion:" 10456 "count_done_tds = 0x%x", pp->pp_count_done_tds); 10457 10458 /* Decrement the done td count */ 10459 pp->pp_count_done_tds--; 10460 10461 if (!pp->pp_count_done_tds) { 10462 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10463 "ohci_check_for_transfers_completion:" 10464 "Sent transfers completion event pp = 0x%p", pp); 10465 10466 /* Send the transfer completion signal */ 10467 cv_signal(&pp->pp_xfer_cmpl_cv); 10468 } 10469 } 10470 } 10471 10472 10473 /* 10474 * ohci_save_data_toggle: 10475 * 10476 * Save the data toggle information. 10477 */ 10478 static void 10479 ohci_save_data_toggle( 10480 ohci_state_t *ohcip, 10481 usba_pipe_handle_data_t *ph) 10482 { 10483 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 10484 usb_ep_descr_t *eptd = &ph->p_ep; 10485 uint_t data_toggle; 10486 usb_cr_t error = pp->pp_error; 10487 ohci_ed_t *ed = pp->pp_ept; 10488 ohci_td_t *headp, *tailp; 10489 10490 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10491 "ohci_save_data_toggle: ph = 0x%p", ph); 10492 10493 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10494 10495 /* Reset the pipe error value */ 10496 pp->pp_error = USB_CR_OK; 10497 10498 /* Return immediately if it is a control or isoc pipe */ 10499 if (((eptd->bmAttributes & USB_EP_ATTR_MASK) == 10500 USB_EP_ATTR_CONTROL) || ((eptd->bmAttributes & 10501 USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH)) { 10502 10503 return; 10504 } 10505 10506 headp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, 10507 Get_ED(ed->hced_headp) & (uint32_t)HC_EPT_TD_HEAD)); 10508 10509 tailp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, 10510 Get_ED(ed->hced_tailp) & (uint32_t)HC_EPT_TD_TAIL)); 10511 10512 /* 10513 * Retrieve the data toggle information either from the endpoint 10514 * (ED) or from the transfer descriptor (TD) depending on the 10515 * situation. 10516 */ 10517 if ((Get_ED(ed->hced_headp) & HC_EPT_Halt) || (headp == tailp)) { 10518 10519 /* Get the data toggle information from the endpoint */ 10520 data_toggle = (Get_ED(ed->hced_headp) & 10521 HC_EPT_Carry)? DATA1:DATA0; 10522 } else { 10523 /* 10524 * Retrieve the data toggle information depending on the 10525 * master data toggle information saved in the transfer 10526 * descriptor (TD) at the head of the endpoint (ED). 10527 * 10528 * Check for master data toggle information . 10529 */ 10530 if (Get_TD(headp->hctd_ctrl) & HC_TD_MS_DT) { 10531 /* Get the data toggle information from td */ 10532 data_toggle = (Get_TD(headp->hctd_ctrl) & 10533 HC_TD_DT_1) ? DATA1:DATA0; 10534 } else { 10535 /* Get the data toggle information from the endpoint */ 10536 data_toggle = (Get_ED(ed->hced_headp) & 10537 HC_EPT_Carry)? DATA1:DATA0; 10538 } 10539 } 10540 10541 /* 10542 * If error is STALL, then, set 10543 * data toggle to zero. 10544 */ 10545 if (error == USB_CR_STALL) { 10546 data_toggle = DATA0; 10547 } 10548 10549 /* 10550 * Save the data toggle information 10551 * in the usb device structure. 10552 */ 10553 mutex_enter(&ph->p_mutex); 10554 usba_hcdi_set_data_toggle(ph->p_usba_device, ph->p_ep.bEndpointAddress, 10555 data_toggle); 10556 mutex_exit(&ph->p_mutex); 10557 } 10558 10559 10560 /* 10561 * ohci_restore_data_toggle: 10562 * 10563 * Restore the data toggle information. 10564 */ 10565 static void 10566 ohci_restore_data_toggle( 10567 ohci_state_t *ohcip, 10568 usba_pipe_handle_data_t *ph) 10569 { 10570 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 10571 usb_ep_descr_t *eptd = &ph->p_ep; 10572 uint_t data_toggle = 0; 10573 10574 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10575 "ohci_restore_data_toggle: ph = 0x%p", ph); 10576 10577 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10578 10579 /* 10580 * Return immediately if it is a control or isoc pipe. 10581 */ 10582 if (((eptd->bmAttributes & USB_EP_ATTR_MASK) == 10583 USB_EP_ATTR_CONTROL) || ((eptd->bmAttributes & 10584 USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH)) { 10585 10586 return; 10587 } 10588 10589 mutex_enter(&ph->p_mutex); 10590 10591 data_toggle = usba_hcdi_get_data_toggle(ph->p_usba_device, 10592 ph->p_ep.bEndpointAddress); 10593 usba_hcdi_set_data_toggle(ph->p_usba_device, ph->p_ep.bEndpointAddress, 10594 0); 10595 10596 mutex_exit(&ph->p_mutex); 10597 10598 /* 10599 * Restore the data toggle bit depending on the 10600 * previous data toggle information. 10601 */ 10602 if (data_toggle) { 10603 Set_ED(pp->pp_ept->hced_headp, 10604 Get_ED(pp->pp_ept->hced_headp) | HC_EPT_Carry); 10605 } else { 10606 Set_ED(pp->pp_ept->hced_headp, 10607 Get_ED(pp->pp_ept->hced_headp) & (~HC_EPT_Carry)); 10608 } 10609 } 10610 10611 10612 /* 10613 * ohci_handle_outstanding_requests 10614 * NOTE: This function is also called from POLLED MODE. 10615 * 10616 * Deallocate interrupt/isochronous request structure for the 10617 * interrupt/isochronous IN transfer. Do the callbacks for all 10618 * unfinished requests. 10619 */ 10620 void 10621 ohci_handle_outstanding_requests( 10622 ohci_state_t *ohcip, 10623 ohci_pipe_private_t *pp) 10624 { 10625 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 10626 usb_ep_descr_t *eptd = &ph->p_ep; 10627 ohci_trans_wrapper_t *curr_tw; 10628 ohci_trans_wrapper_t *next_tw; 10629 usb_opaque_t curr_xfer_reqp; 10630 10631 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10632 "ohci_handle_outstanding_requests: pp = 0x%p", pp); 10633 10634 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10635 10636 /* 10637 * Deallocate all the pre-allocated interrupt requests 10638 */ 10639 next_tw = pp->pp_tw_head; 10640 10641 while (next_tw) { 10642 curr_tw = next_tw; 10643 next_tw = curr_tw->tw_next; 10644 10645 curr_xfer_reqp = curr_tw->tw_curr_xfer_reqp; 10646 10647 /* Deallocate current interrupt request */ 10648 if (curr_xfer_reqp) { 10649 10650 if ((OHCI_PERIODIC_ENDPOINT(eptd)) && 10651 (curr_tw->tw_direction == HC_TD_IN)) { 10652 10653 /* Decrement periodic in request count */ 10654 pp->pp_cur_periodic_req_cnt--; 10655 10656 ohci_deallocate_periodic_in_resource( 10657 ohcip, pp, curr_tw); 10658 } else { 10659 ohci_hcdi_callback(ph, 10660 curr_tw, USB_CR_FLUSHED); 10661 } 10662 } 10663 } 10664 } 10665 10666 10667 /* 10668 * ohci_deallocate_periodic_in_resource 10669 * 10670 * Deallocate interrupt/isochronous request structure for the 10671 * interrupt/isochronous IN transfer. 10672 */ 10673 static void 10674 ohci_deallocate_periodic_in_resource( 10675 ohci_state_t *ohcip, 10676 ohci_pipe_private_t *pp, 10677 ohci_trans_wrapper_t *tw) 10678 { 10679 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 10680 uchar_t ep_attr = ph->p_ep.bmAttributes; 10681 usb_opaque_t curr_xfer_reqp; 10682 10683 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10684 "ohci_deallocate_periodic_in_resource: " 10685 "pp = 0x%p tw = 0x%p", pp, tw); 10686 10687 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10688 10689 curr_xfer_reqp = tw->tw_curr_xfer_reqp; 10690 10691 /* Check the current periodic in request pointer */ 10692 if (curr_xfer_reqp) { 10693 /* 10694 * Reset periodic in request usb isoch 10695 * packet request pointers to null. 10696 */ 10697 tw->tw_curr_xfer_reqp = NULL; 10698 tw->tw_curr_isoc_pktp = NULL; 10699 10700 mutex_enter(&ph->p_mutex); 10701 ph->p_req_count--; 10702 mutex_exit(&ph->p_mutex); 10703 10704 /* 10705 * Free pre-allocated interrupt 10706 * or isochronous requests. 10707 */ 10708 switch (ep_attr & USB_EP_ATTR_MASK) { 10709 case USB_EP_ATTR_INTR: 10710 usb_free_intr_req( 10711 (usb_intr_req_t *)curr_xfer_reqp); 10712 break; 10713 case USB_EP_ATTR_ISOCH: 10714 usb_free_isoc_req( 10715 (usb_isoc_req_t *)curr_xfer_reqp); 10716 break; 10717 } 10718 } 10719 } 10720 10721 10722 /* 10723 * ohci_do_client_periodic_in_req_callback 10724 * 10725 * Do callback for the original client periodic IN request. 10726 */ 10727 static void 10728 ohci_do_client_periodic_in_req_callback( 10729 ohci_state_t *ohcip, 10730 ohci_pipe_private_t *pp, 10731 usb_cr_t completion_reason) 10732 { 10733 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 10734 10735 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10736 "ohci_do_client_periodic_in_req_callback: " 10737 "pp = 0x%p cc = 0x%x", pp, completion_reason); 10738 10739 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10740 10741 /* 10742 * Check for Interrupt/Isochronous IN, whether we need to do 10743 * callback for the original client's periodic IN request. 10744 */ 10745 if (pp->pp_client_periodic_in_reqp) { 10746 ASSERT(pp->pp_cur_periodic_req_cnt == 0); 10747 ohci_hcdi_callback(ph, NULL, completion_reason); 10748 } 10749 } 10750 10751 10752 /* 10753 * ohci_hcdi_callback() 10754 * 10755 * Convenience wrapper around usba_hcdi_cb() other than root hub. 10756 */ 10757 static void 10758 ohci_hcdi_callback( 10759 usba_pipe_handle_data_t *ph, 10760 ohci_trans_wrapper_t *tw, 10761 usb_cr_t completion_reason) 10762 { 10763 ohci_state_t *ohcip = ohci_obtain_state( 10764 ph->p_usba_device->usb_root_hub_dip); 10765 uchar_t attributes = ph->p_ep.bmAttributes & 10766 USB_EP_ATTR_MASK; 10767 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 10768 usb_opaque_t curr_xfer_reqp; 10769 uint_t pipe_state = 0; 10770 10771 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10772 "ohci_hcdi_callback: ph = 0x%p, tw = 0x%p, cr = 0x%x", 10773 ph, tw, completion_reason); 10774 10775 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10776 10777 /* Set the pipe state as per completion reason */ 10778 switch (completion_reason) { 10779 case USB_CR_OK: 10780 pipe_state = pp->pp_state; 10781 break; 10782 case USB_CR_NO_RESOURCES: 10783 case USB_CR_NOT_SUPPORTED: 10784 case USB_CR_STOPPED_POLLING: 10785 case USB_CR_PIPE_RESET: 10786 pipe_state = OHCI_PIPE_STATE_IDLE; 10787 break; 10788 case USB_CR_PIPE_CLOSING: 10789 break; 10790 default: 10791 /* 10792 * Set the pipe state to error 10793 * except for the isoc pipe. 10794 */ 10795 if (attributes != USB_EP_ATTR_ISOCH) { 10796 pipe_state = OHCI_PIPE_STATE_ERROR; 10797 pp->pp_error = completion_reason; 10798 } 10799 break; 10800 10801 } 10802 10803 pp->pp_state = pipe_state; 10804 10805 if (tw && tw->tw_curr_xfer_reqp) { 10806 curr_xfer_reqp = tw->tw_curr_xfer_reqp; 10807 tw->tw_curr_xfer_reqp = NULL; 10808 tw->tw_curr_isoc_pktp = NULL; 10809 } else { 10810 ASSERT(pp->pp_client_periodic_in_reqp != NULL); 10811 10812 curr_xfer_reqp = pp->pp_client_periodic_in_reqp; 10813 pp->pp_client_periodic_in_reqp = NULL; 10814 } 10815 10816 ASSERT(curr_xfer_reqp != NULL); 10817 10818 mutex_exit(&ohcip->ohci_int_mutex); 10819 10820 usba_hcdi_cb(ph, curr_xfer_reqp, completion_reason); 10821 10822 mutex_enter(&ohcip->ohci_int_mutex); 10823 } 10824 10825 10826 /* 10827 * ohci kstat functions 10828 */ 10829 10830 /* 10831 * ohci_create_stats: 10832 * 10833 * Allocate and initialize the ohci kstat structures 10834 */ 10835 static void 10836 ohci_create_stats(ohci_state_t *ohcip) 10837 { 10838 char kstatname[KSTAT_STRLEN]; 10839 const char *dname = ddi_driver_name(ohcip->ohci_dip); 10840 char *usbtypes[USB_N_COUNT_KSTATS] = 10841 {"ctrl", "isoch", "bulk", "intr"}; 10842 uint_t instance = ohcip->ohci_instance; 10843 ohci_intrs_stats_t *isp; 10844 int i; 10845 10846 if (OHCI_INTRS_STATS(ohcip) == NULL) { 10847 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,intrs", 10848 dname, instance); 10849 OHCI_INTRS_STATS(ohcip) = kstat_create("usba", instance, 10850 kstatname, "usb_interrupts", KSTAT_TYPE_NAMED, 10851 sizeof (ohci_intrs_stats_t) / sizeof (kstat_named_t), 10852 KSTAT_FLAG_PERSISTENT); 10853 10854 if (OHCI_INTRS_STATS(ohcip)) { 10855 isp = OHCI_INTRS_STATS_DATA(ohcip); 10856 kstat_named_init(&isp->ohci_hcr_intr_total, 10857 "Interrupts Total", KSTAT_DATA_UINT64); 10858 kstat_named_init(&isp->ohci_hcr_intr_not_claimed, 10859 "Not Claimed", KSTAT_DATA_UINT64); 10860 kstat_named_init(&isp->ohci_hcr_intr_so, 10861 "Schedule Overruns", KSTAT_DATA_UINT64); 10862 kstat_named_init(&isp->ohci_hcr_intr_wdh, 10863 "Writeback Done Head", KSTAT_DATA_UINT64); 10864 kstat_named_init(&isp->ohci_hcr_intr_sof, 10865 "Start Of Frame", KSTAT_DATA_UINT64); 10866 kstat_named_init(&isp->ohci_hcr_intr_rd, 10867 "Resume Detected", KSTAT_DATA_UINT64); 10868 kstat_named_init(&isp->ohci_hcr_intr_ue, 10869 "Unrecoverable Error", KSTAT_DATA_UINT64); 10870 kstat_named_init(&isp->ohci_hcr_intr_fno, 10871 "Frame No. Overflow", KSTAT_DATA_UINT64); 10872 kstat_named_init(&isp->ohci_hcr_intr_rhsc, 10873 "Root Hub Status Change", KSTAT_DATA_UINT64); 10874 kstat_named_init(&isp->ohci_hcr_intr_oc, 10875 "Change In Ownership", KSTAT_DATA_UINT64); 10876 10877 OHCI_INTRS_STATS(ohcip)->ks_private = ohcip; 10878 OHCI_INTRS_STATS(ohcip)->ks_update = nulldev; 10879 kstat_install(OHCI_INTRS_STATS(ohcip)); 10880 } 10881 } 10882 10883 if (OHCI_TOTAL_STATS(ohcip) == NULL) { 10884 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,total", 10885 dname, instance); 10886 OHCI_TOTAL_STATS(ohcip) = kstat_create("usba", instance, 10887 kstatname, "usb_byte_count", KSTAT_TYPE_IO, 1, 10888 KSTAT_FLAG_PERSISTENT); 10889 10890 if (OHCI_TOTAL_STATS(ohcip)) { 10891 kstat_install(OHCI_TOTAL_STATS(ohcip)); 10892 } 10893 } 10894 10895 for (i = 0; i < USB_N_COUNT_KSTATS; i++) { 10896 if (ohcip->ohci_count_stats[i] == NULL) { 10897 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,%s", 10898 dname, instance, usbtypes[i]); 10899 ohcip->ohci_count_stats[i] = kstat_create("usba", 10900 instance, kstatname, "usb_byte_count", 10901 KSTAT_TYPE_IO, 1, KSTAT_FLAG_PERSISTENT); 10902 10903 if (ohcip->ohci_count_stats[i]) { 10904 kstat_install(ohcip->ohci_count_stats[i]); 10905 } 10906 } 10907 } 10908 } 10909 10910 10911 /* 10912 * ohci_destroy_stats: 10913 * 10914 * Clean up ohci kstat structures 10915 */ 10916 static void 10917 ohci_destroy_stats(ohci_state_t *ohcip) 10918 { 10919 int i; 10920 10921 if (OHCI_INTRS_STATS(ohcip)) { 10922 kstat_delete(OHCI_INTRS_STATS(ohcip)); 10923 OHCI_INTRS_STATS(ohcip) = NULL; 10924 } 10925 10926 if (OHCI_TOTAL_STATS(ohcip)) { 10927 kstat_delete(OHCI_TOTAL_STATS(ohcip)); 10928 OHCI_TOTAL_STATS(ohcip) = NULL; 10929 } 10930 10931 for (i = 0; i < USB_N_COUNT_KSTATS; i++) { 10932 if (ohcip->ohci_count_stats[i]) { 10933 kstat_delete(ohcip->ohci_count_stats[i]); 10934 ohcip->ohci_count_stats[i] = NULL; 10935 } 10936 } 10937 } 10938 10939 10940 /* 10941 * ohci_do_intrs_stats: 10942 * 10943 * ohci status information 10944 */ 10945 static void 10946 ohci_do_intrs_stats( 10947 ohci_state_t *ohcip, 10948 int val) 10949 { 10950 if (OHCI_INTRS_STATS(ohcip)) { 10951 OHCI_INTRS_STATS_DATA(ohcip)->ohci_hcr_intr_total.value.ui64++; 10952 switch (val) { 10953 case HCR_INTR_SO: 10954 OHCI_INTRS_STATS_DATA(ohcip)-> 10955 ohci_hcr_intr_so.value.ui64++; 10956 break; 10957 case HCR_INTR_WDH: 10958 OHCI_INTRS_STATS_DATA(ohcip)-> 10959 ohci_hcr_intr_wdh.value.ui64++; 10960 break; 10961 case HCR_INTR_SOF: 10962 OHCI_INTRS_STATS_DATA(ohcip)-> 10963 ohci_hcr_intr_sof.value.ui64++; 10964 break; 10965 case HCR_INTR_RD: 10966 OHCI_INTRS_STATS_DATA(ohcip)-> 10967 ohci_hcr_intr_rd.value.ui64++; 10968 break; 10969 case HCR_INTR_UE: 10970 OHCI_INTRS_STATS_DATA(ohcip)-> 10971 ohci_hcr_intr_ue.value.ui64++; 10972 break; 10973 case HCR_INTR_FNO: 10974 OHCI_INTRS_STATS_DATA(ohcip)-> 10975 ohci_hcr_intr_fno.value.ui64++; 10976 break; 10977 case HCR_INTR_RHSC: 10978 OHCI_INTRS_STATS_DATA(ohcip)-> 10979 ohci_hcr_intr_rhsc.value.ui64++; 10980 break; 10981 case HCR_INTR_OC: 10982 OHCI_INTRS_STATS_DATA(ohcip)-> 10983 ohci_hcr_intr_oc.value.ui64++; 10984 break; 10985 default: 10986 OHCI_INTRS_STATS_DATA(ohcip)-> 10987 ohci_hcr_intr_not_claimed.value.ui64++; 10988 break; 10989 } 10990 } 10991 } 10992 10993 10994 /* 10995 * ohci_do_byte_stats: 10996 * 10997 * ohci data xfer information 10998 */ 10999 static void 11000 ohci_do_byte_stats( 11001 ohci_state_t *ohcip, 11002 size_t len, 11003 uint8_t attr, 11004 uint8_t addr) 11005 { 11006 uint8_t type = attr & USB_EP_ATTR_MASK; 11007 uint8_t dir = addr & USB_EP_DIR_MASK; 11008 11009 if (dir == USB_EP_DIR_IN) { 11010 OHCI_TOTAL_STATS_DATA(ohcip)->reads++; 11011 OHCI_TOTAL_STATS_DATA(ohcip)->nread += len; 11012 switch (type) { 11013 case USB_EP_ATTR_CONTROL: 11014 OHCI_CTRL_STATS(ohcip)->reads++; 11015 OHCI_CTRL_STATS(ohcip)->nread += len; 11016 break; 11017 case USB_EP_ATTR_BULK: 11018 OHCI_BULK_STATS(ohcip)->reads++; 11019 OHCI_BULK_STATS(ohcip)->nread += len; 11020 break; 11021 case USB_EP_ATTR_INTR: 11022 OHCI_INTR_STATS(ohcip)->reads++; 11023 OHCI_INTR_STATS(ohcip)->nread += len; 11024 break; 11025 case USB_EP_ATTR_ISOCH: 11026 OHCI_ISOC_STATS(ohcip)->reads++; 11027 OHCI_ISOC_STATS(ohcip)->nread += len; 11028 break; 11029 } 11030 } else if (dir == USB_EP_DIR_OUT) { 11031 OHCI_TOTAL_STATS_DATA(ohcip)->writes++; 11032 OHCI_TOTAL_STATS_DATA(ohcip)->nwritten += len; 11033 switch (type) { 11034 case USB_EP_ATTR_CONTROL: 11035 OHCI_CTRL_STATS(ohcip)->writes++; 11036 OHCI_CTRL_STATS(ohcip)->nwritten += len; 11037 break; 11038 case USB_EP_ATTR_BULK: 11039 OHCI_BULK_STATS(ohcip)->writes++; 11040 OHCI_BULK_STATS(ohcip)->nwritten += len; 11041 break; 11042 case USB_EP_ATTR_INTR: 11043 OHCI_INTR_STATS(ohcip)->writes++; 11044 OHCI_INTR_STATS(ohcip)->nwritten += len; 11045 break; 11046 case USB_EP_ATTR_ISOCH: 11047 OHCI_ISOC_STATS(ohcip)->writes++; 11048 OHCI_ISOC_STATS(ohcip)->nwritten += len; 11049 break; 11050 } 11051 } 11052 } 11053 11054 11055 /* 11056 * ohci_print_op_regs: 11057 * 11058 * Print Host Controller's (HC) Operational registers. 11059 */ 11060 static void 11061 ohci_print_op_regs(ohci_state_t *ohcip) 11062 { 11063 uint_t i; 11064 11065 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11066 "\n\tOHCI%d Operational Registers\n", 11067 ddi_get_instance(ohcip->ohci_dip)); 11068 11069 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11070 "\thcr_revision: 0x%x \t\thcr_control: 0x%x", 11071 Get_OpReg(hcr_revision), Get_OpReg(hcr_control)); 11072 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11073 "\thcr_cmd_status: 0x%x \t\thcr_intr_enable: 0x%x", 11074 Get_OpReg(hcr_cmd_status), Get_OpReg(hcr_intr_enable)); 11075 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11076 "\thcr_intr_disable: 0x%x \thcr_HCCA: 0x%x", 11077 Get_OpReg(hcr_intr_disable), Get_OpReg(hcr_HCCA)); 11078 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11079 "\thcr_periodic_curr: 0x%x \t\thcr_ctrl_head: 0x%x", 11080 Get_OpReg(hcr_periodic_curr), Get_OpReg(hcr_ctrl_head)); 11081 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11082 "\thcr_ctrl_curr: 0x%x \t\thcr_bulk_head: 0x%x", 11083 Get_OpReg(hcr_ctrl_curr), Get_OpReg(hcr_bulk_head)); 11084 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11085 "\thcr_bulk_curr: 0x%x \t\thcr_done_head: 0x%x", 11086 Get_OpReg(hcr_bulk_curr), Get_OpReg(hcr_done_head)); 11087 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11088 "\thcr_frame_interval: 0x%x " 11089 "\thcr_frame_remaining: 0x%x", Get_OpReg(hcr_frame_interval), 11090 Get_OpReg(hcr_frame_remaining)); 11091 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11092 "\thcr_frame_number: 0x%x \thcr_periodic_strt: 0x%x", 11093 Get_OpReg(hcr_frame_number), Get_OpReg(hcr_periodic_strt)); 11094 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11095 "\thcr_transfer_ls: 0x%x \t\thcr_rh_descriptorA: 0x%x", 11096 Get_OpReg(hcr_transfer_ls), Get_OpReg(hcr_rh_descriptorA)); 11097 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11098 "\thcr_rh_descriptorB: 0x%x \thcr_rh_status: 0x%x", 11099 Get_OpReg(hcr_rh_descriptorB), Get_OpReg(hcr_rh_status)); 11100 11101 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11102 "\tRoot hub port status"); 11103 11104 for (i = 0; i < (Get_OpReg(hcr_rh_descriptorA) & HCR_RHA_NDP); i++) { 11105 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11106 "\thcr_rh_portstatus 0x%x: 0x%x ", i, 11107 Get_OpReg(hcr_rh_portstatus[i])); 11108 } 11109 } 11110 11111 11112 /* 11113 * ohci_print_ed: 11114 */ 11115 static void 11116 ohci_print_ed( 11117 ohci_state_t *ohcip, 11118 ohci_ed_t *ed) 11119 { 11120 uint_t ctrl = Get_ED(ed->hced_ctrl); 11121 11122 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11123 "ohci_print_ed: ed = 0x%p", (void *)ed); 11124 11125 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11126 "\thced_ctrl: 0x%x %s", ctrl, 11127 ((Get_ED(ed->hced_headp) & HC_EPT_Halt) ? "halted": "")); 11128 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11129 "\ttoggle carry: 0x%x", Get_ED(ed->hced_headp) & HC_EPT_Carry); 11130 11131 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11132 "\tctrl: 0x%x", Get_ED(ed->hced_ctrl)); 11133 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11134 "\ttailp: 0x%x", Get_ED(ed->hced_tailp)); 11135 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11136 "\theadp: 0x%x", Get_ED(ed->hced_headp)); 11137 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11138 "\tnext: 0x%x", Get_ED(ed->hced_next)); 11139 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11140 "\tprev: 0x%x", Get_ED(ed->hced_prev)); 11141 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11142 "\tnode: 0x%x", Get_ED(ed->hced_node)); 11143 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11144 "\treclaim_next: 0x%x", Get_ED(ed->hced_reclaim_next)); 11145 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11146 "\treclaim_frame: 0x%x", Get_ED(ed->hced_reclaim_frame)); 11147 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11148 "\tstate: 0x%x", Get_ED(ed->hced_state)); 11149 } 11150 11151 11152 /* 11153 * ohci_print_td: 11154 */ 11155 static void 11156 ohci_print_td( 11157 ohci_state_t *ohcip, 11158 ohci_td_t *td) 11159 { 11160 uint_t i; 11161 uint_t ctrl = Get_TD(td->hctd_ctrl); 11162 11163 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11164 "ohci_print_td: td = 0x%p", (void *)td); 11165 11166 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11167 "\tPID: 0x%x ", ctrl & HC_TD_PID); 11168 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11169 "\tDelay Intr: 0x%x ", ctrl & HC_TD_DI); 11170 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11171 "\tData Toggle: 0x%x ", ctrl & HC_TD_DT); 11172 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11173 "\tError Count: 0x%x ", ctrl & HC_TD_EC); 11174 11175 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11176 "\tctrl: 0x%x ", Get_TD(td->hctd_ctrl)); 11177 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11178 "\tcbp: 0x%x ", Get_TD(td->hctd_cbp)); 11179 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11180 "\tnext_td: 0x%x ", Get_TD(td->hctd_next_td)); 11181 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11182 "\tbuf_end: 0x%x ", Get_TD(td->hctd_buf_end)); 11183 11184 for (i = 0; i < 4; i++) { 11185 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11186 "\toffset[%d]: 0x%x ", i, Get_TD(td->hctd_offsets[i])); 11187 } 11188 11189 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11190 "\ttrans_wrapper: 0x%x ", Get_TD(td->hctd_trans_wrapper)); 11191 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11192 "\tstate: 0x%x ", Get_TD(td->hctd_state)); 11193 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11194 "\ttw_next_td: 0x%x ", Get_TD(td->hctd_tw_next_td)); 11195 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11196 "\tctrl_phase: 0x%x ", Get_TD(td->hctd_ctrl_phase)); 11197 } 11198