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