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