1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #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, DDI_DEV_AUTOINCR); 259 } 260 261 /* 262 * Insert the td again into the lattice. 263 */ 264 SetTD_dtogg(uhcip, td, GetTD_dtogg(uhcip, td) == 0 ? 1 : 0); 265 266 SetTD_status(uhcip, td, UHCI_TD_ACTIVE); 267 SetQH32(uhcip, uhci_polledp->uhci_polled_qh->element_ptr, 268 TD_PADDR(td)); 269 270 /* Clear the interrupt status register */ 271 intr_status = Get_OpReg16(USBSTS); 272 Set_OpReg16(USBSTS, intr_status); 273 } 274 275 #ifndef lint 276 _NOTE(COMPETING_THREADS_NOW); 277 #endif 278 279 return (USB_SUCCESS); 280 } 281 282 /* 283 * uhci_hcdi_polled_output_init: 284 * This is the initialization routine for handling the USB serial 285 * output in POLLED mode. This routine is called after input_init 286 * succeeded. 287 */ 288 int 289 uhci_hcdi_polled_output_init(usba_pipe_handle_data_t *ph, 290 usb_console_info_impl_t *console_output_info) 291 { 292 int ret; 293 uhci_polled_t *uhci_polledp; 294 uhci_state_t *uhcip; 295 296 uhcip = uhci_obtain_state(ph->p_usba_device->usb_root_hub_dip); 297 298 /* 299 * Grab the uhci_int_mutex so that things don't change on us 300 * if an interrupt comes in. 301 */ 302 mutex_enter(&uhcip->uhci_int_mutex); 303 ret = uhci_polled_init(ph, uhcip, console_output_info); 304 if (ret != USB_SUCCESS) { 305 mutex_exit(&uhcip->uhci_int_mutex); 306 307 return (ret); 308 } 309 310 uhci_polledp = (uhci_polled_t *)console_output_info->uci_private; 311 /* 312 * Mark the structure so that if we are using it, we don't free 313 * the structures if one of them is unplugged. 314 */ 315 uhci_polledp->uhci_polled_flags |= POLLED_OUTPUT_MODE; 316 317 mutex_exit(&uhcip->uhci_int_mutex); 318 319 return (USB_SUCCESS); 320 } 321 322 323 /* 324 * uhci_hcdi_polled_output_fini: 325 */ 326 int 327 uhci_hcdi_polled_output_fini(usb_console_info_impl_t *info) 328 { 329 int ret; 330 uhci_state_t *uhcip; 331 uhci_polled_t *uhci_polledp; 332 333 uhci_polledp = (uhci_polled_t *)info->uci_private; 334 uhcip = uhci_polledp->uhci_polled_uhcip; 335 mutex_enter(&uhcip->uhci_int_mutex); 336 337 ret = uhci_polled_fini(uhci_polledp, uhcip); 338 info->uci_private = NULL; 339 mutex_exit(&uhcip->uhci_int_mutex); 340 341 return (ret); 342 } 343 344 345 /* 346 * uhci_hcdi_polled_output_enter: 347 * everything is done in input enter 348 */ 349 int 350 uhci_hcdi_polled_output_enter(usb_console_info_impl_t *info) 351 { 352 uhci_state_t *uhcip; 353 uhci_polled_t *uhci_polledp; 354 355 uhci_polledp = (uhci_polled_t *)info->uci_private; 356 uhcip = uhci_polledp->uhci_polled_uhcip; 357 358 /* 359 * Check if the number of devices reaches the max number 360 * we can support in polled mode 361 */ 362 if (uhcip->uhci_polled_count + 1 > MAX_NUM_FOR_KEYBORAD) { 363 364 return (USB_FAILURE); 365 } 366 367 return (USB_SUCCESS); 368 } 369 370 371 /* 372 * uhci_hcdi_polled_output_exit: 373 * everything is done in input exit 374 */ 375 /*ARGSUSED*/ 376 int 377 uhci_hcdi_polled_output_exit(usb_console_info_impl_t *info) 378 { 379 return (USB_SUCCESS); 380 } 381 382 /* 383 * uhci_hcdi_polled_write: 384 * Put a key character -- rewrite this! 385 */ 386 int 387 uhci_hcdi_polled_write(usb_console_info_impl_t *info, uchar_t *buf, 388 uint_t num_characters, uint_t *num_characters_written) 389 { 390 int i; 391 uhci_state_t *uhcip; 392 uhci_polled_t *uhci_polledp; 393 uhci_td_t *td; 394 uhci_trans_wrapper_t *tw; 395 uhci_pipe_private_t *pp; 396 usba_pipe_handle_data_t *ph; 397 398 #ifndef lint 399 _NOTE(NO_COMPETING_THREADS_NOW); 400 #endif 401 402 uhci_polledp = (uhci_polled_t *)info->uci_private; 403 uhcip = uhci_polledp->uhci_polled_uhcip; 404 ph = uhci_polledp->uhci_polled_ph; 405 pp = (uhci_pipe_private_t *)ph->p_hcd_private; 406 407 td = uhci_polledp->uhci_polled_td; 408 tw = td->tw; 409 410 /* copy transmit buffer */ 411 if (num_characters > POLLED_RAW_BUF_SIZE) { 412 cmn_err(CE_NOTE, "polled write size %d bigger than %d", 413 num_characters, POLLED_RAW_BUF_SIZE); 414 num_characters = POLLED_RAW_BUF_SIZE; 415 } 416 tw->tw_length = num_characters; 417 ddi_put8(tw->tw_accesshandle, (uint8_t *)tw->tw_buf, *buf); 418 ddi_rep_put8(tw->tw_accesshandle, buf, (uint8_t *)tw->tw_buf, 419 num_characters, DDI_DEV_AUTOINCR); 420 421 bzero((char *)td, sizeof (uhci_td_t)); 422 423 td->tw = tw; 424 SetTD_c_err(uhcip, td, UHCI_MAX_ERR_COUNT); 425 SetTD_status(uhcip, td, UHCI_TD_ACTIVE); 426 SetTD_ioc(uhcip, td, INTERRUPT_ON_COMPLETION); 427 SetTD_mlen(uhcip, td, num_characters - 1); 428 SetTD_dtogg(uhcip, td, pp->pp_data_toggle); 429 ADJ_DATA_TOGGLE(pp); 430 SetTD_devaddr(uhcip, td, ph->p_usba_device->usb_addr); 431 SetTD_endpt(uhcip, td, ph->p_ep.bEndpointAddress & 432 END_POINT_ADDRESS_MASK); 433 SetTD_PID(uhcip, td, PID_OUT); 434 SetTD32(uhcip, td->buffer_address, tw->tw_cookie.dmac_address); 435 436 SetQH32(uhcip, uhci_polledp->uhci_polled_qh->element_ptr, 437 TD_PADDR(td)); 438 439 /* 440 * Now, add the endpoint to the lattice that we will hang our 441 * TD's off of. 442 */ 443 for (i = uhcip->uhci_polled_count; i < NUM_FRAME_LST_ENTRIES; 444 i += MIN_LOW_SPEED_POLL_INTERVAL) { 445 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[i], 446 QH_PADDR(uhci_polledp->uhci_polled_qh) | HC_QUEUE_HEAD); 447 } 448 449 /* wait for xfer to finish */ 450 while (GetTD_status(uhcip, td) & UHCI_TD_ACTIVE) 451 #ifndef __sparc 452 invalidate_cache(); 453 #else 454 ; 455 #endif 456 *num_characters_written = GetTD_alen(uhcip, td) + 1; 457 458 /* Now, remove the endpoint from the lattice */ 459 for (i = uhcip->uhci_polled_count; i < NUM_FRAME_LST_ENTRIES; 460 i += MIN_LOW_SPEED_POLL_INTERVAL) { 461 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[i], 462 HC_END_OF_LIST); 463 } 464 465 #ifndef lint 466 _NOTE(COMPETING_THREADS_NOW); 467 #endif 468 469 return (USB_SUCCESS); 470 } 471 472 473 /* 474 * uhci_polled_init: 475 * Initialize generic information that is needed to provide USB/POLLED 476 * support. 477 */ 478 static int 479 uhci_polled_init(usba_pipe_handle_data_t *ph, 480 uhci_state_t *uhcip, 481 usb_console_info_impl_t *console_info) 482 { 483 uhci_polled_t *uhci_polledp; 484 485 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 486 487 /* 488 * If the structure has already been initialized, then we don't 489 * need to redo it. 490 */ 491 if (console_info->uci_private != NULL) { 492 493 return (USB_SUCCESS); 494 } 495 496 /* Allocate and intitialize a polled mode state structure */ 497 uhci_polledp = kmem_zalloc(sizeof (uhci_polled_t), KM_SLEEP); 498 499 /* 500 * Keep a copy of normal mode state structure and pipe handle. 501 */ 502 uhci_polledp->uhci_polled_uhcip = uhcip; 503 uhci_polledp->uhci_polled_ph = ph; 504 505 /* 506 * Allocate a queue head for the device. This queue head wiil be 507 * put in action when we switch to polled mode in _enter point. 508 */ 509 uhci_polledp->uhci_polled_qh = uhci_alloc_queue_head(uhcip); 510 511 if (uhci_polledp->uhci_polled_qh == NULL) { 512 kmem_free(uhci_polledp, sizeof (uhci_polled_t)); 513 514 return (USB_NO_RESOURCES); 515 } 516 517 /* 518 * Insert a TD onto the queue head. 519 */ 520 if ((uhci_polled_insert_td_on_qh(uhci_polledp, 521 uhci_polledp->uhci_polled_ph)) != USB_SUCCESS) { 522 uhci_polledp->uhci_polled_qh->qh_flag = QUEUE_HEAD_FLAG_FREE; 523 kmem_free(uhci_polledp, sizeof (uhci_polled_t)); 524 525 return (USB_NO_RESOURCES); 526 } 527 528 console_info->uci_private = (usb_console_info_private_t)uhci_polledp; 529 530 return (USB_SUCCESS); 531 } 532 533 534 /* 535 * uhci_polled_fini: 536 */ 537 static int 538 uhci_polled_fini(uhci_polled_t *uhci_polledp, uhci_state_t *uhcip) 539 { 540 uhci_td_t *td = uhci_polledp->uhci_polled_td; 541 542 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 543 544 /* 545 * Free the transfer wrapper 546 */ 547 uhci_free_tw(uhcip, td->tw); 548 549 /* 550 * Free the queue head and transfer descriptor allocated. 551 */ 552 uhci_polledp->uhci_polled_qh->qh_flag = QUEUE_HEAD_FLAG_FREE; 553 uhci_polledp->uhci_polled_td->flag = TD_FLAG_FREE; 554 555 /* 556 * Deallocate the memory for the polled mode state structure. 557 */ 558 kmem_free(uhci_polledp, sizeof (uhci_polled_t)); 559 560 return (USB_SUCCESS); 561 } 562 563 564 /* 565 * uhci_polled_save_state: 566 */ 567 static void 568 uhci_polled_save_state(uhci_polled_t *uhci_polledp) 569 { 570 int i; 571 uhci_td_t *td, *polled_td; 572 uhci_state_t *uhcip; 573 usba_pipe_handle_data_t *ph; 574 575 #ifndef lint 576 _NOTE(NO_COMPETING_THREADS_NOW); 577 #endif 578 579 /* 580 * If either of these two flags are set, then we have already 581 * saved off the state information and setup the controller. 582 */ 583 if (uhci_polledp->uhci_polled_flags & POLLED_INPUT_MODE_INUSE) { 584 #ifndef lint 585 _NOTE(COMPETING_THREADS_NOW); 586 #endif 587 588 return; 589 } 590 591 uhcip = uhci_polledp->uhci_polled_uhcip; 592 593 /* 594 * Check if the number of keyboard reaches the max number we can 595 * support in polled mode 596 */ 597 if (++ uhcip->uhci_polled_count > MAX_NUM_FOR_KEYBORAD) { 598 #ifndef lint 599 _NOTE(COMPETING_THREADS_NOW); 600 #endif 601 return; 602 } 603 604 /* 605 * Get the normal mode usb pipe handle. 606 */ 607 ph = (usba_pipe_handle_data_t *)uhci_polledp->uhci_polled_ph; 608 /* 609 * Only the first keyboard enter disable the interrutps, stop the 610 * host controller processing and initialize the interrupt table. 611 */ 612 if (uhcip->uhci_polled_count == 1) { 613 /* 614 * Disable interrupts to prevent the interrupt handler getting 615 * called while we are switing to POLLed mode. 616 */ 617 618 Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); 619 620 /* 621 * Stop the HC controller from processing TD's 622 */ 623 Set_OpReg16(USBCMD, 0); 624 625 /* 626 * Save the current interrupt lattice and replace this lattice 627 * with an lattice used in POLLED mode. We will restore lattice 628 * back when we exit from the POLLED mode. 629 */ 630 for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) { 631 uhcip->uhci_polled_save_IntTble[i] = 632 uhcip->uhci_frame_lst_tablep[i]; 633 } 634 635 /* 636 * Zero out the entire interrupt lattice tree. 637 */ 638 for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) { 639 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[i], 640 HC_END_OF_LIST); 641 } 642 } 643 644 /* 645 * Now, add the endpoint to the lattice that we will hang our 646 * TD's off of. We (assume always) need to poll this device at 647 * every 8 ms. 648 */ 649 for (i = uhcip->uhci_polled_count - 1; i < NUM_FRAME_LST_ENTRIES; 650 i += MIN_LOW_SPEED_POLL_INTERVAL) { 651 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[i], 652 QH_PADDR(uhci_polledp->uhci_polled_qh) | HC_QUEUE_HEAD); 653 } 654 655 /* 656 * Adjust the data toggle 657 */ 658 td = uhcip->uhci_outst_tds_head; 659 while (td != NULL) { 660 if (td->tw->tw_pipe_private->pp_pipe_handle == ph) { 661 polled_td = uhci_polledp->uhci_polled_td; 662 if (GetTD_status(uhcip, td) & UHCI_TD_ACTIVE) { 663 SetTD_dtogg(uhcip, polled_td, 664 GetTD_dtogg(uhcip, td)); 665 } else { 666 SetTD_dtogg(uhcip, polled_td, 667 (GetTD_dtogg(uhcip, td) ^ 1)); 668 uhcip->uhci_polled_flag = 669 UHCI_POLLED_FLAG_TD_COMPL; 670 } 671 break; 672 } 673 td = td->outst_td_next; 674 } 675 /* 676 * Only the first keyboard enter reset the frame number and start 677 * the host controler processing. 678 */ 679 if (uhcip->uhci_polled_count == 1) { 680 /* Set the frame number to zero */ 681 Set_OpReg16(FRNUM, 0); 682 683 /* 684 * Start the Host controller processing 685 */ 686 Set_OpReg16(USBCMD, (USBCMD_REG_HC_RUN | USBCMD_REG_MAXPKT_64 | 687 USBCMD_REG_CONFIG_FLAG)); 688 } 689 690 #ifndef lint 691 _NOTE(COMPETING_THREADS_NOW); 692 #endif 693 } 694 695 696 /* 697 * uhci_polled_restore_state: 698 */ 699 static void 700 uhci_polled_restore_state(uhci_polled_t *uhci_polledp) 701 { 702 int i; 703 ushort_t real_data_toggle; 704 uhci_td_t *td, *polled_td; 705 uhci_state_t *uhcip; 706 uhci_pipe_private_t *pp; 707 708 #ifndef lint 709 _NOTE(NO_COMPETING_THREADS_NOW); 710 #endif 711 /* 712 * If this flags is set, then we are still using this structure, 713 * so don't restore any controller state information yet. 714 */ 715 if (uhci_polledp->uhci_polled_flags & POLLED_INPUT_MODE_INUSE) { 716 #ifndef lint 717 _NOTE(COMPETING_THREADS_NOW); 718 #endif 719 return; 720 } 721 722 uhcip = uhci_polledp->uhci_polled_uhcip; 723 uhcip->uhci_polled_count --; 724 725 /* Just first leave keyboard entry turn off the controller */ 726 if (Get_OpReg16(USBCMD)) { 727 Set_OpReg16(USBCMD, 0x0); 728 } 729 /* Only the last leave keyboard entry restore the interrupt table */ 730 if (uhcip->uhci_polled_count == 0) { 731 /* 732 * Replace the lattice 733 */ 734 for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) { 735 uhcip->uhci_frame_lst_tablep[i] = 736 uhcip->uhci_polled_save_IntTble[i]; 737 } 738 } 739 740 /* 741 * Adjust data toggle 742 */ 743 pp = (uhci_pipe_private_t *) 744 uhci_polledp->uhci_polled_ph->p_hcd_private; 745 746 polled_td = uhci_polledp->uhci_polled_td; 747 real_data_toggle = (GetTD_status(uhcip, polled_td) & UHCI_TD_ACTIVE) ? 748 GetTD_dtogg(uhcip, polled_td) : 749 !GetTD_dtogg(uhcip, polled_td); 750 751 td = uhcip->uhci_outst_tds_head; 752 while (td != NULL) { 753 if (td->tw->tw_pipe_private->pp_pipe_handle == 754 uhci_polledp->uhci_polled_ph) { 755 if (GetTD_status(uhcip, td) & UHCI_TD_ACTIVE) { 756 SetTD_dtogg(uhcip, td, real_data_toggle); 757 pp->pp_data_toggle = 758 (real_data_toggle == 0) ? 1 : 0; 759 } else { 760 pp->pp_data_toggle = real_data_toggle; 761 } 762 } 763 td = td->outst_td_next; 764 } 765 766 /* 767 * Only the last leave keyboard entry enable the interrupts, 768 * start Host controller processing. 769 */ 770 if (uhcip->uhci_polled_count == 0) { 771 Set_OpReg16(USBINTR, ENABLE_ALL_INTRS); 772 Set_OpReg16(USBCMD, (USBCMD_REG_HC_RUN | USBCMD_REG_MAXPKT_64 | 773 USBCMD_REG_CONFIG_FLAG)); 774 if (uhcip->uhci_polled_flag == UHCI_POLLED_FLAG_TD_COMPL) { 775 uhcip->uhci_polled_flag = UHCI_POLLED_FLAG_TRUE; 776 } 777 } 778 779 #ifndef lint 780 _NOTE(COMPETING_THREADS_NOW); 781 #endif 782 } 783 784 785 /* 786 * uhci_polled_insert_td: 787 * Initializes the transfer descriptor for polling and inserts on the 788 * polled queue head. This will be put in action when entered in to 789 * polled mode. 790 */ 791 static int 792 uhci_polled_insert_td_on_qh(uhci_polled_t *uhci_polledp, 793 usba_pipe_handle_data_t *ph) 794 { 795 uhci_td_t *td; 796 uhci_state_t *uhcip = uhci_polledp->uhci_polled_uhcip; 797 usb_ep_descr_t *eptd; 798 uhci_trans_wrapper_t *tw; 799 uint_t direction; 800 801 /* Create the transfer wrapper */ 802 if ((tw = uhci_polled_create_tw(uhci_polledp->uhci_polled_uhcip)) == 803 NULL) { 804 805 return (USB_FAILURE); 806 } 807 808 /* Use the dummy TD allocated for the queue head */ 809 td = uhci_polledp->uhci_polled_qh->td_tailp; 810 bzero((char *)td, sizeof (uhci_td_t)); 811 812 uhci_polledp->uhci_polled_td = td; 813 td->tw = tw; 814 td->flag = TD_FLAG_BUSY; 815 SetTD32(uhcip, td->link_ptr, HC_END_OF_LIST); 816 817 mutex_enter(&ph->p_usba_device->usb_mutex); 818 if (ph->p_usba_device->usb_port_status == USBA_LOW_SPEED_DEV) { 819 SetTD_ls(uhcip, td, LOW_SPEED_DEVICE); 820 } 821 822 eptd = &ph->p_ep; 823 direction = (UHCI_XFER_DIR(eptd) == USB_EP_DIR_OUT) ? PID_OUT : PID_IN; 824 SetTD_c_err(uhcip, td, UHCI_MAX_ERR_COUNT); 825 SetTD_mlen(uhcip, td, POLLED_RAW_BUF_SIZE - 1); 826 SetTD_devaddr(uhcip, td, ph->p_usba_device->usb_addr); 827 SetTD_endpt(uhcip, td, eptd->bEndpointAddress & END_POINT_ADDRESS_MASK); 828 SetTD_PID(uhcip, td, direction); 829 SetTD32(uhcip, td->buffer_address, tw->tw_cookie.dmac_address); 830 SetTD_ioc(uhcip, td, INTERRUPT_ON_COMPLETION); 831 SetTD_status(uhcip, td, UHCI_TD_ACTIVE); 832 mutex_exit(&ph->p_usba_device->usb_mutex); 833 834 SetQH32(uhcip, uhci_polledp->uhci_polled_qh->element_ptr, TD_PADDR(td)); 835 836 return (USB_SUCCESS); 837 } 838 839 840 /* 841 * uhci_polled_create_wrapper_t: 842 * Creates the transfer wrapper used in polled mode. 843 */ 844 static uhci_trans_wrapper_t * 845 uhci_polled_create_tw(uhci_state_t *uhcip) 846 { 847 uint_t result, ccount; 848 size_t real_length; 849 uhci_trans_wrapper_t *tw; 850 ddi_device_acc_attr_t dev_attr; 851 852 /* Allocate space for the transfer wrapper */ 853 if ((tw = kmem_zalloc(sizeof (uhci_trans_wrapper_t), KM_NOSLEEP)) == 854 NULL) { 855 856 return (NULL); 857 } 858 859 tw->tw_length = POLLED_RAW_BUF_SIZE; 860 861 /* Allocate the DMA handle */ 862 if ((result = ddi_dma_alloc_handle(uhcip->uhci_dip, 863 &uhcip->uhci_dma_attr, DDI_DMA_DONTWAIT, 0, &tw->tw_dmahandle)) != 864 DDI_SUCCESS) { 865 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 866 867 return (NULL); 868 } 869 870 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 871 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 872 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 873 874 /* Allocate the memory */ 875 if ((result = ddi_dma_mem_alloc(tw->tw_dmahandle, POLLED_RAW_BUF_SIZE, 876 &dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, 877 &tw->tw_buf, &real_length, &tw->tw_accesshandle)) != 878 DDI_SUCCESS) { 879 ddi_dma_free_handle(&tw->tw_dmahandle); 880 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 881 882 return (NULL); 883 } 884 885 /* Bind the handle */ 886 if ((result = ddi_dma_addr_bind_handle(tw->tw_dmahandle, NULL, 887 tw->tw_buf, real_length, DDI_DMA_RDWR|DDI_DMA_CONSISTENT, 888 DDI_DMA_DONTWAIT, NULL, &tw->tw_cookie, &ccount)) != 889 DDI_DMA_MAPPED) { 890 ddi_dma_mem_free(&tw->tw_accesshandle); 891 ddi_dma_free_handle(&tw->tw_dmahandle); 892 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 893 894 return (NULL); 895 } 896 897 /* The cookie count should be 1 */ 898 if (ccount != 1) { 899 result = ddi_dma_unbind_handle(tw->tw_dmahandle); 900 ASSERT(result == DDI_SUCCESS); 901 902 ddi_dma_mem_free(&tw->tw_accesshandle); 903 ddi_dma_free_handle(&tw->tw_dmahandle); 904 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 905 906 return (NULL); 907 } 908 909 return (tw); 910 } 911