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