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