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