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