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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Open Host Controller Driver (OHCI) 28 * 29 * The USB Open Host Controller driver is a software driver which interfaces 30 * to the Universal Serial Bus layer (USBA) and the USB Open Host Controller. 31 * The interface to USB Open Host Controller is defined by the OpenHCI Host 32 * Controller Interface. 33 * 34 * This module contains the specific ohci code used in POLLED mode and this 35 * code is in a separate file since it will never become part of ohci driver. 36 */ 37 #include <sys/usb/hcd/openhci/ohcid.h> 38 #include <sys/usb/hcd/openhci/ohci_polled.h> 39 40 /* 41 * Internal Function Prototypes 42 */ 43 44 /* Polled initialization routines */ 45 static int ohci_polled_init( 46 usba_pipe_handle_data_t *ph, 47 ohci_state_t *ohcip, 48 usb_console_info_impl_t *console_input_info); 49 50 /* Polled deinitialization routines */ 51 static int ohci_polled_fini(ohci_polled_t *ohci_polledp); 52 53 /* Polled save state routines */ 54 static void ohci_polled_save_state(ohci_polled_t *ohci_polledp); 55 static void ohci_polled_stop_processing( 56 ohci_polled_t *ohci_polledp); 57 58 /* Polled restore state routines */ 59 static void ohci_polled_restore_state(ohci_polled_t *ohci_polledp); 60 static void ohci_polled_start_processing( 61 ohci_polled_t *ohci_polledp); 62 63 /* Polled read routines */ 64 static ohci_td_t *ohci_polled_pickup_done_list( 65 ohci_polled_t *ohci_polledp, 66 ohci_td_t *done_head); 67 static int ohci_polled_check_done_list( 68 ohci_polled_t *ohci_polledp); 69 static void ohci_polled_create_input_list( 70 ohci_polled_t *ohci_polledp, 71 ohci_td_t *head_done_list); 72 static int ohci_polled_process_input_list( 73 ohci_polled_t *ohci_polledp); 74 static int ohci_polled_handle_normal_td( 75 ohci_polled_t *ohci_polledp, 76 ohci_td_t *td); 77 static void ohci_polled_insert_td(ohci_state_t *ohcip, 78 ohci_td_t *td); 79 static void ohci_polled_fill_in_td(ohci_state_t *ohcip, 80 ohci_td_t *td, 81 ohci_td_t *new_dummy, 82 uint_t hctd_ctrl, 83 uint32_t hctd_iommu_cbp, 84 size_t hctd_length, 85 ohci_trans_wrapper_t *tw); 86 static void ohci_polled_insert_td_on_tw( 87 ohci_state_t *ohcip, 88 ohci_trans_wrapper_t *tw, 89 ohci_td_t *td); 90 static void ohci_polled_handle_frame_number_overflow( 91 ohci_state_t *ohcip); 92 static void ohci_polled_finish_interrupt( 93 ohci_state_t *ohcip, 94 uint_t intr); 95 /* 96 * POLLED entry points 97 * 98 * These functions are entry points into the POLLED code. 99 */ 100 101 /* 102 * ohci_hcdi_polled_input_init: 103 * 104 * This is the initialization routine for handling the USB keyboard 105 * in POLLED mode. This routine is not called from POLLED mode, so 106 * it is OK to acquire mutexes. 107 */ 108 int 109 ohci_hcdi_polled_input_init( 110 usba_pipe_handle_data_t *ph, 111 uchar_t **polled_buf, 112 usb_console_info_impl_t *console_input_info) 113 { 114 ohci_polled_t *ohci_polledp; 115 ohci_state_t *ohcip; 116 int ret; 117 118 ohcip = ohci_obtain_state(ph->p_usba_device->usb_root_hub_dip); 119 120 /* 121 * Grab the ohci_int_mutex so that things don't change on us 122 * if an interrupt comes in. 123 */ 124 mutex_enter(&ohcip->ohci_int_mutex); 125 126 ret = ohci_polled_init(ph, ohcip, console_input_info); 127 128 if (ret != USB_SUCCESS) { 129 130 /* Allow interrupts to continue */ 131 mutex_exit(&ohcip->ohci_int_mutex); 132 133 return (ret); 134 } 135 136 ohci_polledp = (ohci_polled_t *)console_input_info->uci_private; 137 138 /* 139 * Mark the structure so that if we are using it, we don't free 140 * the structures if one of them is unplugged. 141 */ 142 ohci_polledp->ohci_polled_flags |= POLLED_INPUT_MODE; 143 144 /* increase the polled kbd counter for keyboard connected */ 145 ohcip->ohci_polled_kbd_count ++; 146 147 /* 148 * This is the buffer we will copy characters into. It will be 149 * copied into at this layer, so we need to keep track of it. 150 */ 151 ohci_polledp->ohci_polled_buf = 152 (uchar_t *)kmem_zalloc(POLLED_RAW_BUF_SIZE, KM_SLEEP); 153 154 *polled_buf = ohci_polledp->ohci_polled_buf; 155 156 /* 157 * This is a software workaround to fix schizo hardware bug. 158 * Existence of "no-prom-cdma-sync" property means consistent 159 * dma sync should not be done while in prom or polled mode. 160 */ 161 if (ddi_prop_exists(DDI_DEV_T_ANY, ohcip->ohci_dip, 162 DDI_PROP_NOTPROM, "no-prom-cdma-sync")) { 163 ohci_polledp->ohci_polled_no_sync_flag = B_TRUE; 164 } 165 166 /* Allow interrupts to continue */ 167 mutex_exit(&ohcip->ohci_int_mutex); 168 169 return (USB_SUCCESS); 170 } 171 172 173 /* 174 * ohci_hcdi_polled_input_fini: 175 */ 176 int 177 ohci_hcdi_polled_input_fini(usb_console_info_impl_t *info) 178 { 179 ohci_polled_t *ohci_polledp; 180 ohci_state_t *ohcip; 181 int ret; 182 183 ohci_polledp = (ohci_polled_t *)info->uci_private; 184 185 ohcip = ohci_polledp->ohci_polled_ohcip; 186 187 mutex_enter(&ohcip->ohci_int_mutex); 188 189 /* 190 * Reset the POLLED_INPUT_MODE flag so that we can tell if 191 * this structure is in use in the ohci_polled_fini routine. 192 */ 193 ohci_polledp->ohci_polled_flags &= ~POLLED_INPUT_MODE; 194 195 /* Decrease the polled kbd counter for keyboard disconnected */ 196 ohcip->ohci_polled_kbd_count --; 197 198 /* Free the buffer that we copied data into */ 199 kmem_free(ohci_polledp->ohci_polled_buf, POLLED_RAW_BUF_SIZE); 200 201 ret = ohci_polled_fini(ohci_polledp); 202 203 mutex_exit(&ohcip->ohci_int_mutex); 204 205 return (ret); 206 } 207 208 209 /* 210 * ohci_hcdi_polled_input_enter: 211 * 212 * This is where we enter into POLLED mode. This routine sets up 213 * everything so that calls to ohci_hcdi_polled_read will return 214 * characters. 215 */ 216 int 217 ohci_hcdi_polled_input_enter(usb_console_info_impl_t *info) 218 { 219 ohci_polled_t *ohci_polledp; 220 221 ohci_polledp = (ohci_polled_t *)info->uci_private; 222 ohci_polledp->ohci_polled_entry++; 223 /* 224 * If the controller is already switched over, just return 225 */ 226 if (ohci_polledp->ohci_polled_entry > 1) { 227 228 return (USB_SUCCESS); 229 } 230 ohci_polled_save_state(ohci_polledp); 231 232 ohci_polledp->ohci_polled_flags |= POLLED_INPUT_MODE_INUSE; 233 234 return (USB_SUCCESS); 235 } 236 237 238 /* 239 * ohci_hcdi_polled_input_exit: 240 * 241 * This is where we exit POLLED mode. This routine restores 242 * everything that is needed to continue operation. 243 */ 244 int 245 ohci_hcdi_polled_input_exit(usb_console_info_impl_t *info) 246 { 247 ohci_polled_t *ohci_polledp; 248 249 ohci_polledp = (ohci_polled_t *)info->uci_private; 250 251 ohci_polledp->ohci_polled_entry--; 252 253 /* 254 * If there are still outstanding "enters", just return 255 */ 256 if (ohci_polledp->ohci_polled_entry > 0) 257 return (USB_SUCCESS); 258 259 ohci_polledp->ohci_polled_flags &= ~POLLED_INPUT_MODE_INUSE; 260 ohci_polled_restore_state(ohci_polledp); 261 262 return (USB_SUCCESS); 263 } 264 265 266 /* 267 * ohci_hcdi_polled_read: 268 * 269 * Get a key character 270 */ 271 int 272 ohci_hcdi_polled_read( 273 usb_console_info_impl_t *info, 274 uint_t *num_characters) 275 { 276 ohci_state_t *ohcip; 277 ohci_polled_t *ohci_polledp; 278 uint_t intr; 279 ohci_polledp = (ohci_polled_t *)info->uci_private; 280 281 ohcip = ohci_polledp->ohci_polled_ohcip; 282 283 #ifndef lint 284 _NOTE(NO_COMPETING_THREADS_NOW); 285 #endif 286 *num_characters = 0; 287 intr = (Get_OpReg(hcr_intr_status) & Get_OpReg(hcr_intr_enable)); 288 289 /* 290 * Check whether any Frame Number Overflow interrupt is pending 291 * and if it is pending, process this interrupt. 292 */ 293 294 if (intr & HCR_INTR_FNO) { 295 ohci_handle_frame_number_overflow(ohcip); 296 297 /* Acknowledge the FNO interrupt */ 298 ohci_polled_finish_interrupt(ohcip, HCR_INTR_FNO); 299 } 300 if (intr & HCR_INTR_WDH) { 301 302 /* Check to see if there are any TD's for this input device */ 303 if (ohci_polled_check_done_list(ohci_polledp) == USB_SUCCESS) { 304 305 /* Process any TD's on the input done list */ 306 *num_characters = 307 ohci_polled_process_input_list(ohci_polledp); 308 } 309 310 /* 311 * To make sure after we get the done list from DoneHead, 312 * every input device get his own TD's in the 313 * ohci_polled_done_list and then clear the interrupt status. 314 */ 315 if (ohcip->ohci_polled_done_list == NULL) { 316 317 /* Acknowledge the WDH interrupt */ 318 ohci_polled_finish_interrupt(ohcip, HCR_INTR_WDH); 319 } 320 } 321 #ifndef lint 322 _NOTE(COMPETING_THREADS_NOW); 323 #endif 324 325 return (USB_SUCCESS); 326 } 327 328 329 /* 330 * Internal Functions 331 */ 332 333 /* 334 * Polled initialization routines 335 */ 336 337 338 /* 339 * ohci_polled_init: 340 * 341 * Initialize generic information Uthat is needed to provide USB/POLLED 342 * support. 343 */ 344 static int 345 ohci_polled_init( 346 usba_pipe_handle_data_t *ph, 347 ohci_state_t *ohcip, 348 usb_console_info_impl_t *console_info) 349 { 350 ohci_polled_t *ohci_polledp; 351 ohci_pipe_private_t *pp; 352 353 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 354 355 /* 356 * We have already initialized this structure. If the structure 357 * has already been initialized, then we don't need to redo it. 358 */ 359 if (console_info->uci_private) { 360 361 return (USB_SUCCESS); 362 } 363 364 /* Allocate and intitialize a state structure */ 365 ohci_polledp = (ohci_polled_t *) 366 kmem_zalloc(sizeof (ohci_polled_t), KM_SLEEP); 367 368 console_info->uci_private = (usb_console_info_private_t)ohci_polledp; 369 370 /* 371 * Store away the ohcip so that we can get to it when we are in 372 * POLLED mode. We don't want to have to call ohci_obtain_state 373 * every time we want to access this structure. Also save ohci 374 * polled state information in ohcip. 375 */ 376 ohci_polledp->ohci_polled_ohcip = ohcip; 377 378 /* 379 * Save usb device and endpoint number information from the usb 380 * pipe handle. 381 */ 382 mutex_enter(&ph->p_mutex); 383 ohci_polledp->ohci_polled_usb_dev = ph->p_usba_device; 384 ohci_polledp->ohci_polled_ep_addr = ph->p_ep.bEndpointAddress; 385 mutex_exit(&ph->p_mutex); 386 387 /* 388 * Allocate memory to make duplicate of original usb pipe handle. 389 */ 390 ohci_polledp->ohci_polled_input_pipe_handle = 391 kmem_zalloc(sizeof (usba_pipe_handle_data_t), KM_SLEEP); 392 393 /* 394 * Copy the USB handle into the new pipe handle. Also 395 * create new lock for the new pipe handle. 396 */ 397 bcopy((void *)ph, 398 (void *)ohci_polledp->ohci_polled_input_pipe_handle, 399 sizeof (usba_pipe_handle_data_t)); 400 401 /* 402 * uint64_t typecast to make sure amd64 can compile 403 */ 404 mutex_init(&ohci_polledp->ohci_polled_input_pipe_handle->p_mutex, 405 NULL, MUTEX_DRIVER, DDI_INTR_PRI(ohcip->ohci_intr_pri)); 406 407 /* Create a new ohci pipe private structure */ 408 pp = (ohci_pipe_private_t *) 409 kmem_zalloc(sizeof (ohci_pipe_private_t), KM_SLEEP); 410 411 /* 412 * Store the pointer in the pipe handle. This structure was also 413 * just allocated. 414 */ 415 mutex_enter(&ohci_polledp->ohci_polled_input_pipe_handle->p_mutex); 416 417 ohci_polledp->ohci_polled_input_pipe_handle-> 418 p_hcd_private = (usb_opaque_t)pp; 419 420 mutex_exit(&ohci_polledp->ohci_polled_input_pipe_handle->p_mutex); 421 422 /* 423 * Store a pointer to the pipe handle. This structure was just 424 * allocated and it is not in use yet. The locking is there to 425 * satisfy warlock. 426 */ 427 mutex_enter(&ph->p_mutex); 428 429 bcopy(&ph->p_policy, &pp->pp_policy, sizeof (usb_pipe_policy_t)); 430 431 mutex_exit(&ph->p_mutex); 432 433 pp->pp_pipe_handle = ohci_polledp->ohci_polled_input_pipe_handle; 434 435 /* 436 * Allocate a dummy for the interrupt table. This dummy will be 437 * put into the action when we switch interrupt tables during 438 * ohci_hcdi_polled_enter. Dummy is placed on the unused lattice 439 * entries. When the ED is allocated we will replace dummy ED by 440 * valid interrupt ED in one or more locations in the interrupt 441 * lattice depending on the requested polling interval. Also we 442 * will hang a dummy TD to the ED & dummy TD is used to indicate 443 * the end of the TD chain. 444 */ 445 ohci_polledp->ohci_polled_dummy_ed = ohci_alloc_hc_ed(ohcip, NULL); 446 447 if (ohci_polledp->ohci_polled_dummy_ed == NULL) { 448 449 return (USB_NO_RESOURCES); 450 } 451 452 /* 453 * Allocate the interrupt endpoint. This ED will be inserted in 454 * to the lattice chain for the keyboard device. This endpoint 455 * will have the TDs hanging off of it for the processing. 456 */ 457 ohci_polledp->ohci_polled_ed = ohci_alloc_hc_ed(ohcip, 458 ohci_polledp->ohci_polled_input_pipe_handle); 459 460 if (ohci_polledp->ohci_polled_ed == NULL) { 461 462 return (USB_NO_RESOURCES); 463 } 464 465 /* Set the state of pipe as idle */ 466 pp->pp_state = OHCI_PIPE_STATE_IDLE; 467 468 /* Insert the endpoint onto the pipe handle */ 469 pp->pp_ept = ohci_polledp->ohci_polled_ed; 470 471 /* 472 * Set soft interrupt handler flag in the normal mode usb 473 * pipe handle. 474 */ 475 mutex_enter(&ph->p_mutex); 476 ph->p_spec_flag |= USBA_PH_FLAG_USE_SOFT_INTR; 477 mutex_exit(&ph->p_mutex); 478 479 /* 480 * Insert a Interrupt polling request onto the endpoint. 481 * 482 * There will now be two TDs on the ED, one is the dummy TD that 483 * was allocated above in the ohci_alloc_hc_ed and this new one. 484 */ 485 if ((ohci_start_periodic_pipe_polling(ohcip, 486 ohci_polledp->ohci_polled_input_pipe_handle, 487 NULL, USB_FLAGS_SLEEP)) != USB_SUCCESS) { 488 489 return (USB_NO_RESOURCES); 490 } 491 492 return (USB_SUCCESS); 493 } 494 495 496 /* 497 * Polled deinitialization routines 498 */ 499 500 501 /* 502 * ohci_polled_fini: 503 */ 504 static int 505 ohci_polled_fini(ohci_polled_t *ohci_polledp) 506 { 507 ohci_state_t *ohcip = ohci_polledp->ohci_polled_ohcip; 508 ohci_pipe_private_t *pp; 509 ohci_td_t *curr_td, *next_td; 510 ohci_trans_wrapper_t *curr_tw, *next_tw; 511 ASSERT(mutex_owned(&ohcip->ohci_int_mutex)); 512 513 /* 514 * If the structure is already in use, then don't free it. 515 */ 516 if (ohci_polledp->ohci_polled_flags & POLLED_INPUT_MODE) { 517 518 return (USB_SUCCESS); 519 } 520 521 pp = (ohci_pipe_private_t *) 522 ohci_polledp->ohci_polled_input_pipe_handle->p_hcd_private; 523 524 /* 525 * Deallocate all the pre-allocated interrupt requests 526 */ 527 ohci_handle_outstanding_requests(ohcip, pp); 528 529 /* 530 * Traverse the list of TD's on this endpoint and these TD's 531 * have outstanding transfer requests. Since list processing 532 * is stopped, these TDs can be deallocated. 533 */ 534 ohci_traverse_tds(ohcip, pp->pp_pipe_handle); 535 536 /* 537 * For each transfer wrapper on this pipe, free the TD and 538 * free the TW. We don't free the last TD in the chain 539 * because it will be freed by ohci_deallocate_ed. All TD's 540 * on this TW are also on the end point associated with this 541 * pipe. 542 */ 543 next_tw = pp->pp_tw_head; 544 545 while (next_tw) { 546 next_td = (ohci_td_t *)next_tw->tw_hctd_head; 547 548 /* 549 * Walk through each TD for this transfer 550 * wrapper and free that TD. 551 */ 552 while (next_td) { 553 curr_td = next_td; 554 555 next_td = ohci_td_iommu_to_cpu(ohcip, 556 Get_TD(next_td->hctd_tw_next_td)); 557 558 ohci_deallocate_td(ohcip, curr_td); 559 } 560 561 curr_tw = next_tw; 562 next_tw = curr_tw->tw_next; 563 564 /* Free the transfer wrapper */ 565 ohci_deallocate_tw_resources(ohcip, pp, curr_tw); 566 } 567 568 /* 569 * Deallocate the endpoint descriptors that we allocated 570 * with ohci_alloc_hc_ed. 571 */ 572 if (ohci_polledp->ohci_polled_dummy_ed) { 573 ohci_deallocate_ed(ohcip, ohci_polledp->ohci_polled_dummy_ed); 574 } 575 576 if (ohci_polledp->ohci_polled_ed) { 577 ohci_deallocate_ed(ohcip, ohci_polledp->ohci_polled_ed); 578 } 579 580 mutex_destroy(&ohci_polledp->ohci_polled_input_pipe_handle->p_mutex); 581 582 /* 583 * Destroy everything about the pipe that we allocated in 584 * ohci_polled_duplicate_pipe_handle 585 */ 586 kmem_free(pp, sizeof (ohci_pipe_private_t)); 587 588 kmem_free(ohci_polledp->ohci_polled_input_pipe_handle, 589 sizeof (usba_pipe_handle_data_t)); 590 591 /* 592 * We use this field to determine if a TD is for input or not, 593 * so NULL the pointer so we don't check deallocated data. 594 */ 595 ohci_polledp->ohci_polled_input_pipe_handle = NULL; 596 597 /* 598 * Finally, free off the structure that we use to keep track 599 * of all this. 600 */ 601 kmem_free(ohci_polledp, sizeof (ohci_polled_t)); 602 603 return (USB_SUCCESS); 604 } 605 606 607 /* 608 * Polled save state routines 609 */ 610 611 612 /* 613 * ohci_polled_save_state: 614 */ 615 static void 616 ohci_polled_save_state(ohci_polled_t *ohci_polledp) 617 { 618 ohci_state_t *ohcip; 619 int i; 620 uint_t polled_toggle; 621 uint_t real_toggle; 622 ohci_pipe_private_t *pp = NULL; /* Normal mode Pipe */ 623 ohci_pipe_private_t *polled_pp; /* Polled mode Pipe */ 624 usba_pipe_handle_data_t *ph; 625 uint8_t ep_addr; 626 ohci_save_intr_sts_t *ohci_intr_sts; 627 ohci_regs_t *ohci_polled_regsp; 628 ohci_td_t *td, *prev_td; 629 ohci_td_t *done_head, **done_list; 630 631 #ifndef lint 632 _NOTE(NO_COMPETING_THREADS_NOW); 633 #endif 634 635 /* 636 * If either of these two flags are set, then we have already 637 * saved off the state information and setup the controller. 638 */ 639 if (ohci_polledp->ohci_polled_flags & POLLED_INPUT_MODE_INUSE) { 640 #ifndef lint 641 _NOTE(COMPETING_THREADS_NOW); 642 #endif 643 return; 644 } 645 646 ohcip = ohci_polledp->ohci_polled_ohcip; 647 648 /* 649 * Check if the number of keyboard reach the max number we can 650 * support in polled mode 651 */ 652 if (++ ohcip->ohci_polled_enter_count > MAX_NUM_FOR_KEYBOARD) { 653 #ifndef lint 654 _NOTE(COMPETING_THREADS_NOW); 655 #endif 656 return; 657 } 658 /* Get the endpoint addr. */ 659 ep_addr = ohci_polledp->ohci_polled_ep_addr; 660 661 /* Get the normal mode usb pipe handle */ 662 ph = usba_hcdi_get_ph_data(ohci_polledp->ohci_polled_usb_dev, ep_addr); 663 ohci_intr_sts = &ohcip->ohci_save_intr_sts; 664 ohci_polled_regsp = &ohcip->ohci_polled_save_regs; 665 666 /* 667 * Only the first enter keyboard entry disable the interrupt, save the 668 * information of normal mode, stop the processing, initialize the 669 * frame list table. 670 */ 671 if (ohcip->ohci_polled_enter_count == 1) { 672 /* 673 * Prevent the ohci interrupt handler from handling interrupt. 674 * We will turn off interrupts. This keeps us from generating 675 * a hardware interrupt.This is the useful for testing because 676 * in POLLED mode we can't get interrupts anyway. We can test 677 * this code by shutting off hardware interrupt generation and 678 * polling for the interrupts. 679 */ 680 Set_OpReg(hcr_intr_disable, HCR_INTR_MIE); 681 /* 682 * Save the current normal mode ohci registers and later this 683 * saved register copy is used to replace some of required ohci 684 * registers before switching from polled mode to normal mode. 685 */ 686 bzero((void *)ohci_polled_regsp, sizeof (ohci_regs_t)); 687 688 ohci_polled_regsp->hcr_control = Get_OpReg(hcr_control); 689 ohci_polled_regsp->hcr_cmd_status = Get_OpReg(hcr_cmd_status); 690 ohci_polled_regsp->hcr_intr_enable = Get_OpReg(hcr_intr_enable); 691 ohci_polled_regsp->hcr_HCCA = Get_OpReg(hcr_HCCA); 692 ohci_polled_regsp->hcr_done_head = Get_OpReg(hcr_done_head); 693 ohci_polled_regsp->hcr_bulk_head = Get_OpReg(hcr_bulk_head); 694 ohci_polled_regsp->hcr_ctrl_head = Get_OpReg(hcr_ctrl_head); 695 696 /* 697 * The functionality & importance of critical code section in 698 * the normal mode ohci interrupt handler and its usage in the 699 * polled mode is explained below. 700 * 701 * (a) Normal mode: 702 * 703 * - Set the flag indicating that processing critical code 704 * in ohci interrupt handler. 705 * 706 * - Process the missed ohci interrupts by copying missed 707 * interrupt events & done head list fields information 708 * to the critical interrupt events & done list fields. 709 * 710 * - Reset the missed ohci interrupt events and done head 711 * list fields so that the new missed interrupt events 712 * and done head list information can be saved. 713 * 714 * - All above steps will be executed within the critical 715 * section of the interrupt handler. Then ohci missed 716 * interrupt handler will be called to service the ohci 717 * missed interrupts. 718 * 719 * (b) Polled mode: 720 * 721 * - On entering the polled code, checks for the critical 722 * section code execution within normal mode interrupt 723 * handler. 724 * 725 * - If critical section code is executing in the normal 726 * mode ohci interrupt handler & if copying of the ohci 727 * missed interrupt events and done head list fields to 728 * the critical fields is finished then, save the "any 729 * missed interrupt events and done head list" because 730 * of current polled mode switch into "critical missed 731 * interrupt events & done list fields" instead actual 732 * missed events and done list fields. 733 * 734 * - Otherwise save "any missed interrupt events and done 735 * list" because of this current polled mode switch in 736 * the actual missed interrupt events & done head list 737 * fields. 738 */ 739 740 /* 741 * Check and save the pending SOF interrupt condition for the 742 * ohci normal mode. This information will be saved either in 743 * the critical missed event fields or in actual missed event 744 * fields depending on the whether the critical code section's 745 * execution flag was set or not when switched to polled mode 746 * from normal mode. 747 */ 748 if ((ohci_intr_sts->ohci_intr_flag & OHCI_INTR_CRITICAL) && 749 (ohci_intr_sts->ohci_critical_intr_sts != 0)) { 750 751 ohci_intr_sts->ohci_critical_intr_sts |= 752 ((Get_OpReg(hcr_intr_status) & 753 Get_OpReg(hcr_intr_enable)) & HCR_INTR_SOF); 754 } else { 755 ohci_intr_sts->ohci_missed_intr_sts |= 756 ((Get_OpReg(hcr_intr_status) & 757 Get_OpReg(hcr_intr_enable)) & HCR_INTR_SOF); 758 } 759 ohci_polled_stop_processing(ohci_polledp); 760 761 /* Process any missed Frame Number Overflow (FNO) interrupt */ 762 ohci_polled_handle_frame_number_overflow(ohcip); 763 764 /* 765 * By this time all list processing has been stopped.Now check 766 * and save the information about the pending HCCA done list, 767 * done head ohci register and WDH bit in the interrupt status 768 * register. This information will be saved either in critical 769 * missed event fields or in actual missed event fields depend 770 * on the whether the critical code section's execution flag 771 * was set or not when switched to polled mode from the normal 772 * mode. 773 */ 774 775 /* Read and Save the HCCA DoneHead value */ 776 done_head = (ohci_td_t *)(uintptr_t)(Get_HCCA( 777 ohcip->ohci_hccap->HccaDoneHead) & HCCA_DONE_HEAD_MASK); 778 779 if ((done_head) && 780 (done_head != ohci_intr_sts->ohci_curr_done_lst)) { 781 782 if ((ohci_intr_sts->ohci_intr_flag & 783 OHCI_INTR_CRITICAL) && 784 ((ohci_intr_sts->ohci_critical_done_lst) || 785 (ohci_intr_sts->ohci_missed_done_lst == NULL))) { 786 787 done_list = 788 &ohci_intr_sts->ohci_critical_done_lst; 789 ohci_intr_sts->ohci_critical_intr_sts |= 790 HCR_INTR_WDH; 791 } else { 792 done_list = 793 &ohci_intr_sts->ohci_missed_done_lst; 794 ohci_intr_sts->ohci_missed_intr_sts |= 795 HCR_INTR_WDH; 796 } 797 798 if (*done_list) { 799 td = (ohci_td_t *) 800 ohci_td_iommu_to_cpu(ohcip, 801 (uintptr_t)done_head); 802 803 while (td) { 804 prev_td = td; 805 td = ohci_td_iommu_to_cpu(ohcip, 806 Get_TD(td->hctd_next_td)); 807 } 808 809 Set_TD(prev_td->hctd_next_td, *done_list); 810 811 *done_list = done_head; 812 } else { 813 *done_list = (ohci_td_t *)done_head; 814 } 815 } 816 817 /* 818 * Save the latest hcr_done_head ohci register value, so that 819 * this value can be replaced when exit from the POLLED mode. 820 */ 821 ohci_polled_regsp->hcr_done_head = Get_OpReg(hcr_done_head); 822 /* 823 * Reset the HCCA done head and ohci done head register. 824 */ 825 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, NULL); 826 Set_OpReg(hcr_done_head, (uint32_t)0x0); 827 828 /* 829 * Clear the WriteDoneHead interrupt bit in the ohci interrupt 830 * status register. 831 */ 832 Set_OpReg(hcr_intr_status, HCR_INTR_WDH); 833 834 /* 835 * Save the current interrupt lattice and replace this lattice 836 * with an lattice used in POLLED mode. We will restore lattice 837 * back when we exit from the POLLED mode. 838 */ 839 for (i = 0; i < NUM_INTR_ED_LISTS; i++) { 840 ohcip->ohci_polled_save_IntTble[i] = 841 (ohci_ed_t *)(uintptr_t)Get_HCCA( 842 ohcip->ohci_hccap->HccaIntTble[i]); 843 } 844 /* 845 * Fill in the lattice with dummy EDs. These EDs are used so the 846 * controller can tell that it is at the end of the ED list. 847 */ 848 for (i = 0; i < NUM_INTR_ED_LISTS; i++) { 849 Set_HCCA(ohcip->ohci_hccap->HccaIntTble[i], 850 ohci_ed_cpu_to_iommu(ohcip, 851 ohci_polledp->ohci_polled_dummy_ed)); 852 } 853 } 854 /* Get the polled mode ohci pipe private structure */ 855 polled_pp = (ohci_pipe_private_t *) 856 ohci_polledp->ohci_polled_input_pipe_handle->p_hcd_private; 857 858 /* 859 * Before replacing the lattice, adjust the data togggle on the 860 * on the ohci's interrupt ed 861 */ 862 polled_toggle = (Get_ED(polled_pp->pp_ept->hced_headp) & 863 HC_EPT_Carry) ? DATA1:DATA0; 864 865 /* 866 * If normal mode interrupt pipe endpoint is active, get the data 867 * toggle from the this interrupt endpoint through the corresponding 868 * interrupt pipe handle. Else get the data toggle information from 869 * the usb device structure and this information is saved during the 870 * normal mode interrupt pipe close. Use this data toggle information 871 * to fix the data toggle of polled mode interrupt endpoint. 872 */ 873 if (ph) { 874 /* Get the normal mode ohci pipe private structure */ 875 pp = (ohci_pipe_private_t *)ph->p_hcd_private; 876 877 real_toggle = (Get_ED(pp->pp_ept->hced_headp) & 878 HC_EPT_Carry) ? DATA1:DATA0; 879 } else { 880 real_toggle = usba_hcdi_get_data_toggle( 881 ohci_polledp->ohci_polled_usb_dev, ep_addr); 882 } 883 884 if (polled_toggle != real_toggle) { 885 if (real_toggle == DATA0) { 886 Set_ED(polled_pp->pp_ept->hced_headp, 887 Get_ED(polled_pp->pp_ept->hced_headp) & 888 ~HC_EPT_Carry); 889 } else { 890 Set_ED(polled_pp->pp_ept->hced_headp, 891 Get_ED(polled_pp->pp_ept->hced_headp) | 892 HC_EPT_Carry); 893 } 894 } 895 896 /* 897 * Check whether Halt bit is set in the ED and if so clear the 898 * halt bit. 899 */ 900 if (polled_pp->pp_ept->hced_headp & HC_EPT_Halt) { 901 902 /* Clear the halt bit */ 903 Set_ED(polled_pp->pp_ept->hced_headp, 904 (Get_ED(polled_pp->pp_ept->hced_headp) & ~HC_EPT_Halt)); 905 } 906 907 /* 908 * Now, add the endpoint to the lattice that we will hang our 909 * TD's off of. We need to poll this device at every 8 ms and 910 * hence add this ED needs 4 entries in interrupt lattice. 911 */ 912 for (i = (ohcip->ohci_polled_enter_count -1); i < NUM_INTR_ED_LISTS; 913 i = i + MIN_LOW_SPEED_POLL_INTERVAL) { 914 Set_HCCA(ohcip->ohci_hccap->HccaIntTble[i], 915 ohci_ed_cpu_to_iommu(ohcip, 916 ohci_polledp->ohci_polled_ed)); 917 } 918 /* 919 * Only the first enter keyboard entry clear the contents of 920 * periodic ED register and enable the WDH interrupt and 921 * start process the periodic list. 922 */ 923 if (ohcip->ohci_polled_enter_count == 1) { 924 /* 925 * Clear the contents of current ohci periodic ED register that 926 * is physical address of current Isochronous or Interrupt ED. 927 */ 928 929 Set_OpReg(hcr_periodic_curr, (uint32_t)0x0); 930 931 /* Make sure WriteDoneHead interrupt is enabled */ 932 Set_OpReg(hcr_intr_enable, HCR_INTR_WDH); 933 934 /* 935 * Enable the periodic list. We will now start processing EDs & 936 * TDs again. 937 */ 938 Set_OpReg(hcr_control, 939 (Get_OpReg(hcr_control) | HCR_CONTROL_PLE)); 940 } 941 #ifndef lint 942 _NOTE(COMPETING_THREADS_NOW); 943 #endif 944 } 945 946 947 /* 948 * ohci_polled_stop_processing: 949 */ 950 static void 951 ohci_polled_stop_processing(ohci_polled_t *ohci_polledp) 952 { 953 ohci_state_t *ohcip; 954 uint_t count; 955 ohci_regs_t *ohci_polled_regsp; 956 957 ohcip = ohci_polledp->ohci_polled_ohcip; 958 ohci_polled_regsp = &ohcip->ohci_polled_save_regs; 959 960 /* 961 * Turn off all list processing. This will take place starting 962 * at the next frame. 963 */ 964 Set_OpReg(hcr_control, 965 (ohci_polled_regsp->hcr_control) & ~(HCR_CONTROL_CLE| 966 HCR_CONTROL_PLE| HCR_CONTROL_BLE|HCR_CONTROL_IE)); 967 968 /* 969 * Make sure that the SOF interrupt bit is cleared in the ohci 970 * interrupt status register. 971 */ 972 Set_OpReg(hcr_intr_status, HCR_INTR_SOF); 973 974 /* Enable SOF interrupt */ 975 Set_OpReg(hcr_intr_enable, HCR_INTR_SOF); 976 977 /* 978 * According to OHCI Specification, we have to wait for eight 979 * start of frames to make sure that the Host Controller writes 980 * contents of done head register to done head filed of HCCA. 981 */ 982 for (count = 0; count <= DONE_QUEUE_INTR_COUNTER; count++) { 983 while (!((Get_OpReg(hcr_intr_status)) & HCR_INTR_SOF)) { 984 continue; 985 } 986 987 /* Acknowledge the SOF interrupt */ 988 ohci_polled_finish_interrupt(ohcip, HCR_INTR_SOF); 989 } 990 991 Set_OpReg(hcr_intr_disable, HCR_INTR_SOF); 992 } 993 994 995 /* 996 * Polled restore state routines 997 */ 998 999 /* 1000 * ohci_polled_restore_state: 1001 */ 1002 static void 1003 ohci_polled_restore_state(ohci_polled_t *ohci_polledp) 1004 { 1005 ohci_state_t *ohcip; 1006 int i; 1007 uint_t polled_toggle; 1008 uint_t real_toggle; 1009 ohci_pipe_private_t *pp = NULL; /* Normal mode Pipe */ 1010 ohci_pipe_private_t *polled_pp; /* Polled mode Pipe */ 1011 ohci_td_t *td; 1012 ohci_td_t *next_td; /* TD pointers */ 1013 uint_t count; 1014 ohci_save_intr_sts_t *ohci_intr_sts; 1015 ohci_regs_t *ohci_polled_regsp; 1016 uint32_t mask; 1017 usba_pipe_handle_data_t *ph; 1018 uint8_t ep_addr; 1019 1020 #ifndef lint 1021 _NOTE(NO_COMPETING_THREADS_NOW); 1022 #endif 1023 1024 /* 1025 * If this flag is set, then we are still using this structure, 1026 * so don't restore any controller state information yet. 1027 */ 1028 if (ohci_polledp->ohci_polled_flags & POLLED_INPUT_MODE_INUSE) { 1029 1030 #ifndef lint 1031 _NOTE(COMPETING_THREADS_NOW); 1032 #endif 1033 1034 return; 1035 } 1036 1037 ohcip = ohci_polledp->ohci_polled_ohcip; 1038 ohci_intr_sts = &ohcip->ohci_save_intr_sts; 1039 ohci_polled_regsp = &ohcip->ohci_polled_save_regs; 1040 ohcip->ohci_polled_enter_count --; 1041 1042 /* Get the endpoint addr. */ 1043 ep_addr = ohci_polledp->ohci_polled_ep_addr; 1044 /* Get the normal mode usb pipe handle */ 1045 ph = usba_hcdi_get_ph_data(ohci_polledp->ohci_polled_usb_dev, ep_addr); 1046 1047 /* 1048 * Only the first leave keyboard entry turn off all list processing. 1049 * This will take place starting at the next frame. 1050 */ 1051 if (Get_OpReg(hcr_control) & HCR_CONTROL_PLE) { 1052 Set_OpReg(hcr_control, 1053 (Get_OpReg(hcr_control) & ~HCR_CONTROL_PLE)); 1054 } 1055 1056 /* 1057 * Only the last leave keyboard entry restore the info for 1058 * normal mode. 1059 */ 1060 if (ohcip->ohci_polled_enter_count == 0) { 1061 Set_OpReg(hcr_intr_enable, HCR_INTR_SOF); 1062 1063 /* 1064 * According to OHCI Specification, we have to wait for eight 1065 * start of frames to make sure that the Host Controller writes 1066 * contents of done head register to done head filed of HCCA. 1067 */ 1068 for (count = 0; count <= DONE_QUEUE_INTR_COUNTER; count++) { 1069 while (!((Get_OpReg(hcr_intr_status)) & HCR_INTR_SOF)) { 1070 continue; 1071 } 1072 /* Acknowledge the SOF interrupt */ 1073 ohci_polled_finish_interrupt(ohcip, HCR_INTR_SOF); 1074 } 1075 1076 /* 1077 * Check any Frame Number Overflow interrupt (FNO) is pending. 1078 */ 1079 ohci_polled_handle_frame_number_overflow(ohcip); 1080 1081 /* 1082 * Before switching back, we have to process last TD in the 1083 * POLLED mode. It may be in the hcr_done_head register or 1084 * in done list or in the lattice. If it is either on the 1085 * hcr_done_head register or in the done list, just re-inserted 1086 * into the ED's TD list. 1087 * 1088 * First look up at the TD's that are in the hcr_done_head 1089 * register and re-insert them back into the ED's TD list. 1090 */ 1091 td = ohci_td_iommu_to_cpu(ohcip, 1092 (uintptr_t)Get_OpReg(hcr_done_head)); 1093 1094 while (td) { 1095 1096 next_td = ohci_td_iommu_to_cpu(ohcip, Get_TD(td->hctd_next_td)); 1097 1098 /* 1099 * Insert valid interrupt TD back into ED's 1100 * TD list. No periodic TD's will be processed 1101 * since all processing has been stopped. 1102 */ 1103 ohci_polled_insert_td(ohcip, td); 1104 1105 td = next_td; 1106 } 1107 1108 /* 1109 * Now look up at the TD's that are in the HCCA done head list & 1110 * re-insert them back into the ED's TD list. 1111 */ 1112 td = ohci_td_iommu_to_cpu(ohcip, (Get_HCCA( 1113 ohcip->ohci_hccap->HccaDoneHead) & HCCA_DONE_HEAD_MASK)); 1114 1115 while (td) { 1116 1117 next_td = ohci_td_iommu_to_cpu(ohcip, 1118 Get_TD(td->hctd_next_td)); 1119 1120 /* 1121 * Insert valid interrupt TD back into ED's 1122 * TD list. No periodic TD's will be processed 1123 * since all processing has been stopped. 1124 */ 1125 ohci_polled_insert_td(ohcip, td); 1126 1127 td = next_td; 1128 } 1129 /* Reset the HCCA done head list to NULL */ 1130 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, NULL); 1131 1132 /* 1133 * Replace the hcr_done_head register field with the saved copy 1134 * of current normal mode hcr_done_head register contents. 1135 */ 1136 Set_OpReg(hcr_done_head, 1137 (uint32_t)ohci_polled_regsp->hcr_done_head); 1138 1139 /* 1140 * Clear the WriteDoneHead and SOF interrupt bits in the ohci 1141 * interrupt status register. 1142 */ 1143 Set_OpReg(hcr_intr_status, (HCR_INTR_WDH | HCR_INTR_SOF)); 1144 } 1145 1146 /* Get the polled mode ohci pipe private structure */ 1147 polled_pp = (ohci_pipe_private_t *) 1148 ohci_polledp->ohci_polled_input_pipe_handle->p_hcd_private; 1149 1150 /* 1151 * Before replacing the lattice, adjust the data togggle 1152 * on the on the ohci's interrupt ed 1153 */ 1154 polled_toggle = (Get_ED(polled_pp->pp_ept->hced_headp) & 1155 HC_EPT_Carry) ? DATA1:DATA0; 1156 1157 /* 1158 * If normal mode interrupt pipe endpoint is active, fix the 1159 * data toggle for this interrupt endpoint by getting the data 1160 * toggle information from the polled interrupt endpoint. Else 1161 * save the data toggle information in usb device structure. 1162 */ 1163 if (ph) { 1164 /* Get the normal mode ohci pipe private structure */ 1165 pp = (ohci_pipe_private_t *)ph->p_hcd_private; 1166 1167 real_toggle = (Get_ED(pp->pp_ept->hced_headp) & 1168 HC_EPT_Carry) ? DATA1:DATA0; 1169 1170 if (polled_toggle != real_toggle) { 1171 if (polled_toggle == DATA0) { 1172 Set_ED(pp->pp_ept->hced_headp, 1173 Get_ED(pp->pp_ept->hced_headp) & 1174 ~HC_EPT_Carry); 1175 } else { 1176 Set_ED(pp->pp_ept->hced_headp, 1177 Get_ED(pp->pp_ept->hced_headp) | 1178 HC_EPT_Carry); 1179 } 1180 } 1181 } else { 1182 usba_hcdi_set_data_toggle(ohci_polledp->ohci_polled_usb_dev, 1183 ep_addr, polled_toggle); 1184 } 1185 /* 1186 * Only the last leave keyboard entry restore the Interrupt table, 1187 * start processing and enable the interrupt. 1188 */ 1189 if (ohcip->ohci_polled_enter_count == 0) { 1190 /* Replace the lattice */ 1191 for (i = 0; i < NUM_INTR_ED_LISTS; i++) { 1192 Set_HCCA(ohcip->ohci_hccap->HccaIntTble[i], 1193 (uintptr_t)ohcip->ohci_polled_save_IntTble[i]); 1194 } 1195 1196 /* 1197 * Clear the contents of current ohci periodic ED register that 1198 * is physical address of current Isochronous or Interrupt ED. 1199 */ 1200 Set_OpReg(hcr_periodic_curr, (uint32_t)0x0); 1201 1202 ohci_polled_start_processing(ohci_polledp); 1203 1204 /* 1205 * Check and enable required ohci interrupts before switching 1206 * back to normal mode from the POLLED mode. 1207 */ 1208 mask = (uint32_t)ohci_polled_regsp->hcr_intr_enable & 1209 (HCR_INTR_SOF | HCR_INTR_WDH); 1210 1211 if (ohci_intr_sts->ohci_intr_flag & OHCI_INTR_HANDLING) { 1212 Set_OpReg(hcr_intr_enable, mask); 1213 } else { 1214 Set_OpReg(hcr_intr_enable, mask | HCR_INTR_MIE); 1215 } 1216 } 1217 1218 #ifndef lint 1219 _NOTE(COMPETING_THREADS_NOW); 1220 #endif 1221 } 1222 1223 /* 1224 * ohci_polled_start_processing: 1225 */ 1226 static void 1227 ohci_polled_start_processing(ohci_polled_t *ohci_polledp) 1228 { 1229 ohci_state_t *ohcip; 1230 uint32_t control; 1231 uint32_t mask; 1232 ohci_regs_t *ohci_polled_regsp; 1233 1234 ohcip = ohci_polledp->ohci_polled_ohcip; 1235 ohci_polled_regsp = &ohcip->ohci_polled_save_regs; 1236 1237 mask = ((uint32_t)ohci_polled_regsp->hcr_control) & (HCR_CONTROL_CLE | 1238 HCR_CONTROL_PLE | HCR_CONTROL_BLE | HCR_CONTROL_IE); 1239 1240 control = Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE | 1241 HCR_CONTROL_PLE | HCR_CONTROL_BLE | HCR_CONTROL_IE); 1242 1243 Set_OpReg(hcr_control, (control | mask)); 1244 } 1245 1246 1247 /* 1248 * Polled read routines 1249 */ 1250 1251 1252 /* 1253 * ohci_polled_check_done_list: 1254 * 1255 * Check to see it there are any TD's on the done head. If there are 1256 * then reverse the done list and put the TD's on the appropriated list. 1257 */ 1258 static int 1259 ohci_polled_check_done_list(ohci_polled_t *ohci_polledp) 1260 { 1261 ohci_state_t *ohcip = ohci_polledp->ohci_polled_ohcip; 1262 ohci_td_t *done_head, *done_list; 1263 1264 /* Sync HCCA area */ 1265 if (ohci_polledp->ohci_polled_no_sync_flag == B_FALSE) { 1266 Sync_HCCA(ohcip); 1267 } 1268 1269 /* Read and Save the HCCA DoneHead value */ 1270 done_head = (ohci_td_t *)(uintptr_t) 1271 (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) & HCCA_DONE_HEAD_MASK); 1272 1273 /* 1274 * Look at the Done Head and if it is NULL and ohci done list is NULL, 1275 * just return; else if ohci done list is not NULL, should check it. 1276 */ 1277 if (done_head == NULL) { 1278 if (ohcip->ohci_polled_done_list) { 1279 done_head = ohcip->ohci_polled_done_list; 1280 } else { 1281 1282 return (USB_FAILURE); 1283 } 1284 } else { 1285 /* Reset the done head to NULL */ 1286 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, NULL); 1287 ohcip->ohci_polled_done_list = NULL; 1288 } 1289 1290 /* Sync ED and TD pool */ 1291 if (ohci_polledp->ohci_polled_no_sync_flag == B_FALSE) { 1292 Sync_ED_TD_Pool(ohcip); 1293 } 1294 1295 /* Pickup own tds in the done head */ 1296 done_list = ohci_polled_pickup_done_list(ohci_polledp, done_head); 1297 1298 /* 1299 * Look at the own done list which is pickup'ed 1300 * and if it is NULL, just return. 1301 */ 1302 if (done_list == NULL) { 1303 1304 return (USB_FAILURE); 1305 } 1306 /* Create the input done list */ 1307 ohci_polled_create_input_list(ohci_polledp, done_list); 1308 1309 return (USB_SUCCESS); 1310 } 1311 1312 /* 1313 * ohci_polled_pickup_done_list: 1314 * 1315 * Pickup the TDs of own in the Done Head List 1316 */ 1317 static ohci_td_t * 1318 ohci_polled_pickup_done_list( 1319 ohci_polled_t *ohci_polledp, 1320 ohci_td_t *done_head) 1321 { 1322 ohci_state_t *ohcip = ohci_polledp->ohci_polled_ohcip; 1323 ohci_td_t *reserve_head = NULL, *reserve_tail = NULL; 1324 ohci_td_t *create_head = NULL, *current_td, *td; 1325 ohci_trans_wrapper_t *tw; 1326 ohci_pipe_private_t *pp; 1327 1328 /* 1329 * Current_td pointers point to the done head. 1330 */ 1331 current_td = (ohci_td_t *) 1332 ohci_td_iommu_to_cpu(ohcip, (uintptr_t)done_head); 1333 while (current_td) { 1334 td = (ohci_td_t *)ohci_td_iommu_to_cpu(ohcip, 1335 Get_TD(current_td->hctd_next_td)); 1336 1337 Set_TD(current_td->hctd_next_td, NULL); 1338 1339 /* Obtain the transfer wrapper from the TD */ 1340 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID( 1341 (uint32_t)Get_TD(current_td->hctd_trans_wrapper)); 1342 1343 /* Get the pipe handle for this transfer wrapper. */ 1344 pp = tw->tw_pipe_private; 1345 1346 /* 1347 * Figure out which done list to put this TD on and put it 1348 * there. If the pipe handle of the TD matches the pipe 1349 * handle we are using for the input device, then this must 1350 * be an input TD, reverse the order and link to the list for 1351 * this input device. Else put the TD to the reserve done list 1352 * for other input devices. 1353 */ 1354 1355 if (pp->pp_pipe_handle == 1356 ohci_polledp->ohci_polled_input_pipe_handle) { 1357 if (create_head == NULL) { 1358 create_head = current_td; 1359 } else { 1360 Set_TD(current_td->hctd_next_td, 1361 ohci_td_cpu_to_iommu(ohcip, create_head)); 1362 create_head = current_td; 1363 } 1364 } else { 1365 if (reserve_head == NULL) { 1366 reserve_head = reserve_tail = current_td; 1367 } else { 1368 Set_TD(reserve_tail->hctd_next_td, 1369 ohci_td_cpu_to_iommu(ohcip, current_td)); 1370 reserve_tail = current_td; 1371 } 1372 } 1373 current_td = td; 1374 } 1375 1376 /* Check if there is other TDs left for other input devices */ 1377 if (reserve_head) { 1378 ohcip->ohci_polled_done_list = (ohci_td_t *)(uintptr_t) 1379 ohci_td_cpu_to_iommu(ohcip, reserve_head); 1380 1381 } else { 1382 ohcip->ohci_polled_done_list = NULL; 1383 } 1384 1385 return (create_head); 1386 } 1387 1388 /* 1389 * ohci_polled_create_input_list: 1390 * 1391 * Create the input done list from the actual done head list. 1392 */ 1393 static void 1394 ohci_polled_create_input_list( 1395 ohci_polled_t *ohci_polledp, 1396 ohci_td_t *head_done_list) 1397 { 1398 ohci_state_t *ohcip = ohci_polledp->ohci_polled_ohcip; 1399 ohci_td_t *cpu_save, *td; 1400 1401 ASSERT(head_done_list != NULL); 1402 1403 /* Get the done head list */ 1404 td = (ohci_td_t *)head_done_list; 1405 1406 /* 1407 * Traverse the done list and create the input done list. 1408 */ 1409 while (td) { 1410 1411 /* 1412 * Convert the iommu pointer to a cpu pointer. No point 1413 * in doing this over and over, might as well do it once. 1414 */ 1415 cpu_save = ohci_td_iommu_to_cpu(ohcip, 1416 Get_TD(td->hctd_next_td)); 1417 1418 /* 1419 * Terminate this TD by setting its next pointer to NULL. 1420 */ 1421 Set_TD(td->hctd_next_td, NULL); 1422 1423 /* This is an input TD, so put it on the input done list */ 1424 if (ohci_polledp->ohci_polled_input_done_head == NULL) { 1425 1426 /* 1427 * There is nothing on the input done list, 1428 * so put this TD on the head. 1429 */ 1430 ohci_polledp->ohci_polled_input_done_head = td; 1431 } else { 1432 Set_TD(ohci_polledp-> 1433 ohci_polled_input_done_tail->hctd_next_td, 1434 ohci_td_cpu_to_iommu(ohcip, td)); 1435 } 1436 1437 /* The tail points to the new TD */ 1438 ohci_polledp->ohci_polled_input_done_tail = td; 1439 td = cpu_save; 1440 } 1441 } 1442 1443 1444 /* 1445 * ohci_polled_process_input_list: 1446 * 1447 * This routine takes the TD's off of the input done head and processes 1448 * them. It returns the number of characters that have been copied for 1449 * input. 1450 */ 1451 static int 1452 ohci_polled_process_input_list(ohci_polled_t *ohci_polledp) 1453 { 1454 ohci_state_t *ohcip = ohci_polledp->ohci_polled_ohcip; 1455 ohci_td_t *td, *next_td; 1456 uint_t ctrl; 1457 uint_t num_characters; 1458 ohci_trans_wrapper_t *tw; 1459 ohci_pipe_private_t *pp; 1460 1461 /* 1462 * Get the first TD on the input done head. 1463 */ 1464 td = ohci_polledp->ohci_polled_input_done_head; 1465 1466 ohci_polledp->ohci_polled_input_done_head = NULL; 1467 1468 num_characters = 0; 1469 1470 /* 1471 * Traverse the list of transfer descriptors. We can't destroy 1472 * hctd_next_td pointers of these TDs because we are using it 1473 * to traverse the done list. Therefore, we can not put these 1474 * TDs back on the ED until we are done processing all of them. 1475 */ 1476 while (td) { 1477 1478 /* Get the next TD from the input done list */ 1479 next_td = (ohci_td_t *) 1480 ohci_td_iommu_to_cpu(ohcip, Get_TD(td->hctd_next_td)); 1481 1482 /* Look at the status */ 1483 ctrl = (uint_t)Get_TD(td->hctd_ctrl) & (uint32_t)HC_TD_CC; 1484 1485 /* 1486 * Check to see if there is an error. If there is error 1487 * clear the halt condition in the Endpoint Descriptor 1488 * (ED) associated with this Transfer Descriptor (TD). 1489 */ 1490 if (ctrl != HC_TD_CC_NO_E) { 1491 /* Obtain the transfer wrapper from the TD */ 1492 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID( 1493 (uint32_t)Get_TD(td->hctd_trans_wrapper)); 1494 1495 /* Get the pipe handle for this transfer wrapper */ 1496 pp = tw->tw_pipe_private; 1497 1498 /* Clear the halt bit */ 1499 Set_ED(pp->pp_ept->hced_headp, 1500 (Get_ED(pp->pp_ept->hced_headp) & ~HC_EPT_Halt)); 1501 } else { 1502 num_characters += 1503 ohci_polled_handle_normal_td(ohci_polledp, td); 1504 } 1505 1506 /* Insert this interrupt TD back onto the ED's TD list */ 1507 ohci_polled_insert_td(ohcip, td); 1508 1509 td = next_td; 1510 } 1511 1512 return (num_characters); 1513 } 1514 1515 1516 /* 1517 * ohci_polled_handle_normal_td: 1518 */ 1519 static int 1520 ohci_polled_handle_normal_td( 1521 ohci_polled_t *ohci_polledp, 1522 ohci_td_t *td) 1523 { 1524 ohci_state_t *ohcip = ohci_polledp->ohci_polled_ohcip; 1525 uchar_t *buf; 1526 ohci_trans_wrapper_t *tw; 1527 size_t length, residue; 1528 1529 /* Obtain the transfer wrapper from the TD */ 1530 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID((uint32_t) 1531 Get_TD(td->hctd_trans_wrapper)); 1532 1533 ASSERT(tw != NULL); 1534 1535 buf = (uchar_t *)tw->tw_buf; 1536 1537 length = tw->tw_length; 1538 1539 /* 1540 * If "CurrentBufferPointer" of Transfer Descriptor (TD) is 1541 * not equal to zero, then we received less data from the 1542 * device than requested by us. In that case, get the actual 1543 * received data size. 1544 */ 1545 if (Get_TD(td->hctd_cbp)) { 1546 1547 residue = ohci_get_td_residue(ohcip, td); 1548 length = Get_TD(td->hctd_xfer_offs) + 1549 Get_TD(td->hctd_xfer_len) - residue; 1550 } 1551 1552 /* Sync IO buffer */ 1553 if (ohci_polledp->ohci_polled_no_sync_flag == B_FALSE) { 1554 Sync_IO_Buffer(tw->tw_dmahandle, length); 1555 } 1556 1557 /* Copy the data into the message */ 1558 ddi_rep_get8(tw->tw_accesshandle, 1559 (uint8_t *)ohci_polledp->ohci_polled_buf, 1560 (uint8_t *)buf, length, DDI_DEV_AUTOINCR); 1561 1562 return (length); 1563 } 1564 1565 1566 /* 1567 * ohci_polled_insert_td: 1568 * 1569 * Insert a Transfer Descriptor (TD) on an Endpoint Descriptor (ED). 1570 */ 1571 static void 1572 ohci_polled_insert_td( 1573 ohci_state_t *ohcip, 1574 ohci_td_t *td) 1575 { 1576 ohci_pipe_private_t *pp; 1577 ohci_ed_t *ept; 1578 uint_t td_control; 1579 ohci_trans_wrapper_t *tw; 1580 ohci_td_t *cpu_current_dummy; 1581 usb_intr_req_t *intr_req; 1582 1583 /* Obtain the transfer wrapper from the TD */ 1584 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID( 1585 (uint32_t)Get_TD(td->hctd_trans_wrapper)); 1586 1587 /* Ensure the DMA cookie is valid for reuse */ 1588 ASSERT((tw->tw_cookie_idx == 0) && (tw->tw_dma_offs == 0)); 1589 1590 /* 1591 * Take this TD off the transfer wrapper's list since 1592 * the pipe is FIFO, this must be the first TD on the 1593 * list. 1594 */ 1595 ASSERT((ohci_td_t *)tw->tw_hctd_head == td); 1596 1597 tw->tw_hctd_head = (ohci_td_t *) 1598 ohci_td_iommu_to_cpu(ohcip, Get_TD(td->hctd_tw_next_td)); 1599 1600 /* 1601 * If the head becomes NULL, then there are no more 1602 * active TD's for this transfer wrapper. Also set 1603 * the tail to NULL. 1604 */ 1605 if (tw->tw_hctd_head == NULL) { 1606 tw->tw_hctd_tail = NULL; 1607 } 1608 1609 /* Convert current valid TD as new dummy TD */ 1610 bzero((char *)td, sizeof (ohci_td_t)); 1611 Set_TD(td->hctd_state, HC_TD_DUMMY); 1612 1613 pp = tw->tw_pipe_private; 1614 1615 /* Obtain the endpoint and interrupt request */ 1616 ept = pp->pp_ept; 1617 1618 intr_req = (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 1619 1620 if (intr_req->intr_attributes & USB_ATTRS_SHORT_XFER_OK) { 1621 td_control = HC_TD_IN|HC_TD_1I|HC_TD_R; 1622 } else { 1623 td_control = HC_TD_IN|HC_TD_1I; 1624 } 1625 1626 /* Get the current dummy */ 1627 cpu_current_dummy = (ohci_td_t *) 1628 (ohci_td_iommu_to_cpu(ohcip, Get_ED(ept->hced_tailp))); 1629 1630 /* 1631 * Fill in the current dummy td and 1632 * add the new dummy to the end. 1633 */ 1634 ohci_polled_fill_in_td(ohcip, cpu_current_dummy, td, 1635 td_control, 0, tw->tw_length, tw); 1636 1637 /* Insert this td onto the tw */ 1638 ohci_polled_insert_td_on_tw(ohcip, tw, cpu_current_dummy); 1639 1640 /* 1641 * Add the new dummy to the ED's list. When this occurs, 1642 * the Host Controller will see the newly filled in dummy 1643 * TD. 1644 */ 1645 Set_ED(ept->hced_tailp, (ohci_td_cpu_to_iommu(ohcip, td))); 1646 } 1647 1648 1649 /* 1650 * ohci_polled_fill_in_td: 1651 * 1652 * Fill in the fields of a Transfer Descriptor (TD). 1653 */ 1654 static void 1655 ohci_polled_fill_in_td( 1656 ohci_state_t *ohcip, 1657 ohci_td_t *td, 1658 ohci_td_t *new_dummy, 1659 uint_t hctd_ctrl, 1660 uint32_t hctd_dma_offs, 1661 size_t hctd_length, 1662 ohci_trans_wrapper_t *tw) 1663 { 1664 /* Assert that the td to be filled in is a dummy */ 1665 ASSERT(Get_TD(td->hctd_state) == HC_TD_DUMMY); 1666 1667 /* Clear the TD */ 1668 bzero((char *)td, sizeof (ohci_td_t)); 1669 1670 /* Update the dummy with control information */ 1671 Set_TD(td->hctd_ctrl, (hctd_ctrl | HC_TD_CC_NA)); 1672 1673 /* Update the beginning and end of the buffer */ 1674 ohci_init_td(ohcip, tw, hctd_dma_offs, hctd_length, td); 1675 1676 /* The current dummy now points to the new dummy */ 1677 Set_TD(td->hctd_next_td, (ohci_td_cpu_to_iommu(ohcip, new_dummy))); 1678 1679 /* Fill in the wrapper portion of the TD */ 1680 Set_TD(td->hctd_trans_wrapper, (uint32_t)tw->tw_id); 1681 Set_TD(td->hctd_tw_next_td, NULL); 1682 } 1683 1684 1685 /* 1686 * ohci_polled_insert_td_on_tw: 1687 * 1688 * The transfer wrapper keeps a list of all Transfer Descriptors (TD) that 1689 * are allocated for this transfer. Insert a TD onto this list. The list 1690 * of TD's does not include the dummy TD that is at the end of the list of 1691 * TD's for the endpoint. 1692 */ 1693 static void 1694 ohci_polled_insert_td_on_tw( 1695 ohci_state_t *ohcip, 1696 ohci_trans_wrapper_t *tw, 1697 ohci_td_t *td) 1698 { 1699 1700 /* 1701 * Set the next pointer to NULL because 1702 * this is the last TD on list. 1703 */ 1704 Set_TD(td->hctd_tw_next_td, NULL); 1705 1706 if (tw->tw_hctd_head == NULL) { 1707 ASSERT(tw->tw_hctd_tail == NULL); 1708 tw->tw_hctd_head = td; 1709 tw->tw_hctd_tail = td; 1710 } else { 1711 ohci_td_t *dummy = (ohci_td_t *)tw->tw_hctd_tail; 1712 1713 ASSERT(dummy != NULL); 1714 ASSERT(dummy != td); 1715 ASSERT(Get_TD(td->hctd_state) == HC_TD_DUMMY); 1716 1717 /* Add the td to the end of the list */ 1718 Set_TD(dummy->hctd_tw_next_td, ohci_td_cpu_to_iommu(ohcip, td)); 1719 tw->tw_hctd_tail = td; 1720 1721 ASSERT(Get_TD(td->hctd_tw_next_td) == NULL); 1722 } 1723 } 1724 1725 1726 /* 1727 * ohci_polled_handle_frame_number_overflow: 1728 * 1729 * Process Frame Number Overflow (FNO) interrupt in polled mode. 1730 */ 1731 static void 1732 ohci_polled_handle_frame_number_overflow(ohci_state_t *ohcip) 1733 { 1734 uint_t intr; 1735 1736 /* Read the Interrupt Status & Interrupt enable register */ 1737 intr = (Get_OpReg(hcr_intr_status) & Get_OpReg(hcr_intr_enable)); 1738 1739 /* 1740 * Check whether any Frame Number Overflow interrupt is pending 1741 * and if it is pending, process this interrupt. 1742 */ 1743 if (intr & HCR_INTR_FNO) { 1744 ohci_handle_frame_number_overflow(ohcip); 1745 1746 /* Acknowledge the FNO interrupt */ 1747 ohci_polled_finish_interrupt(ohcip, HCR_INTR_FNO); 1748 } 1749 } 1750 1751 1752 /* 1753 * ohci_polled_finish_interrupt: 1754 */ 1755 static void 1756 ohci_polled_finish_interrupt( 1757 ohci_state_t *ohcip, 1758 uint_t intr) 1759 { 1760 /* Acknowledge the interrupt */ 1761 Set_OpReg(hcr_intr_status, intr); 1762 1763 /* 1764 * Read interrupt status register to make sure that any PIO 1765 * store to clear the ISR has made it on the PCI bus before 1766 * returning from its interrupt handler. 1767 */ 1768 (void) Get_OpReg(hcr_intr_status); 1769 } 1770