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 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * This module contains the specific uhci code used in POLLED mode. 30 */ 31 #include <sys/usb/hcd/uhci/uhcid.h> 32 #include <sys/usb/hcd/uhci/uhcipolled.h> 33 34 #ifndef __sparc 35 extern void invalidate_cache(); 36 #endif 37 /* 38 * Internal Function Prototypes 39 */ 40 /* Polled initialization routine */ 41 static int uhci_polled_init(usba_pipe_handle_data_t *, uhci_state_t *, 42 usb_console_info_impl_t *); 43 44 /* Polled fini routine */ 45 static int uhci_polled_fini(uhci_polled_t *, uhci_state_t *); 46 47 /* Polled save state routine */ 48 static void uhci_polled_save_state(uhci_polled_t *); 49 50 /* Polled restore state routine */ 51 static void uhci_polled_restore_state(uhci_polled_t *); 52 53 /* Polled read routines */ 54 static int uhci_polled_insert_td_on_qh(uhci_polled_t *, 55 usba_pipe_handle_data_t *); 56 static uhci_trans_wrapper_t 57 *uhci_polled_create_tw(uhci_state_t *); 58 59 60 /* 61 * POLLED entry points 62 * 63 * These functions are entry points into the POLLED code. 64 */ 65 66 /* 67 * uhci_hcdi_polled_input_init: 68 * This is the initialization routine for handling the USB keyboard 69 * in POLLED mode. This routine is not called from POLLED mode, so 70 * it is OK to acquire mutexes. 71 */ 72 int 73 uhci_hcdi_polled_input_init(usba_pipe_handle_data_t *ph, 74 uchar_t **polled_buf, 75 usb_console_info_impl_t *console_input_info) 76 { 77 int ret; 78 uhci_polled_t *uhci_polledp; 79 uhci_state_t *uhcip; 80 81 uhcip = uhci_obtain_state(ph->p_usba_device->usb_root_hub_dip); 82 83 /* 84 * Grab the uhci_int_mutex so that things don't change on us 85 * if an interrupt comes in. 86 */ 87 mutex_enter(&uhcip->uhci_int_mutex); 88 ret = uhci_polled_init(ph, uhcip, console_input_info); 89 if (ret != USB_SUCCESS) { 90 mutex_exit(&uhcip->uhci_int_mutex); 91 92 return (ret); 93 } 94 95 uhci_polledp = (uhci_polled_t *)console_input_info->uci_private; 96 /* 97 * Mark the structure so that if we are using it, we don't free 98 * the structures if one of them is unplugged. 99 */ 100 uhci_polledp->uhci_polled_flags |= POLLED_INPUT_MODE; 101 102 /* 103 * This is the buffer we will copy characters into. It will be 104 * copied into at this layer, so we need to keep track of it. 105 */ 106 uhci_polledp->uhci_polled_buf = 107 (uchar_t *)kmem_zalloc(POLLED_RAW_BUF_SIZE, KM_SLEEP); 108 109 *polled_buf = uhci_polledp->uhci_polled_buf; 110 111 mutex_exit(&uhcip->uhci_int_mutex); 112 return (USB_SUCCESS); 113 } 114 115 116 /* 117 * uhci_hcdi_polled_input_fini: 118 */ 119 int 120 uhci_hcdi_polled_input_fini(usb_console_info_impl_t *info) 121 { 122 int ret; 123 uhci_state_t *uhcip; 124 uhci_polled_t *uhci_polledp; 125 126 uhci_polledp = (uhci_polled_t *)info->uci_private; 127 uhcip = uhci_polledp->uhci_polled_uhcip; 128 mutex_enter(&uhcip->uhci_int_mutex); 129 130 /* Free the buffer that we copied data into */ 131 kmem_free(uhci_polledp->uhci_polled_buf, POLLED_RAW_BUF_SIZE); 132 ret = uhci_polled_fini(uhci_polledp, uhcip); 133 info->uci_private = NULL; 134 mutex_exit(&uhcip->uhci_int_mutex); 135 136 return (ret); 137 } 138 139 140 /* 141 * uhci_hcdi_polled_input_enter: 142 * This is where we enter into POLLED mode. This routine sets up 143 * everything so that calls to uhci_hcdi_polled_read will return 144 * characters. 145 */ 146 int 147 uhci_hcdi_polled_input_enter(usb_console_info_impl_t *info) 148 { 149 uhci_polled_t *uhci_polledp; 150 151 uhci_polledp = (uhci_polled_t *)info->uci_private; 152 uhci_polledp->uhci_polled_entry++; 153 154 /* 155 * If the controller is already switched over, just return 156 */ 157 if (uhci_polledp->uhci_polled_entry > 1) { 158 159 return (USB_SUCCESS); 160 } 161 162 uhci_polled_save_state(uhci_polledp); 163 uhci_polledp->uhci_polled_flags |= POLLED_INPUT_MODE_INUSE; 164 165 return (USB_SUCCESS); 166 } 167 168 169 /* 170 * uhci_hcdi_polled_input_exit: 171 * This is where we exit POLLED mode. This routine restores 172 * everything that is needed to continue operation. 173 */ 174 int 175 uhci_hcdi_polled_input_exit(usb_console_info_impl_t *info) 176 { 177 uhci_polled_t *uhci_polledp; 178 179 uhci_polledp = (uhci_polled_t *)info->uci_private; 180 uhci_polledp->uhci_polled_entry--; 181 182 /* 183 * If there are still outstanding "enters", just return 184 */ 185 if (uhci_polledp->uhci_polled_entry > 0) { 186 187 return (USB_SUCCESS); 188 } 189 190 uhci_polledp->uhci_polled_flags &= ~POLLED_INPUT_MODE_INUSE; 191 uhci_polled_restore_state(uhci_polledp); 192 193 return (USB_SUCCESS); 194 } 195 196 197 /* 198 * uhci_hcdi_polled_read: 199 * Get a key character 200 */ 201 int 202 uhci_hcdi_polled_read(usb_console_info_impl_t *info, uint_t *num_characters) 203 { 204 uhci_state_t *uhcip; 205 uhci_polled_t *uhci_polledp; 206 uhci_td_t *td; 207 uhci_trans_wrapper_t *tw; 208 ushort_t intr_status; 209 210 uhci_polledp = (uhci_polled_t *)info->uci_private; 211 uhcip = uhci_polledp->uhci_polled_uhcip; 212 213 /* 214 * This is a temporary work around for halt problem. The upper 215 * layer code does not call the right sequence of entry points 216 * points for reading a character in a polled mode. Once the 217 * upper layer code is fixed, the following code (two lines) 218 * must be removed. 219 */ 220 if (uhci_polledp->uhci_polled_entry == 0) { 221 if (uhci_hcdi_polled_input_enter(info) != USB_SUCCESS) { 222 cmn_err(CE_WARN, "Entering Polled Mode failed"); 223 } 224 } 225 226 #ifndef lint 227 _NOTE(NO_COMPETING_THREADS_NOW); 228 #endif 229 #ifndef __sparc 230 invalidate_cache(); 231 #endif 232 233 td = uhci_polledp->uhci_polled_td; 234 235 /* 236 * Check to see if there are any TD's on the done head. 237 */ 238 if (GetTD_status(uhcip, td) & UHCI_TD_ACTIVE) { 239 *num_characters = 0; 240 } else { 241 242 /* 243 * If the TD does not complete, retry. 244 */ 245 if ((GetTD_status(uhcip, td) & TD_STATUS_MASK) || 246 (GetTD_alen(uhcip, td) == ZERO_LENGTH)) { 247 *num_characters = 0; 248 SetTD_alen(uhcip, td, 0); 249 } else { 250 *num_characters = GetTD_alen(uhcip, td) + 1; 251 252 tw = td->tw; 253 254 /* Copy the data into the message */ 255 ddi_rep_get8(tw->tw_accesshandle, 256 (uint8_t *)uhci_polledp->uhci_polled_buf, 257 (uint8_t *)td->tw->tw_buf, 258 *num_characters, 259 DDI_DEV_AUTOINCR); 260 } 261 262 /* 263 * Insert the td again into the lattice. 264 */ 265 SetTD_dtogg(uhcip, td, GetTD_dtogg(uhcip, td) == 0 ? 1 : 0); 266 267 SetTD_status(uhcip, td, UHCI_TD_ACTIVE); 268 SetQH32(uhcip, uhci_polledp->uhci_polled_qh->element_ptr, 269 TD_PADDR(td)); 270 271 /* Clear the interrupt status register */ 272 intr_status = Get_OpReg16(USBSTS); 273 Set_OpReg16(USBSTS, intr_status); 274 } 275 276 #ifndef lint 277 _NOTE(COMPETING_THREADS_NOW); 278 #endif 279 280 return (USB_SUCCESS); 281 } 282 283 /* 284 * uhci_hcdi_polled_output_init: 285 * This is the initialization routine for handling the USB serial 286 * output in POLLED mode. This routine is called after input_init 287 * succeeded. 288 */ 289 int 290 uhci_hcdi_polled_output_init(usba_pipe_handle_data_t *ph, 291 usb_console_info_impl_t *console_output_info) 292 { 293 int ret; 294 uhci_polled_t *uhci_polledp; 295 uhci_state_t *uhcip; 296 297 uhcip = uhci_obtain_state(ph->p_usba_device->usb_root_hub_dip); 298 299 /* 300 * Grab the uhci_int_mutex so that things don't change on us 301 * if an interrupt comes in. 302 */ 303 mutex_enter(&uhcip->uhci_int_mutex); 304 ret = uhci_polled_init(ph, uhcip, console_output_info); 305 if (ret != USB_SUCCESS) { 306 mutex_exit(&uhcip->uhci_int_mutex); 307 308 return (ret); 309 } 310 311 uhci_polledp = (uhci_polled_t *)console_output_info->uci_private; 312 /* 313 * Mark the structure so that if we are using it, we don't free 314 * the structures if one of them is unplugged. 315 */ 316 uhci_polledp->uhci_polled_flags |= POLLED_OUTPUT_MODE; 317 318 mutex_exit(&uhcip->uhci_int_mutex); 319 320 return (USB_SUCCESS); 321 } 322 323 324 /* 325 * uhci_hcdi_polled_output_fini: 326 */ 327 int 328 uhci_hcdi_polled_output_fini(usb_console_info_impl_t *info) 329 { 330 int ret; 331 uhci_state_t *uhcip; 332 uhci_polled_t *uhci_polledp; 333 334 uhci_polledp = (uhci_polled_t *)info->uci_private; 335 uhcip = uhci_polledp->uhci_polled_uhcip; 336 mutex_enter(&uhcip->uhci_int_mutex); 337 338 ret = uhci_polled_fini(uhci_polledp, uhcip); 339 info->uci_private = NULL; 340 mutex_exit(&uhcip->uhci_int_mutex); 341 342 return (ret); 343 } 344 345 346 /* 347 * uhci_hcdi_polled_output_enter: 348 * everything is done in input enter 349 */ 350 int 351 uhci_hcdi_polled_output_enter(usb_console_info_impl_t *info) 352 { 353 uhci_state_t *uhcip; 354 uhci_polled_t *uhci_polledp; 355 356 uhci_polledp = (uhci_polled_t *)info->uci_private; 357 uhcip = uhci_polledp->uhci_polled_uhcip; 358 359 /* 360 * Check if the number of devices reaches the max number 361 * we can support in polled mode 362 */ 363 if (uhcip->uhci_polled_count + 1 > MAX_NUM_FOR_KEYBORAD) { 364 365 return (USB_FAILURE); 366 } 367 368 return (USB_SUCCESS); 369 } 370 371 372 /* 373 * uhci_hcdi_polled_output_exit: 374 * everything is done in input exit 375 */ 376 /*ARGSUSED*/ 377 int 378 uhci_hcdi_polled_output_exit(usb_console_info_impl_t *info) 379 { 380 return (USB_SUCCESS); 381 } 382 383 static int uhci_polled_status; 384 385 /* 386 * uhci_hcdi_polled_write: 387 * Put a key character -- rewrite this! 388 */ 389 int 390 uhci_hcdi_polled_write(usb_console_info_impl_t *info, uchar_t *buf, 391 uint_t num_characters, uint_t *num_characters_written) 392 { 393 int i; 394 uhci_state_t *uhcip; 395 uhci_polled_t *uhci_polledp; 396 uhci_td_t *td; 397 uhci_trans_wrapper_t *tw; 398 uhci_pipe_private_t *pp; 399 usba_pipe_handle_data_t *ph; 400 401 uhci_polledp = (uhci_polled_t *)info->uci_private; 402 uhcip = uhci_polledp->uhci_polled_uhcip; 403 ph = uhci_polledp->uhci_polled_ph; 404 pp = (uhci_pipe_private_t *)ph->p_hcd_private; 405 406 td = uhci_polledp->uhci_polled_td; 407 tw = td->tw; 408 409 /* copy transmit buffer */ 410 if (num_characters > POLLED_RAW_BUF_SIZE) { 411 cmn_err(CE_NOTE, "polled write size %d bigger than %d", 412 num_characters, POLLED_RAW_BUF_SIZE); 413 num_characters = POLLED_RAW_BUF_SIZE; 414 } 415 tw->tw_length = num_characters; 416 ddi_put8(tw->tw_accesshandle, (uint8_t *)tw->tw_buf, *buf); 417 ddi_rep_put8(tw->tw_accesshandle, buf, (uint8_t *)tw->tw_buf, 418 num_characters, DDI_DEV_AUTOINCR); 419 420 bzero((char *)td, sizeof (uhci_td_t)); 421 422 td->tw = tw; 423 SetTD_c_err(uhcip, td, UHCI_MAX_ERR_COUNT); 424 SetTD_status(uhcip, td, UHCI_TD_ACTIVE); 425 SetTD_ioc(uhcip, td, INTERRUPT_ON_COMPLETION); 426 SetTD_mlen(uhcip, td, num_characters - 1); 427 SetTD_dtogg(uhcip, td, pp->pp_data_toggle); 428 ADJ_DATA_TOGGLE(pp); 429 SetTD_devaddr(uhcip, td, ph->p_usba_device->usb_addr); 430 SetTD_endpt(uhcip, td, ph->p_ep.bEndpointAddress & 431 END_POINT_ADDRESS_MASK); 432 SetTD_PID(uhcip, td, PID_OUT); 433 SetTD32(uhcip, td->buffer_address, tw->tw_cookie.dmac_address); 434 435 SetQH32(uhcip, uhci_polledp->uhci_polled_qh->element_ptr, 436 TD_PADDR(td)); 437 438 /* 439 * Now, add the endpoint to the lattice that we will hang our 440 * TD's off of. 441 */ 442 for (i = uhcip->uhci_polled_count; i < NUM_FRAME_LST_ENTRIES; 443 i += MIN_LOW_SPEED_POLL_INTERVAL) { 444 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[i], 445 QH_PADDR(uhci_polledp->uhci_polled_qh) | HC_QUEUE_HEAD); 446 } 447 448 /* wait for xfer to finish */ 449 while (GetTD_status(uhcip, td) & UHCI_TD_ACTIVE) 450 #ifndef __sparc 451 invalidate_cache(); 452 #else 453 ; 454 #endif 455 *num_characters_written = GetTD_alen(uhcip, td) + 1; 456 457 /* Now, remove the endpoint from the lattice */ 458 for (i = uhcip->uhci_polled_count; i < NUM_FRAME_LST_ENTRIES; 459 i += MIN_LOW_SPEED_POLL_INTERVAL) { 460 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[i], 461 HC_END_OF_LIST); 462 } 463 464 return (USB_SUCCESS); 465 } 466 467 468 /* 469 * uhci_polled_init: 470 * Initialize generic information that is needed to provide USB/POLLED 471 * support. 472 */ 473 static int 474 uhci_polled_init(usba_pipe_handle_data_t *ph, 475 uhci_state_t *uhcip, 476 usb_console_info_impl_t *console_info) 477 { 478 uhci_polled_t *uhci_polledp; 479 480 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 481 482 /* 483 * If the structure has already been initialized, then we don't 484 * need to redo it. 485 */ 486 if (console_info->uci_private != NULL) { 487 488 return (USB_SUCCESS); 489 } 490 491 /* Allocate and intitialize a polled mode state structure */ 492 uhci_polledp = (uhci_polled_t *)kmem_zalloc(sizeof (uhci_polled_t), 493 KM_SLEEP); 494 495 /* 496 * Keep a copy of normal mode state structure and pipe handle. 497 */ 498 uhci_polledp->uhci_polled_uhcip = uhcip; 499 uhci_polledp->uhci_polled_ph = ph; 500 501 /* 502 * Allocate a queue head for the device. This queue head wiil be 503 * put in action when we switch to polled mode in _enter point. 504 */ 505 uhci_polledp->uhci_polled_qh = uhci_alloc_queue_head(uhcip); 506 507 if (uhci_polledp->uhci_polled_qh == NULL) { 508 kmem_free(uhci_polledp, sizeof (uhci_polled_t)); 509 510 return (USB_NO_RESOURCES); 511 } 512 513 /* 514 * Insert a TD onto the queue head. 515 */ 516 if ((uhci_polled_insert_td_on_qh(uhci_polledp, 517 uhci_polledp->uhci_polled_ph)) != USB_SUCCESS) { 518 uhci_polledp->uhci_polled_qh->qh_flag = QUEUE_HEAD_FLAG_FREE; 519 kmem_free(uhci_polledp, sizeof (uhci_polled_t)); 520 521 return (USB_NO_RESOURCES); 522 } 523 524 console_info->uci_private = (usb_console_info_private_t)uhci_polledp; 525 526 return (USB_SUCCESS); 527 } 528 529 530 /* 531 * uhci_polled_fini: 532 */ 533 static int 534 uhci_polled_fini(uhci_polled_t *uhci_polledp, uhci_state_t *uhcip) 535 { 536 uhci_td_t *td = uhci_polledp->uhci_polled_td; 537 538 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 539 540 /* 541 * Free the transfer wrapper 542 */ 543 uhci_free_tw(uhcip, td->tw); 544 545 /* 546 * Free the queue head and transfer descriptor allocated. 547 */ 548 uhci_polledp->uhci_polled_qh->qh_flag = QUEUE_HEAD_FLAG_FREE; 549 uhci_polledp->uhci_polled_td->flag = TD_FLAG_FREE; 550 551 /* 552 * Deallocate the memory for the polled mode state structure. 553 */ 554 kmem_free(uhci_polledp, sizeof (uhci_polled_t)); 555 556 return (USB_SUCCESS); 557 } 558 559 560 /* 561 * uhci_polled_save_state: 562 */ 563 static void 564 uhci_polled_save_state(uhci_polled_t *uhci_polledp) 565 { 566 int i; 567 uhci_td_t *td, *polled_td; 568 uhci_state_t *uhcip; 569 usba_pipe_handle_data_t *ph; 570 571 #ifndef lint 572 _NOTE(NO_COMPETING_THREADS_NOW); 573 #endif 574 575 /* 576 * If either of these two flags are set, then we have already 577 * saved off the state information and setup the controller. 578 */ 579 if (uhci_polledp->uhci_polled_flags & POLLED_INPUT_MODE_INUSE) { 580 #ifndef lint 581 _NOTE(COMPETING_THREADS_NOW); 582 #endif 583 584 return; 585 } 586 587 uhcip = uhci_polledp->uhci_polled_uhcip; 588 589 /* 590 * Check if the number of keyboard reaches the max number we can 591 * support in polled mode 592 */ 593 if (++ uhcip->uhci_polled_count > MAX_NUM_FOR_KEYBORAD) { 594 #ifndef lint 595 _NOTE(COMPETING_THREADS_NOW); 596 #endif 597 return; 598 } 599 600 /* 601 * Get the normal mode usb pipe handle. 602 */ 603 ph = (usba_pipe_handle_data_t *)uhci_polledp->uhci_polled_ph; 604 /* 605 * Only the first keyboard enter disable the interrutps, stop the 606 * host controller processing and initialize the interrupt table. 607 */ 608 if (uhcip->uhci_polled_count == 1) { 609 /* 610 * Disable interrupts to prevent the interrupt handler getting 611 * called while we are switing to POLLed mode. 612 */ 613 614 Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); 615 616 /* 617 * Stop the HC controller from processing TD's 618 */ 619 Set_OpReg16(USBCMD, 0); 620 621 /* 622 * Save the current interrupt lattice and replace this lattice 623 * with an lattice used in POLLED mode. We will restore lattice 624 * back when we exit from the POLLED mode. 625 */ 626 for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) { 627 uhcip->uhci_polled_save_IntTble[i] = 628 uhcip->uhci_frame_lst_tablep[i]; 629 } 630 631 /* 632 * Zero out the entire interrupt lattice tree. 633 */ 634 for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) { 635 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[i], 636 HC_END_OF_LIST); 637 } 638 } 639 640 /* 641 * Now, add the endpoint to the lattice that we will hang our 642 * TD's off of. We (assume always) need to poll this device at 643 * every 8 ms. 644 */ 645 for (i = uhcip->uhci_polled_count - 1; i < NUM_FRAME_LST_ENTRIES; 646 i += MIN_LOW_SPEED_POLL_INTERVAL) { 647 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[i], 648 QH_PADDR(uhci_polledp->uhci_polled_qh) | HC_QUEUE_HEAD); 649 } 650 651 /* 652 * Adjust the data toggle 653 */ 654 td = uhcip->uhci_outst_tds_head; 655 while (td != NULL) { 656 if (td->tw->tw_pipe_private->pp_pipe_handle == ph) { 657 polled_td = uhci_polledp->uhci_polled_td; 658 if (GetTD_status(uhcip, td) & UHCI_TD_ACTIVE) { 659 SetTD_dtogg(uhcip, polled_td, 660 GetTD_dtogg(uhcip, td)); 661 } else { 662 SetTD_dtogg(uhcip, polled_td, 663 (GetTD_dtogg(uhcip, td) ^ 1)); 664 uhcip->uhci_polled_flag = 665 UHCI_POLLED_FLAG_TD_COMPL; 666 } 667 break; 668 } 669 td = td->outst_td_next; 670 } 671 /* 672 * Only the first keyboard enter reset the frame number and start 673 * the host controler processing. 674 */ 675 if (uhcip->uhci_polled_count == 1) { 676 /* Set the frame number to zero */ 677 Set_OpReg16(FRNUM, 0); 678 679 /* 680 * Start the Host controller processing 681 */ 682 Set_OpReg16(USBCMD, (USBCMD_REG_HC_RUN | USBCMD_REG_MAXPKT_64 | 683 USBCMD_REG_CONFIG_FLAG)); 684 } 685 686 #ifndef lint 687 _NOTE(COMPETING_THREADS_NOW); 688 #endif 689 } 690 691 692 /* 693 * uhci_polled_restore_state: 694 */ 695 static void 696 uhci_polled_restore_state(uhci_polled_t *uhci_polledp) 697 { 698 int i; 699 ushort_t real_data_toggle; 700 uhci_td_t *td, *polled_td; 701 uhci_state_t *uhcip; 702 uhci_pipe_private_t *pp; 703 704 #ifndef lint 705 _NOTE(NO_COMPETING_THREADS_NOW); 706 #endif 707 /* 708 * If this flags is set, then we are still using this structure, 709 * so don't restore any controller state information yet. 710 */ 711 if (uhci_polledp->uhci_polled_flags & POLLED_INPUT_MODE_INUSE) { 712 #ifndef lint 713 _NOTE(COMPETING_THREADS_NOW); 714 #endif 715 return; 716 } 717 718 uhcip = uhci_polledp->uhci_polled_uhcip; 719 uhcip->uhci_polled_count --; 720 721 /* Just first leave keyboard entry turn off the controller */ 722 if (Get_OpReg16(USBCMD)) { 723 Set_OpReg16(USBCMD, 0x0); 724 } 725 /* Only the last leave keyboard entry restore the interrupt table */ 726 if (uhcip->uhci_polled_count == 0) { 727 /* 728 * Replace the lattice 729 */ 730 for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) { 731 uhcip->uhci_frame_lst_tablep[i] = 732 uhcip->uhci_polled_save_IntTble[i]; 733 } 734 } 735 736 /* 737 * Adjust data toggle 738 */ 739 pp = (uhci_pipe_private_t *) 740 uhci_polledp->uhci_polled_ph->p_hcd_private; 741 742 polled_td = uhci_polledp->uhci_polled_td; 743 real_data_toggle = (GetTD_status(uhcip, polled_td) & UHCI_TD_ACTIVE) ? 744 GetTD_dtogg(uhcip, polled_td) : 745 !GetTD_dtogg(uhcip, polled_td); 746 747 td = uhcip->uhci_outst_tds_head; 748 while (td != NULL) { 749 if (td->tw->tw_pipe_private->pp_pipe_handle == 750 uhci_polledp->uhci_polled_ph) { 751 if (GetTD_status(uhcip, td) & UHCI_TD_ACTIVE) { 752 SetTD_dtogg(uhcip, td, real_data_toggle); 753 pp->pp_data_toggle = 754 (real_data_toggle == 0) ? 1 : 0; 755 } else { 756 pp->pp_data_toggle = real_data_toggle; 757 } 758 } 759 td = td->outst_td_next; 760 } 761 762 /* 763 * Only the last leave keyboard entry enable the interrupts, 764 * start Host controller processing. 765 */ 766 if (uhcip->uhci_polled_count == 0) { 767 Set_OpReg16(USBINTR, ENABLE_ALL_INTRS); 768 Set_OpReg16(USBCMD, (USBCMD_REG_HC_RUN | USBCMD_REG_MAXPKT_64 | 769 USBCMD_REG_CONFIG_FLAG)); 770 if (uhcip->uhci_polled_flag == UHCI_POLLED_FLAG_TD_COMPL) { 771 uhcip->uhci_polled_flag = UHCI_POLLED_FLAG_TRUE; 772 } 773 } 774 775 #ifndef lint 776 _NOTE(COMPETING_THREADS_NOW); 777 #endif 778 } 779 780 781 /* 782 * uhci_polled_insert_td: 783 * Initializes the transfer descriptor for polling and inserts on the 784 * polled queue head. This will be put in action when entered in to 785 * polled mode. 786 */ 787 static int 788 uhci_polled_insert_td_on_qh(uhci_polled_t *uhci_polledp, 789 usba_pipe_handle_data_t *ph) 790 { 791 uhci_td_t *td; 792 uhci_state_t *uhcip = uhci_polledp->uhci_polled_uhcip; 793 usb_ep_descr_t *eptd; 794 uhci_trans_wrapper_t *tw; 795 uint_t direction; 796 797 /* Create the transfer wrapper */ 798 if ((tw = uhci_polled_create_tw(uhci_polledp->uhci_polled_uhcip)) == 799 NULL) { 800 801 return (USB_FAILURE); 802 } 803 804 /* Use the dummy TD allocated for the queue head */ 805 td = uhci_polledp->uhci_polled_qh->td_tailp; 806 bzero((char *)td, sizeof (uhci_td_t)); 807 808 uhci_polledp->uhci_polled_td = td; 809 td->tw = tw; 810 td->flag = TD_FLAG_BUSY; 811 SetTD32(uhcip, td->link_ptr, HC_END_OF_LIST); 812 813 mutex_enter(&ph->p_usba_device->usb_mutex); 814 if (ph->p_usba_device->usb_port_status == USBA_LOW_SPEED_DEV) { 815 SetTD_ls(uhcip, td, LOW_SPEED_DEVICE); 816 } 817 818 eptd = &ph->p_ep; 819 direction = (UHCI_XFER_DIR(eptd) == USB_EP_DIR_OUT) ? PID_OUT : PID_IN; 820 SetTD_c_err(uhcip, td, UHCI_MAX_ERR_COUNT); 821 SetTD_mlen(uhcip, td, POLLED_RAW_BUF_SIZE - 1); 822 SetTD_devaddr(uhcip, td, ph->p_usba_device->usb_addr); 823 SetTD_endpt(uhcip, td, eptd->bEndpointAddress & END_POINT_ADDRESS_MASK); 824 SetTD_PID(uhcip, td, direction); 825 SetTD32(uhcip, td->buffer_address, tw->tw_cookie.dmac_address); 826 SetTD_ioc(uhcip, td, INTERRUPT_ON_COMPLETION); 827 SetTD_status(uhcip, td, UHCI_TD_ACTIVE); 828 mutex_exit(&ph->p_usba_device->usb_mutex); 829 830 SetQH32(uhcip, uhci_polledp->uhci_polled_qh->element_ptr, TD_PADDR(td)); 831 832 return (USB_SUCCESS); 833 } 834 835 836 /* 837 * uhci_polled_create_wrapper_t: 838 * Creates the transfer wrapper used in polled mode. 839 */ 840 static uhci_trans_wrapper_t * 841 uhci_polled_create_tw(uhci_state_t *uhcip) 842 { 843 uint_t result, ccount; 844 size_t real_length; 845 uhci_trans_wrapper_t *tw; 846 ddi_device_acc_attr_t dev_attr; 847 848 /* Allocate space for the transfer wrapper */ 849 if ((tw = kmem_zalloc(sizeof (uhci_trans_wrapper_t), KM_NOSLEEP)) == 850 NULL) { 851 852 return (NULL); 853 } 854 855 tw->tw_length = POLLED_RAW_BUF_SIZE; 856 857 /* Allocate the DMA handle */ 858 if ((result = ddi_dma_alloc_handle(uhcip->uhci_dip, 859 &uhcip->uhci_dma_attr, DDI_DMA_DONTWAIT, 0, &tw->tw_dmahandle)) != 860 DDI_SUCCESS) { 861 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 862 863 return (NULL); 864 } 865 866 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 867 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 868 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 869 870 /* Allocate the memory */ 871 if ((result = ddi_dma_mem_alloc(tw->tw_dmahandle, POLLED_RAW_BUF_SIZE, 872 &dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, 873 &tw->tw_buf, &real_length, &tw->tw_accesshandle)) != 874 DDI_SUCCESS) { 875 ddi_dma_free_handle(&tw->tw_dmahandle); 876 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 877 878 return (NULL); 879 } 880 881 /* Bind the handle */ 882 if ((result = ddi_dma_addr_bind_handle(tw->tw_dmahandle, NULL, 883 tw->tw_buf, real_length, DDI_DMA_RDWR|DDI_DMA_CONSISTENT, 884 DDI_DMA_DONTWAIT, NULL, &tw->tw_cookie, &ccount)) != 885 DDI_DMA_MAPPED) { 886 ddi_dma_mem_free(&tw->tw_accesshandle); 887 ddi_dma_free_handle(&tw->tw_dmahandle); 888 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 889 890 return (NULL); 891 } 892 893 /* The cookie count should be 1 */ 894 if (ccount != 1) { 895 result = ddi_dma_unbind_handle(tw->tw_dmahandle); 896 ASSERT(result == DDI_SUCCESS); 897 898 ddi_dma_mem_free(&tw->tw_accesshandle); 899 ddi_dma_free_handle(&tw->tw_dmahandle); 900 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 901 902 return (NULL); 903 } 904 905 return (tw); 906 } 907