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