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