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