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