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