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