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