ehci_polled.c revision 7492:2387323b838f
113679Swosch/* 213679Swosch * CDDL HEADER START 313679Swosch * 413679Swosch * The contents of this file are subject to the terms of the 513679Swosch * Common Development and Distribution License (the "License"). 613679Swosch * You may not use this file except in compliance with the License. 713679Swosch * 813679Swosch * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 913679Swosch * or http://www.opensolaris.org/os/licensing. 1013679Swosch * See the License for the specific language governing permissions 1113679Swosch * and limitations under the License. 1213679Swosch * 1313679Swosch * When distributing Covered Code, include this CDDL HEADER in each 1413679Swosch * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1513679Swosch * If applicable, add the following below this CDDL HEADER, with the 1613679Swosch * fields enclosed by brackets "[]" replaced with your own identifying 1713679Swosch * information: Portions Copyright [yyyy] [name of copyright owner] 1813679Swosch * 1913679Swosch * CDDL HEADER END 2013679Swosch */ 2113679Swosch/* 2213679Swosch * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2313679Swosch * Use is subject to license terms. 2413679Swosch */ 2513679Swosch 2613679Swosch/* 2713679Swosch * EHCI Host Controller Driver (EHCI) 2813679Swosch * 2950476Speter * The EHCI driver is a software driver which interfaces to the Universal 3013679Swosch * Serial Bus layer (USBA) and the Host Controller (HC). The interface to 31169439Syar * the Host Controller is defined by the EHCI Host Controller Interface. 3213679Swosch * 3379530Sru * This module contains the specific EHCI code used in POLLED mode. This 3413679Swosch * code is in a separate file since it will never become part of the EHCI 3513679Swosch * driver. 3613679Swosch */ 3713679Swosch 3879754Sdd#include <sys/usb/usba/usbai_version.h> 3968640Snik#include <sys/usb/hcd/ehci/ehcid.h> 40169439Syar#include <sys/usb/hcd/ehci/ehci_xfer.h> 41169439Syar#include <sys/usb/hcd/ehci/ehci_intr.h> 42169439Syar#include <sys/usb/hcd/ehci/ehci_util.h> 43169439Syar#include <sys/usb/hcd/ehci/ehci_polled.h> 44169439Syar 45169439Syar/* 4668640Snik * Internal Function Prototypes 4768640Snik */ 4868640Snik 4968640Snik/* Polled initialization routines */ 5068640Snikstatic int ehci_polled_init( 5113679Swosch usba_pipe_handle_data_t *ph, 52169439Syar ehci_state_t *ehcip, 53169439Syar usb_console_info_impl_t *console_input_info); 54169439Syar 55169439Syar/* Polled deinitialization routines */ 56169439Syarstatic int ehci_polled_fini(ehci_polled_t *ehci_polledp); 57169439Syar 58169439Syar/* Polled save state routines */ 59169439Syarstatic void ehci_polled_save_state(ehci_polled_t *ehci_polledp); 60169439Syar 61169439Syar/* Polled restore state routines */ 62169439Syarstatic void ehci_polled_restore_state(ehci_polled_t *ehci_polledp); 63169439Syarstatic void ehci_polled_stop_processing( 64169439Syar ehci_polled_t *ehci_polledp); 65169439Syarstatic void ehci_polled_start_processing( 66169439Syar ehci_polled_t *ehci_polledp); 67169439Syar 68169439Syar/* Polled read routines */ 69169439Syarstatic int ehci_polled_process_active_intr_qtd_list( 70169439Syar ehci_polled_t *ehci_polledp); 71169439Syarstatic int ehci_polled_handle_normal_qtd( 72169439Syar ehci_polled_t *ehci_polledp, 73169439Syar ehci_qtd_t *qtd); 74169439Syarstatic void ehci_polled_insert_qtd( 75169439Syar ehci_polled_t *ehci_polledp, 76169439Syar ehci_qtd_t *qtd); 77169439Syarstatic void ehci_polled_fill_in_qtd( 78169439Syar ehci_state_t *ehcip, 79169439Syar ehci_qtd_t *qtd, 80169439Syar uint_t qtd_ctrl, 81169439Syar size_t qtd_dma_offs, 82169439Syar size_t qtd_length, 8313679Swosch ehci_trans_wrapper_t *tw); 84130420Srustatic void ehci_polled_insert_qtd_on_tw( 8542587Sasami ehci_state_t *ehcip, 86169439Syar ehci_trans_wrapper_t *tw, 87169439Syar ehci_qtd_t *qtd); 8813679Swoschstatic ehci_qtd_t *ehci_polled_create_done_qtd_list( 8913679Swosch ehci_polled_t *ehci_polledp); 9013679Swoschstatic void ehci_polled_insert_qtd_into_active_intr_qtd_list( 91169439Syar ehci_polled_t *ehci_polledp, 92169439Syar ehci_qtd_t *curr_qtd); 93169439Syarstatic void ehci_polled_remove_qtd_from_active_intr_qtd_list( 9443509Swosch ehci_polled_t *ehci_polledp, 95169439Syar ehci_qtd_t *curr_qtd); 9613679Swoschstatic void ehci_polled_traverse_qtds( 97 ehci_polled_t *ehci_polledp, 98 usba_pipe_handle_data_t *ph); 99static void ehci_polled_finish_interrupt( 100 ehci_state_t *ehcip, 101 uint_t intr); 102 103/* 104 * POLLED entry points 105 * 106 * These functions are entry points into the POLLED code. 107 */ 108 109/* 110 * ehci_hcdi_polled_input_init: 111 * 112 * This is the initialization routine for handling the USB keyboard 113 * in POLLED mode. This routine is not called from POLLED mode, so 114 * it is OK to acquire mutexes. 115 */ 116int 117ehci_hcdi_polled_input_init( 118 usba_pipe_handle_data_t *ph, 119 uchar_t **polled_buf, 120 usb_console_info_impl_t *console_input_info) 121{ 122 ehci_polled_t *ehci_polledp; 123 ehci_state_t *ehcip; 124 int ret; 125 126 ehcip = ehci_obtain_state(ph->p_usba_device->usb_root_hub_dip); 127 128 /* 129 * Grab the ehci_int_mutex so that things don't change on us 130 * if an interrupt comes in. 131 */ 132 mutex_enter(&ehcip->ehci_int_mutex); 133 134 ret = ehci_polled_init(ph, ehcip, console_input_info); 135 136 if (ret != USB_SUCCESS) { 137 138 /* Allow interrupts to continue */ 139 mutex_exit(&ehcip->ehci_int_mutex); 140 return (ret); 141 } 142 143 ehci_polledp = (ehci_polled_t *)console_input_info->uci_private; 144 145 /* 146 * Mark the structure so that if we are using it, we don't free 147 * the structures if one of them is unplugged. 148 */ 149 ehci_polledp->ehci_polled_flags |= POLLED_INPUT_MODE; 150 151 /* increase the counter for keyboard connected */ 152 ehcip->ehci_polled_kbd_count ++; 153 154 /* 155 * This is the buffer we will copy characters into. It will be 156 * copied into at this layer, so we need to keep track of it. 157 */ 158 ehci_polledp->ehci_polled_buf = 159 (uchar_t *)kmem_zalloc(POLLED_RAW_BUF_SIZE, KM_SLEEP); 160 161 *polled_buf = ehci_polledp->ehci_polled_buf; 162 163 /* 164 * This is a software workaround to fix schizo hardware bug. 165 * Existence of "no-prom-cdma-sync" property means consistent 166 * dma sync should not be done while in prom or polled mode. 167 */ 168 if (ddi_prop_exists(DDI_DEV_T_ANY, ehcip->ehci_dip, 169 DDI_PROP_NOTPROM, "no-prom-cdma-sync")) { 170 ehci_polledp->ehci_polled_no_sync_flag = B_TRUE; 171 } 172 173 /* Allow interrupts to continue */ 174 mutex_exit(&ehcip->ehci_int_mutex); 175 176 return (USB_SUCCESS); 177} 178 179 180/* 181 * ehci_hcdi_polled_input_fini: 182 */ 183int 184ehci_hcdi_polled_input_fini(usb_console_info_impl_t *info) 185{ 186 ehci_polled_t *ehci_polledp; 187 ehci_state_t *ehcip; 188 int ret; 189 190 ehci_polledp = (ehci_polled_t *)info->uci_private; 191 192 ehcip = ehci_polledp->ehci_polled_ehcip; 193 194 mutex_enter(&ehcip->ehci_int_mutex); 195 196 /* 197 * Reset the POLLED_INPUT_MODE flag so that we can tell if 198 * this structure is in use in the ehci_polled_fini routine. 199 */ 200 ehci_polledp->ehci_polled_flags &= ~POLLED_INPUT_MODE; 201 202 /* decrease the counter for keyboard disconnected */ 203 ehcip->ehci_polled_kbd_count --; 204 205 /* Free the buffer that we copied data into */ 206 kmem_free(ehci_polledp->ehci_polled_buf, POLLED_RAW_BUF_SIZE); 207 208 ret = ehci_polled_fini(ehci_polledp); 209 210 mutex_exit(&ehcip->ehci_int_mutex); 211 212 return (ret); 213} 214 215 216/* 217 * ehci_hcdi_polled_input_enter: 218 * 219 * This is where we enter into POLLED mode. This routine sets up 220 * everything so that calls to ehci_hcdi_polled_read will return 221 * characters. 222 */ 223int 224ehci_hcdi_polled_input_enter(usb_console_info_impl_t *info) 225{ 226 ehci_polled_t *ehci_polledp; 227 228 ehci_polledp = (ehci_polled_t *)info->uci_private; 229 230 ehci_polledp->ehci_polled_entry++; 231 232 /* 233 * If the controller is already switched over, just return 234 */ 235 if (ehci_polledp->ehci_polled_entry > 1) { 236 237 return (USB_SUCCESS); 238 } 239 240 ehci_polled_save_state(ehci_polledp); 241 242 ehci_polledp->ehci_polled_flags |= POLLED_INPUT_MODE_INUSE; 243 244 return (USB_SUCCESS); 245} 246 247 248/* 249 * ehci_hcdi_polled_input_exit: 250 * 251 * This is where we exit POLLED mode. This routine restores 252 * everything that is needed to continue operation. 253 */ 254int 255ehci_hcdi_polled_input_exit(usb_console_info_impl_t *info) 256{ 257 ehci_polled_t *ehci_polledp; 258 259 ehci_polledp = (ehci_polled_t *)info->uci_private; 260 261 ehci_polledp->ehci_polled_entry--; 262 263 /* 264 * If there are still outstanding "enters", just return 265 */ 266 if (ehci_polledp->ehci_polled_entry > 0) { 267 268 return (USB_SUCCESS); 269 } 270 271 ehci_polledp->ehci_polled_flags &= ~POLLED_INPUT_MODE_INUSE; 272 273 ehci_polled_restore_state(ehci_polledp); 274 275 return (USB_SUCCESS); 276} 277 278 279/* 280 * ehci_hcdi_polled_read: 281 * 282 * Get a key character 283 */ 284int 285ehci_hcdi_polled_read( 286 usb_console_info_impl_t *info, 287 uint_t *num_characters) 288{ 289 ehci_state_t *ehcip; 290 ehci_polled_t *ehci_polledp; 291 uint_t intr; 292 293 ehci_polledp = (ehci_polled_t *)info->uci_private; 294 295 ehcip = ehci_polledp->ehci_polled_ehcip; 296 297#ifndef lint 298 _NOTE(NO_COMPETING_THREADS_NOW); 299#endif 300 301 *num_characters = 0; 302 303 intr = ((Get_OpReg(ehci_status) & Get_OpReg(ehci_interrupt)) & 304 (EHCI_INTR_FRAME_LIST_ROLLOVER | 305 EHCI_INTR_USB | EHCI_INTR_USB_ERROR)); 306 307 /* 308 * Check whether any frame list rollover interrupt is pending 309 * and if it is pending, process this interrupt. 310 */ 311 if (intr & EHCI_INTR_FRAME_LIST_ROLLOVER) { 312 /* Check any frame list rollover interrupt is pending */ 313 ehci_handle_frame_list_rollover(ehcip); 314 ehci_polled_finish_interrupt(ehcip, 315 EHCI_INTR_FRAME_LIST_ROLLOVER); 316 } 317 318 /* Check for any USB transaction completion notification */ 319 if (intr & (EHCI_INTR_USB | EHCI_INTR_USB_ERROR)) { 320 ehcip->ehci_polled_read_count ++; 321 /* Process any QTD's on the active interrupt qtd list */ 322 *num_characters = 323 ehci_polled_process_active_intr_qtd_list(ehci_polledp); 324 325 if (ehcip->ehci_polled_read_count == 326 ehcip->ehci_polled_enter_count) { 327 /* Acknowledge the frame list rollover interrupt */ 328 ehci_polled_finish_interrupt(ehcip, 329 intr & (EHCI_INTR_USB | EHCI_INTR_USB_ERROR)); 330 ehcip->ehci_polled_read_count = 0; 331 } 332 } 333 334#ifndef lint 335 _NOTE(COMPETING_THREADS_NOW); 336#endif 337 338 return (USB_SUCCESS); 339} 340 341 342/* 343 * Internal Functions 344 */ 345 346/* 347 * Polled initialization routines 348 */ 349 350 351/* 352 * ehci_polled_init: 353 * 354 * Initialize generic information Uthat is needed to provide USB/POLLED 355 * support. 356 */ 357static int 358ehci_polled_init( 359 usba_pipe_handle_data_t *ph, 360 ehci_state_t *ehcip, 361 usb_console_info_impl_t *console_info) 362{ 363 ehci_polled_t *ehci_polledp; 364 ehci_pipe_private_t *pp; 365 ehci_qtd_t *qtd; 366 367 ASSERT(mutex_owned(&ehcip->ehci_int_mutex)); 368 369 /* 370 * We have already initialized this structure. If the structure 371 * has already been initialized, then we don't need to redo it. 372 */ 373 if (console_info->uci_private) { 374 375 return (USB_SUCCESS); 376 } 377 378 /* Allocate and intitialize a state structure */ 379 ehci_polledp = (ehci_polled_t *) 380 kmem_zalloc(sizeof (ehci_polled_t), KM_SLEEP); 381 382 console_info->uci_private = (usb_console_info_private_t)ehci_polledp; 383 384 /* 385 * Store away the ehcip so that we can get to it when we are in 386 * POLLED mode. We don't want to have to call ehci_obtain_state 387 * every time we want to access this structure. 388 */ 389 ehci_polledp->ehci_polled_ehcip = ehcip; 390 /* 391 * Save usb device and endpoint number information from the usb 392 * pipe handle. 393 */ 394 mutex_enter(&ph->p_mutex); 395 ehci_polledp->ehci_polled_usb_dev = ph->p_usba_device; 396 ehci_polledp->ehci_polled_ep_addr = ph->p_ep.bEndpointAddress; 397 mutex_exit(&ph->p_mutex); 398 399 /* 400 * Allocate memory to make duplicate of original usb pipe handle. 401 */ 402 ehci_polledp->ehci_polled_input_pipe_handle = 403 kmem_zalloc(sizeof (usba_pipe_handle_data_t), KM_SLEEP); 404 405 /* 406 * Copy the USB handle into the new pipe handle. Also 407 * create new lock for the new pipe handle. 408 */ 409 bcopy((void *)ph, 410 (void *)ehci_polledp->ehci_polled_input_pipe_handle, 411 sizeof (usba_pipe_handle_data_t)); 412 413 /* 414 * uint64_t typecast to make sure amd64 can compile 415 */ 416 mutex_init(&ehci_polledp->ehci_polled_input_pipe_handle->p_mutex, 417 NULL, MUTEX_DRIVER, DDI_INTR_PRI(ehcip->ehci_intr_pri)); 418 419 /* 420 * Create a new ehci pipe private structure 421 */ 422 pp = (ehci_pipe_private_t *) 423 kmem_zalloc(sizeof (ehci_pipe_private_t), KM_SLEEP); 424 425 /* 426 * Store the pointer in the pipe handle. This structure was also 427 * just allocated. 428 */ 429 mutex_enter(&ehci_polledp->ehci_polled_input_pipe_handle->p_mutex); 430 431 ehci_polledp->ehci_polled_input_pipe_handle-> 432 p_hcd_private = (usb_opaque_t)pp; 433 434 mutex_exit(&ehci_polledp->ehci_polled_input_pipe_handle->p_mutex); 435 436 /* 437 * Store a pointer to the pipe handle. This structure was just 438 * allocated and it is not in use yet. The locking is there to 439 * satisfy warlock. 440 */ 441 mutex_enter(&ph->p_mutex); 442 443 bcopy(&ph->p_policy, &pp->pp_policy, sizeof (usb_pipe_policy_t)); 444 445 mutex_exit(&ph->p_mutex); 446 447 pp->pp_pipe_handle = ehci_polledp->ehci_polled_input_pipe_handle; 448 449 /* 450 * Allocate a dummy for the interrupt table. This dummy will be 451 * put into the action when we switch interrupt tables during 452 * ehci_hcdi_polled_enter. Dummy is placed on the unused lattice 453 * entries. When the QH is allocated we will replace dummy QH by 454 * valid interrupt QH in one or more locations in the interrupt 455 * lattice depending on the requested polling interval. Also we 456 * will hang a dummy QTD to the QH & dummy QTD is used to indicate 457 * the end of the QTD chain. 458 */ 459 ehci_polledp->ehci_polled_dummy_qh = 460 ehci_alloc_qh(ehcip, NULL, EHCI_POLLED_MODE_FLAG); 461 462 if (ehci_polledp->ehci_polled_dummy_qh == NULL) { 463 464 return (USB_NO_RESOURCES); 465 } 466 467 /* 468 * Allocate the interrupt endpoint. This QH will be inserted in 469 * to the lattice chain for the keyboard device. This endpoint 470 * will have the QTDs hanging off of it for the processing. 471 */ 472 ehci_polledp->ehci_polled_qh = ehci_alloc_qh( 473 ehcip, ph, EHCI_POLLED_MODE_FLAG); 474 475 if (ehci_polledp->ehci_polled_qh == NULL) { 476 477 return (USB_NO_RESOURCES); 478 } 479 480 /* Set the state of pipe as idle */ 481 pp->pp_state = EHCI_PIPE_STATE_IDLE; 482 483 /* Set polled mode flag */ 484 pp->pp_flag = EHCI_POLLED_MODE_FLAG; 485 486 /* Insert the endpoint onto the pipe handle */ 487 pp->pp_qh = ehci_polledp->ehci_polled_qh; 488 489 /* 490 * Set soft interrupt handler flag in the normal mode usb 491 * pipe handle. 492 */ 493 mutex_enter(&ph->p_mutex); 494 ph->p_spec_flag |= USBA_PH_FLAG_USE_SOFT_INTR; 495 mutex_exit(&ph->p_mutex); 496 497 /* 498 * Insert a Interrupt polling request onto the endpoint. 499 * 500 * There will now be two QTDs on the QH, one is the dummy QTD that 501 * was allocated above in the ehci_alloc_qh and this new one. 502 */ 503 if ((ehci_start_periodic_pipe_polling(ehcip, 504 ehci_polledp->ehci_polled_input_pipe_handle, 505 NULL, USB_FLAGS_SLEEP)) != USB_SUCCESS) { 506 507 return (USB_NO_RESOURCES); 508 } 509 510 /* Get the given new interrupt qtd */ 511 qtd = (ehci_qtd_t *)(ehci_qtd_iommu_to_cpu(ehcip, 512 (Get_QH(pp->pp_qh->qh_next_qtd) & EHCI_QH_NEXT_QTD_PTR))); 513 514 /* Insert this qtd into active interrupt QTD list */ 515 ehci_polled_insert_qtd_into_active_intr_qtd_list(ehci_polledp, qtd); 516 517 return (USB_SUCCESS); 518} 519 520 521/* 522 * Polled deinitialization routines 523 */ 524 525 526/* 527 * ehci_polled_fini: 528 */ 529static int 530ehci_polled_fini(ehci_polled_t *ehci_polledp) 531{ 532 ehci_state_t *ehcip = ehci_polledp->ehci_polled_ehcip; 533 ehci_pipe_private_t *pp; 534 535 ASSERT(mutex_owned(&ehcip->ehci_int_mutex)); 536 537 /* If the structure is already in use, then don't free it */ 538 if (ehci_polledp->ehci_polled_flags & POLLED_INPUT_MODE) { 539 540 return (USB_SUCCESS); 541 } 542 543 pp = (ehci_pipe_private_t *) 544 ehci_polledp->ehci_polled_input_pipe_handle->p_hcd_private; 545 546 /* Deallocate all the pre-allocated interrupt requests */ 547 ehci_handle_outstanding_requests(ehcip, pp); 548 549 /* 550 * Traverse the list of QTD's on this endpoint and these QTD's 551 * have outstanding transfer requests. Since list processing 552 * is stopped, these QTDs can be deallocated. 553 */ 554 ehci_polled_traverse_qtds(ehci_polledp, pp->pp_pipe_handle); 555 556 /* Free DMA resources */ 557 ehci_free_dma_resources(ehcip, pp->pp_pipe_handle); 558 559 /* 560 * Deallocate the endpoint descriptors that we allocated 561 * with ehci_alloc_qh. 562 */ 563 if (ehci_polledp->ehci_polled_dummy_qh) { 564 ehci_deallocate_qh(ehcip, ehci_polledp->ehci_polled_dummy_qh); 565 } 566 567 if (ehci_polledp->ehci_polled_qh) { 568 ehci_deallocate_qh(ehcip, ehci_polledp->ehci_polled_qh); 569 } 570 571 mutex_destroy(&ehci_polledp->ehci_polled_input_pipe_handle->p_mutex); 572 573 /* 574 * Destroy everything about the pipe that we allocated in 575 * ehci_polled_duplicate_pipe_handle 576 */ 577 kmem_free(pp, sizeof (ehci_pipe_private_t)); 578 579 kmem_free(ehci_polledp->ehci_polled_input_pipe_handle, 580 sizeof (usba_pipe_handle_data_t)); 581 582 /* 583 * We use this field to determine if a QTD is for input or not, 584 * so NULL the pointer so we don't check deallocated data. 585 */ 586 ehci_polledp->ehci_polled_input_pipe_handle = NULL; 587 588 /* 589 * Finally, free off the structure that we use to keep track 590 * of all this. 591 */ 592 kmem_free(ehci_polledp, sizeof (ehci_polled_t)); 593 594 return (USB_SUCCESS); 595} 596 597 598/* 599 * Polled save state routines 600 */ 601 602 603/* 604 * ehci_polled_save_state: 605 */ 606static void 607ehci_polled_save_state(ehci_polled_t *ehci_polledp) 608{ 609 int i; 610 ehci_state_t *ehcip; 611 uint_t polled_toggle; 612 uint_t real_toggle; 613 ehci_pipe_private_t *pp = NULL; /* Normal mode Pipe */ 614 ehci_pipe_private_t *polled_pp; /* Polled mode Pipe */ 615 usba_pipe_handle_data_t *ph; 616 uint8_t ep_addr; 617 ehci_regs_t *ehci_polled_regsp; 618 ehci_qh_t *qh; 619 620#ifndef lint 621 _NOTE(NO_COMPETING_THREADS_NOW); 622#endif 623 624 /* 625 * If either of these two flags are set, then we have already 626 * saved off the state information and setup the controller. 627 */ 628 if (ehci_polledp->ehci_polled_flags & POLLED_INPUT_MODE_INUSE) { 629#ifndef lint 630 _NOTE(COMPETING_THREADS_NOW); 631#endif 632 return; 633 } 634 635 ehcip = ehci_polledp->ehci_polled_ehcip; 636 637 /* 638 * Check if the number of keyboard reach the max number we can 639 * support in polled mode 640 */ 641 if (++ ehcip->ehci_polled_enter_count > MAX_NUM_FOR_KEYBOARD) { 642#ifndef lint 643 _NOTE(COMPETING_THREADS_NOW); 644#endif 645 return; 646 } 647 ehci_polled_regsp = &ehcip->ehci_polled_save_regs; 648 649 /* Get the endpoint addr. */ 650 ep_addr = ehci_polledp->ehci_polled_ep_addr; 651 652 /* Get the normal mode usb pipe handle */ 653 ph = usba_hcdi_get_ph_data(ehci_polledp->ehci_polled_usb_dev, ep_addr); 654 655 /* 656 * The first enter keyboard entry should save info of the normal mode, 657 * disable all list processing and interrupt, initialize the 658 * frame list table with dummy QHs. 659 */ 660 if (ehcip->ehci_polled_enter_count == 1) { 661 /* 662 * Save the current normal mode ehci registers and later this 663 * saved register copy is used to replace some of required ehci 664 * registers before switching from polled mode to normal mode. 665 */ 666 667 bzero((void *)ehci_polled_regsp, sizeof (ehci_regs_t)); 668 669 /* Save current ehci registers */ 670 ehci_polled_regsp->ehci_command = Get_OpReg(ehci_command); 671 ehci_polled_regsp->ehci_interrupt = Get_OpReg(ehci_interrupt); 672 ehci_polled_regsp->ehci_ctrl_segment = 673 Get_OpReg(ehci_ctrl_segment); 674 ehci_polled_regsp-> 675 ehci_async_list_addr = Get_OpReg(ehci_async_list_addr); 676 ehci_polled_regsp->ehci_config_flag = 677 Get_OpReg(ehci_config_flag); 678 ehci_polled_regsp->ehci_periodic_list_base = 679 Get_OpReg(ehci_periodic_list_base); 680 681 /* Disable all list processing and interrupts */ 682 Set_OpReg(ehci_command, Get_OpReg(ehci_command) & 683 ~(EHCI_CMD_ASYNC_SCHED_ENABLE | 684 EHCI_CMD_PERIODIC_SCHED_ENABLE)); 685 686 /* Wait for few milliseconds */ 687 drv_usecwait(EHCI_POLLED_TIMEWAIT); 688 689 /* Save any unprocessed normal mode ehci interrupts */ 690 ehcip->ehci_missed_intr_sts = EHCI_INTR_USB; 691 692 /* 693 * Save the current interrupt lattice and replace this lattice 694 * with an lattice used in POLLED mode. We will restore lattice 695 * back when we exit from the POLLED mode. 696 */ 697 for (i = 0; i < EHCI_NUM_PERIODIC_FRAME_LISTS; i++) { 698 ehcip->ehci_polled_frame_list_table[i] = 699 (ehci_qh_t *)(uintptr_t)Get_PFLT(ehcip-> 700 ehci_periodic_frame_list_tablep-> 701 ehci_periodic_frame_list_table[i]); 702 } 703 704 /* 705 * Fill in the lattice with dummy QHs. These QHs are used so the 706 * controller can tell that it is at the end of the QH list. 707 */ 708 for (i = 0; i < EHCI_NUM_PERIODIC_FRAME_LISTS; i++) { 709 Set_PFLT(ehcip->ehci_periodic_frame_list_tablep-> 710 ehci_periodic_frame_list_table[i], 711 ehci_qh_cpu_to_iommu(ehcip, 712 ehci_polledp->ehci_polled_dummy_qh) | 713 (EHCI_QH_LINK_REF_QH | EHCI_QH_LINK_PTR_VALID)); 714 } 715 716 } 717 718 /* Get the polled mode ehci pipe private structure */ 719 polled_pp = (ehci_pipe_private_t *) 720 ehci_polledp->ehci_polled_input_pipe_handle->p_hcd_private; 721 722 /* 723 * Before replacing the lattice, adjust the data togggle on the 724 * on the ehci's interrupt ed 725 */ 726 polled_toggle = (Get_QH(polled_pp->pp_qh->qh_status) & 727 EHCI_QH_STS_DATA_TOGGLE) ? DATA1:DATA0; 728 729 /* 730 * If normal mode interrupt pipe endpoint is active, get the data 731 * toggle from the this interrupt endpoint through the corresponding 732 * interrupt pipe handle. Else get the data toggle information from 733 * the usb device structure and this information is saved during the 734 * normal mode interrupt pipe close. Use this data toggle information 735 * to fix the data toggle of polled mode interrupt endpoint. 736 */ 737 if (ph) { 738 /* Get the normal mode ehci pipe private structure */ 739 pp = (ehci_pipe_private_t *)ph->p_hcd_private; 740 741 real_toggle = (Get_QH(pp->pp_qh->qh_status) & 742 EHCI_QH_STS_DATA_TOGGLE) ? DATA1:DATA0; 743 } else { 744 real_toggle = usba_hcdi_get_data_toggle( 745 ehci_polledp->ehci_polled_usb_dev, ep_addr); 746 } 747 748 if (polled_toggle != real_toggle) { 749 if (real_toggle == DATA0) { 750 Set_QH(polled_pp->pp_qh->qh_status, 751 Get_QH(polled_pp->pp_qh->qh_status) & 752 ~EHCI_QH_STS_DATA_TOGGLE); 753 } else { 754 Set_QH(polled_pp->pp_qh->qh_status, 755 Get_QH(polled_pp->pp_qh->qh_status) | 756 EHCI_QH_STS_DATA_TOGGLE); 757 } 758 } 759 760 /* 761 * Check whether Halt bit is set in the QH and if so clear the 762 * halt bit. 763 */ 764 if (polled_pp->pp_qh->qh_status & EHCI_QH_STS_HALTED) { 765 766 /* Clear the halt bit */ 767 Set_QH(polled_pp->pp_qh->qh_status, 768 (Get_QH(polled_pp->pp_qh->qh_status) & 769 ~EHCI_QH_STS_HALTED)); 770 } 771 772 /* 773 * Initialize the qh overlay area 774 */ 775 qh = ehci_polledp->ehci_polled_qh; 776 for (i = 0; i < 5; i++) { 777 Set_QH(qh->qh_buf[i], NULL); 778 Set_QH(qh->qh_buf_high[i], NULL); 779 } 780 Set_QH(qh->qh_next_qtd, ehci_qtd_cpu_to_iommu(ehcip, 781 ehci_polledp->ehci_polled_active_intr_qtd_list)); 782 783 /* 784 * Now, add the endpoint to the lattice that we will hang our 785 * QTD's off of. We need to poll this device at every 8 ms and 786 * hence add this QH needs 4 entries in interrupt lattice. 787 */ 788 for (i = ehcip->ehci_polled_enter_count - 1; 789 i < EHCI_NUM_PERIODIC_FRAME_LISTS; 790 i = i + LS_MIN_POLL_INTERVAL) { 791 Set_PFLT(ehcip->ehci_periodic_frame_list_tablep-> 792 ehci_periodic_frame_list_table[i], 793 ehci_qh_cpu_to_iommu(ehcip, 794 ehci_polledp->ehci_polled_qh) | EHCI_QH_LINK_REF_QH); 795 } 796 /* The first enter keyboard entry enable interrupts and periodic list */ 797 if (ehcip->ehci_polled_enter_count == 1) { 798 /* Enable USB and Frame list rollover interrupts */ 799 Set_OpReg(ehci_interrupt, (EHCI_INTR_USB | 800 EHCI_INTR_USB_ERROR | EHCI_INTR_FRAME_LIST_ROLLOVER)); 801 802 /* Enable the periodic list */ 803 Set_OpReg(ehci_command, 804 (Get_OpReg(ehci_command) | EHCI_CMD_PERIODIC_SCHED_ENABLE)); 805 806 /* Wait for few milliseconds */ 807 drv_usecwait(EHCI_POLLED_TIMEWAIT); 808 } 809#ifndef lint 810 _NOTE(COMPETING_THREADS_NOW); 811#endif 812} 813 814 815/* 816 * Polled restore state routines 817 */ 818 819 820/* 821 * ehci_polled_restore_state: 822 */ 823static void 824ehci_polled_restore_state(ehci_polled_t *ehci_polledp) 825{ 826 ehci_state_t *ehcip; 827 int i; 828 uint_t polled_toggle; 829 uint_t real_toggle; 830 ehci_pipe_private_t *pp = NULL; /* Normal mode Pipe */ 831 ehci_pipe_private_t *polled_pp; /* Polled mode Pipe */ 832 usba_pipe_handle_data_t *ph; 833 uint8_t ep_addr; 834 835#ifndef lint 836 _NOTE(NO_COMPETING_THREADS_NOW); 837#endif 838 839 /* 840 * If this flag is set, then we are still using this structure, 841 * so don't restore any controller state information yet. 842 */ 843 if (ehci_polledp->ehci_polled_flags & POLLED_INPUT_MODE_INUSE) { 844 845#ifndef lint 846 _NOTE(COMPETING_THREADS_NOW); 847#endif 848 849 return; 850 } 851 852 ehcip = ehci_polledp->ehci_polled_ehcip; 853 ehcip->ehci_polled_enter_count --; 854 855 /* Get the endpoint addr */ 856 ep_addr = ehci_polledp->ehci_polled_ep_addr; 857 858 /* Get the normal mode usb pipe handle */ 859 ph = usba_hcdi_get_ph_data(ehci_polledp->ehci_polled_usb_dev, ep_addr); 860 861 /* Disable list processing and other things */ 862 ehci_polled_stop_processing(ehci_polledp); 863 864 /* Get the polled mode ehci pipe private structure */ 865 polled_pp = (ehci_pipe_private_t *) 866 ehci_polledp->ehci_polled_input_pipe_handle->p_hcd_private; 867 868 /* 869 * Before replacing the lattice, adjust the data togggle 870 * on the on the ehci's interrupt ed 871 */ 872 polled_toggle = (Get_QH(polled_pp->pp_qh->qh_status) & 873 EHCI_QH_STS_DATA_TOGGLE) ? DATA1:DATA0; 874 875 /* 876 * If normal mode interrupt pipe endpoint is active, fix the 877 * data toggle for this interrupt endpoint by getting the data 878 * toggle information from the polled interrupt endpoint. Else 879 * save the data toggle information in usb device structure. 880 */ 881 if (ph) { 882 /* Get the normal mode ehci pipe private structure */ 883 pp = (ehci_pipe_private_t *)ph->p_hcd_private; 884 885 real_toggle = (Get_QH(pp->pp_qh->qh_status) & 886 EHCI_QH_STS_DATA_TOGGLE) ? DATA1:DATA0; 887 888 if (polled_toggle != real_toggle) { 889 if (polled_toggle == DATA0) { 890 Set_QH(pp->pp_qh->qh_status, 891 Get_QH(pp->pp_qh->qh_status) & 892 ~EHCI_QH_STS_DATA_TOGGLE); 893 } else { 894 Set_QH(pp->pp_qh->qh_status, 895 Get_QH(pp->pp_qh->qh_status) | 896 EHCI_QH_STS_DATA_TOGGLE); 897 } 898 } 899 } else { 900 usba_hcdi_set_data_toggle(ehci_polledp->ehci_polled_usb_dev, 901 ep_addr, polled_toggle); 902 } 903 904 /* 905 * Only the last leave keyboard entry restore the save frame 906 * list table and start processing. 907 */ 908 if (ehcip->ehci_polled_enter_count == 0) { 909 910 /* Replace the lattice */ 911 for (i = 0; i < EHCI_NUM_PERIODIC_FRAME_LISTS; i++) { 912 Set_PFLT(ehcip->ehci_periodic_frame_list_tablep-> 913 ehci_periodic_frame_list_table[i], 914 ehcip->ehci_polled_frame_list_table[i]); 915 } 916 ehci_polled_start_processing(ehci_polledp); 917 } 918 919#ifndef lint 920 _NOTE(COMPETING_THREADS_NOW); 921#endif 922} 923 924 925/* 926 * ehci_polled_stop_processing: 927 */ 928static void 929ehci_polled_stop_processing(ehci_polled_t *ehci_polledp) 930{ 931 ehci_state_t *ehcip; 932 ehci_qh_t *qh = ehci_polledp->ehci_polled_qh; 933 934 ehcip = ehci_polledp->ehci_polled_ehcip; 935 936 /* First inactive this QH */ 937 Set_QH(qh->qh_ctrl, 938 Get_QH(qh->qh_ctrl) | EHCI_QH_CTRL_ED_INACTIVATE); 939 940 /* Only first leave keyboard entry turn off periodic list processing */ 941 if (Get_OpReg(ehci_command) & EHCI_CMD_PERIODIC_SCHED_ENABLE) { 942 Set_OpReg(ehci_command, (Get_OpReg(ehci_command) & 943 ~EHCI_CMD_PERIODIC_SCHED_ENABLE)); 944 945 /* Wait for few milliseconds */ 946 drv_usecwait(EHCI_POLLED_TIMEWAIT); 947 } 948 /* 949 * Now clear all required fields of QH 950 * including inactive bit. 951 */ 952 Set_QH(qh->qh_ctrl, 953 Get_QH(qh->qh_ctrl) & ~(EHCI_QH_CTRL_ED_INACTIVATE)); 954 Set_QH(qh->qh_status, 955 Get_QH(qh->qh_status) & ~(EHCI_QH_STS_XACT_STATUS)); 956 Set_QH(qh->qh_curr_qtd, NULL); 957 Set_QH(qh->qh_alt_next_qtd, EHCI_QH_ALT_NEXT_QTD_PTR_VALID); 958 959 /* 960 * Now look up at the QTD's that are in the active qtd list & 961 * re-insert them back into the QH's QTD list. 962 */ 963 (void) ehci_polled_process_active_intr_qtd_list(ehci_polledp); 964} 965 966 967/* 968 * ehci_polled_start_processing: 969 */ 970static void 971ehci_polled_start_processing(ehci_polled_t *ehci_polledp) 972{ 973 ehci_state_t *ehcip; 974 uint32_t mask; 975 ehci_regs_t *ehci_polled_regsp; 976 977 ehcip = ehci_polledp->ehci_polled_ehcip; 978 ehci_polled_regsp = &ehcip->ehci_polled_save_regs; 979 980 mask = ((uint32_t)ehci_polled_regsp->ehci_interrupt & 981 (EHCI_INTR_HOST_SYSTEM_ERROR | EHCI_INTR_FRAME_LIST_ROLLOVER | 982 EHCI_INTR_USB_ERROR | EHCI_INTR_USB | EHCI_INTR_ASYNC_ADVANCE)); 983 984 /* Enable all required EHCI interrupts */ 985 Set_OpReg(ehci_interrupt, mask); 986 987 mask = ((uint32_t)ehci_polled_regsp->ehci_command & 988 (EHCI_CMD_ASYNC_SCHED_ENABLE | EHCI_CMD_PERIODIC_SCHED_ENABLE)); 989 990 /* Enable all reuired list processing */ 991 Set_OpReg(ehci_command, (Get_OpReg(ehci_command) | mask)); 992 993 /* Wait for few milliseconds */ 994 drv_usecwait(EHCI_POLLED_TIMEWAIT); 995} 996 997 998/* 999 * Polled read routines 1000 */ 1001 1002 1003/* 1004 * ehci_polled_process_active_intr_qtd_list: 1005 * 1006 * This routine takes the QTD's off of the input done head and processes 1007 * them. It returns the number of characters that have been copied for 1008 * input. 1009 */ 1010static int 1011ehci_polled_process_active_intr_qtd_list(ehci_polled_t *ehci_polledp) 1012{ 1013 ehci_state_t *ehcip = ehci_polledp->ehci_polled_ehcip; 1014 ehci_qtd_t *qtd, *next_qtd; 1015 uint_t num_characters = 0; 1016 uint_t ctrl; 1017 ehci_trans_wrapper_t *tw; 1018 ehci_pipe_private_t *pp; 1019 usb_cr_t error; 1020 1021 /* Sync QH and QTD pool */ 1022 if (ehci_polledp->ehci_polled_no_sync_flag == B_FALSE) { 1023 Sync_QH_QTD_Pool(ehcip); 1024 } 1025 1026 /* Create done qtd list */ 1027 qtd = ehci_polled_create_done_qtd_list(ehci_polledp); 1028 1029 /* 1030 * Traverse the list of transfer descriptors. We can't destroy 1031 * the qtd_next pointers of these QTDs because we are using it 1032 * to traverse the done list. Therefore, we can not put these 1033 * QTD's back on the QH until we are done processing all of them. 1034 */ 1035 while (qtd) { 1036 /* Get next active QTD from the active QTD list */ 1037 next_qtd = ehci_qtd_iommu_to_cpu(ehcip, 1038 Get_QTD(qtd->qtd_active_qtd_next)); 1039 1040 /* Obtain the transfer wrapper from the QTD */ 1041 tw = (ehci_trans_wrapper_t *)EHCI_LOOKUP_ID( 1042 (uint32_t)Get_QTD(qtd->qtd_trans_wrapper)); 1043 1044 /* Get ohci pipe from transfer wrapper */ 1045 pp = tw->tw_pipe_private; 1046 1047 /* Look at the status */ 1048 ctrl = (uint_t)Get_QTD(qtd->qtd_ctrl) & 1049 (uint32_t)EHCI_QTD_CTRL_XACT_STATUS; 1050 1051 error = ehci_check_for_error(ehcip, pp, tw, qtd, ctrl); 1052 1053 /* 1054 * Check to see if there is an error. If there is error 1055 * clear the halt condition in the Endpoint Descriptor 1056 * (QH) associated with this Transfer Descriptor (QTD). 1057 */ 1058 if (error == USB_CR_OK) { 1059 num_characters += 1060 ehci_polled_handle_normal_qtd(ehci_polledp, qtd); 1061 } else { 1062 /* Clear the halt bit */ 1063 Set_QH(pp->pp_qh->qh_status, 1064 Get_QH(pp->pp_qh->qh_status) & 1065 ~(EHCI_QH_STS_XACT_STATUS)); 1066 } 1067 1068 /* Insert this qtd back into QH's qtd list */ 1069 ehci_polled_insert_qtd(ehci_polledp, qtd); 1070 1071 qtd = next_qtd; 1072 } 1073 1074 return (num_characters); 1075} 1076 1077 1078/* 1079 * ehci_polled_handle_normal_qtd: 1080 */ 1081static int 1082ehci_polled_handle_normal_qtd( 1083 ehci_polled_t *ehci_polledp, 1084 ehci_qtd_t *qtd) 1085{ 1086 ehci_state_t *ehcip = ehci_polledp->ehci_polled_ehcip; 1087 uchar_t *buf; 1088 ehci_trans_wrapper_t *tw; 1089 size_t length; 1090 uint32_t residue; 1091 1092 /* Obtain the transfer wrapper from the QTD */ 1093 tw = (ehci_trans_wrapper_t *)EHCI_LOOKUP_ID((uint32_t) 1094 Get_QTD(qtd->qtd_trans_wrapper)); 1095 1096 ASSERT(tw != NULL); 1097 1098 buf = (uchar_t *)tw->tw_buf; 1099 1100 length = tw->tw_length; 1101 1102 /* 1103 * If "Total bytes of xfer" in control field of qtd is not equal to 0, 1104 * then we received less data from the usb device than requested by us. 1105 * In that case, get the actual received data size. 1106 */ 1107 residue = ((Get_QTD(qtd->qtd_ctrl) & 1108 EHCI_QTD_CTRL_BYTES_TO_XFER) >> EHCI_QTD_CTRL_BYTES_TO_XFER_SHIFT); 1109 1110 if (residue) { 1111 1112 length = Get_QTD(qtd->qtd_xfer_offs) + 1113 Get_QTD(qtd->qtd_xfer_len) - residue; 1114 } 1115 1116 /* Sync IO buffer */ 1117 if (ehci_polledp->ehci_polled_no_sync_flag == B_FALSE) { 1118 Sync_IO_Buffer(tw->tw_dmahandle, length); 1119 } 1120 1121 /* Copy the data into the message */ 1122 bcopy(buf, ehci_polledp->ehci_polled_buf, length); 1123 1124 return ((int)length); 1125} 1126 1127 1128/* 1129 * ehci_polled_insert_qtd: 1130 * 1131 * Insert a Transfer Descriptor (QTD) on an Endpoint Descriptor (QH). 1132 */ 1133static void 1134ehci_polled_insert_qtd( 1135 ehci_polled_t *ehci_polledp, 1136 ehci_qtd_t *qtd) 1137{ 1138 ehci_state_t *ehcip = ehci_polledp->ehci_polled_ehcip; 1139 ehci_qtd_t *curr_dummy_qtd, *next_dummy_qtd; 1140 ehci_qtd_t *new_dummy_qtd; 1141 uint_t qtd_control; 1142 ehci_pipe_private_t *pp; 1143 ehci_qh_t *qh; 1144 ehci_trans_wrapper_t *tw; 1145 1146 /* Obtain the transfer wrapper from the QTD */ 1147 tw = (ehci_trans_wrapper_t *)EHCI_LOOKUP_ID( 1148 (uint32_t)Get_QTD(qtd->qtd_trans_wrapper)); 1149 1150 pp = tw->tw_pipe_private; 1151 1152 /* Obtain the endpoint and interrupt request */ 1153 qh = pp->pp_qh; 1154 1155 /* 1156 * Take this QTD off the transfer wrapper's list since 1157 * the pipe is FIFO, this must be the first QTD on the 1158 * list. 1159 */ 1160 ASSERT((ehci_qtd_t *)tw->tw_qtd_head == qtd); 1161 1162 tw->tw_qtd_head = (ehci_qtd_t *) 1163 ehci_qtd_iommu_to_cpu(ehcip, Get_QTD(qtd->qtd_tw_next_qtd)); 1164 1165 /* 1166 * If the head becomes NULL, then there are no more 1167 * active QTD's for this transfer wrapper. Also set 1168 * the tail to NULL. 1169 */ 1170 if (tw->tw_qtd_head == NULL) { 1171 tw->tw_qtd_tail = NULL; 1172 } 1173 1174 /* Convert current valid QTD as new dummy QTD */ 1175 bzero((char *)qtd, sizeof (ehci_qtd_t)); 1176 Set_QTD(qtd->qtd_state, EHCI_QTD_DUMMY); 1177 1178 /* Rename qtd as new_dummy_qtd */ 1179 new_dummy_qtd = qtd; 1180 1181 /* Get the current and next dummy QTDs */ 1182 curr_dummy_qtd = ehci_qtd_iommu_to_cpu(ehcip, 1183 Get_QH(qh->qh_dummy_qtd)); 1184 next_dummy_qtd = ehci_qtd_iommu_to_cpu(ehcip, 1185 Get_QTD(curr_dummy_qtd->qtd_next_qtd)); 1186 1187 /* Update QH's dummy qtd field */ 1188 Set_QH(qh->qh_dummy_qtd, ehci_qtd_cpu_to_iommu(ehcip, next_dummy_qtd)); 1189 1190 /* Update next dummy's next qtd pointer */ 1191 Set_QTD(next_dummy_qtd->qtd_next_qtd, 1192 ehci_qtd_cpu_to_iommu(ehcip, new_dummy_qtd)); 1193 1194 qtd_control = (tw->tw_direction | EHCI_QTD_CTRL_INTR_ON_COMPLETE); 1195 1196 /* 1197 * Fill in the current dummy qtd and 1198 * add the new dummy to the end. 1199 */ 1200 ehci_polled_fill_in_qtd(ehcip, curr_dummy_qtd, qtd_control, 1201 0, tw->tw_length, tw); 1202 1203 /* Insert this qtd onto the tw */ 1204 ehci_polled_insert_qtd_on_tw(ehcip, tw, curr_dummy_qtd); 1205 1206 /* Insert this qtd into active interrupt QTD list */ 1207 ehci_polled_insert_qtd_into_active_intr_qtd_list( 1208 ehci_polledp, curr_dummy_qtd); 1209} 1210 1211 1212/* 1213 * ehci_polled_fill_in_qtd: 1214 * 1215 * Fill in the fields of a Transfer Descriptor (QTD). 1216 * The "Buffer Pointer" fields of a QTD are retrieved from the TW 1217 * it is associated with. 1218 * 1219 * Unlike the it's ehci_fill_in_qtd counterpart, we do not 1220 * set the alternative ptr in polled mode. There is not need 1221 * for it in polled mode, because it doesn't need to cleanup 1222 * short xfer conditions. 1223 * 1224 * Note: 1225 * qtd_dma_offs - the starting offset into the TW buffer, where the QTD 1226 * should transfer from. It should be 4K aligned. And when 1227 * a TW has more than one QTDs, the QTDs must be filled in 1228 * increasing order. 1229 * qtd_length - the total bytes to transfer. 1230 */ 1231static void 1232ehci_polled_fill_in_qtd( 1233 ehci_state_t *ehcip, 1234 ehci_qtd_t *qtd, 1235 uint_t qtd_ctrl, 1236 size_t qtd_dma_offs, 1237 size_t qtd_length, 1238 ehci_trans_wrapper_t *tw) 1239{ 1240 uint32_t buf_addr; 1241 size_t buf_len = qtd_length; 1242 uint32_t ctrl = qtd_ctrl; 1243 uint_t i = 0; 1244 int rem_len; 1245 1246 /* Assert that the qtd to be filled in is a dummy */ 1247 ASSERT(Get_QTD(qtd->qtd_state) == EHCI_QTD_DUMMY); 1248 1249 /* Change QTD's state Active */ 1250 Set_QTD(qtd->qtd_state, EHCI_QTD_ACTIVE); 1251 1252 /* Set the total length data tarnsfer */ 1253 ctrl |= (((qtd_length << EHCI_QTD_CTRL_BYTES_TO_XFER_SHIFT) 1254 & EHCI_QTD_CTRL_BYTES_TO_XFER) | EHCI_QTD_CTRL_MAX_ERR_COUNTS); 1255 1256 /* 1257 * QTDs must be filled in increasing DMA offset order. 1258 * tw_dma_offs is initialized to be 0 at TW creation and 1259 * is only increased in this function. 1260 */ 1261 ASSERT(buf_len == 0 || qtd_dma_offs >= tw->tw_dma_offs); 1262 1263 /* 1264 * Save the starting dma buffer offset used and 1265 * length of data that will be transfered in 1266 * the current QTD. 1267 */ 1268 Set_QTD(qtd->qtd_xfer_offs, qtd_dma_offs); 1269 Set_QTD(qtd->qtd_xfer_len, buf_len); 1270 1271 while (buf_len) { 1272 /* 1273 * Advance to the next DMA cookie until finding the cookie 1274 * that qtd_dma_offs falls in. 1275 * It is very likely this loop will never repeat more than 1276 * once. It is here just to accommodate the case qtd_dma_offs 1277 * is increased by multiple cookies during two consecutive 1278 * calls into this function. In that case, the interim DMA 1279 * buffer is allowed to be skipped. 1280 */ 1281 while ((tw->tw_dma_offs + tw->tw_cookie.dmac_size) <= 1282 qtd_dma_offs) { 1283 /* 1284 * tw_dma_offs always points to the starting offset 1285 * of a cookie 1286 */ 1287 tw->tw_dma_offs += tw->tw_cookie.dmac_size; 1288 ddi_dma_nextcookie(tw->tw_dmahandle, &tw->tw_cookie); 1289 tw->tw_cookie_idx++; 1290 ASSERT(tw->tw_cookie_idx < tw->tw_ncookies); 1291 } 1292 1293 /* 1294 * Counting the remained buffer length to be filled in 1295 * the QTD for current DMA cookie 1296 */ 1297 rem_len = (tw->tw_dma_offs + tw->tw_cookie.dmac_size) - 1298 qtd_dma_offs; 1299 1300 /* Update the beginning of the buffer */ 1301 buf_addr = (qtd_dma_offs - tw->tw_dma_offs) + 1302 tw->tw_cookie.dmac_address; 1303 ASSERT((buf_addr % EHCI_4K_ALIGN) == 0); 1304 Set_QTD(qtd->qtd_buf[i], buf_addr); 1305 1306 if (buf_len <= EHCI_MAX_QTD_BUF_SIZE) { 1307 ASSERT(buf_len <= rem_len); 1308 break; 1309 } else { 1310 ASSERT(rem_len >= EHCI_MAX_QTD_BUF_SIZE); 1311 buf_len -= EHCI_MAX_QTD_BUF_SIZE; 1312 qtd_dma_offs += EHCI_MAX_QTD_BUF_SIZE; 1313 } 1314 1315 i++; 1316 } 1317 1318 /* 1319 * For control, bulk and interrupt QTD, now 1320 * enable current QTD by setting active bit. 1321 */ 1322 Set_QTD(qtd->qtd_ctrl, (ctrl | EHCI_QTD_CTRL_ACTIVE_XACT)); 1323 1324 Set_QTD(qtd->qtd_trans_wrapper, (uint32_t)tw->tw_id); 1325} 1326 1327 1328/* 1329 * ehci_polled_insert_qtd_on_tw: 1330 * 1331 * The transfer wrapper keeps a list of all Transfer Descriptors (QTD) that 1332 * are allocated for this transfer. Insert a QTD onto this list. The list 1333 * of QTD's does not include the dummy QTD that is at the end of the list of 1334 * QTD's for the endpoint. 1335 */ 1336static void 1337ehci_polled_insert_qtd_on_tw( 1338 ehci_state_t *ehcip, 1339 ehci_trans_wrapper_t *tw, 1340 ehci_qtd_t *qtd) 1341{ 1342 /* 1343 * Set the next pointer to NULL because 1344 * this is the last QTD on list. 1345 */ 1346 Set_QTD(qtd->qtd_tw_next_qtd, NULL); 1347 1348 if (tw->tw_qtd_head == NULL) { 1349 ASSERT(tw->tw_qtd_tail == NULL); 1350 tw->tw_qtd_head = qtd; 1351 tw->tw_qtd_tail = qtd; 1352 } else { 1353 ehci_qtd_t *dummy = (ehci_qtd_t *)tw->tw_qtd_tail; 1354 1355 ASSERT(dummy != NULL); 1356 ASSERT(dummy != qtd); 1357 ASSERT(Get_QTD(qtd->qtd_state) != EHCI_QTD_DUMMY); 1358 1359 /* Add the qtd to the end of the list */ 1360 Set_QTD(dummy->qtd_tw_next_qtd, 1361 ehci_qtd_cpu_to_iommu(ehcip, qtd)); 1362 1363 tw->tw_qtd_tail = qtd; 1364 1365 ASSERT(Get_QTD(qtd->qtd_tw_next_qtd) == NULL); 1366 } 1367} 1368 1369 1370/* 1371 * ehci_polled_create_done_qtd_list: 1372 * 1373 * Create done qtd list from active qtd list. 1374 */ 1375static ehci_qtd_t * 1376ehci_polled_create_done_qtd_list( 1377 ehci_polled_t *ehci_polledp) 1378{ 1379 ehci_state_t *ehcip = ehci_polledp->ehci_polled_ehcip; 1380 ehci_qtd_t *curr_qtd = NULL, *next_qtd = NULL; 1381 ehci_qtd_t *done_qtd_list = NULL, *last_done_qtd = NULL; 1382 1383 USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl, 1384 "ehci_polled_create_done_qtd_list:"); 1385 1386 curr_qtd = ehci_polledp->ehci_polled_active_intr_qtd_list; 1387 1388 while (curr_qtd) { 1389 1390 /* Get next qtd from the active qtd list */ 1391 next_qtd = ehci_qtd_iommu_to_cpu(ehcip, 1392 Get_QTD(curr_qtd->qtd_active_qtd_next)); 1393 1394 /* Check this QTD has been processed by Host Controller */ 1395 if (!(Get_QTD(curr_qtd->qtd_ctrl) & 1396 EHCI_QTD_CTRL_ACTIVE_XACT)) { 1397 1398 /* Remove this QTD from active QTD list */ 1399 ehci_polled_remove_qtd_from_active_intr_qtd_list( 1400 ehci_polledp, curr_qtd); 1401 1402 Set_QTD(curr_qtd->qtd_active_qtd_next, NULL); 1403 1404 if (done_qtd_list) { 1405 Set_QTD(last_done_qtd->qtd_active_qtd_next, 1406 ehci_qtd_cpu_to_iommu(ehcip, curr_qtd)); 1407 1408 last_done_qtd = curr_qtd; 1409 } else { 1410 done_qtd_list = curr_qtd; 1411 last_done_qtd = curr_qtd; 1412 } 1413 } 1414 1415 curr_qtd = next_qtd; 1416 } 1417 1418 return (done_qtd_list); 1419} 1420 1421 1422/* 1423 * ehci_polled_insert_qtd_into_active_intr_qtd_list: 1424 * 1425 * Insert current QTD into active interrupt QTD list. 1426 */ 1427static void 1428ehci_polled_insert_qtd_into_active_intr_qtd_list( 1429 ehci_polled_t *ehci_polledp, 1430 ehci_qtd_t *qtd) 1431{ 1432 ehci_state_t *ehcip = ehci_polledp->ehci_polled_ehcip; 1433 ehci_qtd_t *curr_qtd, *next_qtd; 1434 1435 curr_qtd = ehci_polledp->ehci_polled_active_intr_qtd_list; 1436 1437 /* Insert this qtd into active intr qtd list */ 1438 if (curr_qtd) { 1439 next_qtd = ehci_qtd_iommu_to_cpu(ehcip, 1440 Get_QTD(curr_qtd->qtd_active_qtd_next)); 1441 1442 while (next_qtd) { 1443 curr_qtd = next_qtd; 1444 next_qtd = ehci_qtd_iommu_to_cpu(ehcip, 1445 Get_QTD(curr_qtd->qtd_active_qtd_next)); 1446 } 1447 1448 Set_QTD(qtd->qtd_active_qtd_prev, 1449 ehci_qtd_cpu_to_iommu(ehcip, curr_qtd)); 1450 1451 Set_QTD(curr_qtd->qtd_active_qtd_next, 1452 ehci_qtd_cpu_to_iommu(ehcip, qtd)); 1453 } else { 1454 ehci_polledp->ehci_polled_active_intr_qtd_list = qtd; 1455 Set_QTD(qtd->qtd_active_qtd_next, NULL); 1456 Set_QTD(qtd->qtd_active_qtd_prev, NULL); 1457 } 1458} 1459 1460 1461/* 1462 * ehci_polled_remove_qtd_from_active_intr_qtd_list: 1463 * 1464 * Remove current QTD from the active QTD list. 1465 */ 1466void 1467ehci_polled_remove_qtd_from_active_intr_qtd_list( 1468 ehci_polled_t *ehci_polledp, 1469 ehci_qtd_t *qtd) 1470{ 1471 ehci_state_t *ehcip = ehci_polledp->ehci_polled_ehcip; 1472 ehci_qtd_t *curr_qtd, *prev_qtd, *next_qtd; 1473 1474 ASSERT(qtd != NULL); 1475 1476 curr_qtd = ehci_polledp->ehci_polled_active_intr_qtd_list; 1477 1478 while ((curr_qtd) && (curr_qtd != qtd)) { 1479 curr_qtd = ehci_qtd_iommu_to_cpu(ehcip, 1480 Get_QTD(curr_qtd->qtd_active_qtd_next)); 1481 } 1482 1483 if ((curr_qtd) && (curr_qtd == qtd)) { 1484 prev_qtd = ehci_qtd_iommu_to_cpu(ehcip, 1485 Get_QTD(curr_qtd->qtd_active_qtd_prev)); 1486 next_qtd = ehci_qtd_iommu_to_cpu(ehcip, 1487 Get_QTD(curr_qtd->qtd_active_qtd_next)); 1488 1489 if (prev_qtd) { 1490 Set_QTD(prev_qtd->qtd_active_qtd_next, 1491 Get_QTD(curr_qtd->qtd_active_qtd_next)); 1492 } else { 1493 ehci_polledp-> 1494 ehci_polled_active_intr_qtd_list = next_qtd; 1495 } 1496 1497 if (next_qtd) { 1498 Set_QTD(next_qtd->qtd_active_qtd_prev, 1499 Get_QTD(curr_qtd->qtd_active_qtd_prev)); 1500 } 1501 } 1502} 1503 1504 1505/* 1506 * ehci_polled_traverse_qtds: 1507 * 1508 * Traverse the list of QTDs for given pipe using transfer wrapper. Since 1509 * the endpoint is marked as Halted, the Host Controller (HC) is no longer 1510 * accessing these QTDs. Remove all the QTDs that are attached to endpoint. 1511 */ 1512static void 1513ehci_polled_traverse_qtds( 1514 ehci_polled_t *ehci_polledp, 1515 usba_pipe_handle_data_t *ph) 1516{ 1517 ehci_state_t *ehcip = ehci_polledp->ehci_polled_ehcip; 1518 ehci_pipe_private_t *pp = (ehci_pipe_private_t *)ph->p_hcd_private; 1519 ehci_trans_wrapper_t *next_tw; 1520 ehci_qtd_t *qtd; 1521 ehci_qtd_t *next_qtd; 1522 1523 /* Process the transfer wrappers for this pipe */ 1524 next_tw = pp->pp_tw_head; 1525 1526 while (next_tw) { 1527 qtd = (ehci_qtd_t *)next_tw->tw_qtd_head; 1528 1529 /* Walk through each QTD for this transfer wrapper */ 1530 while (qtd) { 1531 /* Remove this QTD from active QTD list */ 1532 ehci_polled_remove_qtd_from_active_intr_qtd_list( 1533 ehci_polledp, qtd); 1534 1535 next_qtd = ehci_qtd_iommu_to_cpu(ehcip, 1536 Get_QTD(qtd->qtd_tw_next_qtd)); 1537 1538 /* Deallocate this QTD */ 1539 ehci_deallocate_qtd(ehcip, qtd); 1540 1541 qtd = next_qtd; 1542 } 1543 1544 next_tw = next_tw->tw_next; 1545 } 1546 1547 /* Clear current qtd pointer */ 1548 Set_QH(pp->pp_qh->qh_curr_qtd, (uint32_t)0x00000000); 1549 1550 /* Update the next qtd pointer in the QH */ 1551 Set_QH(pp->pp_qh->qh_next_qtd, Get_QH(pp->pp_qh->qh_dummy_qtd)); 1552} 1553 1554 1555/* 1556 * ehci_polled_finish_interrupt: 1557 */ 1558static void 1559ehci_polled_finish_interrupt( 1560 ehci_state_t *ehcip, 1561 uint_t intr) 1562{ 1563 /* Acknowledge the interrupt */ 1564 Set_OpReg(ehci_status, intr); 1565 1566 /* 1567 * Read interrupt status register to make sure that any PIO 1568 * store to clear the ISR has made it on the PCI bus before 1569 * returning from its interrupt handler. 1570 */ 1571 (void) Get_OpReg(ehci_status); 1572} 1573