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 while holding mutex */ 6888 kmem_flag = KM_NOSLEEP; 6889 dmamem_wait = DDI_DMA_DONTWAIT; 6890 6891 /* Allocate space for the transfer wrapper */ 6892 tw = kmem_zalloc(sizeof (ohci_trans_wrapper_t), kmem_flag); 6893 6894 if (tw == NULL) { 6895 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6896 "ohci_create_transfer_wrapper: kmem_zalloc failed"); 6897 6898 return (NULL); 6899 } 6900 6901 /* zero-length packet doesn't need to allocate dma memory */ 6902 if (length == 0) { 6903 6904 goto dmadone; 6905 } 6906 6907 /* allow sg lists for transfer wrapper dma memory */ 6908 bcopy(&ohcip->ohci_dma_attr, &dma_attr, sizeof (ddi_dma_attr_t)); 6909 dma_attr.dma_attr_sgllen = OHCI_DMA_ATTR_TW_SGLLEN; 6910 dma_attr.dma_attr_align = OHCI_DMA_ATTR_ALIGNMENT; 6911 6912 /* Allocate the DMA handle */ 6913 result = ddi_dma_alloc_handle(ohcip->ohci_dip, 6914 &dma_attr, dmamem_wait, 0, &tw->tw_dmahandle); 6915 6916 if (result != DDI_SUCCESS) { 6917 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6918 "ohci_create_transfer_wrapper: Alloc handle failed"); 6919 6920 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 6921 6922 return (NULL); 6923 } 6924 6925 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 6926 6927 /* The host controller will be little endian */ 6928 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_BE_ACC; 6929 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 6930 6931 /* Allocate the memory */ 6932 result = ddi_dma_mem_alloc(tw->tw_dmahandle, length, 6933 &dev_attr, DDI_DMA_CONSISTENT, dmamem_wait, NULL, 6934 (caddr_t *)&tw->tw_buf, &real_length, &tw->tw_accesshandle); 6935 6936 if (result != DDI_SUCCESS) { 6937 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6938 "ohci_create_transfer_wrapper: dma_mem_alloc fail"); 6939 6940 ddi_dma_free_handle(&tw->tw_dmahandle); 6941 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 6942 6943 return (NULL); 6944 } 6945 6946 ASSERT(real_length >= length); 6947 6948 /* Bind the handle */ 6949 result = ddi_dma_addr_bind_handle(tw->tw_dmahandle, NULL, 6950 (caddr_t)tw->tw_buf, real_length, DDI_DMA_RDWR|DDI_DMA_CONSISTENT, 6951 dmamem_wait, NULL, &tw->tw_cookie, &tw->tw_ncookies); 6952 6953 if (result != DDI_DMA_MAPPED) { 6954 ohci_decode_ddi_dma_addr_bind_handle_result(ohcip, result); 6955 6956 ddi_dma_mem_free(&tw->tw_accesshandle); 6957 ddi_dma_free_handle(&tw->tw_dmahandle); 6958 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 6959 6960 return (NULL); 6961 } 6962 6963 tw->tw_cookie_idx = 0; 6964 tw->tw_dma_offs = 0; 6965 6966 dmadone: 6967 /* 6968 * Only allow one wrapper to be added at a time. Insert the 6969 * new transaction wrapper into the list for this pipe. 6970 */ 6971 if (pp->pp_tw_head == NULL) { 6972 pp->pp_tw_head = tw; 6973 pp->pp_tw_tail = tw; 6974 } else { 6975 pp->pp_tw_tail->tw_next = tw; 6976 pp->pp_tw_tail = tw; 6977 } 6978 6979 /* Store the transfer length */ 6980 tw->tw_length = length; 6981 6982 /* Store a back pointer to the pipe private structure */ 6983 tw->tw_pipe_private = pp; 6984 6985 /* Store the transfer type - synchronous or asynchronous */ 6986 tw->tw_flags = usb_flags; 6987 6988 /* Get and Store 32bit ID */ 6989 tw->tw_id = OHCI_GET_ID((void *)tw); 6990 6991 ASSERT(tw->tw_id != NULL); 6992 6993 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 6994 "ohci_create_transfer_wrapper: tw = 0x%p, ncookies = %u", 6995 (void *)tw, tw->tw_ncookies); 6996 6997 return (tw); 6998 } 6999 7000 7001 /* 7002 * Transfer Wrapper functions 7003 * 7004 * ohci_create_isoc_transfer_wrapper: 7005 * 7006 * Create a Transaction Wrapper (TW) for isoc transfer 7007 * and this involves the allocating of DMA resources. 7008 */ 7009 static ohci_trans_wrapper_t * 7010 ohci_create_isoc_transfer_wrapper( 7011 ohci_state_t *ohcip, 7012 ohci_pipe_private_t *pp, 7013 size_t length, 7014 usb_isoc_pkt_descr_t *descr, 7015 ushort_t pkt_count, 7016 size_t td_count, 7017 uint_t usb_flags) 7018 { 7019 ddi_device_acc_attr_t dev_attr; 7020 int result; 7021 size_t real_length, xfer_size; 7022 uint_t ccount; 7023 ohci_trans_wrapper_t *tw; 7024 ddi_dma_attr_t dma_attr; 7025 int kmem_flag; 7026 uint_t i, j, frame_count, residue; 7027 int (*dmamem_wait)(caddr_t); 7028 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 7029 usb_isoc_pkt_descr_t *isoc_pkt_descr = descr; 7030 7031 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7032 "ohci_create_isoc_transfer_wrapper: length = 0x%lx flags = 0x%x", 7033 length, usb_flags); 7034 7035 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7036 7037 /* non-isochronous pipe should not call into this function */ 7038 if ((ph->p_ep.bmAttributes & USB_EP_ATTR_MASK) != 7039 USB_EP_ATTR_ISOCH) { 7040 7041 return (NULL); 7042 } 7043 7044 /* SLEEP flag should not be used in interrupt context */ 7045 if (servicing_interrupt()) { 7046 kmem_flag = KM_NOSLEEP; 7047 dmamem_wait = DDI_DMA_DONTWAIT; 7048 } else { 7049 kmem_flag = KM_SLEEP; 7050 dmamem_wait = DDI_DMA_SLEEP; 7051 } 7052 7053 /* Allocate space for the transfer wrapper */ 7054 tw = kmem_zalloc(sizeof (ohci_trans_wrapper_t), kmem_flag); 7055 7056 if (tw == NULL) { 7057 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7058 "ohci_create_transfer_wrapper: kmem_zalloc failed"); 7059 7060 return (NULL); 7061 } 7062 7063 /* Allocate space for the isoc buffer handles */ 7064 tw->tw_isoc_strtlen = sizeof (ohci_isoc_buf_t) * td_count; 7065 if ((tw->tw_isoc_bufs = kmem_zalloc(tw->tw_isoc_strtlen, 7066 kmem_flag)) == NULL) { 7067 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 7068 "ohci_create_isoc_transfer_wrapper: kmem_alloc " 7069 "isoc buffer failed"); 7070 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 7071 7072 return (NULL); 7073 } 7074 7075 /* allow sg lists for transfer wrapper dma memory */ 7076 bcopy(&ohcip->ohci_dma_attr, &dma_attr, sizeof (ddi_dma_attr_t)); 7077 dma_attr.dma_attr_sgllen = OHCI_DMA_ATTR_TD_SGLLEN; 7078 dma_attr.dma_attr_align = OHCI_DMA_ATTR_ALIGNMENT; 7079 7080 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 7081 7082 /* The host controller will be little endian */ 7083 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_BE_ACC; 7084 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 7085 7086 residue = pkt_count % OHCI_ISOC_PKTS_PER_TD; 7087 7088 for (i = 0; i < td_count; i++) { 7089 tw->tw_isoc_bufs[i].index = i; 7090 7091 if ((i == (td_count - 1)) && (residue != 0)) { 7092 frame_count = residue; 7093 } else { 7094 frame_count = OHCI_ISOC_PKTS_PER_TD; 7095 } 7096 7097 /* Allocate the DMA handle */ 7098 result = ddi_dma_alloc_handle(ohcip->ohci_dip, &dma_attr, 7099 dmamem_wait, 0, &tw->tw_isoc_bufs[i].dma_handle); 7100 7101 if (result != DDI_SUCCESS) { 7102 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7103 "ohci_create_isoc_transfer_wrapper: " 7104 "Alloc handle failed"); 7105 7106 for (j = 0; j < i; j++) { 7107 result = ddi_dma_unbind_handle( 7108 tw->tw_isoc_bufs[j].dma_handle); 7109 ASSERT(result == USB_SUCCESS); 7110 ddi_dma_mem_free(&tw->tw_isoc_bufs[j]. 7111 mem_handle); 7112 ddi_dma_free_handle(&tw->tw_isoc_bufs[j]. 7113 dma_handle); 7114 } 7115 kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen); 7116 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 7117 7118 return (NULL); 7119 } 7120 7121 /* Compute the memory length */ 7122 for (xfer_size = 0, j = 0; j < frame_count; j++) { 7123 ASSERT(isoc_pkt_descr != NULL); 7124 xfer_size += isoc_pkt_descr->isoc_pkt_length; 7125 isoc_pkt_descr++; 7126 } 7127 7128 /* Allocate the memory */ 7129 result = ddi_dma_mem_alloc(tw->tw_isoc_bufs[i].dma_handle, 7130 xfer_size, &dev_attr, DDI_DMA_CONSISTENT, dmamem_wait, 7131 NULL, (caddr_t *)&tw->tw_isoc_bufs[i].buf_addr, 7132 &real_length, &tw->tw_isoc_bufs[i].mem_handle); 7133 7134 if (result != DDI_SUCCESS) { 7135 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7136 "ohci_create_isoc_transfer_wrapper: " 7137 "dma_mem_alloc %d fail", i); 7138 ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle); 7139 7140 for (j = 0; j < i; j++) { 7141 result = ddi_dma_unbind_handle( 7142 tw->tw_isoc_bufs[j].dma_handle); 7143 ASSERT(result == USB_SUCCESS); 7144 ddi_dma_mem_free(&tw->tw_isoc_bufs[j]. 7145 mem_handle); 7146 ddi_dma_free_handle(&tw->tw_isoc_bufs[j]. 7147 dma_handle); 7148 } 7149 kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen); 7150 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 7151 7152 return (NULL); 7153 } 7154 7155 ASSERT(real_length >= xfer_size); 7156 7157 /* Bind the handle */ 7158 result = ddi_dma_addr_bind_handle( 7159 tw->tw_isoc_bufs[i].dma_handle, NULL, 7160 (caddr_t)tw->tw_isoc_bufs[i].buf_addr, real_length, 7161 DDI_DMA_RDWR|DDI_DMA_CONSISTENT, dmamem_wait, NULL, 7162 &tw->tw_isoc_bufs[i].cookie, &ccount); 7163 7164 if ((result == DDI_DMA_MAPPED) && 7165 (ccount <= OHCI_DMA_ATTR_TD_SGLLEN)) { 7166 tw->tw_isoc_bufs[i].length = xfer_size; 7167 tw->tw_isoc_bufs[i].ncookies = ccount; 7168 7169 continue; 7170 } else { 7171 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7172 "ohci_create_isoc_transfer_wrapper: " 7173 "Bind handle %d failed", i); 7174 if (result == DDI_DMA_MAPPED) { 7175 result = ddi_dma_unbind_handle( 7176 tw->tw_isoc_bufs[i].dma_handle); 7177 ASSERT(result == USB_SUCCESS); 7178 } 7179 ddi_dma_mem_free(&tw->tw_isoc_bufs[i].mem_handle); 7180 ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle); 7181 7182 for (j = 0; j < i; j++) { 7183 result = ddi_dma_unbind_handle( 7184 tw->tw_isoc_bufs[j].dma_handle); 7185 ASSERT(result == USB_SUCCESS); 7186 ddi_dma_mem_free(&tw->tw_isoc_bufs[j]. 7187 mem_handle); 7188 ddi_dma_free_handle(&tw->tw_isoc_bufs[j]. 7189 dma_handle); 7190 } 7191 kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen); 7192 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 7193 7194 return (NULL); 7195 } 7196 } 7197 7198 /* 7199 * Only allow one wrapper to be added at a time. Insert the 7200 * new transaction wrapper into the list for this pipe. 7201 */ 7202 if (pp->pp_tw_head == NULL) { 7203 pp->pp_tw_head = tw; 7204 pp->pp_tw_tail = tw; 7205 } else { 7206 pp->pp_tw_tail->tw_next = tw; 7207 pp->pp_tw_tail = tw; 7208 } 7209 7210 /* Store the transfer length */ 7211 tw->tw_length = length; 7212 7213 /* Store the td numbers */ 7214 tw->tw_ncookies = (uint_t)td_count; 7215 7216 /* Store a back pointer to the pipe private structure */ 7217 tw->tw_pipe_private = pp; 7218 7219 /* Store the transfer type - synchronous or asynchronous */ 7220 tw->tw_flags = usb_flags; 7221 7222 /* Get and Store 32bit ID */ 7223 tw->tw_id = OHCI_GET_ID((void *)tw); 7224 7225 ASSERT(tw->tw_id != NULL); 7226 7227 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7228 "ohci_create_isoc_transfer_wrapper: tw = 0x%p", (void *)tw); 7229 7230 return (tw); 7231 } 7232 7233 7234 /* 7235 * ohci_start_xfer_timer: 7236 * 7237 * Start the timer for the control, bulk and for one time interrupt 7238 * transfers. 7239 */ 7240 /* ARGSUSED */ 7241 static void 7242 ohci_start_xfer_timer( 7243 ohci_state_t *ohcip, 7244 ohci_pipe_private_t *pp, 7245 ohci_trans_wrapper_t *tw) 7246 { 7247 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 7248 "ohci_start_xfer_timer: tw = 0x%p", (void *)tw); 7249 7250 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7251 7252 /* 7253 * The timeout handling is done only for control, bulk and for 7254 * one time Interrupt transfers. 7255 * 7256 * NOTE: If timeout is zero; Assume infinite timeout and don't 7257 * insert this transfer on the timeout list. 7258 */ 7259 if (tw->tw_timeout) { 7260 /* 7261 * Increase timeout value by one second and this extra one 7262 * second is used to halt the endpoint if given transfer 7263 * times out. 7264 */ 7265 tw->tw_timeout++; 7266 7267 /* 7268 * Add this transfer wrapper into the transfer timeout list. 7269 */ 7270 if (ohcip->ohci_timeout_list) { 7271 tw->tw_timeout_next = ohcip->ohci_timeout_list; 7272 } 7273 7274 ohcip->ohci_timeout_list = tw; 7275 ohci_start_timer(ohcip); 7276 } 7277 } 7278 7279 7280 /* 7281 * ohci_stop_xfer_timer: 7282 * 7283 * Start the timer for the control, bulk and for one time interrupt 7284 * transfers. 7285 */ 7286 void 7287 ohci_stop_xfer_timer( 7288 ohci_state_t *ohcip, 7289 ohci_trans_wrapper_t *tw, 7290 uint_t flag) 7291 { 7292 timeout_id_t timer_id; 7293 7294 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 7295 "ohci_stop_xfer_timer: tw = 0x%p", (void *)tw); 7296 7297 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7298 7299 /* 7300 * The timeout handling is done only for control, bulk 7301 * and for one time Interrupt transfers. 7302 */ 7303 if (ohcip->ohci_timeout_list == NULL) { 7304 return; 7305 } 7306 7307 switch (flag) { 7308 case OHCI_REMOVE_XFER_IFLAST: 7309 if (tw->tw_hctd_head != tw->tw_hctd_tail) { 7310 break; 7311 } 7312 /* FALLTHRU */ 7313 case OHCI_REMOVE_XFER_ALWAYS: 7314 ohci_remove_tw_from_timeout_list(ohcip, tw); 7315 7316 if ((ohcip->ohci_timeout_list == NULL) && 7317 (ohcip->ohci_timer_id)) { 7318 7319 timer_id = ohcip->ohci_timer_id; 7320 7321 /* Reset the timer id to zero */ 7322 ohcip->ohci_timer_id = 0; 7323 7324 mutex_exit(&ohcip->ohci_int_mutex); 7325 7326 (void) untimeout(timer_id); 7327 7328 mutex_enter(&ohcip->ohci_int_mutex); 7329 } 7330 break; 7331 default: 7332 break; 7333 } 7334 } 7335 7336 7337 /* 7338 * ohci_xfer_timeout_handler: 7339 * 7340 * Control or bulk transfer timeout handler. 7341 */ 7342 static void 7343 ohci_xfer_timeout_handler(void *arg) 7344 { 7345 ohci_state_t *ohcip = (ohci_state_t *)arg; 7346 ohci_trans_wrapper_t *exp_xfer_list_head = NULL; 7347 ohci_trans_wrapper_t *exp_xfer_list_tail = NULL; 7348 ohci_trans_wrapper_t *tw, *next; 7349 ohci_td_t *td; 7350 usb_flags_t flags; 7351 7352 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 7353 "ohci_xfer_timeout_handler: ohcip = 0x%p", (void *)ohcip); 7354 7355 mutex_enter(&ohcip->ohci_int_mutex); 7356 7357 /* Set the required flags */ 7358 flags = OHCI_FLAGS_NOSLEEP | OHCI_FLAGS_DMA_SYNC; 7359 7360 /* 7361 * Check whether still timeout handler is valid. 7362 */ 7363 if (ohcip->ohci_timer_id) { 7364 7365 /* Reset the timer id to zero */ 7366 ohcip->ohci_timer_id = 0; 7367 } else { 7368 mutex_exit(&ohcip->ohci_int_mutex); 7369 7370 return; 7371 } 7372 7373 /* Get the transfer timeout list head */ 7374 tw = ohcip->ohci_timeout_list; 7375 7376 /* 7377 * Process ohci timeout list and look whether the timer 7378 * has expired for any transfers. Create a temporary list 7379 * of expired transfers and process them later. 7380 */ 7381 while (tw) { 7382 /* Get the transfer on the timeout list */ 7383 next = tw->tw_timeout_next; 7384 7385 tw->tw_timeout--; 7386 7387 /* 7388 * Set the sKip bit to stop all transactions on 7389 * this pipe 7390 */ 7391 if (tw->tw_timeout == 1) { 7392 ohci_modify_sKip_bit(ohcip, 7393 tw->tw_pipe_private, SET_sKip, flags); 7394 7395 /* Reset dma sync flag */ 7396 flags &= ~OHCI_FLAGS_DMA_SYNC; 7397 } 7398 7399 /* Remove tw from the timeout list */ 7400 if (tw->tw_timeout == 0) { 7401 7402 ohci_remove_tw_from_timeout_list(ohcip, tw); 7403 7404 /* Add tw to the end of expire list */ 7405 if (exp_xfer_list_head) { 7406 exp_xfer_list_tail->tw_timeout_next = tw; 7407 } else { 7408 exp_xfer_list_head = tw; 7409 } 7410 exp_xfer_list_tail = tw; 7411 tw->tw_timeout_next = NULL; 7412 } 7413 7414 tw = next; 7415 } 7416 7417 /* Get the expired transfer timeout list head */ 7418 tw = exp_xfer_list_head; 7419 7420 if (tw && (flags & OHCI_FLAGS_DMA_SYNC)) { 7421 /* Sync ED and TD pool */ 7422 Sync_ED_TD_Pool(ohcip); 7423 } 7424 7425 /* 7426 * Process the expired transfers by notifing the corrsponding 7427 * client driver through the exception callback. 7428 */ 7429 while (tw) { 7430 /* Get the transfer on the expired transfer timeout list */ 7431 next = tw->tw_timeout_next; 7432 7433 td = tw->tw_hctd_head; 7434 7435 while (td) { 7436 /* Set TD state to TIMEOUT */ 7437 Set_TD(td->hctd_state, HC_TD_TIMEOUT); 7438 7439 /* Get the next TD from the wrapper */ 7440 td = ohci_td_iommu_to_cpu(ohcip, 7441 Get_TD(td->hctd_tw_next_td)); 7442 } 7443 7444 ohci_handle_error(ohcip, tw->tw_hctd_head, USB_CR_TIMEOUT); 7445 7446 tw = next; 7447 } 7448 7449 ohci_start_timer(ohcip); 7450 mutex_exit(&ohcip->ohci_int_mutex); 7451 } 7452 7453 7454 /* 7455 * ohci_remove_tw_from_timeout_list: 7456 * 7457 * Remove Control or bulk transfer from the timeout list. 7458 */ 7459 static void 7460 ohci_remove_tw_from_timeout_list( 7461 ohci_state_t *ohcip, 7462 ohci_trans_wrapper_t *tw) 7463 { 7464 ohci_trans_wrapper_t *prev, *next; 7465 7466 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 7467 "ohci_remove_tw_from_timeout_list: tw = 0x%p", (void *)tw); 7468 7469 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7470 7471 if (ohcip->ohci_timeout_list == tw) { 7472 ohcip->ohci_timeout_list = tw->tw_timeout_next; 7473 } else { 7474 prev = ohcip->ohci_timeout_list; 7475 next = prev->tw_timeout_next; 7476 7477 while (next && (next != tw)) { 7478 prev = next; 7479 next = next->tw_timeout_next; 7480 } 7481 7482 if (next == tw) { 7483 prev->tw_timeout_next = next->tw_timeout_next; 7484 } 7485 } 7486 7487 /* Reset the xfer timeout */ 7488 tw->tw_timeout_next = NULL; 7489 } 7490 7491 7492 /* 7493 * ohci_start_timer: 7494 * 7495 * Start the ohci timer 7496 */ 7497 static void 7498 ohci_start_timer(ohci_state_t *ohcip) 7499 { 7500 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 7501 "ohci_start_timer: ohcip = 0x%p", (void *)ohcip); 7502 7503 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7504 7505 /* 7506 * Start the global timer only if currently timer is not 7507 * running and if there are any transfers on the timeout 7508 * list. This timer will be per USB Host Controller. 7509 */ 7510 if ((!ohcip->ohci_timer_id) && (ohcip->ohci_timeout_list)) { 7511 ohcip->ohci_timer_id = timeout(ohci_xfer_timeout_handler, 7512 (void *)ohcip, drv_usectohz(1000000)); 7513 } 7514 } 7515 7516 7517 /* 7518 * ohci_deallocate_tw_resources: 7519 * NOTE: This function is also called from POLLED MODE. 7520 * 7521 * Deallocate of a Transaction Wrapper (TW) and this involves the freeing of 7522 * of DMA resources. 7523 */ 7524 void 7525 ohci_deallocate_tw_resources( 7526 ohci_state_t *ohcip, 7527 ohci_pipe_private_t *pp, 7528 ohci_trans_wrapper_t *tw) 7529 { 7530 ohci_trans_wrapper_t *prev, *next; 7531 7532 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7533 "ohci_deallocate_tw_resources: tw = 0x%p", (void *)tw); 7534 7535 /* 7536 * If the transfer wrapper has no Host Controller (HC) 7537 * Transfer Descriptors (TD) associated with it, then 7538 * remove the transfer wrapper. 7539 */ 7540 if (tw->tw_hctd_head) { 7541 ASSERT(tw->tw_hctd_tail != NULL); 7542 7543 return; 7544 } 7545 7546 ASSERT(tw->tw_hctd_tail == NULL); 7547 7548 /* Make sure we return all the unused td's to the pool as well */ 7549 ohci_free_tw_tds_resources(ohcip, tw); 7550 7551 /* 7552 * If pp->pp_tw_head and pp->pp_tw_tail are pointing to 7553 * given TW then set the head and tail equal to NULL. 7554 * Otherwise search for this TW in the linked TW's list 7555 * and then remove this TW from the list. 7556 */ 7557 if (pp->pp_tw_head == tw) { 7558 if (pp->pp_tw_tail == tw) { 7559 pp->pp_tw_head = NULL; 7560 pp->pp_tw_tail = NULL; 7561 } else { 7562 pp->pp_tw_head = tw->tw_next; 7563 } 7564 } else { 7565 prev = pp->pp_tw_head; 7566 next = prev->tw_next; 7567 7568 while (next && (next != tw)) { 7569 prev = next; 7570 next = next->tw_next; 7571 } 7572 7573 if (next == tw) { 7574 prev->tw_next = next->tw_next; 7575 7576 if (pp->pp_tw_tail == tw) { 7577 pp->pp_tw_tail = prev; 7578 } 7579 } 7580 } 7581 7582 ohci_free_tw(ohcip, tw); 7583 } 7584 7585 7586 /* 7587 * ohci_free_dma_resources: 7588 * 7589 * Free dma resources of a Transfer Wrapper (TW) and also free the TW. 7590 */ 7591 static void 7592 ohci_free_dma_resources( 7593 ohci_state_t *ohcip, 7594 usba_pipe_handle_data_t *ph) 7595 { 7596 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 7597 ohci_trans_wrapper_t *head_tw = pp->pp_tw_head; 7598 ohci_trans_wrapper_t *next_tw, *tw; 7599 7600 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7601 "ohci_free_dma_resources: ph = 0x%p", (void *)ph); 7602 7603 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7604 7605 /* Process the Transfer Wrappers */ 7606 next_tw = head_tw; 7607 while (next_tw) { 7608 tw = next_tw; 7609 next_tw = tw->tw_next; 7610 7611 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7612 "ohci_free_dma_resources: Free TW = 0x%p", (void *)tw); 7613 7614 ohci_free_tw(ohcip, tw); 7615 } 7616 7617 /* Adjust the head and tail pointers */ 7618 pp->pp_tw_head = NULL; 7619 pp->pp_tw_tail = NULL; 7620 } 7621 7622 7623 /* 7624 * ohci_free_tw: 7625 * 7626 * Free the Transfer Wrapper (TW). 7627 */ 7628 static void 7629 ohci_free_tw( 7630 ohci_state_t *ohcip, 7631 ohci_trans_wrapper_t *tw) 7632 { 7633 int rval, i; 7634 7635 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl, 7636 "ohci_free_tw: tw = 0x%p", (void *)tw); 7637 7638 ASSERT(tw != NULL); 7639 ASSERT(tw->tw_id != NULL); 7640 7641 /* Free 32bit ID */ 7642 OHCI_FREE_ID((uint32_t)tw->tw_id); 7643 7644 if (tw->tw_isoc_strtlen > 0) { 7645 ASSERT(tw->tw_isoc_bufs != NULL); 7646 for (i = 0; i < tw->tw_ncookies; i++) { 7647 if (tw->tw_isoc_bufs[i].ncookies > 0) { 7648 rval = ddi_dma_unbind_handle( 7649 tw->tw_isoc_bufs[i].dma_handle); 7650 ASSERT(rval == USB_SUCCESS); 7651 } 7652 ddi_dma_mem_free(&tw->tw_isoc_bufs[i].mem_handle); 7653 ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle); 7654 } 7655 kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen); 7656 } else if (tw->tw_dmahandle != NULL) { 7657 if (tw->tw_ncookies > 0) { 7658 rval = ddi_dma_unbind_handle(tw->tw_dmahandle); 7659 ASSERT(rval == DDI_SUCCESS); 7660 } 7661 ddi_dma_mem_free(&tw->tw_accesshandle); 7662 ddi_dma_free_handle(&tw->tw_dmahandle); 7663 } 7664 7665 /* Free transfer wrapper */ 7666 kmem_free(tw, sizeof (ohci_trans_wrapper_t)); 7667 } 7668 7669 7670 /* 7671 * Interrupt Handling functions 7672 */ 7673 7674 /* 7675 * ohci_intr: 7676 * 7677 * OpenHCI (OHCI) interrupt handling routine. 7678 */ 7679 static uint_t 7680 ohci_intr(caddr_t arg1, caddr_t arg2) 7681 { 7682 ohci_state_t *ohcip = (ohci_state_t *)arg1; 7683 uint_t intr; 7684 ohci_td_t *done_head = NULL; 7685 ohci_save_intr_sts_t *ohci_intr_sts = &ohcip->ohci_save_intr_sts; 7686 7687 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7688 "ohci_intr: Interrupt occurred, arg1 0x%p arg2 0x%p", 7689 (void *)arg1, (void *)arg2); 7690 7691 mutex_enter(&ohcip->ohci_int_mutex); 7692 7693 /* Any interrupt is not handled for the suspended device. */ 7694 if (ohcip->ohci_hc_soft_state == OHCI_CTLR_SUSPEND_STATE) { 7695 mutex_exit(&ohcip->ohci_int_mutex); 7696 7697 return (DDI_INTR_UNCLAIMED); 7698 } 7699 7700 /* 7701 * Suppose if we switched to the polled mode from the normal 7702 * mode when interrupt handler is executing then we need to 7703 * save the interrupt status information in the polled mode 7704 * to avoid race conditions. The following flag will be set 7705 * and reset on entering & exiting of ohci interrupt handler 7706 * respectively. This flag will be used in the polled mode 7707 * to check whether the interrupt handler was running when we 7708 * switched to the polled mode from the normal mode. 7709 */ 7710 ohci_intr_sts->ohci_intr_flag = OHCI_INTR_HANDLING; 7711 7712 /* Temporarily turn off interrupts */ 7713 Set_OpReg(hcr_intr_disable, HCR_INTR_MIE); 7714 7715 /* 7716 * Handle any missed ohci interrupt especially WriteDoneHead 7717 * and SOF interrupts because of previous polled mode switch. 7718 */ 7719 ohci_handle_missed_intr(ohcip); 7720 7721 /* 7722 * Now process the actual ohci interrupt events that caused 7723 * invocation of this ohci interrupt handler. 7724 */ 7725 7726 /* 7727 * Updating the WriteDoneHead interrupt: 7728 * 7729 * (a) Host Controller 7730 * 7731 * - First Host controller (HC) checks whether WDH bit 7732 * in the interrupt status register is cleared. 7733 * 7734 * - If WDH bit is cleared then HC writes new done head 7735 * list information into the HCCA done head field. 7736 * 7737 * - Set WDH bit in the interrupt status register. 7738 * 7739 * (b) Host Controller Driver (HCD) 7740 * 7741 * - First read the interrupt status register. The HCCA 7742 * done head and WDH bit may be set or may not be set 7743 * while reading the interrupt status register. 7744 * 7745 * - Read the HCCA done head list. By this time may be 7746 * HC has updated HCCA done head and WDH bit in ohci 7747 * interrupt status register. 7748 * 7749 * - If done head is non-null and if WDH bit is not set 7750 * then Host Controller has updated HCCA done head & 7751 * WDH bit in the interrupt stats register in between 7752 * reading the interrupt status register & HCCA done 7753 * head. In that case, definitely WDH bit will be set 7754 * in the interrupt status register & driver can take 7755 * it for granted. 7756 * 7757 * Now read the Interrupt Status & Interrupt enable register 7758 * to determine the exact interrupt events. 7759 */ 7760 intr = ohci_intr_sts->ohci_curr_intr_sts = 7761 (Get_OpReg(hcr_intr_status) & Get_OpReg(hcr_intr_enable)); 7762 7763 if (ohcip->ohci_hccap) { 7764 /* Sync HCCA area */ 7765 Sync_HCCA(ohcip); 7766 7767 /* Read and Save the HCCA DoneHead value */ 7768 done_head = ohci_intr_sts->ohci_curr_done_lst = 7769 (ohci_td_t *)(uintptr_t) 7770 (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) & 7771 HCCA_DONE_HEAD_MASK); 7772 7773 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7774 "ohci_intr: Done head! 0x%p", (void *)done_head); 7775 } 7776 7777 /* Update kstat values */ 7778 ohci_do_intrs_stats(ohcip, intr); 7779 7780 /* 7781 * Look at the HccaDoneHead, if it is a non-zero valid address, 7782 * a done list update interrupt is indicated. Otherwise, this 7783 * intr bit is cleared. 7784 */ 7785 if (ohci_check_done_head(ohcip, done_head) == USB_SUCCESS) { 7786 7787 /* Set the WriteDoneHead bit in the interrupt events */ 7788 intr |= HCR_INTR_WDH; 7789 } else { 7790 7791 /* Clear the WriteDoneHead bit */ 7792 intr &= ~HCR_INTR_WDH; 7793 } 7794 7795 /* 7796 * We could have gotten a spurious interrupts. If so, do not 7797 * claim it. This is quite possible on some architectures 7798 * where more than one PCI slots share the IRQs. If so, the 7799 * associated driver's interrupt routine may get called even 7800 * if the interrupt is not meant for them. 7801 * 7802 * By unclaiming the interrupt, the other driver gets chance 7803 * to service its interrupt. 7804 */ 7805 if (!intr) { 7806 7807 /* Reset the interrupt handler flag */ 7808 ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_HANDLING; 7809 7810 Set_OpReg(hcr_intr_enable, HCR_INTR_MIE); 7811 mutex_exit(&ohcip->ohci_int_mutex); 7812 return (DDI_INTR_UNCLAIMED); 7813 } 7814 7815 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7816 "Interrupt status 0x%x", intr); 7817 7818 /* 7819 * Check for Frame Number Overflow. 7820 */ 7821 if (intr & HCR_INTR_FNO) { 7822 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7823 "ohci_intr: Frame Number Overflow"); 7824 7825 ohci_handle_frame_number_overflow(ohcip); 7826 } 7827 7828 if (intr & HCR_INTR_SOF) { 7829 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7830 "ohci_intr: Start of Frame"); 7831 7832 /* Set ohci_sof_flag indicating SOF interrupt occurred */ 7833 ohcip->ohci_sof_flag = B_TRUE; 7834 7835 /* Disabel SOF interrupt */ 7836 Set_OpReg(hcr_intr_disable, HCR_INTR_SOF); 7837 7838 /* 7839 * Call cv_broadcast on every SOF interrupt to wakeup 7840 * all the threads that are waiting the SOF. Calling 7841 * cv_broadcast on every SOF has no effect even if no 7842 * threads are waiting for the SOF. 7843 */ 7844 cv_broadcast(&ohcip->ohci_SOF_cv); 7845 } 7846 7847 if (intr & HCR_INTR_SO) { 7848 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7849 "ohci_intr: Schedule overrun"); 7850 7851 ohcip->ohci_so_error++; 7852 } 7853 7854 if ((intr & HCR_INTR_WDH) && (done_head)) { 7855 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7856 "ohci_intr: Done Head"); 7857 7858 /* 7859 * Currently if we are processing one WriteDoneHead 7860 * interrupt and also if we switched to the polled 7861 * mode at least once during this time, then there 7862 * may be chance that Host Controller generates one 7863 * more Write DoneHead or Start of Frame interrupts 7864 * for the normal since the polled code clears WDH & 7865 * SOF interrupt bits before returning to the normal 7866 * mode. Under this condition, we must not clear the 7867 * HCCA done head field & also we must not clear WDH 7868 * interrupt bit in the interrupt status register. 7869 */ 7870 if (done_head == (ohci_td_t *)(uintptr_t) 7871 (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) & 7872 HCCA_DONE_HEAD_MASK)) { 7873 7874 /* Reset the done head to NULL */ 7875 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, NULL); 7876 } else { 7877 intr &= ~HCR_INTR_WDH; 7878 } 7879 7880 /* Clear the current done head field */ 7881 ohci_intr_sts->ohci_curr_done_lst = NULL; 7882 7883 ohci_traverse_done_list(ohcip, done_head); 7884 } 7885 7886 /* Process endpoint reclaimation list */ 7887 if (ohcip->ohci_reclaim_list) { 7888 ohci_handle_endpoint_reclaimation(ohcip); 7889 } 7890 7891 if (intr & HCR_INTR_RD) { 7892 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7893 "ohci_intr: Resume Detected"); 7894 } 7895 7896 if (intr & HCR_INTR_RHSC) { 7897 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7898 "ohci_intr: Root hub status change"); 7899 } 7900 7901 if (intr & HCR_INTR_OC) { 7902 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7903 "ohci_intr: Change ownership"); 7904 7905 } 7906 7907 if (intr & HCR_INTR_UE) { 7908 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7909 "ohci_intr: Unrecoverable error"); 7910 7911 ohci_handle_ue(ohcip); 7912 } 7913 7914 /* Acknowledge the interrupt */ 7915 Set_OpReg(hcr_intr_status, intr); 7916 7917 /* Clear the current interrupt event field */ 7918 ohci_intr_sts->ohci_curr_intr_sts = 0; 7919 7920 /* 7921 * Reset the following flag indicating exiting the interrupt 7922 * handler and this flag will be used in the polled mode to 7923 * do some extra processing. 7924 */ 7925 ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_HANDLING; 7926 7927 Set_OpReg(hcr_intr_enable, HCR_INTR_MIE); 7928 7929 /* 7930 * Read interrupt status register to make sure that any PIO 7931 * store to clear the ISR has made it on the PCI bus before 7932 * returning from its interrupt handler. 7933 */ 7934 (void) Get_OpReg(hcr_intr_status); 7935 7936 mutex_exit(&ohcip->ohci_int_mutex); 7937 7938 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7939 "Interrupt handling completed"); 7940 7941 return (DDI_INTR_CLAIMED); 7942 } 7943 7944 /* 7945 * Check whether done_head is a valid td point address. 7946 * It should be non-zero, 16-byte aligned, and fall in ohci_td_pool. 7947 */ 7948 static int 7949 ohci_check_done_head(ohci_state_t *ohcip, ohci_td_t *done_head) 7950 { 7951 uintptr_t lower, upper, headp; 7952 lower = ohcip->ohci_td_pool_cookie.dmac_address; 7953 upper = lower + ohcip->ohci_td_pool_cookie.dmac_size; 7954 headp = (uintptr_t)done_head; 7955 7956 if (headp && !(headp & ~HCCA_DONE_HEAD_MASK) && 7957 (headp >= lower) && (headp < upper)) { 7958 7959 return (USB_SUCCESS); 7960 } else { 7961 7962 return (USB_FAILURE); 7963 } 7964 } 7965 7966 /* 7967 * ohci_handle_missed_intr: 7968 * 7969 * Handle any ohci missed interrupts because of polled mode switch. 7970 */ 7971 static void 7972 ohci_handle_missed_intr(ohci_state_t *ohcip) 7973 { 7974 ohci_save_intr_sts_t *ohci_intr_sts = 7975 &ohcip->ohci_save_intr_sts; 7976 ohci_td_t *done_head; 7977 uint_t intr; 7978 7979 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 7980 7981 /* 7982 * Check whether we have missed any ohci interrupts because 7983 * of the polled mode switch during previous ohci interrupt 7984 * handler execution. Only Write Done Head & SOF interrupts 7985 * saved in the polled mode. First process these interrupts 7986 * before processing actual interrupts that caused invocation 7987 * of ohci interrupt handler. 7988 */ 7989 if (!ohci_intr_sts->ohci_missed_intr_sts) { 7990 /* No interrupts are missed, simply return */ 7991 7992 return; 7993 } 7994 7995 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 7996 "ohci_handle_missed_intr: Handle ohci missed interrupts"); 7997 7998 /* 7999 * The functionality and importance of critical code section 8000 * in the normal mode ohci interrupt handler & its usage in 8001 * the polled mode is explained below. 8002 * 8003 * (a) Normal mode: 8004 * 8005 * - Set the flag indicating that processing critical 8006 * code in ohci interrupt handler. 8007 * 8008 * - Process the missed ohci interrupts by copying the 8009 * miised interrupt events and done head list fields 8010 * information to the critical interrupt event & done 8011 * list fields. 8012 * 8013 * - Reset the missed ohci interrupt events & done head 8014 * list fields so that the new missed interrupt event 8015 * and done head list information can be saved. 8016 * 8017 * - All above steps will be executed with in critical 8018 * section of the interrupt handler.Then ohci missed 8019 * interrupt handler will be called to service missed 8020 * ohci interrupts. 8021 * 8022 * (b) Polled mode: 8023 * 8024 * - On entering the polled code,it checks for critical 8025 * section code execution within the normal mode ohci 8026 * interrupt handler. 8027 * 8028 * - If the critical section code is executing in normal 8029 * mode ohci interrupt handler and if copying of ohci 8030 * missed interrupt events & done head list fields to 8031 * the critical fields is finished then save the "any 8032 * missed interrupt events & done head list" because 8033 * of current polled mode switch into "critical missed 8034 * interrupt events & done list fields" instead actual 8035 * missed events and done list fields. 8036 * 8037 * - Otherwise save "any missed interrupt events & done 8038 * list" because of this current polled mode switch 8039 * in the actual missed interrupt events & done head 8040 * list fields. 8041 */ 8042 8043 /* 8044 * Set flag indicating that interrupt handler is processing 8045 * critical interrupt code, so that polled mode code checks 8046 * for this condition & will do extra processing as explained 8047 * above in order to aviod the race conditions. 8048 */ 8049 ohci_intr_sts->ohci_intr_flag |= OHCI_INTR_CRITICAL; 8050 ohci_intr_sts->ohci_critical_intr_sts |= 8051 ohci_intr_sts->ohci_missed_intr_sts; 8052 8053 if (ohci_intr_sts->ohci_missed_done_lst) { 8054 8055 ohci_intr_sts->ohci_critical_done_lst = 8056 ohci_intr_sts->ohci_missed_done_lst; 8057 } 8058 8059 ohci_intr_sts->ohci_missed_intr_sts = 0; 8060 ohci_intr_sts->ohci_missed_done_lst = NULL; 8061 ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_CRITICAL; 8062 8063 intr = ohci_intr_sts->ohci_critical_intr_sts; 8064 done_head = ohci_intr_sts->ohci_critical_done_lst; 8065 8066 if (intr & HCR_INTR_SOF) { 8067 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8068 "ohci_handle_missed_intr: Start of Frame"); 8069 8070 /* 8071 * Call cv_broadcast on every SOF interrupt to wakeup 8072 * all the threads that are waiting the SOF. Calling 8073 * cv_broadcast on every SOF has no effect even if no 8074 * threads are waiting for the SOF. 8075 */ 8076 cv_broadcast(&ohcip->ohci_SOF_cv); 8077 } 8078 8079 if ((intr & HCR_INTR_WDH) && (done_head)) { 8080 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8081 "ohci_handle_missed_intr: Done Head"); 8082 8083 /* Clear the critical done head field */ 8084 ohci_intr_sts->ohci_critical_done_lst = NULL; 8085 8086 ohci_traverse_done_list(ohcip, done_head); 8087 } 8088 8089 /* Clear the critical interrupt event field */ 8090 ohci_intr_sts->ohci_critical_intr_sts = 0; 8091 } 8092 8093 8094 /* 8095 * ohci_handle_ue: 8096 * 8097 * Handling of Unrecoverable Error interrupt (UE). 8098 */ 8099 static void 8100 ohci_handle_ue(ohci_state_t *ohcip) 8101 { 8102 usb_frame_number_t before_frame_number, after_frame_number; 8103 8104 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8105 8106 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8107 "ohci_handle_ue: Handling of UE interrupt"); 8108 8109 /* 8110 * First check whether current UE error occured due to USB or 8111 * due to some other subsystem. This can be verified by reading 8112 * usb frame numbers before & after a delay of few milliseconds. 8113 * If usb frame number read after delay is greater than the one 8114 * read before delay, then, USB subsystem is fine. In this case, 8115 * disable UE error interrupt and return without shutdowning the 8116 * USB subsystem. 8117 * 8118 * Otherwise, if usb frame number read after delay is less than 8119 * or equal to one read before the delay, then, current UE error 8120 * occured from USB susbsystem. In this case,go ahead with actual 8121 * UE error recovery procedure. 8122 * 8123 * Get the current usb frame number before waiting for few 8124 * milliseconds. 8125 */ 8126 before_frame_number = ohci_get_current_frame_number(ohcip); 8127 8128 /* Wait for few milliseconds */ 8129 drv_usecwait(OHCI_TIMEWAIT); 8130 8131 /* 8132 * Get the current usb frame number after waiting for 8133 * milliseconds. 8134 */ 8135 after_frame_number = ohci_get_current_frame_number(ohcip); 8136 8137 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8138 "ohci_handle_ue: Before Frm No 0x%llx After Frm No 0x%llx", 8139 (unsigned long long)before_frame_number, 8140 (unsigned long long)after_frame_number); 8141 8142 if (after_frame_number > before_frame_number) { 8143 8144 /* Disable UE interrupt */ 8145 Set_OpReg(hcr_intr_disable, HCR_INTR_UE); 8146 8147 return; 8148 } 8149 8150 /* 8151 * This UE is due to USB hardware error. Reset ohci controller 8152 * and reprogram to bring it back to functional state. 8153 */ 8154 if ((ohci_do_soft_reset(ohcip)) != USB_SUCCESS) { 8155 USB_DPRINTF_L0(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8156 "Unrecoverable USB Hardware Error"); 8157 8158 /* Disable UE interrupt */ 8159 Set_OpReg(hcr_intr_disable, HCR_INTR_UE); 8160 8161 /* Set host controller soft state to error */ 8162 ohcip->ohci_hc_soft_state = OHCI_CTLR_ERROR_STATE; 8163 } 8164 } 8165 8166 8167 /* 8168 * ohci_handle_frame_number_overflow: 8169 * 8170 * Update software based usb frame number part on every frame number 8171 * overflow interrupt. 8172 * 8173 * NOTE: This function is also called from POLLED MODE. 8174 * 8175 * Refer ohci spec 1.0a, section 5.3, page 81 for more details. 8176 */ 8177 void 8178 ohci_handle_frame_number_overflow(ohci_state_t *ohcip) 8179 { 8180 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8181 "ohci_handle_frame_number_overflow:"); 8182 8183 ohcip->ohci_fno += (0x10000 - 8184 (((Get_HCCA(ohcip->ohci_hccap->HccaFrameNo) & 8185 0xFFFF) ^ ohcip->ohci_fno) & 0x8000)); 8186 8187 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8188 "ohci_handle_frame_number_overflow:" 8189 "Frame Number Higher Part 0x%llx\n", 8190 (unsigned long long)(ohcip->ohci_fno)); 8191 } 8192 8193 8194 /* 8195 * ohci_handle_endpoint_reclaimation: 8196 * 8197 * Reclamation of Host Controller (HC) Endpoint Descriptors (ED). 8198 */ 8199 static void 8200 ohci_handle_endpoint_reclaimation(ohci_state_t *ohcip) 8201 { 8202 usb_frame_number_t current_frame_number; 8203 usb_frame_number_t endpoint_frame_number; 8204 ohci_ed_t *reclaim_ed; 8205 8206 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8207 "ohci_handle_endpoint_reclaimation:"); 8208 8209 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8210 8211 current_frame_number = ohci_get_current_frame_number(ohcip); 8212 8213 /* 8214 * Deallocate all Endpoint Descriptors (ED) which are on the 8215 * reclaimation list. These ED's are already removed from the 8216 * interrupt lattice tree. 8217 */ 8218 while (ohcip->ohci_reclaim_list) { 8219 reclaim_ed = ohcip->ohci_reclaim_list; 8220 8221 endpoint_frame_number = (usb_frame_number_t)(uintptr_t) 8222 (OHCI_LOOKUP_ID(Get_ED(reclaim_ed->hced_reclaim_frame))); 8223 8224 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8225 "ohci_handle_endpoint_reclaimation:" 8226 "current frame number 0x%llx endpoint frame number 0x%llx", 8227 (unsigned long long)current_frame_number, 8228 (unsigned long long)endpoint_frame_number); 8229 8230 /* 8231 * Deallocate current endpoint only if endpoint's usb frame 8232 * number is less than or equal to current usb frame number. 8233 * 8234 * If endpoint's usb frame number is greater than the current 8235 * usb frame number, ignore rest of the endpoints in the list 8236 * since rest of the endpoints are inserted into the reclaim 8237 * list later than the current reclaim endpoint. 8238 */ 8239 if (endpoint_frame_number > current_frame_number) { 8240 break; 8241 } 8242 8243 /* Get the next endpoint from the rec. list */ 8244 ohcip->ohci_reclaim_list = ohci_ed_iommu_to_cpu(ohcip, 8245 Get_ED(reclaim_ed->hced_reclaim_next)); 8246 8247 /* Free 32bit ID */ 8248 OHCI_FREE_ID((uint32_t)Get_ED(reclaim_ed->hced_reclaim_frame)); 8249 8250 /* Deallocate the endpoint */ 8251 ohci_deallocate_ed(ohcip, reclaim_ed); 8252 } 8253 } 8254 8255 8256 /* 8257 * ohci_traverse_done_list: 8258 */ 8259 static void 8260 ohci_traverse_done_list( 8261 ohci_state_t *ohcip, 8262 ohci_td_t *head_done_list) 8263 { 8264 uint_t state; /* TD state */ 8265 ohci_td_t *td, *old_td; /* TD pointers */ 8266 usb_cr_t error; /* Error from TD */ 8267 ohci_trans_wrapper_t *tw = NULL; /* Transfer wrapper */ 8268 ohci_pipe_private_t *pp = NULL; /* Pipe private field */ 8269 8270 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8271 "ohci_traverse_done_list:"); 8272 8273 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8274 8275 /* Sync ED and TD pool */ 8276 Sync_ED_TD_Pool(ohcip); 8277 8278 /* Reverse the done list */ 8279 td = ohci_reverse_done_list(ohcip, head_done_list); 8280 8281 /* Traverse the list of transfer descriptors */ 8282 while (td) { 8283 /* Check for TD state */ 8284 state = Get_TD(td->hctd_state); 8285 8286 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8287 "ohci_traverse_done_list:\n\t" 8288 "td = 0x%p state = 0x%x", (void *)td, state); 8289 8290 /* 8291 * Obtain the transfer wrapper only if the TD is 8292 * not marked as RECLAIM. 8293 * 8294 * A TD that is marked as RECLAIM has had its DMA 8295 * mappings, ED, TD and pipe private structure are 8296 * ripped down. Just deallocate this TD. 8297 */ 8298 if (state != HC_TD_RECLAIM) { 8299 8300 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID( 8301 (uint32_t)Get_TD(td->hctd_trans_wrapper)); 8302 8303 ASSERT(tw != NULL); 8304 8305 pp = tw->tw_pipe_private; 8306 8307 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8308 "ohci_traverse_done_list: PP = 0x%p TW = 0x%p", 8309 (void *)pp, (void *)tw); 8310 } 8311 8312 /* 8313 * Don't process the TD if its state is marked as 8314 * either RECLAIM or TIMEOUT. 8315 * 8316 * A TD that is marked as TIMEOUT has already been 8317 * processed by TD timeout handler & client driver 8318 * has been informed through exception callback. 8319 */ 8320 if ((state != HC_TD_RECLAIM) && (state != HC_TD_TIMEOUT)) { 8321 8322 /* Look at the error status */ 8323 error = ohci_parse_error(ohcip, td); 8324 8325 if (error == USB_CR_OK) { 8326 ohci_handle_normal_td(ohcip, td, tw); 8327 } else { 8328 /* handle the error condition */ 8329 ohci_handle_error(ohcip, td, error); 8330 } 8331 } else { 8332 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8333 "ohci_traverse_done_list: TD State = %d", state); 8334 } 8335 8336 /* 8337 * Save a pointer to the current transfer descriptor 8338 */ 8339 old_td = td; 8340 8341 td = ohci_td_iommu_to_cpu(ohcip, Get_TD(td->hctd_next_td)); 8342 8343 /* Deallocate this transfer descriptor */ 8344 ohci_deallocate_td(ohcip, old_td); 8345 8346 /* 8347 * Deallocate the transfer wrapper if there are no more 8348 * TD's for the transfer wrapper. ohci_deallocate_tw_resources() 8349 * will not deallocate the tw for a periodic endpoint 8350 * since it will always have a TD attached to it. 8351 * 8352 * Do not deallocate the TW if it is a isoc or intr pipe in. 8353 * The tw's are reused. 8354 * 8355 * An TD that is marked as reclaim doesn't have a pipe 8356 * or a TW associated with it anymore so don't call this 8357 * function. 8358 */ 8359 if (state != HC_TD_RECLAIM) { 8360 ASSERT(tw != NULL); 8361 ohci_deallocate_tw_resources(ohcip, pp, tw); 8362 } 8363 } 8364 } 8365 8366 8367 /* 8368 * ohci_reverse_done_list: 8369 * 8370 * Reverse the order of the Transfer Descriptor (TD) Done List. 8371 */ 8372 static ohci_td_t * 8373 ohci_reverse_done_list( 8374 ohci_state_t *ohcip, 8375 ohci_td_t *head_done_list) 8376 { 8377 ohci_td_t *cpu_new_tail, *cpu_new_head, *cpu_save; 8378 8379 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8380 "ohci_reverse_done_list:"); 8381 8382 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8383 ASSERT(head_done_list != NULL); 8384 8385 /* At first, both the tail and head pointers point to the same elem */ 8386 cpu_new_tail = cpu_new_head = 8387 ohci_td_iommu_to_cpu(ohcip, (uintptr_t)head_done_list); 8388 8389 /* See if the list has only one element */ 8390 if (Get_TD(cpu_new_head->hctd_next_td) == NULL) { 8391 8392 return (cpu_new_head); 8393 } 8394 8395 /* Advance the head pointer */ 8396 cpu_new_head = (ohci_td_t *) 8397 ohci_td_iommu_to_cpu(ohcip, Get_TD(cpu_new_head->hctd_next_td)); 8398 8399 /* The new tail now points to nothing */ 8400 Set_TD(cpu_new_tail->hctd_next_td, NULL); 8401 8402 cpu_save = (ohci_td_t *) 8403 ohci_td_iommu_to_cpu(ohcip, Get_TD(cpu_new_head->hctd_next_td)); 8404 8405 /* Reverse the list and store the pointers as CPU addresses */ 8406 while (cpu_save) { 8407 Set_TD(cpu_new_head->hctd_next_td, 8408 ohci_td_cpu_to_iommu(ohcip, cpu_new_tail)); 8409 8410 cpu_new_tail = cpu_new_head; 8411 cpu_new_head = cpu_save; 8412 8413 cpu_save = (ohci_td_t *) 8414 ohci_td_iommu_to_cpu(ohcip, 8415 Get_TD(cpu_new_head->hctd_next_td)); 8416 } 8417 8418 Set_TD(cpu_new_head->hctd_next_td, 8419 ohci_td_cpu_to_iommu(ohcip, cpu_new_tail)); 8420 8421 return (cpu_new_head); 8422 } 8423 8424 8425 /* 8426 * ohci_parse_error: 8427 * 8428 * Parse the result for any errors. 8429 */ 8430 static usb_cr_t 8431 ohci_parse_error( 8432 ohci_state_t *ohcip, 8433 ohci_td_t *td) 8434 { 8435 uint_t ctrl; 8436 usb_ep_descr_t *eptd; 8437 ohci_trans_wrapper_t *tw; 8438 ohci_pipe_private_t *pp; 8439 uint_t flag; 8440 usb_cr_t error; 8441 8442 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8443 "ohci_parse_error:"); 8444 8445 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8446 8447 ASSERT(td != NULL); 8448 8449 /* Obtain the transfer wrapper from the TD */ 8450 tw = (ohci_trans_wrapper_t *) 8451 OHCI_LOOKUP_ID((uint32_t)Get_TD(td->hctd_trans_wrapper)); 8452 8453 ASSERT(tw != NULL); 8454 8455 /* Obtain the pipe private structure */ 8456 pp = tw->tw_pipe_private; 8457 8458 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8459 "ohci_parse_error: PP 0x%p TW 0x%p", (void *)pp, (void *)tw); 8460 8461 eptd = &pp->pp_pipe_handle->p_ep; 8462 8463 ctrl = (uint_t)Get_TD(td->hctd_ctrl) & (uint32_t)HC_TD_CC; 8464 8465 /* 8466 * Check the condition code of completed TD and report errors 8467 * if any. This checking will be done both for the general and 8468 * the isochronous TDs. 8469 */ 8470 if ((error = ohci_check_for_error(ohcip, pp, tw, td, ctrl)) != 8471 USB_CR_OK) { 8472 flag = OHCI_REMOVE_XFER_ALWAYS; 8473 } else { 8474 flag = OHCI_REMOVE_XFER_IFLAST; 8475 } 8476 8477 /* Stop the the transfer timer */ 8478 ohci_stop_xfer_timer(ohcip, tw, flag); 8479 8480 /* 8481 * The isochronous endpoint needs additional error checking 8482 * and special processing. 8483 */ 8484 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) == 8485 USB_EP_ATTR_ISOCH) { 8486 8487 ohci_parse_isoc_error(ohcip, pp, tw, td); 8488 8489 /* always reset error */ 8490 error = USB_CR_OK; 8491 } 8492 8493 return (error); 8494 } 8495 8496 8497 /* 8498 * ohci_parse_isoc_error: 8499 * 8500 * Check for any errors in the isochronous data packets. Also fillup 8501 * the status for each of the isochrnous data packets. 8502 */ 8503 void 8504 ohci_parse_isoc_error( 8505 ohci_state_t *ohcip, 8506 ohci_pipe_private_t *pp, 8507 ohci_trans_wrapper_t *tw, 8508 ohci_td_t *td) 8509 { 8510 usb_isoc_req_t *isoc_reqp; 8511 usb_isoc_pkt_descr_t *isoc_pkt_descr; 8512 uint_t toggle = 0, fc, ctrl, psw; 8513 int i; 8514 8515 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8516 "ohci_parse_isoc_error: td 0x%p", (void *)td); 8517 8518 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8519 8520 fc = ((uint_t)Get_TD(td->hctd_ctrl) & 8521 HC_ITD_FC) >> HC_ITD_FC_SHIFT; 8522 8523 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 8524 "ohci_parse_isoc_error: frame count %d", fc); 8525 8526 /* 8527 * Get the address of current usb isochronous request 8528 * and array of packet descriptors. 8529 */ 8530 isoc_reqp = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp; 8531 isoc_pkt_descr = isoc_reqp->isoc_pkt_descr; 8532 isoc_pkt_descr += tw->tw_pkt_idx; 8533 8534 for (i = 0; i <= fc; i++) { 8535 8536 psw = Get_TD(td->hctd_offsets[i / 2]); 8537 8538 if (toggle) { 8539 ctrl = psw & HC_ITD_ODD_OFFSET; 8540 toggle = 0; 8541 } else { 8542 ctrl = (psw & HC_ITD_EVEN_OFFSET) << 8543 HC_ITD_OFFSET_SHIFT; 8544 toggle = 1; 8545 } 8546 8547 isoc_pkt_descr->isoc_pkt_actual_length = 8548 (ctrl >> HC_ITD_OFFSET_SHIFT) & HC_ITD_OFFSET_ADDR; 8549 8550 ctrl = (uint_t)(ctrl & (uint32_t)HC_TD_CC); 8551 8552 /* Write the status of isoc data packet */ 8553 isoc_pkt_descr->isoc_pkt_status = 8554 ohci_check_for_error(ohcip, pp, tw, td, ctrl); 8555 8556 if (isoc_pkt_descr->isoc_pkt_status) { 8557 /* Increment isoc data packet error count */ 8558 isoc_reqp->isoc_error_count++; 8559 } 8560 8561 /* 8562 * Get the address of next isoc data packet descriptor. 8563 */ 8564 isoc_pkt_descr++; 8565 } 8566 tw->tw_pkt_idx = tw->tw_pkt_idx + fc + 1; 8567 8568 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 8569 "ohci_parse_isoc_error: tw_pkt_idx %d", tw->tw_pkt_idx); 8570 8571 } 8572 8573 8574 /* 8575 * ohci_check_for_error: 8576 * 8577 * Check for any errors. 8578 */ 8579 static usb_cr_t 8580 ohci_check_for_error( 8581 ohci_state_t *ohcip, 8582 ohci_pipe_private_t *pp, 8583 ohci_trans_wrapper_t *tw, 8584 ohci_td_t *td, 8585 uint_t ctrl) 8586 { 8587 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 8588 uchar_t ep_attrs = ph->p_ep.bmAttributes; 8589 usb_cr_t error = USB_CR_OK; 8590 usb_req_attrs_t xfer_attrs; 8591 8592 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8593 "ohci_check_for_error: td = 0x%p ctrl = 0x%x", 8594 (void *)td, ctrl); 8595 8596 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8597 8598 switch (ctrl) { 8599 case HC_TD_CC_NO_E: 8600 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8601 "ohci_check_for_error: No Error"); 8602 error = USB_CR_OK; 8603 break; 8604 case HC_TD_CC_CRC: 8605 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8606 "ohci_check_for_error: CRC error"); 8607 error = USB_CR_CRC; 8608 break; 8609 case HC_TD_CC_BS: 8610 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8611 "ohci_check_for_error: Bit stuffing"); 8612 error = USB_CR_BITSTUFFING; 8613 break; 8614 case HC_TD_CC_DTM: 8615 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8616 "ohci_check_for_error: Data Toggle Mismatch"); 8617 error = USB_CR_DATA_TOGGLE_MM; 8618 break; 8619 case HC_TD_CC_STALL: 8620 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8621 "ohci_check_for_error: Stall"); 8622 error = USB_CR_STALL; 8623 break; 8624 case HC_TD_CC_DNR: 8625 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8626 "ohci_check_for_error: Device not responding"); 8627 error = USB_CR_DEV_NOT_RESP; 8628 break; 8629 case HC_TD_CC_PCF: 8630 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8631 "ohci_check_for_error: PID check failure"); 8632 error = USB_CR_PID_CHECKFAILURE; 8633 break; 8634 case HC_TD_CC_UPID: 8635 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8636 "ohci_check_for_error: Unexpected PID"); 8637 error = USB_CR_UNEXP_PID; 8638 break; 8639 case HC_TD_CC_DO: 8640 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8641 "ohci_check_for_error: Data overrrun"); 8642 error = USB_CR_DATA_OVERRUN; 8643 break; 8644 case HC_TD_CC_DU: 8645 /* 8646 * Check whether short packets are acceptable. 8647 * If so don't report error to client drivers 8648 * and restart the endpoint. Otherwise report 8649 * data underrun error to client driver. 8650 */ 8651 xfer_attrs = ohci_get_xfer_attrs(ohcip, pp, tw); 8652 8653 if (xfer_attrs & USB_ATTRS_SHORT_XFER_OK) { 8654 error = USB_CR_OK; 8655 if ((ep_attrs & USB_EP_ATTR_MASK) != 8656 USB_EP_ATTR_ISOCH) { 8657 /* 8658 * Cleanup the remaining resources that may have 8659 * been allocated for this transfer. 8660 */ 8661 if (ohci_cleanup_data_underrun(ohcip, pp, tw, 8662 td) == USB_SUCCESS) { 8663 /* Clear the halt bit */ 8664 Set_ED(pp->pp_ept->hced_headp, 8665 (Get_ED(pp->pp_ept->hced_headp) & 8666 ~HC_EPT_Halt)); 8667 } else { 8668 error = USB_CR_UNSPECIFIED_ERR; 8669 } 8670 } 8671 } else { 8672 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8673 "ohci_check_for_error: Data underrun"); 8674 8675 error = USB_CR_DATA_UNDERRUN; 8676 } 8677 8678 break; 8679 case HC_TD_CC_BO: 8680 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8681 "ohci_check_for_error: Buffer overrun"); 8682 error = USB_CR_BUFFER_OVERRUN; 8683 break; 8684 case HC_TD_CC_BU: 8685 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8686 "ohci_check_for_error: Buffer underrun"); 8687 error = USB_CR_BUFFER_UNDERRUN; 8688 break; 8689 case HC_TD_CC_NA: 8690 default: 8691 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8692 "ohci_check_for_error: Not accessed"); 8693 error = USB_CR_NOT_ACCESSED; 8694 break; 8695 } 8696 8697 if (error) { 8698 uint_t hced_ctrl = Get_ED(pp->pp_ept->hced_ctrl); 8699 8700 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8701 "ohci_check_for_error: Error %d Device address %d " 8702 "Endpoint number %d", error, (hced_ctrl & HC_EPT_FUNC), 8703 ((hced_ctrl & HC_EPT_EP) >> HC_EPT_EP_SHFT)); 8704 } 8705 8706 return (error); 8707 } 8708 8709 8710 /* 8711 * ohci_handle_error: 8712 * 8713 * Inform USBA about occured transaction errors by calling the USBA callback 8714 * routine. 8715 */ 8716 static void 8717 ohci_handle_error( 8718 ohci_state_t *ohcip, 8719 ohci_td_t *td, 8720 usb_cr_t error) 8721 { 8722 ohci_trans_wrapper_t *tw; 8723 usba_pipe_handle_data_t *ph; 8724 ohci_pipe_private_t *pp; 8725 mblk_t *mp = NULL; 8726 size_t length = 0; 8727 uchar_t attributes; 8728 usb_intr_req_t *curr_intr_reqp; 8729 8730 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8731 "ohci_handle_error: error = 0x%x", error); 8732 8733 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8734 8735 ASSERT(td != NULL); 8736 8737 /* Print the values in the td */ 8738 ohci_print_td(ohcip, td); 8739 8740 /* Obtain the transfer wrapper from the TD */ 8741 tw = (ohci_trans_wrapper_t *) 8742 OHCI_LOOKUP_ID((uint32_t)Get_TD(td->hctd_trans_wrapper)); 8743 8744 ASSERT(tw != NULL); 8745 8746 /* Obtain the pipe private structure */ 8747 pp = tw->tw_pipe_private; 8748 8749 ph = tw->tw_pipe_private->pp_pipe_handle; 8750 attributes = ph->p_ep.bmAttributes & USB_EP_ATTR_MASK; 8751 8752 /* 8753 * Special error handling 8754 */ 8755 if (tw->tw_direction == HC_TD_IN) { 8756 8757 switch (attributes) { 8758 case USB_EP_ATTR_CONTROL: 8759 if (((ph->p_ep.bmAttributes & 8760 USB_EP_ATTR_MASK) == 8761 USB_EP_ATTR_CONTROL) && 8762 (Get_TD(td->hctd_ctrl_phase) == 8763 OHCI_CTRL_SETUP_PHASE)) { 8764 8765 break; 8766 } 8767 /* FALLTHROUGH */ 8768 case USB_EP_ATTR_BULK: 8769 /* 8770 * Call ohci_sendup_td_message 8771 * to send message to upstream. 8772 */ 8773 ohci_sendup_td_message(ohcip, pp, tw, td, error); 8774 8775 return; 8776 case USB_EP_ATTR_INTR: 8777 curr_intr_reqp = 8778 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 8779 8780 if (curr_intr_reqp->intr_attributes & 8781 USB_ATTRS_ONE_XFER) { 8782 8783 ohci_handle_one_xfer_completion(ohcip, tw); 8784 } 8785 8786 /* Decrement periodic in request count */ 8787 pp->pp_cur_periodic_req_cnt--; 8788 break; 8789 case USB_EP_ATTR_ISOCH: 8790 default: 8791 break; 8792 } 8793 } else { 8794 switch (attributes) { 8795 case USB_EP_ATTR_BULK: 8796 case USB_EP_ATTR_INTR: 8797 /* 8798 * If "CurrentBufferPointer" of Transfer 8799 * Descriptor (TD) is not equal to zero, 8800 * then we sent less data to the device 8801 * than requested by client. In that case, 8802 * return the mblk after updating the 8803 * data->r_ptr. 8804 */ 8805 if (Get_TD(td->hctd_cbp)) { 8806 usb_opaque_t xfer_reqp = tw->tw_curr_xfer_reqp; 8807 size_t residue; 8808 8809 residue = ohci_get_td_residue(ohcip, td); 8810 length = Get_TD(td->hctd_xfer_offs) + 8811 Get_TD(td->hctd_xfer_len) - residue; 8812 8813 USB_DPRINTF_L2(PRINT_MASK_INTR, 8814 ohcip->ohci_log_hdl, 8815 "ohci_handle_error: requested data %lu " 8816 "sent data %lu", tw->tw_length, length); 8817 8818 if (attributes == USB_EP_ATTR_BULK) { 8819 mp = (mblk_t *)((usb_bulk_req_t *) 8820 (xfer_reqp))->bulk_data; 8821 } else { 8822 mp = (mblk_t *)((usb_intr_req_t *) 8823 (xfer_reqp))->intr_data; 8824 } 8825 8826 /* Increment the read pointer */ 8827 mp->b_rptr = mp->b_rptr + length; 8828 } 8829 break; 8830 default: 8831 break; 8832 } 8833 } 8834 8835 /* 8836 * Callback the client with the 8837 * failure reason. 8838 */ 8839 ohci_hcdi_callback(ph, tw, error); 8840 8841 /* Check anybody is waiting for transfers completion event */ 8842 ohci_check_for_transfers_completion(ohcip, pp); 8843 } 8844 8845 /* 8846 * ohci_cleanup_data_underrun: 8847 * 8848 * Cleans up resources when a short xfer occurs 8849 */ 8850 static int 8851 ohci_cleanup_data_underrun( 8852 ohci_state_t *ohcip, 8853 ohci_pipe_private_t *pp, 8854 ohci_trans_wrapper_t *tw, 8855 ohci_td_t *td) 8856 { 8857 ohci_td_t *next_td; 8858 ohci_td_t *last_td; 8859 ohci_td_t *temp_td; 8860 uint32_t last_td_addr; 8861 uint_t hced_head; 8862 8863 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8864 "ohci_cleanup_data_underrun: td 0x%p, tw 0x%p", 8865 (void *)td, (void *)tw); 8866 8867 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8868 ASSERT(tw->tw_hctd_head == td); 8869 8870 /* Check if this TD is the last td in the tw */ 8871 last_td = tw->tw_hctd_tail; 8872 if (td == last_td) { 8873 /* There is no need for cleanup */ 8874 return (USB_SUCCESS); 8875 } 8876 8877 /* 8878 * Make sure the ED is halted before we change any td's. 8879 * If for some reason it is not halted, return error to client 8880 * driver so they can reset the port. 8881 */ 8882 hced_head = Get_ED(pp->pp_ept->hced_headp); 8883 if (!(hced_head & HC_EPT_Halt)) { 8884 uint_t hced_ctrl = Get_ED(pp->pp_ept->hced_ctrl); 8885 8886 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8887 "ohci_cleanup_data_underrun: Unable to clean up a short " 8888 "xfer error. Client might send/receive irrelevant data." 8889 " Device address %d Endpoint number %d", 8890 (hced_ctrl & HC_EPT_FUNC), 8891 ((hced_ctrl & HC_EPT_EP) >> HC_EPT_EP_SHFT)); 8892 8893 Set_ED(pp->pp_ept->hced_headp, hced_head | HC_EPT_Halt); 8894 8895 return (USB_FAILURE); 8896 } 8897 8898 /* 8899 * Get the address of the first td of the next transfer (tw). 8900 * This td, may currently be a dummy td, but when a new request 8901 * arrives, it will be transformed into a regular td. 8902 */ 8903 last_td_addr = Get_TD(last_td->hctd_next_td); 8904 /* Set ED head to this last td */ 8905 Set_ED(pp->pp_ept->hced_headp, 8906 (last_td_addr & HC_EPT_TD_HEAD) | 8907 (hced_head & ~HC_EPT_TD_HEAD)); 8908 8909 /* 8910 * Start removing all the unused TD's from the TW, 8911 * but keep the first one. 8912 */ 8913 tw->tw_hctd_tail = td; 8914 8915 /* 8916 * Get the last_td, the next td in the tw list. 8917 * Afterwards completely disassociate the current td from other tds 8918 */ 8919 next_td = (ohci_td_t *)ohci_td_iommu_to_cpu(ohcip, 8920 Get_TD(td->hctd_tw_next_td)); 8921 Set_TD(td->hctd_tw_next_td, NULL); 8922 8923 /* 8924 * Iterate down the tw list and deallocate them 8925 */ 8926 while (next_td != NULL) { 8927 tw->tw_num_tds--; 8928 /* Disassociate this td from it's TW and set to RECLAIM */ 8929 Set_TD(next_td->hctd_trans_wrapper, NULL); 8930 Set_TD(next_td->hctd_state, HC_TD_RECLAIM); 8931 8932 temp_td = next_td; 8933 8934 next_td = (ohci_td_t *)ohci_td_iommu_to_cpu(ohcip, 8935 Get_TD(next_td->hctd_tw_next_td)); 8936 8937 ohci_deallocate_td(ohcip, temp_td); 8938 } 8939 8940 ASSERT(tw->tw_num_tds == 1); 8941 8942 return (USB_SUCCESS); 8943 } 8944 8945 /* 8946 * ohci_handle_normal_td: 8947 */ 8948 static void 8949 ohci_handle_normal_td( 8950 ohci_state_t *ohcip, 8951 ohci_td_t *td, 8952 ohci_trans_wrapper_t *tw) 8953 { 8954 ohci_pipe_private_t *pp; /* Pipe private field */ 8955 8956 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8957 "ohci_handle_normal_td:"); 8958 8959 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8960 ASSERT(tw != NULL); 8961 8962 /* Obtain the pipe private structure */ 8963 pp = tw->tw_pipe_private; 8964 8965 (*tw->tw_handle_td)(ohcip, pp, tw, 8966 td, tw->tw_handle_callback_value); 8967 8968 /* Check anybody is waiting for transfers completion event */ 8969 ohci_check_for_transfers_completion(ohcip, pp); 8970 } 8971 8972 8973 /* 8974 * ohci_handle_ctrl_td: 8975 * 8976 * Handle a control Transfer Descriptor (TD). 8977 */ 8978 /* ARGSUSED */ 8979 static void 8980 ohci_handle_ctrl_td( 8981 ohci_state_t *ohcip, 8982 ohci_pipe_private_t *pp, 8983 ohci_trans_wrapper_t *tw, 8984 ohci_td_t *td, 8985 void *tw_handle_callback_value) 8986 { 8987 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 8988 8989 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 8990 "ohci_handle_ctrl_td: pp = 0x%p tw = 0x%p td = 0x%p state = 0x%x", 8991 (void *)pp, (void *)tw, (void *)td, Get_TD(td->hctd_ctrl_phase)); 8992 8993 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 8994 8995 /* 8996 * Check which control transfer phase got completed. 8997 */ 8998 tw->tw_num_tds--; 8999 switch (Get_TD(td->hctd_ctrl_phase)) { 9000 case OHCI_CTRL_SETUP_PHASE: 9001 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9002 "Setup complete: pp 0x%p td 0x%p", (void *)pp, (void *)td); 9003 9004 break; 9005 case OHCI_CTRL_DATA_PHASE: 9006 /* 9007 * If "CurrentBufferPointer" of Transfer Descriptor (TD) 9008 * is not equal to zero, then we received less data from 9009 * the device than requested by us. In that case, get the 9010 * actual received data size. 9011 */ 9012 if (Get_TD(td->hctd_cbp)) { 9013 size_t length, residue; 9014 9015 residue = ohci_get_td_residue(ohcip, td); 9016 length = Get_TD(td->hctd_xfer_offs) + 9017 Get_TD(td->hctd_xfer_len) - residue; 9018 9019 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9020 "ohci_handle_ctrl_qtd: requested data %lu " 9021 "received data %lu", tw->tw_length, length); 9022 9023 /* Save actual received data length */ 9024 tw->tw_length = length; 9025 } 9026 9027 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9028 "Data complete: pp 0x%p td 0x%p", 9029 (void *)pp, (void *)td); 9030 9031 break; 9032 case OHCI_CTRL_STATUS_PHASE: 9033 if ((tw->tw_length != 0) && 9034 (tw->tw_direction == HC_TD_IN)) { 9035 9036 /* 9037 * Call ohci_sendup_td_message 9038 * to send message to upstream. 9039 */ 9040 ohci_sendup_td_message(ohcip, 9041 pp, tw, td, USB_CR_OK); 9042 } else { 9043 ohci_do_byte_stats(ohcip, 9044 tw->tw_length - OHCI_MAX_TD_BUF_SIZE, 9045 ph->p_ep.bmAttributes, 9046 ph->p_ep.bEndpointAddress); 9047 9048 ohci_hcdi_callback(ph, tw, USB_CR_OK); 9049 } 9050 9051 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9052 "Status complete: pp 0x%p td 0x%p", (void *)pp, (void *)td); 9053 9054 break; 9055 } 9056 } 9057 9058 9059 /* 9060 * ohci_handle_bulk_td: 9061 * 9062 * Handle a bulk Transfer Descriptor (TD). 9063 */ 9064 /* ARGSUSED */ 9065 static void 9066 ohci_handle_bulk_td( 9067 ohci_state_t *ohcip, 9068 ohci_pipe_private_t *pp, 9069 ohci_trans_wrapper_t *tw, 9070 ohci_td_t *td, 9071 void *tw_handle_callback_value) 9072 { 9073 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 9074 usb_ep_descr_t *eptd = &ph->p_ep; 9075 9076 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9077 "ohci_handle_bulk_td:"); 9078 9079 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9080 9081 /* 9082 * Decrement the TDs counter and check whether all the bulk 9083 * data has been send or received. If TDs counter reaches 9084 * zero then inform client driver about completion current 9085 * bulk request. Other wise wait for completion of other bulk 9086 * TDs or transactions on this pipe. 9087 */ 9088 if (--tw->tw_num_tds != 0) { 9089 9090 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9091 "ohci_handle_bulk_td: Number of TDs %d", tw->tw_num_tds); 9092 9093 return; 9094 } 9095 9096 /* 9097 * If this is a bulk in pipe, return the data to the client. 9098 * For a bulk out pipe, there is no need to do anything. 9099 */ 9100 if ((eptd->bEndpointAddress & 9101 USB_EP_DIR_MASK) == USB_EP_DIR_OUT) { 9102 9103 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9104 "ohci_handle_bulk_td: Bulk out pipe"); 9105 9106 ohci_do_byte_stats(ohcip, tw->tw_length, 9107 eptd->bmAttributes, eptd->bEndpointAddress); 9108 9109 /* Do the callback */ 9110 ohci_hcdi_callback(ph, tw, USB_CR_OK); 9111 9112 return; 9113 } 9114 9115 /* Call ohci_sendup_td_message to send message to upstream */ 9116 ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK); 9117 } 9118 9119 9120 /* 9121 * ohci_handle_intr_td: 9122 * 9123 * Handle a interrupt Transfer Descriptor (TD). 9124 */ 9125 /* ARGSUSED */ 9126 static void 9127 ohci_handle_intr_td( 9128 ohci_state_t *ohcip, 9129 ohci_pipe_private_t *pp, 9130 ohci_trans_wrapper_t *tw, 9131 ohci_td_t *td, 9132 void *tw_handle_callback_value) 9133 { 9134 usb_intr_req_t *curr_intr_reqp = 9135 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 9136 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 9137 usb_ep_descr_t *eptd = &ph->p_ep; 9138 usb_req_attrs_t attrs; 9139 int error = USB_SUCCESS; 9140 9141 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9142 "ohci_handle_intr_td: pp=0x%p tw=0x%p td=0x%p" 9143 "intr_reqp=0%p data=0x%p", (void *)pp, (void *)tw, (void *)td, 9144 (void *)curr_intr_reqp, (void *)curr_intr_reqp->intr_data); 9145 9146 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9147 9148 /* Get the interrupt xfer attributes */ 9149 attrs = curr_intr_reqp->intr_attributes; 9150 9151 /* 9152 * For a Interrupt OUT pipe, we just callback and we are done 9153 */ 9154 if ((eptd->bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_OUT) { 9155 9156 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9157 "ohci_handle_intr_td: Intr out pipe, intr_reqp=0x%p," 9158 "data=0x%p", (void *)curr_intr_reqp, 9159 (void *)curr_intr_reqp->intr_data); 9160 9161 ohci_do_byte_stats(ohcip, tw->tw_length, 9162 eptd->bmAttributes, eptd->bEndpointAddress); 9163 9164 /* Do the callback */ 9165 ohci_hcdi_callback(ph, tw, USB_CR_OK); 9166 9167 return; 9168 } 9169 9170 /* Decrement number of interrupt request count */ 9171 pp->pp_cur_periodic_req_cnt--; 9172 9173 /* 9174 * Check usb flag whether USB_FLAGS_ONE_XFER flag is set 9175 * and if so, free duplicate request. 9176 */ 9177 if (attrs & USB_ATTRS_ONE_XFER) { 9178 ohci_handle_one_xfer_completion(ohcip, tw); 9179 } 9180 9181 /* Call ohci_sendup_td_message to callback into client */ 9182 ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK); 9183 9184 /* 9185 * If interrupt pipe state is still active, insert next Interrupt 9186 * request into the Host Controller's Interrupt list. Otherwise 9187 * you are done. 9188 */ 9189 if (pp->pp_state != OHCI_PIPE_STATE_ACTIVE) { 9190 return; 9191 } 9192 9193 if ((error = ohci_allocate_periodic_in_resource(ohcip, pp, tw, 0)) == 9194 USB_SUCCESS) { 9195 curr_intr_reqp = (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 9196 9197 ASSERT(curr_intr_reqp != NULL); 9198 9199 tw->tw_num_tds = 1; 9200 9201 if (ohci_tw_rebind_cookie(ohcip, pp, tw) != USB_SUCCESS) { 9202 ohci_deallocate_periodic_in_resource(ohcip, pp, tw); 9203 error = USB_FAILURE; 9204 } else if (ohci_allocate_tds_for_tw(ohcip, tw, 9205 tw->tw_num_tds) != USB_SUCCESS) { 9206 ohci_deallocate_periodic_in_resource(ohcip, pp, tw); 9207 error = USB_FAILURE; 9208 } 9209 } 9210 9211 if (error != USB_SUCCESS) { 9212 /* 9213 * Set pipe state to stop polling and error to no 9214 * resource. Don't insert any more interrupt polling 9215 * requests. 9216 */ 9217 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING; 9218 pp->pp_error = USB_CR_NO_RESOURCES; 9219 } else { 9220 ohci_insert_intr_req(ohcip, pp, tw, 0); 9221 9222 /* Increment number of interrupt request count */ 9223 pp->pp_cur_periodic_req_cnt++; 9224 9225 ASSERT(pp->pp_cur_periodic_req_cnt == 9226 pp->pp_max_periodic_req_cnt); 9227 } 9228 } 9229 9230 9231 /* 9232 * ohci_handle_one_xfer_completion: 9233 */ 9234 static void 9235 ohci_handle_one_xfer_completion( 9236 ohci_state_t *ohcip, 9237 ohci_trans_wrapper_t *tw) 9238 { 9239 usba_pipe_handle_data_t *ph = tw->tw_pipe_private->pp_pipe_handle; 9240 ohci_pipe_private_t *pp = tw->tw_pipe_private; 9241 usb_intr_req_t *curr_intr_reqp = 9242 (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 9243 9244 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9245 "ohci_handle_one_xfer_completion: tw = 0x%p", (void *)tw); 9246 9247 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9248 ASSERT(curr_intr_reqp->intr_attributes & USB_ATTRS_ONE_XFER); 9249 9250 pp->pp_state = OHCI_PIPE_STATE_IDLE; 9251 9252 /* 9253 * For one xfer, we need to copy back data ptr 9254 * and free current request 9255 */ 9256 ((usb_intr_req_t *)(pp->pp_client_periodic_in_reqp))-> 9257 intr_data = ((usb_intr_req_t *) 9258 (tw->tw_curr_xfer_reqp))->intr_data; 9259 9260 ((usb_intr_req_t *)tw->tw_curr_xfer_reqp)->intr_data = NULL; 9261 9262 /* Now free duplicate current request */ 9263 usb_free_intr_req((usb_intr_req_t *)tw-> tw_curr_xfer_reqp); 9264 9265 mutex_enter(&ph->p_mutex); 9266 ph->p_req_count--; 9267 mutex_exit(&ph->p_mutex); 9268 9269 /* Make client's request the current request */ 9270 tw->tw_curr_xfer_reqp = pp->pp_client_periodic_in_reqp; 9271 pp->pp_client_periodic_in_reqp = NULL; 9272 } 9273 9274 9275 /* 9276 * ohci_handle_isoc_td: 9277 * 9278 * Handle an isochronous Transfer Descriptor (TD). 9279 */ 9280 /* ARGSUSED */ 9281 static void 9282 ohci_handle_isoc_td( 9283 ohci_state_t *ohcip, 9284 ohci_pipe_private_t *pp, 9285 ohci_trans_wrapper_t *tw, 9286 ohci_td_t *td, 9287 void *tw_handle_callback_value) 9288 { 9289 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 9290 usb_ep_descr_t *eptd = &ph->p_ep; 9291 usb_isoc_req_t *curr_isoc_reqp = 9292 (usb_isoc_req_t *)tw->tw_curr_xfer_reqp; 9293 int error = USB_SUCCESS; 9294 9295 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9296 "ohci_handle_isoc_td: pp=0x%p tw=0x%p td=0x%p" 9297 "isoc_reqp=0%p data=0x%p", (void *)pp, (void *)tw, (void *)td, 9298 (void *)curr_isoc_reqp, (void *)curr_isoc_reqp->isoc_data); 9299 9300 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9301 9302 /* 9303 * Decrement the TDs counter and check whether all the isoc 9304 * data has been send or received. If TDs counter reaches 9305 * zero then inform client driver about completion current 9306 * isoc request. Otherwise wait for completion of other isoc 9307 * TDs or transactions on this pipe. 9308 */ 9309 if (--tw->tw_num_tds != 0) { 9310 9311 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9312 "ohci_handle_isoc_td: Number of TDs %d", tw->tw_num_tds); 9313 9314 return; 9315 } 9316 9317 /* 9318 * If this is a isoc in pipe, return the data to the client. 9319 * For a isoc out pipe, there is no need to do anything. 9320 */ 9321 if ((eptd->bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_OUT) { 9322 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9323 "ohci_handle_isoc_td: Isoc out pipe, isoc_reqp=0x%p," 9324 "data=0x%p", (void *)curr_isoc_reqp, 9325 (void *)curr_isoc_reqp->isoc_data); 9326 9327 ohci_do_byte_stats(ohcip, tw->tw_length, 9328 eptd->bmAttributes, eptd->bEndpointAddress); 9329 9330 /* Do the callback */ 9331 ohci_hcdi_callback(ph, tw, USB_CR_OK); 9332 9333 return; 9334 } 9335 9336 /* Decrement number of IN isochronous request count */ 9337 pp->pp_cur_periodic_req_cnt--; 9338 9339 /* Call ohci_sendup_td_message to send message to upstream */ 9340 ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK); 9341 9342 /* 9343 * If isochronous pipe state is still active, insert next isochronous 9344 * request into the Host Controller's isochronous list. 9345 */ 9346 if (pp->pp_state != OHCI_PIPE_STATE_ACTIVE) { 9347 return; 9348 } 9349 9350 if ((error = ohci_allocate_periodic_in_resource(ohcip, pp, tw, 0)) == 9351 USB_SUCCESS) { 9352 curr_isoc_reqp = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp; 9353 9354 ASSERT(curr_isoc_reqp != NULL); 9355 9356 tw->tw_num_tds = 9357 curr_isoc_reqp->isoc_pkts_count / OHCI_ISOC_PKTS_PER_TD; 9358 if (curr_isoc_reqp->isoc_pkts_count % OHCI_ISOC_PKTS_PER_TD) { 9359 tw->tw_num_tds++; 9360 } 9361 9362 if (ohci_tw_rebind_cookie(ohcip, pp, tw) != USB_SUCCESS) { 9363 ohci_deallocate_periodic_in_resource(ohcip, pp, tw); 9364 error = USB_FAILURE; 9365 } else if (ohci_allocate_tds_for_tw(ohcip, tw, 9366 tw->tw_num_tds) != USB_SUCCESS) { 9367 ohci_deallocate_periodic_in_resource(ohcip, pp, tw); 9368 error = USB_FAILURE; 9369 } 9370 } 9371 9372 if (error != USB_SUCCESS || 9373 ohci_insert_isoc_req(ohcip, pp, tw, 0) != USB_SUCCESS) { 9374 /* 9375 * Set pipe state to stop polling and error to no 9376 * resource. Don't insert any more isoch polling 9377 * requests. 9378 */ 9379 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING; 9380 pp->pp_error = USB_CR_NO_RESOURCES; 9381 9382 } else { 9383 /* Increment number of IN isochronous request count */ 9384 pp->pp_cur_periodic_req_cnt++; 9385 9386 ASSERT(pp->pp_cur_periodic_req_cnt == 9387 pp->pp_max_periodic_req_cnt); 9388 } 9389 } 9390 9391 9392 /* 9393 * ohci_tw_rebind_cookie: 9394 * 9395 * If the cookie associated with a DMA buffer has been walked, the cookie 9396 * is not usable any longer. To reuse the DMA buffer, the DMA handle needs 9397 * to rebind for cookies. 9398 */ 9399 static int 9400 ohci_tw_rebind_cookie( 9401 ohci_state_t *ohcip, 9402 ohci_pipe_private_t *pp, 9403 ohci_trans_wrapper_t *tw) 9404 { 9405 usb_ep_descr_t *eptd = &pp->pp_pipe_handle->p_ep; 9406 int rval, i; 9407 uint_t ccount; 9408 9409 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9410 "ohci_tw_rebind_cookie:"); 9411 9412 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9413 9414 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH) { 9415 ASSERT(tw->tw_num_tds == tw->tw_ncookies); 9416 9417 for (i = 0; i < tw->tw_num_tds; i++) { 9418 if (tw->tw_isoc_bufs[i].ncookies == 1) { 9419 9420 /* 9421 * no need to rebind when there is 9422 * only one cookie in a buffer 9423 */ 9424 continue; 9425 } 9426 9427 /* unbind the DMA handle before rebinding */ 9428 rval = ddi_dma_unbind_handle( 9429 tw->tw_isoc_bufs[i].dma_handle); 9430 ASSERT(rval == USB_SUCCESS); 9431 tw->tw_isoc_bufs[i].ncookies = 0; 9432 9433 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9434 "rebind dma_handle %d", i); 9435 9436 /* rebind the handle to get cookies */ 9437 rval = ddi_dma_addr_bind_handle( 9438 tw->tw_isoc_bufs[i].dma_handle, NULL, 9439 (caddr_t)tw->tw_isoc_bufs[i].buf_addr, 9440 tw->tw_isoc_bufs[i].length, 9441 DDI_DMA_RDWR|DDI_DMA_CONSISTENT, 9442 DDI_DMA_DONTWAIT, NULL, 9443 &tw->tw_isoc_bufs[i].cookie, &ccount); 9444 9445 if ((rval == DDI_DMA_MAPPED) && 9446 (ccount <= OHCI_DMA_ATTR_TD_SGLLEN)) { 9447 tw->tw_isoc_bufs[i].ncookies = ccount; 9448 } else { 9449 9450 return (USB_NO_RESOURCES); 9451 } 9452 } 9453 } else { 9454 if (tw->tw_cookie_idx != 0) { 9455 /* unbind the DMA handle before rebinding */ 9456 rval = ddi_dma_unbind_handle(tw->tw_dmahandle); 9457 ASSERT(rval == DDI_SUCCESS); 9458 tw->tw_ncookies = 0; 9459 9460 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9461 "rebind dma_handle"); 9462 9463 /* rebind the handle to get cookies */ 9464 rval = ddi_dma_addr_bind_handle( 9465 tw->tw_dmahandle, NULL, 9466 (caddr_t)tw->tw_buf, tw->tw_length, 9467 DDI_DMA_RDWR|DDI_DMA_CONSISTENT, 9468 DDI_DMA_DONTWAIT, NULL, 9469 &tw->tw_cookie, &ccount); 9470 9471 if (rval == DDI_DMA_MAPPED) { 9472 tw->tw_ncookies = ccount; 9473 tw->tw_dma_offs = 0; 9474 tw->tw_cookie_idx = 0; 9475 } else { 9476 9477 return (USB_NO_RESOURCES); 9478 } 9479 } 9480 } 9481 9482 return (USB_SUCCESS); 9483 } 9484 9485 9486 /* 9487 * ohci_sendup_td_message: 9488 * copy data, if necessary and do callback 9489 */ 9490 static void 9491 ohci_sendup_td_message( 9492 ohci_state_t *ohcip, 9493 ohci_pipe_private_t *pp, 9494 ohci_trans_wrapper_t *tw, 9495 ohci_td_t *td, 9496 usb_cr_t error) 9497 { 9498 usb_ep_descr_t *eptd = &pp->pp_pipe_handle->p_ep; 9499 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 9500 size_t length = 0, skip_len = 0, residue; 9501 mblk_t *mp; 9502 uchar_t *buf; 9503 usb_opaque_t curr_xfer_reqp = tw->tw_curr_xfer_reqp; 9504 9505 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9506 9507 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9508 "ohci_sendup_td_message:"); 9509 9510 ASSERT(tw != NULL); 9511 9512 length = tw->tw_length; 9513 9514 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) { 9515 case USB_EP_ATTR_CONTROL: 9516 /* 9517 * Get the correct length, adjust it for the setup size 9518 * which is not part of the data length in control end 9519 * points. Update tw->tw_length for future references. 9520 */ 9521 if (((usb_ctrl_req_t *)curr_xfer_reqp)->ctrl_wLength) { 9522 tw->tw_length = length = length - OHCI_MAX_TD_BUF_SIZE; 9523 } else { 9524 tw->tw_length = length = length - SETUP_SIZE; 9525 } 9526 9527 /* Set the length of the buffer to skip */ 9528 skip_len = OHCI_MAX_TD_BUF_SIZE; 9529 9530 if (Get_TD(td->hctd_ctrl_phase) != OHCI_CTRL_DATA_PHASE) { 9531 break; 9532 } 9533 /* FALLTHRU */ 9534 case USB_EP_ATTR_BULK: 9535 case USB_EP_ATTR_INTR: 9536 /* 9537 * If error is "data overrun", do not check for the 9538 * "CurrentBufferPointer" and return whatever data 9539 * received to the client driver. 9540 */ 9541 if (error == USB_CR_DATA_OVERRUN) { 9542 break; 9543 } 9544 9545 /* 9546 * If "CurrentBufferPointer" of Transfer Descriptor 9547 * (TD) is not equal to zero, then we received less 9548 * data from the device than requested by us. In that 9549 * case, get the actual received data size. 9550 */ 9551 if (Get_TD(td->hctd_cbp)) { 9552 residue = ohci_get_td_residue(ohcip, td); 9553 length = Get_TD(td->hctd_xfer_offs) + 9554 Get_TD(td->hctd_xfer_len) - residue - skip_len; 9555 9556 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9557 "ohci_sendup_qtd_message: requested data %lu " 9558 "received data %lu", tw->tw_length, length); 9559 } 9560 9561 break; 9562 case USB_EP_ATTR_ISOCH: 9563 default: 9564 break; 9565 } 9566 9567 /* Copy the data into the mblk_t */ 9568 buf = (uchar_t *)tw->tw_buf + skip_len; 9569 9570 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9571 "ohci_sendup_qtd_message: length %lu error %d", length, error); 9572 9573 /* Get the message block */ 9574 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) { 9575 case USB_EP_ATTR_CONTROL: 9576 mp = ((usb_ctrl_req_t *)curr_xfer_reqp)->ctrl_data; 9577 break; 9578 case USB_EP_ATTR_BULK: 9579 mp = ((usb_bulk_req_t *)curr_xfer_reqp)->bulk_data; 9580 break; 9581 case USB_EP_ATTR_INTR: 9582 mp = ((usb_intr_req_t *)curr_xfer_reqp)->intr_data; 9583 break; 9584 case USB_EP_ATTR_ISOCH: 9585 mp = ((usb_isoc_req_t *)curr_xfer_reqp)->isoc_data; 9586 break; 9587 } 9588 9589 ASSERT(mp != NULL); 9590 9591 if (length) { 9592 int i; 9593 uchar_t *p = mp->b_rptr; 9594 9595 /* 9596 * Update kstat byte counts 9597 * The control endpoints don't have direction bits so in 9598 * order for control stats to be counted correctly an in 9599 * bit must be faked on a control read. 9600 */ 9601 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) == 9602 USB_EP_ATTR_CONTROL) { 9603 ohci_do_byte_stats(ohcip, length, 9604 eptd->bmAttributes, USB_EP_DIR_IN); 9605 } else { 9606 ohci_do_byte_stats(ohcip, length, 9607 eptd->bmAttributes, eptd->bEndpointAddress); 9608 } 9609 9610 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) == 9611 USB_EP_ATTR_ISOCH) { 9612 for (i = 0; i < tw->tw_ncookies; i++) { 9613 Sync_IO_Buffer( 9614 tw->tw_isoc_bufs[i].dma_handle, 9615 tw->tw_isoc_bufs[i].length); 9616 9617 ddi_rep_get8(tw->tw_isoc_bufs[i].mem_handle, 9618 p, (uint8_t *)tw->tw_isoc_bufs[i].buf_addr, 9619 tw->tw_isoc_bufs[i].length, 9620 DDI_DEV_AUTOINCR); 9621 p += tw->tw_isoc_bufs[i].length; 9622 } 9623 tw->tw_pkt_idx = 0; 9624 } else { 9625 /* Sync IO buffer */ 9626 Sync_IO_Buffer(tw->tw_dmahandle, (skip_len + length)); 9627 9628 /* Copy the data into the message */ 9629 ddi_rep_get8(tw->tw_accesshandle, 9630 mp->b_rptr, buf, length, DDI_DEV_AUTOINCR); 9631 } 9632 9633 /* Increment the write pointer */ 9634 mp->b_wptr = mp->b_wptr + length; 9635 } else { 9636 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9637 "ohci_sendup_td_message: Zero length packet"); 9638 } 9639 9640 ohci_hcdi_callback(ph, tw, error); 9641 } 9642 9643 9644 /* 9645 * ohci_get_td_residue: 9646 * 9647 * Calculate the bytes not transfered by the TD 9648 */ 9649 size_t 9650 ohci_get_td_residue( 9651 ohci_state_t *ohcip, 9652 ohci_td_t *td) 9653 { 9654 uint32_t buf_addr, end_addr; 9655 size_t residue; 9656 9657 buf_addr = Get_TD(td->hctd_cbp); 9658 end_addr = Get_TD(td->hctd_buf_end); 9659 9660 if ((buf_addr & 0xfffff000) == 9661 (end_addr & 0xfffff000)) { 9662 residue = end_addr - buf_addr + 1; 9663 } else { 9664 residue = OHCI_MAX_TD_BUF_SIZE - 9665 (buf_addr & 0x00000fff) + 9666 (end_addr & 0x00000fff) + 1; 9667 } 9668 9669 return (residue); 9670 } 9671 9672 9673 /* 9674 * Miscellaneous functions 9675 */ 9676 9677 /* 9678 * ohci_obtain_state: 9679 * NOTE: This function is also called from POLLED MODE. 9680 */ 9681 ohci_state_t * 9682 ohci_obtain_state(dev_info_t *dip) 9683 { 9684 int instance = ddi_get_instance(dip); 9685 ohci_state_t *state = ddi_get_soft_state( 9686 ohci_statep, instance); 9687 9688 ASSERT(state != NULL); 9689 9690 return (state); 9691 } 9692 9693 9694 /* 9695 * ohci_state_is_operational: 9696 * 9697 * Check the Host controller state and return proper values. 9698 */ 9699 int 9700 ohci_state_is_operational(ohci_state_t *ohcip) 9701 { 9702 int val; 9703 9704 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9705 9706 switch (ohcip->ohci_hc_soft_state) { 9707 case OHCI_CTLR_INIT_STATE: 9708 case OHCI_CTLR_SUSPEND_STATE: 9709 val = USB_FAILURE; 9710 break; 9711 case OHCI_CTLR_OPERATIONAL_STATE: 9712 val = USB_SUCCESS; 9713 break; 9714 case OHCI_CTLR_ERROR_STATE: 9715 val = USB_HC_HARDWARE_ERROR; 9716 break; 9717 default: 9718 val = USB_FAILURE; 9719 break; 9720 } 9721 9722 return (val); 9723 } 9724 9725 9726 /* 9727 * ohci_do_soft_reset 9728 * 9729 * Do soft reset of ohci host controller. 9730 */ 9731 int 9732 ohci_do_soft_reset(ohci_state_t *ohcip) 9733 { 9734 usb_frame_number_t before_frame_number, after_frame_number; 9735 timeout_id_t xfer_timer_id, rh_timer_id; 9736 ohci_regs_t *ohci_save_regs; 9737 ohci_td_t *done_head; 9738 9739 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9740 9741 /* Increment host controller error count */ 9742 ohcip->ohci_hc_error++; 9743 9744 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9745 "ohci_do_soft_reset:" 9746 "Reset ohci host controller 0x%x", ohcip->ohci_hc_error); 9747 9748 /* 9749 * Allocate space for saving current Host Controller 9750 * registers. Don't do any recovery if allocation 9751 * fails. 9752 */ 9753 ohci_save_regs = (ohci_regs_t *) 9754 kmem_zalloc(sizeof (ohci_regs_t), KM_NOSLEEP); 9755 9756 if (ohci_save_regs == NULL) { 9757 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9758 "ohci_do_soft_reset: kmem_zalloc failed"); 9759 9760 return (USB_FAILURE); 9761 } 9762 9763 /* Save current ohci registers */ 9764 ohci_save_regs->hcr_control = Get_OpReg(hcr_control); 9765 ohci_save_regs->hcr_cmd_status = Get_OpReg(hcr_cmd_status); 9766 ohci_save_regs->hcr_intr_enable = Get_OpReg(hcr_intr_enable); 9767 ohci_save_regs->hcr_periodic_strt = Get_OpReg(hcr_periodic_strt); 9768 ohci_save_regs->hcr_frame_interval = Get_OpReg(hcr_frame_interval); 9769 ohci_save_regs->hcr_HCCA = Get_OpReg(hcr_HCCA); 9770 ohci_save_regs->hcr_bulk_head = Get_OpReg(hcr_bulk_head); 9771 ohci_save_regs->hcr_ctrl_head = Get_OpReg(hcr_ctrl_head); 9772 9773 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9774 "ohci_do_soft_reset: Save reg = 0x%p", (void *)ohci_save_regs); 9775 9776 /* Disable all list processing and interrupts */ 9777 Set_OpReg(hcr_control, (Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE | 9778 HCR_CONTROL_BLE | HCR_CONTROL_PLE | HCR_CONTROL_IE))); 9779 9780 Set_OpReg(hcr_intr_disable, HCR_INTR_SO | 9781 HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE | 9782 HCR_INTR_FNO | HCR_INTR_SOF | HCR_INTR_MIE); 9783 9784 /* Wait for few milliseconds */ 9785 drv_usecwait(OHCI_TIMEWAIT); 9786 9787 /* Root hub interrupt pipe timeout id */ 9788 rh_timer_id = ohcip->ohci_root_hub.rh_intr_pipe_timer_id; 9789 9790 /* Stop the root hub interrupt timer */ 9791 if (rh_timer_id) { 9792 ohcip->ohci_root_hub.rh_intr_pipe_timer_id = 0; 9793 ohcip->ohci_root_hub.rh_intr_pipe_state = 9794 OHCI_PIPE_STATE_IDLE; 9795 9796 mutex_exit(&ohcip->ohci_int_mutex); 9797 (void) untimeout(rh_timer_id); 9798 mutex_enter(&ohcip->ohci_int_mutex); 9799 } 9800 9801 /* Transfer timeout id */ 9802 xfer_timer_id = ohcip->ohci_timer_id; 9803 9804 /* Stop the global transfer timer */ 9805 if (xfer_timer_id) { 9806 ohcip->ohci_timer_id = 0; 9807 mutex_exit(&ohcip->ohci_int_mutex); 9808 (void) untimeout(xfer_timer_id); 9809 mutex_enter(&ohcip->ohci_int_mutex); 9810 } 9811 9812 /* Process any pending HCCA DoneHead */ 9813 done_head = (ohci_td_t *)(uintptr_t) 9814 (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) & HCCA_DONE_HEAD_MASK); 9815 9816 if (ohci_check_done_head(ohcip, done_head) == USB_SUCCESS) { 9817 /* Reset the done head to NULL */ 9818 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, NULL); 9819 9820 ohci_traverse_done_list(ohcip, done_head); 9821 } 9822 9823 /* Process any pending hcr_done_head value */ 9824 done_head = (ohci_td_t *)(uintptr_t) 9825 (Get_OpReg(hcr_done_head) & HCCA_DONE_HEAD_MASK); 9826 if (ohci_check_done_head(ohcip, done_head) == USB_SUCCESS) { 9827 9828 ohci_traverse_done_list(ohcip, done_head); 9829 } 9830 9831 /* Do soft reset of ohci host controller */ 9832 Set_OpReg(hcr_cmd_status, HCR_STATUS_RESET); 9833 9834 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9835 "ohci_do_soft_reset: Reset in progress"); 9836 9837 /* Wait for reset to complete */ 9838 drv_usecwait(OHCI_RESET_TIMEWAIT); 9839 9840 /* Reset HCCA HcFrameNumber */ 9841 Set_HCCA(ohcip->ohci_hccap->HccaFrameNo, 0x00000000); 9842 9843 /* 9844 * Restore previous saved HC register value 9845 * into the current HC registers. 9846 */ 9847 Set_OpReg(hcr_periodic_strt, (uint32_t) 9848 ohci_save_regs->hcr_periodic_strt); 9849 9850 Set_OpReg(hcr_frame_interval, (uint32_t) 9851 ohci_save_regs->hcr_frame_interval); 9852 9853 Set_OpReg(hcr_done_head, 0x0); 9854 9855 Set_OpReg(hcr_bulk_curr, 0x0); 9856 9857 Set_OpReg(hcr_bulk_head, (uint32_t) 9858 ohci_save_regs->hcr_bulk_head); 9859 9860 Set_OpReg(hcr_ctrl_curr, 0x0); 9861 9862 Set_OpReg(hcr_ctrl_head, (uint32_t) 9863 ohci_save_regs->hcr_ctrl_head); 9864 9865 Set_OpReg(hcr_periodic_curr, 0x0); 9866 9867 Set_OpReg(hcr_HCCA, (uint32_t) 9868 ohci_save_regs->hcr_HCCA); 9869 9870 Set_OpReg(hcr_intr_status, 0x0); 9871 9872 /* 9873 * Set HcInterruptEnable to enable all interrupts except 9874 * Root Hub Status change interrupt. 9875 */ 9876 Set_OpReg(hcr_intr_enable, 9877 HCR_INTR_SO | HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE | 9878 HCR_INTR_FNO | HCR_INTR_SOF | HCR_INTR_MIE); 9879 9880 /* Start Control and Bulk list processing */ 9881 Set_OpReg(hcr_cmd_status, (HCR_STATUS_CLF | HCR_STATUS_BLF)); 9882 9883 /* 9884 * Start up Control, Bulk, Periodic and Isochronous lists 9885 * processing. 9886 */ 9887 Set_OpReg(hcr_control, (uint32_t) 9888 (ohci_save_regs->hcr_control & (~HCR_CONTROL_HCFS))); 9889 9890 /* 9891 * Deallocate the space that allocated for saving 9892 * HC registers. 9893 */ 9894 kmem_free((void *) ohci_save_regs, sizeof (ohci_regs_t)); 9895 9896 /* Resume the host controller */ 9897 Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) & 9898 (~HCR_CONTROL_HCFS)) | HCR_CONTROL_RESUME)); 9899 9900 /* Wait for resume to complete */ 9901 drv_usecwait(OHCI_RESUME_TIMEWAIT); 9902 9903 /* Set the Host Controller Functional State to Operational */ 9904 Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) & 9905 (~HCR_CONTROL_HCFS)) | HCR_CONTROL_OPERAT)); 9906 9907 /* Wait 10ms for HC to start sending SOF */ 9908 drv_usecwait(OHCI_TIMEWAIT); 9909 9910 /* 9911 * Get the current usb frame number before waiting for few 9912 * milliseconds. 9913 */ 9914 before_frame_number = ohci_get_current_frame_number(ohcip); 9915 9916 /* Wait for few milliseconds */ 9917 drv_usecwait(OHCI_TIMEWAIT); 9918 9919 /* 9920 * Get the current usb frame number after waiting for few 9921 * milliseconds. 9922 */ 9923 after_frame_number = ohci_get_current_frame_number(ohcip); 9924 9925 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9926 "ohci_do_soft_reset: Before Frm No 0x%llx After Frm No 0x%llx", 9927 (unsigned long long)before_frame_number, 9928 (unsigned long long)after_frame_number); 9929 9930 if (after_frame_number <= before_frame_number) { 9931 9932 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl, 9933 "ohci_do_soft_reset: Soft reset failed"); 9934 9935 return (USB_FAILURE); 9936 } 9937 9938 /* Start the timer for the root hub interrupt pipe polling */ 9939 if (rh_timer_id) { 9940 ohcip->ohci_root_hub.rh_intr_pipe_timer_id = 9941 timeout(ohci_handle_root_hub_status_change, 9942 (void *)ohcip, drv_usectohz(OHCI_RH_POLL_TIME)); 9943 9944 ohcip->ohci_root_hub. 9945 rh_intr_pipe_state = OHCI_PIPE_STATE_ACTIVE; 9946 } 9947 9948 /* Start the global timer */ 9949 if (xfer_timer_id) { 9950 ohcip->ohci_timer_id = timeout(ohci_xfer_timeout_handler, 9951 (void *)ohcip, drv_usectohz(1000000)); 9952 } 9953 9954 return (USB_SUCCESS); 9955 } 9956 9957 9958 /* 9959 * ohci_get_current_frame_number: 9960 * 9961 * Get the current software based usb frame number. 9962 */ 9963 usb_frame_number_t 9964 ohci_get_current_frame_number(ohci_state_t *ohcip) 9965 { 9966 usb_frame_number_t usb_frame_number; 9967 usb_frame_number_t ohci_fno, frame_number; 9968 ohci_save_intr_sts_t *ohci_intr_sts = 9969 &ohcip->ohci_save_intr_sts; 9970 9971 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 9972 9973 /* 9974 * Sync HCCA area only if this function 9975 * is invoked in non interrupt context. 9976 */ 9977 if (!(ohci_intr_sts->ohci_intr_flag & 9978 OHCI_INTR_HANDLING)) { 9979 9980 /* Sync HCCA area */ 9981 Sync_HCCA(ohcip); 9982 } 9983 9984 ohci_fno = ohcip->ohci_fno; 9985 frame_number = Get_HCCA(ohcip->ohci_hccap->HccaFrameNo); 9986 9987 /* 9988 * Calculate current software based usb frame number. 9989 * 9990 * This code accounts for the fact that frame number is 9991 * updated by the Host Controller before the ohci driver 9992 * gets an FrameNumberOverflow (FNO) interrupt that will 9993 * adjust Frame higher part. 9994 * 9995 * Refer ohci specification 1.0a, section 5.4, page 86. 9996 */ 9997 usb_frame_number = ((frame_number & 0x7FFF) | ohci_fno) + 9998 (((frame_number & 0xFFFF) ^ ohci_fno) & 0x8000); 9999 10000 return (usb_frame_number); 10001 } 10002 10003 10004 /* 10005 * ohci_cpr_cleanup: 10006 * 10007 * Cleanup ohci state and other ohci specific informations across 10008 * Check Point Resume (CPR). 10009 */ 10010 static void 10011 ohci_cpr_cleanup(ohci_state_t *ohcip) 10012 { 10013 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10014 10015 /* Reset software part of usb frame number */ 10016 ohcip->ohci_fno = 0; 10017 10018 /* Reset Schedule Overrrun Error Counter */ 10019 ohcip->ohci_so_error = 0; 10020 10021 /* Reset HCCA HcFrameNumber */ 10022 Set_HCCA(ohcip->ohci_hccap->HccaFrameNo, 0x00000000); 10023 } 10024 10025 10026 /* 10027 * ohci_get_xfer_attrs: 10028 * 10029 * Get the attributes of a particular xfer. 10030 */ 10031 static usb_req_attrs_t 10032 ohci_get_xfer_attrs( 10033 ohci_state_t *ohcip, 10034 ohci_pipe_private_t *pp, 10035 ohci_trans_wrapper_t *tw) 10036 { 10037 usb_ep_descr_t *eptd = &pp->pp_pipe_handle->p_ep; 10038 usb_req_attrs_t attrs = 0; 10039 10040 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10041 "ohci_get_xfer_attrs:"); 10042 10043 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10044 10045 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) { 10046 case USB_EP_ATTR_CONTROL: 10047 attrs = ((usb_ctrl_req_t *) 10048 tw->tw_curr_xfer_reqp)->ctrl_attributes; 10049 break; 10050 case USB_EP_ATTR_BULK: 10051 attrs = ((usb_bulk_req_t *) 10052 tw->tw_curr_xfer_reqp)->bulk_attributes; 10053 break; 10054 case USB_EP_ATTR_INTR: 10055 attrs = ((usb_intr_req_t *) 10056 tw->tw_curr_xfer_reqp)->intr_attributes; 10057 break; 10058 case USB_EP_ATTR_ISOCH: 10059 attrs = ((usb_isoc_req_t *) 10060 tw->tw_curr_xfer_reqp)->isoc_attributes; 10061 break; 10062 } 10063 10064 return (attrs); 10065 } 10066 10067 10068 /* 10069 * ohci_allocate_periodic_in_resource 10070 * 10071 * Allocate interrupt/isochronous request structure for the 10072 * interrupt/isochronous IN transfer. 10073 */ 10074 static int 10075 ohci_allocate_periodic_in_resource( 10076 ohci_state_t *ohcip, 10077 ohci_pipe_private_t *pp, 10078 ohci_trans_wrapper_t *tw, 10079 usb_flags_t flags) 10080 { 10081 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 10082 uchar_t ep_attr = ph->p_ep.bmAttributes; 10083 usb_intr_req_t *curr_intr_reqp; 10084 usb_isoc_req_t *curr_isoc_reqp; 10085 usb_opaque_t client_periodic_in_reqp; 10086 size_t length = 0; 10087 10088 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10089 "ohci_allocate_periodic_in_resource:" 10090 "pp = 0x%p tw = 0x%p flags = 0x%x", (void *)pp, (void *)tw, flags); 10091 10092 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10093 ASSERT(tw->tw_curr_xfer_reqp == NULL); 10094 10095 /* Get the client periodic in request pointer */ 10096 client_periodic_in_reqp = pp->pp_client_periodic_in_reqp; 10097 10098 /* 10099 * If it a periodic IN request and periodic request is NULL, 10100 * allocate corresponding usb periodic IN request for the 10101 * current periodic polling request and copy the information 10102 * from the saved periodic request structure. 10103 */ 10104 if ((ep_attr & USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) { 10105 10106 if (client_periodic_in_reqp) { 10107 10108 /* Get the interrupt transfer length */ 10109 length = ((usb_intr_req_t *) 10110 client_periodic_in_reqp)->intr_len; 10111 10112 curr_intr_reqp = usba_hcdi_dup_intr_req( 10113 ph->p_dip, (usb_intr_req_t *) 10114 client_periodic_in_reqp, length, flags); 10115 } else { 10116 curr_intr_reqp = usb_alloc_intr_req( 10117 ph->p_dip, length, flags); 10118 } 10119 10120 if (curr_intr_reqp == NULL) { 10121 10122 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10123 "ohci_allocate_periodic_in_resource: Interrupt " 10124 "request structure allocation failed"); 10125 10126 return (USB_NO_RESOURCES); 10127 } 10128 10129 if (client_periodic_in_reqp == NULL) { 10130 /* For polled mode */ 10131 curr_intr_reqp-> 10132 intr_attributes = USB_ATTRS_SHORT_XFER_OK; 10133 curr_intr_reqp-> 10134 intr_len = ph->p_ep.wMaxPacketSize; 10135 } else { 10136 /* Check and save the timeout value */ 10137 tw->tw_timeout = (curr_intr_reqp->intr_attributes & 10138 USB_ATTRS_ONE_XFER) ? 10139 curr_intr_reqp->intr_timeout: 0; 10140 } 10141 10142 tw->tw_curr_xfer_reqp = (usb_opaque_t)curr_intr_reqp; 10143 tw->tw_length = curr_intr_reqp->intr_len; 10144 } else { 10145 ASSERT(client_periodic_in_reqp != NULL); 10146 10147 curr_isoc_reqp = usba_hcdi_dup_isoc_req(ph->p_dip, 10148 (usb_isoc_req_t *)client_periodic_in_reqp, flags); 10149 10150 if (curr_isoc_reqp == NULL) { 10151 10152 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10153 "ohci_allocate_periodic_in_resource: Isochronous" 10154 "request structure allocation failed"); 10155 10156 return (USB_NO_RESOURCES); 10157 } 10158 10159 /* 10160 * Save the client's isochronous request pointer and 10161 * length of isochronous transfer in transfer wrapper. 10162 * The dup'ed request is saved in pp_client_periodic_in_reqp 10163 */ 10164 tw->tw_curr_xfer_reqp = 10165 (usb_opaque_t)pp->pp_client_periodic_in_reqp; 10166 pp->pp_client_periodic_in_reqp = (usb_opaque_t)curr_isoc_reqp; 10167 } 10168 10169 mutex_enter(&ph->p_mutex); 10170 ph->p_req_count++; 10171 mutex_exit(&ph->p_mutex); 10172 10173 pp->pp_state = OHCI_PIPE_STATE_ACTIVE; 10174 10175 return (USB_SUCCESS); 10176 } 10177 10178 10179 /* 10180 * ohci_wait_for_sof: 10181 * 10182 * Wait for couple of SOF interrupts 10183 */ 10184 static int 10185 ohci_wait_for_sof(ohci_state_t *ohcip) 10186 { 10187 usb_frame_number_t before_frame_number, after_frame_number; 10188 clock_t sof_time_wait; 10189 int rval, sof_wait_count; 10190 10191 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10192 "ohci_wait_for_sof"); 10193 10194 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10195 10196 rval = ohci_state_is_operational(ohcip); 10197 10198 if (rval != USB_SUCCESS) { 10199 10200 return (rval); 10201 } 10202 10203 /* Get the number of clock ticks to wait */ 10204 sof_time_wait = drv_usectohz(OHCI_MAX_SOF_TIMEWAIT * 1000000); 10205 10206 sof_wait_count = 0; 10207 10208 /* 10209 * Get the current usb frame number before waiting for the 10210 * SOF interrupt event. 10211 */ 10212 before_frame_number = ohci_get_current_frame_number(ohcip); 10213 10214 while (sof_wait_count < MAX_SOF_WAIT_COUNT) { 10215 /* Enable the SOF interrupt */ 10216 Set_OpReg(hcr_intr_enable, HCR_INTR_SOF); 10217 10218 ASSERT(Get_OpReg(hcr_intr_enable) & HCR_INTR_SOF); 10219 10220 /* Wait for the SOF or timeout event */ 10221 rval = cv_timedwait(&ohcip->ohci_SOF_cv, 10222 &ohcip->ohci_int_mutex, ddi_get_lbolt() + sof_time_wait); 10223 10224 /* 10225 * Get the current usb frame number after woken up either 10226 * from SOF interrupt or timer expired event. 10227 */ 10228 after_frame_number = ohci_get_current_frame_number(ohcip); 10229 10230 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10231 "ohci_wait_for_sof: before 0x%llx, after 0x%llx", 10232 (unsigned long long)before_frame_number, 10233 (unsigned long long)after_frame_number); 10234 10235 /* 10236 * Return failure, if we are woken up becuase of timer expired 10237 * event and if usb frame number has not been changed. 10238 */ 10239 if ((rval == -1) && 10240 (after_frame_number <= before_frame_number)) { 10241 10242 if ((ohci_do_soft_reset(ohcip)) != USB_SUCCESS) { 10243 10244 USB_DPRINTF_L0(PRINT_MASK_LISTS, 10245 ohcip->ohci_log_hdl, "No SOF interrupts"); 10246 10247 /* Set host controller soft state to error */ 10248 ohcip->ohci_hc_soft_state = 10249 OHCI_CTLR_ERROR_STATE; 10250 10251 return (USB_FAILURE); 10252 } 10253 10254 /* Get new usb frame number */ 10255 after_frame_number = before_frame_number = 10256 ohci_get_current_frame_number(ohcip); 10257 } 10258 10259 ASSERT(after_frame_number >= before_frame_number); 10260 10261 before_frame_number = after_frame_number; 10262 sof_wait_count++; 10263 } 10264 10265 return (USB_SUCCESS); 10266 } 10267 10268 10269 /* 10270 * ohci_pipe_cleanup 10271 * 10272 * Cleanup ohci pipe. 10273 */ 10274 static void 10275 ohci_pipe_cleanup( 10276 ohci_state_t *ohcip, 10277 usba_pipe_handle_data_t *ph) 10278 { 10279 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 10280 usb_ep_descr_t *eptd = &ph->p_ep; 10281 usb_cr_t completion_reason; 10282 uint_t pipe_state = pp->pp_state; 10283 uint_t bit = 0; 10284 10285 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10286 "ohci_pipe_cleanup: ph = 0x%p", (void *)ph); 10287 10288 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10289 10290 switch (pipe_state) { 10291 case OHCI_PIPE_STATE_CLOSE: 10292 if (OHCI_NON_PERIODIC_ENDPOINT(eptd)) { 10293 10294 bit = ((eptd->bmAttributes & 10295 USB_EP_ATTR_MASK) == USB_EP_ATTR_CONTROL) ? 10296 HCR_CONTROL_CLE: HCR_CONTROL_BLE; 10297 10298 Set_OpReg(hcr_control, 10299 (Get_OpReg(hcr_control) & ~(bit))); 10300 10301 /* Wait for the next SOF */ 10302 (void) ohci_wait_for_sof(ohcip); 10303 10304 break; 10305 } 10306 /* FALLTHROUGH */ 10307 case OHCI_PIPE_STATE_RESET: 10308 case OHCI_PIPE_STATE_STOP_POLLING: 10309 /* 10310 * Set the sKip bit to stop all transactions on 10311 * this pipe 10312 */ 10313 ohci_modify_sKip_bit(ohcip, pp, SET_sKip, 10314 OHCI_FLAGS_SLEEP | OHCI_FLAGS_DMA_SYNC); 10315 10316 break; 10317 default: 10318 return; 10319 } 10320 10321 /* 10322 * Wait for processing all completed transfers and 10323 * to send results to upstream. 10324 */ 10325 ohci_wait_for_transfers_completion(ohcip, pp); 10326 10327 /* Save the data toggle information */ 10328 ohci_save_data_toggle(ohcip, ph); 10329 10330 /* 10331 * Traverse the list of TD's on this endpoint and 10332 * these TD's have outstanding transfer requests. 10333 * Since the list processing is stopped, these tds 10334 * can be deallocated. 10335 */ 10336 ohci_traverse_tds(ohcip, ph); 10337 10338 /* 10339 * If all of the endpoint's TD's have been deallocated, 10340 * then the DMA mappings can be torn down. If not there 10341 * are some TD's on the done list that have not been 10342 * processed. Tag these TD's so that they are thrown 10343 * away when the done list is processed. 10344 */ 10345 ohci_done_list_tds(ohcip, ph); 10346 10347 /* Do callbacks for all unfinished requests */ 10348 ohci_handle_outstanding_requests(ohcip, pp); 10349 10350 /* Free DMA resources */ 10351 ohci_free_dma_resources(ohcip, ph); 10352 10353 switch (pipe_state) { 10354 case OHCI_PIPE_STATE_CLOSE: 10355 completion_reason = USB_CR_PIPE_CLOSING; 10356 break; 10357 case OHCI_PIPE_STATE_RESET: 10358 case OHCI_PIPE_STATE_STOP_POLLING: 10359 /* Set completion reason */ 10360 completion_reason = (pipe_state == 10361 OHCI_PIPE_STATE_RESET) ? 10362 USB_CR_PIPE_RESET: USB_CR_STOPPED_POLLING; 10363 10364 /* Restore the data toggle information */ 10365 ohci_restore_data_toggle(ohcip, ph); 10366 10367 /* 10368 * Clear the sKip bit to restart all the 10369 * transactions on this pipe. 10370 */ 10371 ohci_modify_sKip_bit(ohcip, pp, 10372 CLEAR_sKip, OHCI_FLAGS_NOSLEEP); 10373 10374 /* Set pipe state to idle */ 10375 pp->pp_state = OHCI_PIPE_STATE_IDLE; 10376 10377 break; 10378 } 10379 10380 ASSERT((Get_ED(pp->pp_ept->hced_tailp) & HC_EPT_TD_TAIL) == 10381 (Get_ED(pp->pp_ept->hced_headp) & HC_EPT_TD_HEAD)); 10382 10383 ASSERT((pp->pp_tw_head == NULL) && (pp->pp_tw_tail == NULL)); 10384 10385 /* 10386 * Do the callback for the original client 10387 * periodic IN request. 10388 */ 10389 if ((OHCI_PERIODIC_ENDPOINT(eptd)) && 10390 ((ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK) == 10391 USB_EP_DIR_IN)) { 10392 10393 ohci_do_client_periodic_in_req_callback( 10394 ohcip, pp, completion_reason); 10395 } 10396 } 10397 10398 10399 /* 10400 * ohci_wait_for_transfers_completion: 10401 * 10402 * Wait for processing all completed transfers and to send results 10403 * to upstream. 10404 */ 10405 static void 10406 ohci_wait_for_transfers_completion( 10407 ohci_state_t *ohcip, 10408 ohci_pipe_private_t *pp) 10409 { 10410 ohci_trans_wrapper_t *head_tw = pp->pp_tw_head; 10411 ohci_trans_wrapper_t *next_tw; 10412 clock_t xfer_cmpl_time_wait; 10413 ohci_td_t *tailp, *headp, *nextp; 10414 ohci_td_t *head_td, *next_td; 10415 ohci_ed_t *ept = pp->pp_ept; 10416 int rval; 10417 10418 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10419 "ohci_wait_for_transfers_completion: pp = 0x%p", (void *)pp); 10420 10421 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10422 10423 headp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, 10424 Get_ED(ept->hced_headp) & (uint32_t)HC_EPT_TD_HEAD)); 10425 10426 tailp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, 10427 Get_ED(ept->hced_tailp) & (uint32_t)HC_EPT_TD_TAIL)); 10428 10429 rval = ohci_state_is_operational(ohcip); 10430 10431 if (rval != USB_SUCCESS) { 10432 10433 return; 10434 } 10435 10436 pp->pp_count_done_tds = 0; 10437 10438 /* Process the transfer wrappers for this pipe */ 10439 next_tw = head_tw; 10440 while (next_tw) { 10441 head_td = (ohci_td_t *)next_tw->tw_hctd_head; 10442 next_td = head_td; 10443 10444 if (head_td) { 10445 /* 10446 * Walk through each TD for this transfer 10447 * wrapper. If a TD still exists, then it 10448 * is currently on the done list. 10449 */ 10450 while (next_td) { 10451 10452 nextp = headp; 10453 10454 while (nextp != tailp) { 10455 10456 /* TD is on the ED */ 10457 if (nextp == next_td) { 10458 break; 10459 } 10460 10461 nextp = (ohci_td_t *) 10462 (ohci_td_iommu_to_cpu(ohcip, 10463 (Get_TD(nextp->hctd_next_td) & 10464 HC_EPT_TD_TAIL))); 10465 } 10466 10467 if (nextp == tailp) { 10468 pp->pp_count_done_tds++; 10469 } 10470 10471 next_td = ohci_td_iommu_to_cpu(ohcip, 10472 Get_TD(next_td->hctd_tw_next_td)); 10473 } 10474 } 10475 10476 next_tw = next_tw->tw_next; 10477 } 10478 10479 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10480 "ohci_wait_for_transfers_completion: count_done_tds = 0x%x", 10481 pp->pp_count_done_tds); 10482 10483 if (!pp->pp_count_done_tds) { 10484 10485 return; 10486 } 10487 10488 /* Get the number of clock ticks to wait */ 10489 xfer_cmpl_time_wait = drv_usectohz(OHCI_XFER_CMPL_TIMEWAIT * 1000000); 10490 10491 (void) cv_timedwait(&pp->pp_xfer_cmpl_cv, 10492 &ohcip->ohci_int_mutex, 10493 ddi_get_lbolt() + xfer_cmpl_time_wait); 10494 10495 if (pp->pp_count_done_tds) { 10496 10497 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10498 "ohci_wait_for_transfers_completion: No transfers " 10499 "completion confirmation received for 0x%x requests", 10500 pp->pp_count_done_tds); 10501 } 10502 } 10503 10504 10505 /* 10506 * ohci_check_for_transfers_completion: 10507 * 10508 * Check whether anybody is waiting for transfers completion event. If so, send 10509 * this event and also stop initiating any new transfers on this pipe. 10510 */ 10511 static void 10512 ohci_check_for_transfers_completion( 10513 ohci_state_t *ohcip, 10514 ohci_pipe_private_t *pp) 10515 { 10516 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10517 "ohci_check_for_transfers_completion: pp = 0x%p", (void *)pp); 10518 10519 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10520 10521 if ((pp->pp_state == OHCI_PIPE_STATE_STOP_POLLING) && 10522 (pp->pp_error == USB_CR_NO_RESOURCES) && 10523 (pp->pp_cur_periodic_req_cnt == 0)) { 10524 10525 /* Reset pipe error to zero */ 10526 pp->pp_error = 0; 10527 10528 /* Do callback for original request */ 10529 ohci_do_client_periodic_in_req_callback( 10530 ohcip, pp, USB_CR_NO_RESOURCES); 10531 } 10532 10533 if (pp->pp_count_done_tds) { 10534 10535 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10536 "ohci_check_for_transfers_completion:" 10537 "count_done_tds = 0x%x", pp->pp_count_done_tds); 10538 10539 /* Decrement the done td count */ 10540 pp->pp_count_done_tds--; 10541 10542 if (!pp->pp_count_done_tds) { 10543 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10544 "ohci_check_for_transfers_completion:" 10545 "Sent transfers completion event pp = 0x%p", 10546 (void *)pp); 10547 10548 /* Send the transfer completion signal */ 10549 cv_signal(&pp->pp_xfer_cmpl_cv); 10550 } 10551 } 10552 } 10553 10554 10555 /* 10556 * ohci_save_data_toggle: 10557 * 10558 * Save the data toggle information. 10559 */ 10560 static void 10561 ohci_save_data_toggle( 10562 ohci_state_t *ohcip, 10563 usba_pipe_handle_data_t *ph) 10564 { 10565 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 10566 usb_ep_descr_t *eptd = &ph->p_ep; 10567 uint_t data_toggle; 10568 usb_cr_t error = pp->pp_error; 10569 ohci_ed_t *ed = pp->pp_ept; 10570 ohci_td_t *headp, *tailp; 10571 10572 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10573 "ohci_save_data_toggle: ph = 0x%p", (void *)ph); 10574 10575 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10576 10577 /* Reset the pipe error value */ 10578 pp->pp_error = USB_CR_OK; 10579 10580 /* Return immediately if it is a control or isoc pipe */ 10581 if (((eptd->bmAttributes & USB_EP_ATTR_MASK) == 10582 USB_EP_ATTR_CONTROL) || ((eptd->bmAttributes & 10583 USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH)) { 10584 10585 return; 10586 } 10587 10588 headp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, 10589 Get_ED(ed->hced_headp) & (uint32_t)HC_EPT_TD_HEAD)); 10590 10591 tailp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, 10592 Get_ED(ed->hced_tailp) & (uint32_t)HC_EPT_TD_TAIL)); 10593 10594 /* 10595 * Retrieve the data toggle information either from the endpoint 10596 * (ED) or from the transfer descriptor (TD) depending on the 10597 * situation. 10598 */ 10599 if ((Get_ED(ed->hced_headp) & HC_EPT_Halt) || (headp == tailp)) { 10600 10601 /* Get the data toggle information from the endpoint */ 10602 data_toggle = (Get_ED(ed->hced_headp) & 10603 HC_EPT_Carry)? DATA1:DATA0; 10604 } else { 10605 /* 10606 * Retrieve the data toggle information depending on the 10607 * master data toggle information saved in the transfer 10608 * descriptor (TD) at the head of the endpoint (ED). 10609 * 10610 * Check for master data toggle information . 10611 */ 10612 if (Get_TD(headp->hctd_ctrl) & HC_TD_MS_DT) { 10613 /* Get the data toggle information from td */ 10614 data_toggle = (Get_TD(headp->hctd_ctrl) & 10615 HC_TD_DT_1) ? DATA1:DATA0; 10616 } else { 10617 /* Get the data toggle information from the endpoint */ 10618 data_toggle = (Get_ED(ed->hced_headp) & 10619 HC_EPT_Carry)? DATA1:DATA0; 10620 } 10621 } 10622 10623 /* 10624 * If error is STALL, then, set 10625 * data toggle to zero. 10626 */ 10627 if (error == USB_CR_STALL) { 10628 data_toggle = DATA0; 10629 } 10630 10631 /* 10632 * Save the data toggle information 10633 * in the usb device structure. 10634 */ 10635 mutex_enter(&ph->p_mutex); 10636 usba_hcdi_set_data_toggle(ph->p_usba_device, ph->p_ep.bEndpointAddress, 10637 data_toggle); 10638 mutex_exit(&ph->p_mutex); 10639 } 10640 10641 10642 /* 10643 * ohci_restore_data_toggle: 10644 * 10645 * Restore the data toggle information. 10646 */ 10647 static void 10648 ohci_restore_data_toggle( 10649 ohci_state_t *ohcip, 10650 usba_pipe_handle_data_t *ph) 10651 { 10652 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 10653 usb_ep_descr_t *eptd = &ph->p_ep; 10654 uint_t data_toggle = 0; 10655 10656 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10657 "ohci_restore_data_toggle: ph = 0x%p", (void *)ph); 10658 10659 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10660 10661 /* 10662 * Return immediately if it is a control or isoc pipe. 10663 */ 10664 if (((eptd->bmAttributes & USB_EP_ATTR_MASK) == 10665 USB_EP_ATTR_CONTROL) || ((eptd->bmAttributes & 10666 USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH)) { 10667 10668 return; 10669 } 10670 10671 mutex_enter(&ph->p_mutex); 10672 10673 data_toggle = usba_hcdi_get_data_toggle(ph->p_usba_device, 10674 ph->p_ep.bEndpointAddress); 10675 usba_hcdi_set_data_toggle(ph->p_usba_device, ph->p_ep.bEndpointAddress, 10676 0); 10677 10678 mutex_exit(&ph->p_mutex); 10679 10680 /* 10681 * Restore the data toggle bit depending on the 10682 * previous data toggle information. 10683 */ 10684 if (data_toggle) { 10685 Set_ED(pp->pp_ept->hced_headp, 10686 Get_ED(pp->pp_ept->hced_headp) | HC_EPT_Carry); 10687 } else { 10688 Set_ED(pp->pp_ept->hced_headp, 10689 Get_ED(pp->pp_ept->hced_headp) & (~HC_EPT_Carry)); 10690 } 10691 } 10692 10693 10694 /* 10695 * ohci_handle_outstanding_requests 10696 * NOTE: This function is also called from POLLED MODE. 10697 * 10698 * Deallocate interrupt/isochronous request structure for the 10699 * interrupt/isochronous IN transfer. Do the callbacks for all 10700 * unfinished requests. 10701 */ 10702 void 10703 ohci_handle_outstanding_requests( 10704 ohci_state_t *ohcip, 10705 ohci_pipe_private_t *pp) 10706 { 10707 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 10708 usb_ep_descr_t *eptd = &ph->p_ep; 10709 ohci_trans_wrapper_t *curr_tw; 10710 ohci_trans_wrapper_t *next_tw; 10711 usb_opaque_t curr_xfer_reqp; 10712 10713 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10714 "ohci_handle_outstanding_requests: pp = 0x%p", (void *)pp); 10715 10716 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10717 10718 /* 10719 * Deallocate all the pre-allocated interrupt requests 10720 */ 10721 next_tw = pp->pp_tw_head; 10722 10723 while (next_tw) { 10724 curr_tw = next_tw; 10725 next_tw = curr_tw->tw_next; 10726 10727 curr_xfer_reqp = curr_tw->tw_curr_xfer_reqp; 10728 10729 /* Deallocate current interrupt request */ 10730 if (curr_xfer_reqp) { 10731 10732 if ((OHCI_PERIODIC_ENDPOINT(eptd)) && 10733 (curr_tw->tw_direction == HC_TD_IN)) { 10734 10735 /* Decrement periodic in request count */ 10736 pp->pp_cur_periodic_req_cnt--; 10737 10738 ohci_deallocate_periodic_in_resource( 10739 ohcip, pp, curr_tw); 10740 } else { 10741 ohci_hcdi_callback(ph, 10742 curr_tw, USB_CR_FLUSHED); 10743 } 10744 } 10745 } 10746 } 10747 10748 10749 /* 10750 * ohci_deallocate_periodic_in_resource 10751 * 10752 * Deallocate interrupt/isochronous request structure for the 10753 * interrupt/isochronous IN transfer. 10754 */ 10755 static void 10756 ohci_deallocate_periodic_in_resource( 10757 ohci_state_t *ohcip, 10758 ohci_pipe_private_t *pp, 10759 ohci_trans_wrapper_t *tw) 10760 { 10761 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 10762 uchar_t ep_attr = ph->p_ep.bmAttributes; 10763 usb_opaque_t curr_xfer_reqp; 10764 10765 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10766 "ohci_deallocate_periodic_in_resource: " 10767 "pp = 0x%p tw = 0x%p", (void *)pp, (void *)tw); 10768 10769 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10770 10771 curr_xfer_reqp = tw->tw_curr_xfer_reqp; 10772 10773 /* Check the current periodic in request pointer */ 10774 if (curr_xfer_reqp) { 10775 /* 10776 * Reset periodic in request usb isoch 10777 * packet request pointers to null. 10778 */ 10779 tw->tw_curr_xfer_reqp = NULL; 10780 tw->tw_curr_isoc_pktp = NULL; 10781 10782 mutex_enter(&ph->p_mutex); 10783 ph->p_req_count--; 10784 mutex_exit(&ph->p_mutex); 10785 10786 /* 10787 * Free pre-allocated interrupt 10788 * or isochronous requests. 10789 */ 10790 switch (ep_attr & USB_EP_ATTR_MASK) { 10791 case USB_EP_ATTR_INTR: 10792 usb_free_intr_req( 10793 (usb_intr_req_t *)curr_xfer_reqp); 10794 break; 10795 case USB_EP_ATTR_ISOCH: 10796 usb_free_isoc_req( 10797 (usb_isoc_req_t *)curr_xfer_reqp); 10798 break; 10799 } 10800 } 10801 } 10802 10803 10804 /* 10805 * ohci_do_client_periodic_in_req_callback 10806 * 10807 * Do callback for the original client periodic IN request. 10808 */ 10809 static void 10810 ohci_do_client_periodic_in_req_callback( 10811 ohci_state_t *ohcip, 10812 ohci_pipe_private_t *pp, 10813 usb_cr_t completion_reason) 10814 { 10815 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 10816 10817 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10818 "ohci_do_client_periodic_in_req_callback: " 10819 "pp = 0x%p cc = 0x%x", (void *)pp, completion_reason); 10820 10821 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10822 10823 /* 10824 * Check for Interrupt/Isochronous IN, whether we need to do 10825 * callback for the original client's periodic IN request. 10826 */ 10827 if (pp->pp_client_periodic_in_reqp) { 10828 ASSERT(pp->pp_cur_periodic_req_cnt == 0); 10829 ohci_hcdi_callback(ph, NULL, completion_reason); 10830 } 10831 } 10832 10833 10834 /* 10835 * ohci_hcdi_callback() 10836 * 10837 * Convenience wrapper around usba_hcdi_cb() other than root hub. 10838 */ 10839 static void 10840 ohci_hcdi_callback( 10841 usba_pipe_handle_data_t *ph, 10842 ohci_trans_wrapper_t *tw, 10843 usb_cr_t completion_reason) 10844 { 10845 ohci_state_t *ohcip = ohci_obtain_state( 10846 ph->p_usba_device->usb_root_hub_dip); 10847 uchar_t attributes = ph->p_ep.bmAttributes & 10848 USB_EP_ATTR_MASK; 10849 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private; 10850 usb_opaque_t curr_xfer_reqp; 10851 uint_t pipe_state = 0; 10852 10853 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 10854 "ohci_hcdi_callback: ph = 0x%p, tw = 0x%p, cr = 0x%x", 10855 (void *)ph, (void *)tw, completion_reason); 10856 10857 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 10858 10859 /* Set the pipe state as per completion reason */ 10860 switch (completion_reason) { 10861 case USB_CR_OK: 10862 pipe_state = pp->pp_state; 10863 break; 10864 case USB_CR_NO_RESOURCES: 10865 case USB_CR_NOT_SUPPORTED: 10866 case USB_CR_STOPPED_POLLING: 10867 case USB_CR_PIPE_RESET: 10868 pipe_state = OHCI_PIPE_STATE_IDLE; 10869 break; 10870 case USB_CR_PIPE_CLOSING: 10871 break; 10872 default: 10873 /* 10874 * Set the pipe state to error 10875 * except for the isoc pipe. 10876 */ 10877 if (attributes != USB_EP_ATTR_ISOCH) { 10878 pipe_state = OHCI_PIPE_STATE_ERROR; 10879 pp->pp_error = completion_reason; 10880 } 10881 break; 10882 10883 } 10884 10885 pp->pp_state = pipe_state; 10886 10887 if (tw && tw->tw_curr_xfer_reqp) { 10888 curr_xfer_reqp = tw->tw_curr_xfer_reqp; 10889 tw->tw_curr_xfer_reqp = NULL; 10890 tw->tw_curr_isoc_pktp = NULL; 10891 } else { 10892 ASSERT(pp->pp_client_periodic_in_reqp != NULL); 10893 10894 curr_xfer_reqp = pp->pp_client_periodic_in_reqp; 10895 pp->pp_client_periodic_in_reqp = NULL; 10896 } 10897 10898 ASSERT(curr_xfer_reqp != NULL); 10899 10900 mutex_exit(&ohcip->ohci_int_mutex); 10901 10902 usba_hcdi_cb(ph, curr_xfer_reqp, completion_reason); 10903 10904 mutex_enter(&ohcip->ohci_int_mutex); 10905 } 10906 10907 10908 /* 10909 * ohci kstat functions 10910 */ 10911 10912 /* 10913 * ohci_create_stats: 10914 * 10915 * Allocate and initialize the ohci kstat structures 10916 */ 10917 static void 10918 ohci_create_stats(ohci_state_t *ohcip) 10919 { 10920 char kstatname[KSTAT_STRLEN]; 10921 const char *dname = ddi_driver_name(ohcip->ohci_dip); 10922 char *usbtypes[USB_N_COUNT_KSTATS] = 10923 {"ctrl", "isoch", "bulk", "intr"}; 10924 uint_t instance = ohcip->ohci_instance; 10925 ohci_intrs_stats_t *isp; 10926 int i; 10927 10928 if (OHCI_INTRS_STATS(ohcip) == NULL) { 10929 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,intrs", 10930 dname, instance); 10931 OHCI_INTRS_STATS(ohcip) = kstat_create("usba", instance, 10932 kstatname, "usb_interrupts", KSTAT_TYPE_NAMED, 10933 sizeof (ohci_intrs_stats_t) / sizeof (kstat_named_t), 10934 KSTAT_FLAG_PERSISTENT); 10935 10936 if (OHCI_INTRS_STATS(ohcip)) { 10937 isp = OHCI_INTRS_STATS_DATA(ohcip); 10938 kstat_named_init(&isp->ohci_hcr_intr_total, 10939 "Interrupts Total", KSTAT_DATA_UINT64); 10940 kstat_named_init(&isp->ohci_hcr_intr_not_claimed, 10941 "Not Claimed", KSTAT_DATA_UINT64); 10942 kstat_named_init(&isp->ohci_hcr_intr_so, 10943 "Schedule Overruns", KSTAT_DATA_UINT64); 10944 kstat_named_init(&isp->ohci_hcr_intr_wdh, 10945 "Writeback Done Head", KSTAT_DATA_UINT64); 10946 kstat_named_init(&isp->ohci_hcr_intr_sof, 10947 "Start Of Frame", KSTAT_DATA_UINT64); 10948 kstat_named_init(&isp->ohci_hcr_intr_rd, 10949 "Resume Detected", KSTAT_DATA_UINT64); 10950 kstat_named_init(&isp->ohci_hcr_intr_ue, 10951 "Unrecoverable Error", KSTAT_DATA_UINT64); 10952 kstat_named_init(&isp->ohci_hcr_intr_fno, 10953 "Frame No. Overflow", KSTAT_DATA_UINT64); 10954 kstat_named_init(&isp->ohci_hcr_intr_rhsc, 10955 "Root Hub Status Change", KSTAT_DATA_UINT64); 10956 kstat_named_init(&isp->ohci_hcr_intr_oc, 10957 "Change In Ownership", KSTAT_DATA_UINT64); 10958 10959 OHCI_INTRS_STATS(ohcip)->ks_private = ohcip; 10960 OHCI_INTRS_STATS(ohcip)->ks_update = nulldev; 10961 kstat_install(OHCI_INTRS_STATS(ohcip)); 10962 } 10963 } 10964 10965 if (OHCI_TOTAL_STATS(ohcip) == NULL) { 10966 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,total", 10967 dname, instance); 10968 OHCI_TOTAL_STATS(ohcip) = kstat_create("usba", instance, 10969 kstatname, "usb_byte_count", KSTAT_TYPE_IO, 1, 10970 KSTAT_FLAG_PERSISTENT); 10971 10972 if (OHCI_TOTAL_STATS(ohcip)) { 10973 kstat_install(OHCI_TOTAL_STATS(ohcip)); 10974 } 10975 } 10976 10977 for (i = 0; i < USB_N_COUNT_KSTATS; i++) { 10978 if (ohcip->ohci_count_stats[i] == NULL) { 10979 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,%s", 10980 dname, instance, usbtypes[i]); 10981 ohcip->ohci_count_stats[i] = kstat_create("usba", 10982 instance, kstatname, "usb_byte_count", 10983 KSTAT_TYPE_IO, 1, KSTAT_FLAG_PERSISTENT); 10984 10985 if (ohcip->ohci_count_stats[i]) { 10986 kstat_install(ohcip->ohci_count_stats[i]); 10987 } 10988 } 10989 } 10990 } 10991 10992 10993 /* 10994 * ohci_destroy_stats: 10995 * 10996 * Clean up ohci kstat structures 10997 */ 10998 static void 10999 ohci_destroy_stats(ohci_state_t *ohcip) 11000 { 11001 int i; 11002 11003 if (OHCI_INTRS_STATS(ohcip)) { 11004 kstat_delete(OHCI_INTRS_STATS(ohcip)); 11005 OHCI_INTRS_STATS(ohcip) = NULL; 11006 } 11007 11008 if (OHCI_TOTAL_STATS(ohcip)) { 11009 kstat_delete(OHCI_TOTAL_STATS(ohcip)); 11010 OHCI_TOTAL_STATS(ohcip) = NULL; 11011 } 11012 11013 for (i = 0; i < USB_N_COUNT_KSTATS; i++) { 11014 if (ohcip->ohci_count_stats[i]) { 11015 kstat_delete(ohcip->ohci_count_stats[i]); 11016 ohcip->ohci_count_stats[i] = NULL; 11017 } 11018 } 11019 } 11020 11021 11022 /* 11023 * ohci_do_intrs_stats: 11024 * 11025 * ohci status information 11026 */ 11027 static void 11028 ohci_do_intrs_stats( 11029 ohci_state_t *ohcip, 11030 int val) 11031 { 11032 if (OHCI_INTRS_STATS(ohcip)) { 11033 OHCI_INTRS_STATS_DATA(ohcip)->ohci_hcr_intr_total.value.ui64++; 11034 switch (val) { 11035 case HCR_INTR_SO: 11036 OHCI_INTRS_STATS_DATA(ohcip)-> 11037 ohci_hcr_intr_so.value.ui64++; 11038 break; 11039 case HCR_INTR_WDH: 11040 OHCI_INTRS_STATS_DATA(ohcip)-> 11041 ohci_hcr_intr_wdh.value.ui64++; 11042 break; 11043 case HCR_INTR_SOF: 11044 OHCI_INTRS_STATS_DATA(ohcip)-> 11045 ohci_hcr_intr_sof.value.ui64++; 11046 break; 11047 case HCR_INTR_RD: 11048 OHCI_INTRS_STATS_DATA(ohcip)-> 11049 ohci_hcr_intr_rd.value.ui64++; 11050 break; 11051 case HCR_INTR_UE: 11052 OHCI_INTRS_STATS_DATA(ohcip)-> 11053 ohci_hcr_intr_ue.value.ui64++; 11054 break; 11055 case HCR_INTR_FNO: 11056 OHCI_INTRS_STATS_DATA(ohcip)-> 11057 ohci_hcr_intr_fno.value.ui64++; 11058 break; 11059 case HCR_INTR_RHSC: 11060 OHCI_INTRS_STATS_DATA(ohcip)-> 11061 ohci_hcr_intr_rhsc.value.ui64++; 11062 break; 11063 case HCR_INTR_OC: 11064 OHCI_INTRS_STATS_DATA(ohcip)-> 11065 ohci_hcr_intr_oc.value.ui64++; 11066 break; 11067 default: 11068 OHCI_INTRS_STATS_DATA(ohcip)-> 11069 ohci_hcr_intr_not_claimed.value.ui64++; 11070 break; 11071 } 11072 } 11073 } 11074 11075 11076 /* 11077 * ohci_do_byte_stats: 11078 * 11079 * ohci data xfer information 11080 */ 11081 static void 11082 ohci_do_byte_stats( 11083 ohci_state_t *ohcip, 11084 size_t len, 11085 uint8_t attr, 11086 uint8_t addr) 11087 { 11088 uint8_t type = attr & USB_EP_ATTR_MASK; 11089 uint8_t dir = addr & USB_EP_DIR_MASK; 11090 11091 if (dir == USB_EP_DIR_IN) { 11092 OHCI_TOTAL_STATS_DATA(ohcip)->reads++; 11093 OHCI_TOTAL_STATS_DATA(ohcip)->nread += len; 11094 switch (type) { 11095 case USB_EP_ATTR_CONTROL: 11096 OHCI_CTRL_STATS(ohcip)->reads++; 11097 OHCI_CTRL_STATS(ohcip)->nread += len; 11098 break; 11099 case USB_EP_ATTR_BULK: 11100 OHCI_BULK_STATS(ohcip)->reads++; 11101 OHCI_BULK_STATS(ohcip)->nread += len; 11102 break; 11103 case USB_EP_ATTR_INTR: 11104 OHCI_INTR_STATS(ohcip)->reads++; 11105 OHCI_INTR_STATS(ohcip)->nread += len; 11106 break; 11107 case USB_EP_ATTR_ISOCH: 11108 OHCI_ISOC_STATS(ohcip)->reads++; 11109 OHCI_ISOC_STATS(ohcip)->nread += len; 11110 break; 11111 } 11112 } else if (dir == USB_EP_DIR_OUT) { 11113 OHCI_TOTAL_STATS_DATA(ohcip)->writes++; 11114 OHCI_TOTAL_STATS_DATA(ohcip)->nwritten += len; 11115 switch (type) { 11116 case USB_EP_ATTR_CONTROL: 11117 OHCI_CTRL_STATS(ohcip)->writes++; 11118 OHCI_CTRL_STATS(ohcip)->nwritten += len; 11119 break; 11120 case USB_EP_ATTR_BULK: 11121 OHCI_BULK_STATS(ohcip)->writes++; 11122 OHCI_BULK_STATS(ohcip)->nwritten += len; 11123 break; 11124 case USB_EP_ATTR_INTR: 11125 OHCI_INTR_STATS(ohcip)->writes++; 11126 OHCI_INTR_STATS(ohcip)->nwritten += len; 11127 break; 11128 case USB_EP_ATTR_ISOCH: 11129 OHCI_ISOC_STATS(ohcip)->writes++; 11130 OHCI_ISOC_STATS(ohcip)->nwritten += len; 11131 break; 11132 } 11133 } 11134 } 11135 11136 11137 /* 11138 * ohci_print_op_regs: 11139 * 11140 * Print Host Controller's (HC) Operational registers. 11141 */ 11142 static void 11143 ohci_print_op_regs(ohci_state_t *ohcip) 11144 { 11145 uint_t i; 11146 11147 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11148 "\n\tOHCI%d Operational Registers\n", 11149 ddi_get_instance(ohcip->ohci_dip)); 11150 11151 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11152 "\thcr_revision: 0x%x \t\thcr_control: 0x%x", 11153 Get_OpReg(hcr_revision), Get_OpReg(hcr_control)); 11154 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11155 "\thcr_cmd_status: 0x%x \t\thcr_intr_enable: 0x%x", 11156 Get_OpReg(hcr_cmd_status), Get_OpReg(hcr_intr_enable)); 11157 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11158 "\thcr_intr_disable: 0x%x \thcr_HCCA: 0x%x", 11159 Get_OpReg(hcr_intr_disable), Get_OpReg(hcr_HCCA)); 11160 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11161 "\thcr_periodic_curr: 0x%x \t\thcr_ctrl_head: 0x%x", 11162 Get_OpReg(hcr_periodic_curr), Get_OpReg(hcr_ctrl_head)); 11163 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11164 "\thcr_ctrl_curr: 0x%x \t\thcr_bulk_head: 0x%x", 11165 Get_OpReg(hcr_ctrl_curr), Get_OpReg(hcr_bulk_head)); 11166 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11167 "\thcr_bulk_curr: 0x%x \t\thcr_done_head: 0x%x", 11168 Get_OpReg(hcr_bulk_curr), Get_OpReg(hcr_done_head)); 11169 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11170 "\thcr_frame_interval: 0x%x " 11171 "\thcr_frame_remaining: 0x%x", Get_OpReg(hcr_frame_interval), 11172 Get_OpReg(hcr_frame_remaining)); 11173 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11174 "\thcr_frame_number: 0x%x \thcr_periodic_strt: 0x%x", 11175 Get_OpReg(hcr_frame_number), Get_OpReg(hcr_periodic_strt)); 11176 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11177 "\thcr_transfer_ls: 0x%x \t\thcr_rh_descriptorA: 0x%x", 11178 Get_OpReg(hcr_transfer_ls), Get_OpReg(hcr_rh_descriptorA)); 11179 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11180 "\thcr_rh_descriptorB: 0x%x \thcr_rh_status: 0x%x", 11181 Get_OpReg(hcr_rh_descriptorB), Get_OpReg(hcr_rh_status)); 11182 11183 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11184 "\tRoot hub port status"); 11185 11186 for (i = 0; i < (Get_OpReg(hcr_rh_descriptorA) & HCR_RHA_NDP); i++) { 11187 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, 11188 "\thcr_rh_portstatus 0x%x: 0x%x ", i, 11189 Get_OpReg(hcr_rh_portstatus[i])); 11190 } 11191 } 11192 11193 11194 /* 11195 * ohci_print_ed: 11196 */ 11197 static void 11198 ohci_print_ed( 11199 ohci_state_t *ohcip, 11200 ohci_ed_t *ed) 11201 { 11202 uint_t ctrl = Get_ED(ed->hced_ctrl); 11203 11204 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11205 "ohci_print_ed: ed = 0x%p", (void *)ed); 11206 11207 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11208 "\thced_ctrl: 0x%x %s", ctrl, 11209 ((Get_ED(ed->hced_headp) & HC_EPT_Halt) ? "halted": "")); 11210 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11211 "\ttoggle carry: 0x%x", Get_ED(ed->hced_headp) & HC_EPT_Carry); 11212 11213 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11214 "\tctrl: 0x%x", Get_ED(ed->hced_ctrl)); 11215 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11216 "\ttailp: 0x%x", Get_ED(ed->hced_tailp)); 11217 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11218 "\theadp: 0x%x", Get_ED(ed->hced_headp)); 11219 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11220 "\tnext: 0x%x", Get_ED(ed->hced_next)); 11221 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11222 "\tprev: 0x%x", Get_ED(ed->hced_prev)); 11223 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11224 "\tnode: 0x%x", Get_ED(ed->hced_node)); 11225 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11226 "\treclaim_next: 0x%x", Get_ED(ed->hced_reclaim_next)); 11227 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11228 "\treclaim_frame: 0x%x", Get_ED(ed->hced_reclaim_frame)); 11229 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11230 "\tstate: 0x%x", Get_ED(ed->hced_state)); 11231 } 11232 11233 11234 /* 11235 * ohci_print_td: 11236 */ 11237 static void 11238 ohci_print_td( 11239 ohci_state_t *ohcip, 11240 ohci_td_t *td) 11241 { 11242 uint_t i; 11243 uint_t ctrl = Get_TD(td->hctd_ctrl); 11244 11245 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11246 "ohci_print_td: td = 0x%p", (void *)td); 11247 11248 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11249 "\tPID: 0x%x ", ctrl & HC_TD_PID); 11250 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11251 "\tDelay Intr: 0x%x ", ctrl & HC_TD_DI); 11252 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11253 "\tData Toggle: 0x%x ", ctrl & HC_TD_DT); 11254 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11255 "\tError Count: 0x%x ", ctrl & HC_TD_EC); 11256 11257 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11258 "\tctrl: 0x%x ", Get_TD(td->hctd_ctrl)); 11259 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11260 "\tcbp: 0x%x ", Get_TD(td->hctd_cbp)); 11261 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11262 "\tnext_td: 0x%x ", Get_TD(td->hctd_next_td)); 11263 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11264 "\tbuf_end: 0x%x ", Get_TD(td->hctd_buf_end)); 11265 11266 for (i = 0; i < 4; i++) { 11267 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11268 "\toffset[%d]: 0x%x ", i, Get_TD(td->hctd_offsets[i])); 11269 } 11270 11271 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11272 "\ttrans_wrapper: 0x%x ", Get_TD(td->hctd_trans_wrapper)); 11273 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11274 "\tstate: 0x%x ", Get_TD(td->hctd_state)); 11275 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11276 "\ttw_next_td: 0x%x ", Get_TD(td->hctd_tw_next_td)); 11277 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl, 11278 "\tctrl_phase: 0x%x ", Get_TD(td->hctd_ctrl_phase)); 11279 } 11280 11281 /* 11282 * quiesce(9E) entry point. 11283 * 11284 * This function is called when the system is single-threaded at high 11285 * PIL with preemption disabled. Therefore, this function must not be 11286 * blocked. 11287 * 11288 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 11289 * DDI_FAILURE indicates an error condition and should almost never happen. 11290 */ 11291 #ifndef __sparc 11292 int 11293 ohci_quiesce(dev_info_t *dip) 11294 { 11295 ohci_state_t *ohcip = ohci_obtain_state(dip); 11296 11297 if (ohcip == NULL) 11298 return (DDI_FAILURE); 11299 11300 if (ohcip->ohci_flags & OHCI_INTR) { 11301 11302 /* Disable all HC ED list processing */ 11303 Set_OpReg(hcr_control, 11304 (Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE | 11305 HCR_CONTROL_BLE | HCR_CONTROL_PLE | HCR_CONTROL_IE))); 11306 11307 /* Disable all HC interrupts */ 11308 Set_OpReg(hcr_intr_disable, 11309 (HCR_INTR_SO | HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE)); 11310 11311 /* Disable Master and SOF interrupts */ 11312 Set_OpReg(hcr_intr_disable, (HCR_INTR_MIE | HCR_INTR_SOF)); 11313 11314 /* Set the Host Controller Functional State to Reset */ 11315 Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) & 11316 (~HCR_CONTROL_HCFS)) | HCR_CONTROL_RESET)); 11317 11318 /* 11319 * Workaround for ULI1575 chipset. Following OHCI Operational 11320 * Memory Registers are not cleared to their default value 11321 * on reset. Explicitly set the registers to default value. 11322 */ 11323 if (ohcip->ohci_vendor_id == PCI_ULI1575_VENID && 11324 ohcip->ohci_device_id == PCI_ULI1575_DEVID) { 11325 Set_OpReg(hcr_control, HCR_CONTROL_DEFAULT); 11326 Set_OpReg(hcr_intr_enable, HCR_INT_ENABLE_DEFAULT); 11327 Set_OpReg(hcr_HCCA, HCR_HCCA_DEFAULT); 11328 Set_OpReg(hcr_ctrl_head, HCR_CONTROL_HEAD_ED_DEFAULT); 11329 Set_OpReg(hcr_bulk_head, HCR_BULK_HEAD_ED_DEFAULT); 11330 Set_OpReg(hcr_frame_interval, 11331 HCR_FRAME_INTERVAL_DEFAULT); 11332 Set_OpReg(hcr_periodic_strt, 11333 HCR_PERIODIC_START_DEFAULT); 11334 } 11335 11336 ohcip->ohci_hc_soft_state = OHCI_CTLR_SUSPEND_STATE; 11337 } 11338 11339 /* Unmap the OHCI registers */ 11340 if (ohcip->ohci_regs_handle) { 11341 /* Reset the host controller */ 11342 Set_OpReg(hcr_cmd_status, HCR_STATUS_RESET); 11343 } 11344 11345 return (DDI_SUCCESS); 11346 } 11347 #endif /* __sparc */ 11348