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 #ifndef lint 402 _NOTE(NO_COMPETING_THREADS_NOW); 403 #endif 404 405 uhci_polledp = (uhci_polled_t *)info->uci_private; 406 uhcip = uhci_polledp->uhci_polled_uhcip; 407 ph = uhci_polledp->uhci_polled_ph; 408 pp = (uhci_pipe_private_t *)ph->p_hcd_private; 409 410 td = uhci_polledp->uhci_polled_td; 411 tw = td->tw; 412 413 /* copy transmit buffer */ 414 if (num_characters > POLLED_RAW_BUF_SIZE) { 415 cmn_err(CE_NOTE, "polled write size %d bigger than %d", 416 num_characters, POLLED_RAW_BUF_SIZE); 417 num_characters = POLLED_RAW_BUF_SIZE; 418 } 419 tw->tw_length = num_characters; 420 ddi_put8(tw->tw_accesshandle, (uint8_t *)tw->tw_buf, *buf); 421 ddi_rep_put8(tw->tw_accesshandle, buf, (uint8_t *)tw->tw_buf, 422 num_characters, DDI_DEV_AUTOINCR); 423 424 bzero((char *)td, sizeof (uhci_td_t)); 425 426 td->tw = tw; 427 SetTD_c_err(uhcip, td, UHCI_MAX_ERR_COUNT); 428 SetTD_status(uhcip, td, UHCI_TD_ACTIVE); 429 SetTD_ioc(uhcip, td, INTERRUPT_ON_COMPLETION); 430 SetTD_mlen(uhcip, td, num_characters - 1); 431 SetTD_dtogg(uhcip, td, pp->pp_data_toggle); 432 ADJ_DATA_TOGGLE(pp); 433 SetTD_devaddr(uhcip, td, ph->p_usba_device->usb_addr); 434 SetTD_endpt(uhcip, td, ph->p_ep.bEndpointAddress & 435 END_POINT_ADDRESS_MASK); 436 SetTD_PID(uhcip, td, PID_OUT); 437 SetTD32(uhcip, td->buffer_address, tw->tw_cookie.dmac_address); 438 439 SetQH32(uhcip, uhci_polledp->uhci_polled_qh->element_ptr, 440 TD_PADDR(td)); 441 442 /* 443 * Now, add the endpoint to the lattice that we will hang our 444 * TD's off of. 445 */ 446 for (i = uhcip->uhci_polled_count; i < NUM_FRAME_LST_ENTRIES; 447 i += MIN_LOW_SPEED_POLL_INTERVAL) { 448 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[i], 449 QH_PADDR(uhci_polledp->uhci_polled_qh) | HC_QUEUE_HEAD); 450 } 451 452 /* wait for xfer to finish */ 453 while (GetTD_status(uhcip, td) & UHCI_TD_ACTIVE) 454 #ifndef __sparc 455 invalidate_cache(); 456 #else 457 ; 458 #endif 459 *num_characters_written = GetTD_alen(uhcip, td) + 1; 460 461 /* Now, remove the endpoint from the lattice */ 462 for (i = uhcip->uhci_polled_count; i < NUM_FRAME_LST_ENTRIES; 463 i += MIN_LOW_SPEED_POLL_INTERVAL) { 464 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[i], 465 HC_END_OF_LIST); 466 } 467 468 #ifndef lint 469 _NOTE(COMPETING_THREADS_NOW); 470 #endif 471 472 return (USB_SUCCESS); 473 } 474 475 476 /* 477 * uhci_polled_init: 478 * Initialize generic information that is needed to provide USB/POLLED 479 * support. 480 */ 481 static int 482 uhci_polled_init(usba_pipe_handle_data_t *ph, 483 uhci_state_t *uhcip, 484 usb_console_info_impl_t *console_info) 485 { 486 uhci_polled_t *uhci_polledp; 487 488 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 489 490 /* 491 * If the structure has already been initialized, then we don't 492 * need to redo it. 493 */ 494 if (console_info->uci_private != NULL) { 495 496 return (USB_SUCCESS); 497 } 498 499 /* Allocate and intitialize a polled mode state structure */ 500 uhci_polledp = (uhci_polled_t *)kmem_zalloc(sizeof (uhci_polled_t), 501 KM_SLEEP); 502 503 /* 504 * Keep a copy of normal mode state structure and pipe handle. 505 */ 506 uhci_polledp->uhci_polled_uhcip = uhcip; 507 uhci_polledp->uhci_polled_ph = ph; 508 509 /* 510 * Allocate a queue head for the device. This queue head wiil be 511 * put in action when we switch to polled mode in _enter point. 512 */ 513 uhci_polledp->uhci_polled_qh = uhci_alloc_queue_head(uhcip); 514 515 if (uhci_polledp->uhci_polled_qh == NULL) { 516 kmem_free(uhci_polledp, sizeof (uhci_polled_t)); 517 518 return (USB_NO_RESOURCES); 519 } 520 521 /* 522 * Insert a TD onto the queue head. 523 */ 524 if ((uhci_polled_insert_td_on_qh(uhci_polledp, 525 uhci_polledp->uhci_polled_ph)) != USB_SUCCESS) { 526 uhci_polledp->uhci_polled_qh->qh_flag = QUEUE_HEAD_FLAG_FREE; 527 kmem_free(uhci_polledp, sizeof (uhci_polled_t)); 528 529 return (USB_NO_RESOURCES); 530 } 531 532 console_info->uci_private = (usb_console_info_private_t)uhci_polledp; 533 534 return (USB_SUCCESS); 535 } 536 537 538 /* 539 * uhci_polled_fini: 540 */ 541 static int 542 uhci_polled_fini(uhci_polled_t *uhci_polledp, uhci_state_t *uhcip) 543 { 544 uhci_td_t *td = uhci_polledp->uhci_polled_td; 545 546 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 547 548 /* 549 * Free the transfer wrapper 550 */ 551 uhci_free_tw(uhcip, td->tw); 552 553 /* 554 * Free the queue head and transfer descriptor allocated. 555 */ 556 uhci_polledp->uhci_polled_qh->qh_flag = QUEUE_HEAD_FLAG_FREE; 557 uhci_polledp->uhci_polled_td->flag = TD_FLAG_FREE; 558 559 /* 560 * Deallocate the memory for the polled mode state structure. 561 */ 562 kmem_free(uhci_polledp, sizeof (uhci_polled_t)); 563 564 return (USB_SUCCESS); 565 } 566 567 568 /* 569 * uhci_polled_save_state: 570 */ 571 static void 572 uhci_polled_save_state(uhci_polled_t *uhci_polledp) 573 { 574 int i; 575 uhci_td_t *td, *polled_td; 576 uhci_state_t *uhcip; 577 usba_pipe_handle_data_t *ph; 578 579 #ifndef lint 580 _NOTE(NO_COMPETING_THREADS_NOW); 581 #endif 582 583 /* 584 * If either of these two flags are set, then we have already 585 * saved off the state information and setup the controller. 586 */ 587 if (uhci_polledp->uhci_polled_flags & POLLED_INPUT_MODE_INUSE) { 588 #ifndef lint 589 _NOTE(COMPETING_THREADS_NOW); 590 #endif 591 592 return; 593 } 594 595 uhcip = uhci_polledp->uhci_polled_uhcip; 596 597 /* 598 * Check if the number of keyboard reaches the max number we can 599 * support in polled mode 600 */ 601 if (++ uhcip->uhci_polled_count > MAX_NUM_FOR_KEYBORAD) { 602 #ifndef lint 603 _NOTE(COMPETING_THREADS_NOW); 604 #endif 605 return; 606 } 607 608 /* 609 * Get the normal mode usb pipe handle. 610 */ 611 ph = (usba_pipe_handle_data_t *)uhci_polledp->uhci_polled_ph; 612 /* 613 * Only the first keyboard enter disable the interrutps, stop the 614 * host controller processing and initialize the interrupt table. 615 */ 616 if (uhcip->uhci_polled_count == 1) { 617 /* 618 * Disable interrupts to prevent the interrupt handler getting 619 * called while we are switing to POLLed mode. 620 */ 621 622 Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); 623 624 /* 625 * Stop the HC controller from processing TD's 626 */ 627 Set_OpReg16(USBCMD, 0); 628 629 /* 630 * Save the current interrupt lattice and replace this lattice 631 * with an lattice used in POLLED mode. We will restore lattice 632 * back when we exit from the POLLED mode. 633 */ 634 for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) { 635 uhcip->uhci_polled_save_IntTble[i] = 636 uhcip->uhci_frame_lst_tablep[i]; 637 } 638 639 /* 640 * Zero out the entire interrupt lattice tree. 641 */ 642 for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) { 643 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[i], 644 HC_END_OF_LIST); 645 } 646 } 647 648 /* 649 * Now, add the endpoint to the lattice that we will hang our 650 * TD's off of. We (assume always) need to poll this device at 651 * every 8 ms. 652 */ 653 for (i = uhcip->uhci_polled_count - 1; i < NUM_FRAME_LST_ENTRIES; 654 i += MIN_LOW_SPEED_POLL_INTERVAL) { 655 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[i], 656 QH_PADDR(uhci_polledp->uhci_polled_qh) | HC_QUEUE_HEAD); 657 } 658 659 /* 660 * Adjust the data toggle 661 */ 662 td = uhcip->uhci_outst_tds_head; 663 while (td != NULL) { 664 if (td->tw->tw_pipe_private->pp_pipe_handle == ph) { 665 polled_td = uhci_polledp->uhci_polled_td; 666 if (GetTD_status(uhcip, td) & UHCI_TD_ACTIVE) { 667 SetTD_dtogg(uhcip, polled_td, 668 GetTD_dtogg(uhcip, td)); 669 } else { 670 SetTD_dtogg(uhcip, polled_td, 671 (GetTD_dtogg(uhcip, td) ^ 1)); 672 uhcip->uhci_polled_flag = 673 UHCI_POLLED_FLAG_TD_COMPL; 674 } 675 break; 676 } 677 td = td->outst_td_next; 678 } 679 /* 680 * Only the first keyboard enter reset the frame number and start 681 * the host controler processing. 682 */ 683 if (uhcip->uhci_polled_count == 1) { 684 /* Set the frame number to zero */ 685 Set_OpReg16(FRNUM, 0); 686 687 /* 688 * Start the Host controller processing 689 */ 690 Set_OpReg16(USBCMD, (USBCMD_REG_HC_RUN | USBCMD_REG_MAXPKT_64 | 691 USBCMD_REG_CONFIG_FLAG)); 692 } 693 694 #ifndef lint 695 _NOTE(COMPETING_THREADS_NOW); 696 #endif 697 } 698 699 700 /* 701 * uhci_polled_restore_state: 702 */ 703 static void 704 uhci_polled_restore_state(uhci_polled_t *uhci_polledp) 705 { 706 int i; 707 ushort_t real_data_toggle; 708 uhci_td_t *td, *polled_td; 709 uhci_state_t *uhcip; 710 uhci_pipe_private_t *pp; 711 712 #ifndef lint 713 _NOTE(NO_COMPETING_THREADS_NOW); 714 #endif 715 /* 716 * If this flags is set, then we are still using this structure, 717 * so don't restore any controller state information yet. 718 */ 719 if (uhci_polledp->uhci_polled_flags & POLLED_INPUT_MODE_INUSE) { 720 #ifndef lint 721 _NOTE(COMPETING_THREADS_NOW); 722 #endif 723 return; 724 } 725 726 uhcip = uhci_polledp->uhci_polled_uhcip; 727 uhcip->uhci_polled_count --; 728 729 /* Just first leave keyboard entry turn off the controller */ 730 if (Get_OpReg16(USBCMD)) { 731 Set_OpReg16(USBCMD, 0x0); 732 } 733 /* Only the last leave keyboard entry restore the interrupt table */ 734 if (uhcip->uhci_polled_count == 0) { 735 /* 736 * Replace the lattice 737 */ 738 for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) { 739 uhcip->uhci_frame_lst_tablep[i] = 740 uhcip->uhci_polled_save_IntTble[i]; 741 } 742 } 743 744 /* 745 * Adjust data toggle 746 */ 747 pp = (uhci_pipe_private_t *) 748 uhci_polledp->uhci_polled_ph->p_hcd_private; 749 750 polled_td = uhci_polledp->uhci_polled_td; 751 real_data_toggle = (GetTD_status(uhcip, polled_td) & UHCI_TD_ACTIVE) ? 752 GetTD_dtogg(uhcip, polled_td) : 753 !GetTD_dtogg(uhcip, polled_td); 754 755 td = uhcip->uhci_outst_tds_head; 756 while (td != NULL) { 757 if (td->tw->tw_pipe_private->pp_pipe_handle == 758 uhci_polledp->uhci_polled_ph) { 759 if (GetTD_status(uhcip, td) & UHCI_TD_ACTIVE) { 760 SetTD_dtogg(uhcip, td, real_data_toggle); 761 pp->pp_data_toggle = 762 (real_data_toggle == 0) ? 1 : 0; 763 } else { 764 pp->pp_data_toggle = real_data_toggle; 765 } 766 } 767 td = td->outst_td_next; 768 } 769 770 /* 771 * Only the last leave keyboard entry enable the interrupts, 772 * start Host controller processing. 773 */ 774 if (uhcip->uhci_polled_count == 0) { 775 Set_OpReg16(USBINTR, ENABLE_ALL_INTRS); 776 Set_OpReg16(USBCMD, (USBCMD_REG_HC_RUN | USBCMD_REG_MAXPKT_64 | 777 USBCMD_REG_CONFIG_FLAG)); 778 if (uhcip->uhci_polled_flag == UHCI_POLLED_FLAG_TD_COMPL) { 779 uhcip->uhci_polled_flag = UHCI_POLLED_FLAG_TRUE; 780 } 781 } 782 783 #ifndef lint 784 _NOTE(COMPETING_THREADS_NOW); 785 #endif 786 } 787 788 789 /* 790 * uhci_polled_insert_td: 791 * Initializes the transfer descriptor for polling and inserts on the 792 * polled queue head. This will be put in action when entered in to 793 * polled mode. 794 */ 795 static int 796 uhci_polled_insert_td_on_qh(uhci_polled_t *uhci_polledp, 797 usba_pipe_handle_data_t *ph) 798 { 799 uhci_td_t *td; 800 uhci_state_t *uhcip = uhci_polledp->uhci_polled_uhcip; 801 usb_ep_descr_t *eptd; 802 uhci_trans_wrapper_t *tw; 803 uint_t direction; 804 805 /* Create the transfer wrapper */ 806 if ((tw = uhci_polled_create_tw(uhci_polledp->uhci_polled_uhcip)) == 807 NULL) { 808 809 return (USB_FAILURE); 810 } 811 812 /* Use the dummy TD allocated for the queue head */ 813 td = uhci_polledp->uhci_polled_qh->td_tailp; 814 bzero((char *)td, sizeof (uhci_td_t)); 815 816 uhci_polledp->uhci_polled_td = td; 817 td->tw = tw; 818 td->flag = TD_FLAG_BUSY; 819 SetTD32(uhcip, td->link_ptr, HC_END_OF_LIST); 820 821 mutex_enter(&ph->p_usba_device->usb_mutex); 822 if (ph->p_usba_device->usb_port_status == USBA_LOW_SPEED_DEV) { 823 SetTD_ls(uhcip, td, LOW_SPEED_DEVICE); 824 } 825 826 eptd = &ph->p_ep; 827 direction = (UHCI_XFER_DIR(eptd) == USB_EP_DIR_OUT) ? PID_OUT : PID_IN; 828 SetTD_c_err(uhcip, td, UHCI_MAX_ERR_COUNT); 829 SetTD_mlen(uhcip, td, POLLED_RAW_BUF_SIZE - 1); 830 SetTD_devaddr(uhcip, td, ph->p_usba_device->usb_addr); 831 SetTD_endpt(uhcip, td, eptd->bEndpointAddress & END_POINT_ADDRESS_MASK); 832 SetTD_PID(uhcip, td, direction); 833 SetTD32(uhcip, td->buffer_address, tw->tw_cookie.dmac_address); 834 SetTD_ioc(uhcip, td, INTERRUPT_ON_COMPLETION); 835 SetTD_status(uhcip, td, UHCI_TD_ACTIVE); 836 mutex_exit(&ph->p_usba_device->usb_mutex); 837 838 SetQH32(uhcip, uhci_polledp->uhci_polled_qh->element_ptr, TD_PADDR(td)); 839 840 return (USB_SUCCESS); 841 } 842 843 844 /* 845 * uhci_polled_create_wrapper_t: 846 * Creates the transfer wrapper used in polled mode. 847 */ 848 static uhci_trans_wrapper_t * 849 uhci_polled_create_tw(uhci_state_t *uhcip) 850 { 851 uint_t result, ccount; 852 size_t real_length; 853 uhci_trans_wrapper_t *tw; 854 ddi_device_acc_attr_t dev_attr; 855 856 /* Allocate space for the transfer wrapper */ 857 if ((tw = kmem_zalloc(sizeof (uhci_trans_wrapper_t), KM_NOSLEEP)) == 858 NULL) { 859 860 return (NULL); 861 } 862 863 tw->tw_length = POLLED_RAW_BUF_SIZE; 864 865 /* Allocate the DMA handle */ 866 if ((result = ddi_dma_alloc_handle(uhcip->uhci_dip, 867 &uhcip->uhci_dma_attr, DDI_DMA_DONTWAIT, 0, &tw->tw_dmahandle)) != 868 DDI_SUCCESS) { 869 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 870 871 return (NULL); 872 } 873 874 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 875 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 876 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 877 878 /* Allocate the memory */ 879 if ((result = ddi_dma_mem_alloc(tw->tw_dmahandle, POLLED_RAW_BUF_SIZE, 880 &dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, 881 &tw->tw_buf, &real_length, &tw->tw_accesshandle)) != 882 DDI_SUCCESS) { 883 ddi_dma_free_handle(&tw->tw_dmahandle); 884 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 885 886 return (NULL); 887 } 888 889 /* Bind the handle */ 890 if ((result = ddi_dma_addr_bind_handle(tw->tw_dmahandle, NULL, 891 tw->tw_buf, real_length, DDI_DMA_RDWR|DDI_DMA_CONSISTENT, 892 DDI_DMA_DONTWAIT, NULL, &tw->tw_cookie, &ccount)) != 893 DDI_DMA_MAPPED) { 894 ddi_dma_mem_free(&tw->tw_accesshandle); 895 ddi_dma_free_handle(&tw->tw_dmahandle); 896 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 897 898 return (NULL); 899 } 900 901 /* The cookie count should be 1 */ 902 if (ccount != 1) { 903 result = ddi_dma_unbind_handle(tw->tw_dmahandle); 904 ASSERT(result == DDI_SUCCESS); 905 906 ddi_dma_mem_free(&tw->tw_accesshandle); 907 ddi_dma_free_handle(&tw->tw_dmahandle); 908 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 909 910 return (NULL); 911 } 912 913 return (tw); 914 } 915