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