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