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