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