17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
53304303fSsl * Common Development and Distribution License (the "License").
63304303fSsl * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
229b58c2adSzhigang lu - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate * EHCI Host Controller Driver (EHCI)
287c478bd9Sstevel@tonic-gate *
297c478bd9Sstevel@tonic-gate * The EHCI driver is a software driver which interfaces to the Universal
307c478bd9Sstevel@tonic-gate * Serial Bus layer (USBA) and the Host Controller (HC). The interface to
317c478bd9Sstevel@tonic-gate * the Host Controller is defined by the EHCI Host Controller Interface.
327c478bd9Sstevel@tonic-gate *
337c478bd9Sstevel@tonic-gate * This module contains the specific EHCI code used in POLLED mode. This
347c478bd9Sstevel@tonic-gate * code is in a separate file since it will never become part of the EHCI
357c478bd9Sstevel@tonic-gate * driver.
367c478bd9Sstevel@tonic-gate */
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate #include <sys/usb/usba/usbai_version.h>
397c478bd9Sstevel@tonic-gate #include <sys/usb/hcd/ehci/ehcid.h>
407c478bd9Sstevel@tonic-gate #include <sys/usb/hcd/ehci/ehci_xfer.h>
417c478bd9Sstevel@tonic-gate #include <sys/usb/hcd/ehci/ehci_intr.h>
427c478bd9Sstevel@tonic-gate #include <sys/usb/hcd/ehci/ehci_util.h>
437c478bd9Sstevel@tonic-gate #include <sys/usb/hcd/ehci/ehci_polled.h>
447c478bd9Sstevel@tonic-gate
459b58c2adSzhigang lu - Sun Microsystems - Beijing China #ifndef __sparc
469b58c2adSzhigang lu - Sun Microsystems - Beijing China extern void invalidate_cache();
479b58c2adSzhigang lu - Sun Microsystems - Beijing China #endif
489b58c2adSzhigang lu - Sun Microsystems - Beijing China
497c478bd9Sstevel@tonic-gate /*
507c478bd9Sstevel@tonic-gate * Internal Function Prototypes
517c478bd9Sstevel@tonic-gate */
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate /* Polled initialization routines */
547c478bd9Sstevel@tonic-gate static int ehci_polled_init(
557c478bd9Sstevel@tonic-gate usba_pipe_handle_data_t *ph,
567c478bd9Sstevel@tonic-gate ehci_state_t *ehcip,
577c478bd9Sstevel@tonic-gate usb_console_info_impl_t *console_input_info);
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate /* Polled deinitialization routines */
607c478bd9Sstevel@tonic-gate static int ehci_polled_fini(ehci_polled_t *ehci_polledp);
617c478bd9Sstevel@tonic-gate
627c478bd9Sstevel@tonic-gate /* Polled save state routines */
637c478bd9Sstevel@tonic-gate static void ehci_polled_save_state(ehci_polled_t *ehci_polledp);
647c478bd9Sstevel@tonic-gate
657c478bd9Sstevel@tonic-gate /* Polled restore state routines */
667c478bd9Sstevel@tonic-gate static void ehci_polled_restore_state(ehci_polled_t *ehci_polledp);
677c478bd9Sstevel@tonic-gate static void ehci_polled_stop_processing(
687c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp);
697c478bd9Sstevel@tonic-gate static void ehci_polled_start_processing(
707c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp);
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate /* Polled read routines */
737c478bd9Sstevel@tonic-gate static int ehci_polled_process_active_intr_qtd_list(
747c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp);
757c478bd9Sstevel@tonic-gate static int ehci_polled_handle_normal_qtd(
767c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp,
777c478bd9Sstevel@tonic-gate ehci_qtd_t *qtd);
789b58c2adSzhigang lu - Sun Microsystems - Beijing China static void ehci_polled_insert_intr_qtd(
797c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp,
807c478bd9Sstevel@tonic-gate ehci_qtd_t *qtd);
819b58c2adSzhigang lu - Sun Microsystems - Beijing China static void ehci_polled_insert_bulk_qtd(
829b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_t *ehci_polledp);
837c478bd9Sstevel@tonic-gate static void ehci_polled_fill_in_qtd(
847c478bd9Sstevel@tonic-gate ehci_state_t *ehcip,
857c478bd9Sstevel@tonic-gate ehci_qtd_t *qtd,
867c478bd9Sstevel@tonic-gate uint_t qtd_ctrl,
873304303fSsl size_t qtd_dma_offs,
887c478bd9Sstevel@tonic-gate size_t qtd_length,
897c478bd9Sstevel@tonic-gate ehci_trans_wrapper_t *tw);
907c478bd9Sstevel@tonic-gate static void ehci_polled_insert_qtd_on_tw(
917c478bd9Sstevel@tonic-gate ehci_state_t *ehcip,
927c478bd9Sstevel@tonic-gate ehci_trans_wrapper_t *tw,
937c478bd9Sstevel@tonic-gate ehci_qtd_t *qtd);
947c478bd9Sstevel@tonic-gate static ehci_qtd_t *ehci_polled_create_done_qtd_list(
957c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp);
967c478bd9Sstevel@tonic-gate static void ehci_polled_insert_qtd_into_active_intr_qtd_list(
977c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp,
987c478bd9Sstevel@tonic-gate ehci_qtd_t *curr_qtd);
997c478bd9Sstevel@tonic-gate static void ehci_polled_remove_qtd_from_active_intr_qtd_list(
1007c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp,
1017c478bd9Sstevel@tonic-gate ehci_qtd_t *curr_qtd);
1027c478bd9Sstevel@tonic-gate static void ehci_polled_traverse_qtds(
1037c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp,
1047c478bd9Sstevel@tonic-gate usba_pipe_handle_data_t *ph);
1057c478bd9Sstevel@tonic-gate static void ehci_polled_finish_interrupt(
1067c478bd9Sstevel@tonic-gate ehci_state_t *ehcip,
1077c478bd9Sstevel@tonic-gate uint_t intr);
1089b58c2adSzhigang lu - Sun Microsystems - Beijing China static int ehci_polled_create_tw(
1099b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_t *ehci_polledp,
1109b58c2adSzhigang lu - Sun Microsystems - Beijing China usba_pipe_handle_data_t *ph,
1119b58c2adSzhigang lu - Sun Microsystems - Beijing China usb_flags_t usb_flags);
1129b58c2adSzhigang lu - Sun Microsystems - Beijing China static void ehci_polled_insert_async_qh(
1139b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_state_t *ehcip,
1149b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_pipe_private_t *pp);
1159b58c2adSzhigang lu - Sun Microsystems - Beijing China static void ehci_polled_remove_async_qh(
1169b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_state_t *ehcip,
1179b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_pipe_private_t *pp);
1187c478bd9Sstevel@tonic-gate
1197c478bd9Sstevel@tonic-gate /*
1207c478bd9Sstevel@tonic-gate * POLLED entry points
1217c478bd9Sstevel@tonic-gate *
1227c478bd9Sstevel@tonic-gate * These functions are entry points into the POLLED code.
1237c478bd9Sstevel@tonic-gate */
1247c478bd9Sstevel@tonic-gate
1257c478bd9Sstevel@tonic-gate /*
1267c478bd9Sstevel@tonic-gate * ehci_hcdi_polled_input_init:
1277c478bd9Sstevel@tonic-gate *
1289b58c2adSzhigang lu - Sun Microsystems - Beijing China * This is the initialization routine for handling the USB input device
1297c478bd9Sstevel@tonic-gate * in POLLED mode. This routine is not called from POLLED mode, so
1307c478bd9Sstevel@tonic-gate * it is OK to acquire mutexes.
1317c478bd9Sstevel@tonic-gate */
1327c478bd9Sstevel@tonic-gate int
ehci_hcdi_polled_input_init(usba_pipe_handle_data_t * ph,uchar_t ** polled_buf,usb_console_info_impl_t * console_input_info)1337c478bd9Sstevel@tonic-gate ehci_hcdi_polled_input_init(
1347c478bd9Sstevel@tonic-gate usba_pipe_handle_data_t *ph,
1357c478bd9Sstevel@tonic-gate uchar_t **polled_buf,
1367c478bd9Sstevel@tonic-gate usb_console_info_impl_t *console_input_info)
1377c478bd9Sstevel@tonic-gate {
1387c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp;
1397c478bd9Sstevel@tonic-gate ehci_state_t *ehcip;
1407c478bd9Sstevel@tonic-gate int ret;
1417c478bd9Sstevel@tonic-gate
1427c478bd9Sstevel@tonic-gate ehcip = ehci_obtain_state(ph->p_usba_device->usb_root_hub_dip);
1437c478bd9Sstevel@tonic-gate
1447c478bd9Sstevel@tonic-gate /*
1457c478bd9Sstevel@tonic-gate * Grab the ehci_int_mutex so that things don't change on us
1467c478bd9Sstevel@tonic-gate * if an interrupt comes in.
1477c478bd9Sstevel@tonic-gate */
1487c478bd9Sstevel@tonic-gate mutex_enter(&ehcip->ehci_int_mutex);
1497c478bd9Sstevel@tonic-gate
1507c478bd9Sstevel@tonic-gate ret = ehci_polled_init(ph, ehcip, console_input_info);
1517c478bd9Sstevel@tonic-gate
1527c478bd9Sstevel@tonic-gate if (ret != USB_SUCCESS) {
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate /* Allow interrupts to continue */
1557c478bd9Sstevel@tonic-gate mutex_exit(&ehcip->ehci_int_mutex);
1567c478bd9Sstevel@tonic-gate return (ret);
1577c478bd9Sstevel@tonic-gate }
1587c478bd9Sstevel@tonic-gate
1597c478bd9Sstevel@tonic-gate ehci_polledp = (ehci_polled_t *)console_input_info->uci_private;
1607c478bd9Sstevel@tonic-gate
1617c478bd9Sstevel@tonic-gate /*
1627c478bd9Sstevel@tonic-gate * Mark the structure so that if we are using it, we don't free
1637c478bd9Sstevel@tonic-gate * the structures if one of them is unplugged.
1647c478bd9Sstevel@tonic-gate */
1657c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_flags |= POLLED_INPUT_MODE;
1667c478bd9Sstevel@tonic-gate
1677c478bd9Sstevel@tonic-gate /* increase the counter for keyboard connected */
1687c478bd9Sstevel@tonic-gate ehcip->ehci_polled_kbd_count ++;
1697c478bd9Sstevel@tonic-gate
1707c478bd9Sstevel@tonic-gate /*
1717c478bd9Sstevel@tonic-gate * This is the buffer we will copy characters into. It will be
1727c478bd9Sstevel@tonic-gate * copied into at this layer, so we need to keep track of it.
1737c478bd9Sstevel@tonic-gate */
1747c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_buf =
1757c478bd9Sstevel@tonic-gate (uchar_t *)kmem_zalloc(POLLED_RAW_BUF_SIZE, KM_SLEEP);
1767c478bd9Sstevel@tonic-gate
1777c478bd9Sstevel@tonic-gate *polled_buf = ehci_polledp->ehci_polled_buf;
1787c478bd9Sstevel@tonic-gate
1797c478bd9Sstevel@tonic-gate /*
1807c478bd9Sstevel@tonic-gate * This is a software workaround to fix schizo hardware bug.
1817c478bd9Sstevel@tonic-gate * Existence of "no-prom-cdma-sync" property means consistent
1827c478bd9Sstevel@tonic-gate * dma sync should not be done while in prom or polled mode.
1837c478bd9Sstevel@tonic-gate */
1847c478bd9Sstevel@tonic-gate if (ddi_prop_exists(DDI_DEV_T_ANY, ehcip->ehci_dip,
1857c478bd9Sstevel@tonic-gate DDI_PROP_NOTPROM, "no-prom-cdma-sync")) {
1867c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_no_sync_flag = B_TRUE;
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate
1897c478bd9Sstevel@tonic-gate /* Allow interrupts to continue */
1907c478bd9Sstevel@tonic-gate mutex_exit(&ehcip->ehci_int_mutex);
1917c478bd9Sstevel@tonic-gate
1927c478bd9Sstevel@tonic-gate return (USB_SUCCESS);
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gate
1967c478bd9Sstevel@tonic-gate /*
1977c478bd9Sstevel@tonic-gate * ehci_hcdi_polled_input_fini:
1987c478bd9Sstevel@tonic-gate */
1997c478bd9Sstevel@tonic-gate int
ehci_hcdi_polled_input_fini(usb_console_info_impl_t * info)2007c478bd9Sstevel@tonic-gate ehci_hcdi_polled_input_fini(usb_console_info_impl_t *info)
2017c478bd9Sstevel@tonic-gate {
2027c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp;
2037c478bd9Sstevel@tonic-gate ehci_state_t *ehcip;
2047c478bd9Sstevel@tonic-gate int ret;
2057c478bd9Sstevel@tonic-gate
2067c478bd9Sstevel@tonic-gate ehci_polledp = (ehci_polled_t *)info->uci_private;
2077c478bd9Sstevel@tonic-gate
2087c478bd9Sstevel@tonic-gate ehcip = ehci_polledp->ehci_polled_ehcip;
2097c478bd9Sstevel@tonic-gate
2107c478bd9Sstevel@tonic-gate mutex_enter(&ehcip->ehci_int_mutex);
2117c478bd9Sstevel@tonic-gate
2127c478bd9Sstevel@tonic-gate /*
2137c478bd9Sstevel@tonic-gate * Reset the POLLED_INPUT_MODE flag so that we can tell if
2147c478bd9Sstevel@tonic-gate * this structure is in use in the ehci_polled_fini routine.
2157c478bd9Sstevel@tonic-gate */
2167c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_flags &= ~POLLED_INPUT_MODE;
2177c478bd9Sstevel@tonic-gate
2187c478bd9Sstevel@tonic-gate /* decrease the counter for keyboard disconnected */
2197c478bd9Sstevel@tonic-gate ehcip->ehci_polled_kbd_count --;
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate /* Free the buffer that we copied data into */
2227c478bd9Sstevel@tonic-gate kmem_free(ehci_polledp->ehci_polled_buf, POLLED_RAW_BUF_SIZE);
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate ret = ehci_polled_fini(ehci_polledp);
2257c478bd9Sstevel@tonic-gate
2267c478bd9Sstevel@tonic-gate mutex_exit(&ehcip->ehci_int_mutex);
2277c478bd9Sstevel@tonic-gate
2287c478bd9Sstevel@tonic-gate return (ret);
2297c478bd9Sstevel@tonic-gate }
2307c478bd9Sstevel@tonic-gate
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate /*
2337c478bd9Sstevel@tonic-gate * ehci_hcdi_polled_input_enter:
2347c478bd9Sstevel@tonic-gate *
2357c478bd9Sstevel@tonic-gate * This is where we enter into POLLED mode. This routine sets up
2367c478bd9Sstevel@tonic-gate * everything so that calls to ehci_hcdi_polled_read will return
2377c478bd9Sstevel@tonic-gate * characters.
2387c478bd9Sstevel@tonic-gate */
2397c478bd9Sstevel@tonic-gate int
ehci_hcdi_polled_input_enter(usb_console_info_impl_t * info)2407c478bd9Sstevel@tonic-gate ehci_hcdi_polled_input_enter(usb_console_info_impl_t *info)
2417c478bd9Sstevel@tonic-gate {
2427c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp;
2439b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_state_t *ehcip;
2449b58c2adSzhigang lu - Sun Microsystems - Beijing China usba_pipe_handle_data_t *ph;
2459b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_pipe_private_t *pp;
2469b58c2adSzhigang lu - Sun Microsystems - Beijing China int pipe_attr;
2477c478bd9Sstevel@tonic-gate
2489b58c2adSzhigang lu - Sun Microsystems - Beijing China #ifndef lint
2499b58c2adSzhigang lu - Sun Microsystems - Beijing China _NOTE(NO_COMPETING_THREADS_NOW);
2509b58c2adSzhigang lu - Sun Microsystems - Beijing China #endif
2517c478bd9Sstevel@tonic-gate ehci_polledp = (ehci_polled_t *)info->uci_private;
2529b58c2adSzhigang lu - Sun Microsystems - Beijing China ehcip = ehci_polledp->ehci_polled_ehcip;
2539b58c2adSzhigang lu - Sun Microsystems - Beijing China ph = ehci_polledp->ehci_polled_input_pipe_handle;
2549b58c2adSzhigang lu - Sun Microsystems - Beijing China pp = (ehci_pipe_private_t *)ph->p_hcd_private;
2557c478bd9Sstevel@tonic-gate
2569b58c2adSzhigang lu - Sun Microsystems - Beijing China pipe_attr = ph->p_ep.bmAttributes & USB_EP_ATTR_MASK;
2579b58c2adSzhigang lu - Sun Microsystems - Beijing China #ifndef lint
2589b58c2adSzhigang lu - Sun Microsystems - Beijing China _NOTE(COMPETING_THREADS_NOW);
2599b58c2adSzhigang lu - Sun Microsystems - Beijing China #endif
2607c478bd9Sstevel@tonic-gate
2619b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polledp->ehci_polled_entry++;
2627c478bd9Sstevel@tonic-gate /*
2637c478bd9Sstevel@tonic-gate * If the controller is already switched over, just return
2647c478bd9Sstevel@tonic-gate */
2657c478bd9Sstevel@tonic-gate if (ehci_polledp->ehci_polled_entry > 1) {
2667c478bd9Sstevel@tonic-gate
2677c478bd9Sstevel@tonic-gate return (USB_SUCCESS);
2687c478bd9Sstevel@tonic-gate }
2697c478bd9Sstevel@tonic-gate
2709b58c2adSzhigang lu - Sun Microsystems - Beijing China switch (pipe_attr) {
2719b58c2adSzhigang lu - Sun Microsystems - Beijing China case USB_EP_ATTR_INTR:
2729b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_save_state(ehci_polledp);
2739b58c2adSzhigang lu - Sun Microsystems - Beijing China break;
2749b58c2adSzhigang lu - Sun Microsystems - Beijing China case USB_EP_ATTR_BULK:
2759b58c2adSzhigang lu - Sun Microsystems - Beijing China #ifndef lint
2769b58c2adSzhigang lu - Sun Microsystems - Beijing China _NOTE(NO_COMPETING_THREADS_NOW);
2779b58c2adSzhigang lu - Sun Microsystems - Beijing China #endif
2789b58c2adSzhigang lu - Sun Microsystems - Beijing China Set_OpReg(ehci_command, (Get_OpReg(ehci_command) &
2799b58c2adSzhigang lu - Sun Microsystems - Beijing China ~(EHCI_CMD_PERIODIC_SCHED_ENABLE |
2809b58c2adSzhigang lu - Sun Microsystems - Beijing China EHCI_CMD_ASYNC_SCHED_ENABLE)));
2819b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Wait for few milliseconds */
2829b58c2adSzhigang lu - Sun Microsystems - Beijing China drv_usecwait(EHCI_POLLED_TIMEWAIT);
2839b58c2adSzhigang lu - Sun Microsystems - Beijing China
2849b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_insert_async_qh(ehcip, pp);
2859b58c2adSzhigang lu - Sun Microsystems - Beijing China
2869b58c2adSzhigang lu - Sun Microsystems - Beijing China Set_OpReg(ehci_command,
2879b58c2adSzhigang lu - Sun Microsystems - Beijing China (Get_OpReg(ehci_command) | EHCI_CMD_ASYNC_SCHED_ENABLE));
2889b58c2adSzhigang lu - Sun Microsystems - Beijing China #ifndef lint
2899b58c2adSzhigang lu - Sun Microsystems - Beijing China _NOTE(COMPETING_THREADS_NOW);
2909b58c2adSzhigang lu - Sun Microsystems - Beijing China #endif
2919b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Wait for few milliseconds */
2929b58c2adSzhigang lu - Sun Microsystems - Beijing China drv_usecwait(EHCI_POLLED_TIMEWAIT);
2939b58c2adSzhigang lu - Sun Microsystems - Beijing China break;
2949b58c2adSzhigang lu - Sun Microsystems - Beijing China default:
2959b58c2adSzhigang lu - Sun Microsystems - Beijing China return (USB_FAILURE);
2969b58c2adSzhigang lu - Sun Microsystems - Beijing China }
2977c478bd9Sstevel@tonic-gate
2987c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_flags |= POLLED_INPUT_MODE_INUSE;
2997c478bd9Sstevel@tonic-gate
3007c478bd9Sstevel@tonic-gate return (USB_SUCCESS);
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate /*
3057c478bd9Sstevel@tonic-gate * ehci_hcdi_polled_input_exit:
3067c478bd9Sstevel@tonic-gate *
3077c478bd9Sstevel@tonic-gate * This is where we exit POLLED mode. This routine restores
3087c478bd9Sstevel@tonic-gate * everything that is needed to continue operation.
3097c478bd9Sstevel@tonic-gate */
3107c478bd9Sstevel@tonic-gate int
ehci_hcdi_polled_input_exit(usb_console_info_impl_t * info)3117c478bd9Sstevel@tonic-gate ehci_hcdi_polled_input_exit(usb_console_info_impl_t *info)
3127c478bd9Sstevel@tonic-gate {
3137c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp;
3149b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_state_t *ehcip;
3159b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_pipe_private_t *pp;
3169b58c2adSzhigang lu - Sun Microsystems - Beijing China int pipe_attr;
3177c478bd9Sstevel@tonic-gate
3189b58c2adSzhigang lu - Sun Microsystems - Beijing China #ifndef lint
3199b58c2adSzhigang lu - Sun Microsystems - Beijing China _NOTE(NO_COMPETING_THREADS_NOW);
3209b58c2adSzhigang lu - Sun Microsystems - Beijing China #endif
3217c478bd9Sstevel@tonic-gate ehci_polledp = (ehci_polled_t *)info->uci_private;
3229b58c2adSzhigang lu - Sun Microsystems - Beijing China ehcip = ehci_polledp->ehci_polled_ehcip;
3239b58c2adSzhigang lu - Sun Microsystems - Beijing China pp = (ehci_pipe_private_t *)ehci_polledp->
3249b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_input_pipe_handle->p_hcd_private;
3259b58c2adSzhigang lu - Sun Microsystems - Beijing China
3269b58c2adSzhigang lu - Sun Microsystems - Beijing China pipe_attr = ehci_polledp->ehci_polled_input_pipe_handle->
3279b58c2adSzhigang lu - Sun Microsystems - Beijing China p_ep.bmAttributes & USB_EP_ATTR_MASK;
3289b58c2adSzhigang lu - Sun Microsystems - Beijing China #ifndef lint
3299b58c2adSzhigang lu - Sun Microsystems - Beijing China _NOTE(COMPETING_THREADS_NOW);
3309b58c2adSzhigang lu - Sun Microsystems - Beijing China #endif
3317c478bd9Sstevel@tonic-gate
3327c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_entry--;
3337c478bd9Sstevel@tonic-gate
3347c478bd9Sstevel@tonic-gate /*
3357c478bd9Sstevel@tonic-gate * If there are still outstanding "enters", just return
3367c478bd9Sstevel@tonic-gate */
3377c478bd9Sstevel@tonic-gate if (ehci_polledp->ehci_polled_entry > 0) {
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate return (USB_SUCCESS);
3407c478bd9Sstevel@tonic-gate }
3417c478bd9Sstevel@tonic-gate
3427c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_flags &= ~POLLED_INPUT_MODE_INUSE;
3437c478bd9Sstevel@tonic-gate
3449b58c2adSzhigang lu - Sun Microsystems - Beijing China switch (pipe_attr & USB_EP_ATTR_MASK) {
3459b58c2adSzhigang lu - Sun Microsystems - Beijing China case USB_EP_ATTR_INTR:
3469b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_restore_state(ehci_polledp);
3479b58c2adSzhigang lu - Sun Microsystems - Beijing China break;
3489b58c2adSzhigang lu - Sun Microsystems - Beijing China case USB_EP_ATTR_BULK:
3499b58c2adSzhigang lu - Sun Microsystems - Beijing China #ifndef lint
3509b58c2adSzhigang lu - Sun Microsystems - Beijing China _NOTE(NO_COMPETING_THREADS_NOW);
3519b58c2adSzhigang lu - Sun Microsystems - Beijing China #endif
3529b58c2adSzhigang lu - Sun Microsystems - Beijing China Set_OpReg(ehci_command, (Get_OpReg(ehci_command) &
3539b58c2adSzhigang lu - Sun Microsystems - Beijing China ~(EHCI_CMD_PERIODIC_SCHED_ENABLE |
3549b58c2adSzhigang lu - Sun Microsystems - Beijing China EHCI_CMD_ASYNC_SCHED_ENABLE)));
3559b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Wait for few milliseconds */
3569b58c2adSzhigang lu - Sun Microsystems - Beijing China drv_usecwait(EHCI_POLLED_TIMEWAIT);
3579b58c2adSzhigang lu - Sun Microsystems - Beijing China
3589b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_remove_async_qh(ehcip, pp);
3599b58c2adSzhigang lu - Sun Microsystems - Beijing China
3609b58c2adSzhigang lu - Sun Microsystems - Beijing China Set_OpReg(ehci_command,
3619b58c2adSzhigang lu - Sun Microsystems - Beijing China (Get_OpReg(ehci_command) | EHCI_CMD_ASYNC_SCHED_ENABLE |
3629b58c2adSzhigang lu - Sun Microsystems - Beijing China EHCI_CMD_ASYNC_SCHED_ENABLE));
3639b58c2adSzhigang lu - Sun Microsystems - Beijing China #ifndef lint
3649b58c2adSzhigang lu - Sun Microsystems - Beijing China _NOTE(COMPETING_THREADS_NOW);
3659b58c2adSzhigang lu - Sun Microsystems - Beijing China #endif
3669b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Wait for few milliseconds */
3679b58c2adSzhigang lu - Sun Microsystems - Beijing China drv_usecwait(EHCI_POLLED_TIMEWAIT);
3689b58c2adSzhigang lu - Sun Microsystems - Beijing China break;
3699b58c2adSzhigang lu - Sun Microsystems - Beijing China default:
3709b58c2adSzhigang lu - Sun Microsystems - Beijing China return (USB_FAILURE);
3719b58c2adSzhigang lu - Sun Microsystems - Beijing China
3729b58c2adSzhigang lu - Sun Microsystems - Beijing China }
3737c478bd9Sstevel@tonic-gate
3747c478bd9Sstevel@tonic-gate return (USB_SUCCESS);
3757c478bd9Sstevel@tonic-gate }
3767c478bd9Sstevel@tonic-gate
3777c478bd9Sstevel@tonic-gate
3787c478bd9Sstevel@tonic-gate /*
3797c478bd9Sstevel@tonic-gate * ehci_hcdi_polled_read:
3807c478bd9Sstevel@tonic-gate *
3817c478bd9Sstevel@tonic-gate * Get a key character
3827c478bd9Sstevel@tonic-gate */
3837c478bd9Sstevel@tonic-gate int
ehci_hcdi_polled_read(usb_console_info_impl_t * info,uint_t * num_characters)3847c478bd9Sstevel@tonic-gate ehci_hcdi_polled_read(
3857c478bd9Sstevel@tonic-gate usb_console_info_impl_t *info,
3867c478bd9Sstevel@tonic-gate uint_t *num_characters)
3877c478bd9Sstevel@tonic-gate {
3887c478bd9Sstevel@tonic-gate ehci_state_t *ehcip;
3897c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp;
3907c478bd9Sstevel@tonic-gate uint_t intr;
3919b58c2adSzhigang lu - Sun Microsystems - Beijing China int pipe_attr;
3927c478bd9Sstevel@tonic-gate
3937c478bd9Sstevel@tonic-gate ehci_polledp = (ehci_polled_t *)info->uci_private;
3947c478bd9Sstevel@tonic-gate
3957c478bd9Sstevel@tonic-gate ehcip = ehci_polledp->ehci_polled_ehcip;
3967c478bd9Sstevel@tonic-gate
3977c478bd9Sstevel@tonic-gate #ifndef lint
3987c478bd9Sstevel@tonic-gate _NOTE(NO_COMPETING_THREADS_NOW);
3997c478bd9Sstevel@tonic-gate #endif
4007c478bd9Sstevel@tonic-gate
4017c478bd9Sstevel@tonic-gate *num_characters = 0;
4027c478bd9Sstevel@tonic-gate
4039b58c2adSzhigang lu - Sun Microsystems - Beijing China pipe_attr = ehci_polledp->ehci_polled_input_pipe_handle->
4049b58c2adSzhigang lu - Sun Microsystems - Beijing China p_ep.bmAttributes & USB_EP_ATTR_MASK;
4059b58c2adSzhigang lu - Sun Microsystems - Beijing China
4069b58c2adSzhigang lu - Sun Microsystems - Beijing China if (pipe_attr == USB_EP_ATTR_BULK) {
4079b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_insert_bulk_qtd(ehci_polledp);
4089b58c2adSzhigang lu - Sun Microsystems - Beijing China }
4099b58c2adSzhigang lu - Sun Microsystems - Beijing China
4107c478bd9Sstevel@tonic-gate intr = ((Get_OpReg(ehci_status) & Get_OpReg(ehci_interrupt)) &
4117c478bd9Sstevel@tonic-gate (EHCI_INTR_FRAME_LIST_ROLLOVER |
4127c478bd9Sstevel@tonic-gate EHCI_INTR_USB | EHCI_INTR_USB_ERROR));
4137c478bd9Sstevel@tonic-gate
4147c478bd9Sstevel@tonic-gate /*
4157c478bd9Sstevel@tonic-gate * Check whether any frame list rollover interrupt is pending
4167c478bd9Sstevel@tonic-gate * and if it is pending, process this interrupt.
4177c478bd9Sstevel@tonic-gate */
4187c478bd9Sstevel@tonic-gate if (intr & EHCI_INTR_FRAME_LIST_ROLLOVER) {
4197c478bd9Sstevel@tonic-gate /* Check any frame list rollover interrupt is pending */
4207c478bd9Sstevel@tonic-gate ehci_handle_frame_list_rollover(ehcip);
4217c478bd9Sstevel@tonic-gate ehci_polled_finish_interrupt(ehcip,
4227c478bd9Sstevel@tonic-gate EHCI_INTR_FRAME_LIST_ROLLOVER);
4237c478bd9Sstevel@tonic-gate }
4247c478bd9Sstevel@tonic-gate
4259b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Process any QTD's on the active interrupt qtd list */
4269b58c2adSzhigang lu - Sun Microsystems - Beijing China *num_characters =
4279b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_process_active_intr_qtd_list(ehci_polledp);
4289b58c2adSzhigang lu - Sun Microsystems - Beijing China
4299b58c2adSzhigang lu - Sun Microsystems - Beijing China #ifndef lint
4309b58c2adSzhigang lu - Sun Microsystems - Beijing China _NOTE(COMPETING_THREADS_NOW);
4319b58c2adSzhigang lu - Sun Microsystems - Beijing China #endif
4329b58c2adSzhigang lu - Sun Microsystems - Beijing China
4339b58c2adSzhigang lu - Sun Microsystems - Beijing China return (USB_SUCCESS);
4349b58c2adSzhigang lu - Sun Microsystems - Beijing China }
4359b58c2adSzhigang lu - Sun Microsystems - Beijing China
4369b58c2adSzhigang lu - Sun Microsystems - Beijing China
4379b58c2adSzhigang lu - Sun Microsystems - Beijing China /*
4389b58c2adSzhigang lu - Sun Microsystems - Beijing China * ehci_hcdi_polled_output_init:
4399b58c2adSzhigang lu - Sun Microsystems - Beijing China *
4409b58c2adSzhigang lu - Sun Microsystems - Beijing China * This is the initialization routine for handling the USB serial output
4419b58c2adSzhigang lu - Sun Microsystems - Beijing China * in POLLED mode. This routine is not called from POLLED mode, so
4429b58c2adSzhigang lu - Sun Microsystems - Beijing China * it is OK to acquire mutexes.
4439b58c2adSzhigang lu - Sun Microsystems - Beijing China */
4449b58c2adSzhigang lu - Sun Microsystems - Beijing China int
ehci_hcdi_polled_output_init(usba_pipe_handle_data_t * ph,usb_console_info_impl_t * console_output_info)4459b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_hcdi_polled_output_init(
4469b58c2adSzhigang lu - Sun Microsystems - Beijing China usba_pipe_handle_data_t *ph,
4479b58c2adSzhigang lu - Sun Microsystems - Beijing China usb_console_info_impl_t *console_output_info)
4489b58c2adSzhigang lu - Sun Microsystems - Beijing China {
4499b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_t *ehci_polledp;
4509b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_state_t *ehcip;
4519b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_pipe_private_t *pp;
4529b58c2adSzhigang lu - Sun Microsystems - Beijing China int ret;
4539b58c2adSzhigang lu - Sun Microsystems - Beijing China
4549b58c2adSzhigang lu - Sun Microsystems - Beijing China ehcip = ehci_obtain_state(ph->p_usba_device->usb_root_hub_dip);
4559b58c2adSzhigang lu - Sun Microsystems - Beijing China
4569b58c2adSzhigang lu - Sun Microsystems - Beijing China /*
4579b58c2adSzhigang lu - Sun Microsystems - Beijing China * Grab the ehci_int_mutex so that things don't change on us
4589b58c2adSzhigang lu - Sun Microsystems - Beijing China * if an interrupt comes in.
4599b58c2adSzhigang lu - Sun Microsystems - Beijing China */
4609b58c2adSzhigang lu - Sun Microsystems - Beijing China mutex_enter(&ehcip->ehci_int_mutex);
4619b58c2adSzhigang lu - Sun Microsystems - Beijing China
4629b58c2adSzhigang lu - Sun Microsystems - Beijing China ret = ehci_polled_init(ph, ehcip, console_output_info);
4639b58c2adSzhigang lu - Sun Microsystems - Beijing China
4649b58c2adSzhigang lu - Sun Microsystems - Beijing China if (ret != USB_SUCCESS) {
4659b58c2adSzhigang lu - Sun Microsystems - Beijing China
4669b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Allow interrupts to continue */
4679b58c2adSzhigang lu - Sun Microsystems - Beijing China mutex_exit(&ehcip->ehci_int_mutex);
4689b58c2adSzhigang lu - Sun Microsystems - Beijing China
4699b58c2adSzhigang lu - Sun Microsystems - Beijing China return (ret);
4709b58c2adSzhigang lu - Sun Microsystems - Beijing China }
4719b58c2adSzhigang lu - Sun Microsystems - Beijing China
4729b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polledp = (ehci_polled_t *)console_output_info->uci_private;
4739b58c2adSzhigang lu - Sun Microsystems - Beijing China /*
4749b58c2adSzhigang lu - Sun Microsystems - Beijing China * Mark the structure so that if we are using it, we don't free
4759b58c2adSzhigang lu - Sun Microsystems - Beijing China * the structures if one of them is unplugged.
4769b58c2adSzhigang lu - Sun Microsystems - Beijing China */
4779b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polledp->ehci_polled_flags |= POLLED_OUTPUT_MODE;
4789b58c2adSzhigang lu - Sun Microsystems - Beijing China
4799b58c2adSzhigang lu - Sun Microsystems - Beijing China /*
4809b58c2adSzhigang lu - Sun Microsystems - Beijing China * Insert the Endpoint Descriptor to appropriate endpoint list.
4819b58c2adSzhigang lu - Sun Microsystems - Beijing China */
4829b58c2adSzhigang lu - Sun Microsystems - Beijing China pp = (ehci_pipe_private_t *)ehci_polledp->
4839b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_input_pipe_handle->p_hcd_private;
4849b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_insert_async_qh(ehcip, pp);
4859b58c2adSzhigang lu - Sun Microsystems - Beijing China
4869b58c2adSzhigang lu - Sun Microsystems - Beijing China /*
4879b58c2adSzhigang lu - Sun Microsystems - Beijing China * This is a software workaround to fix schizo hardware bug.
4889b58c2adSzhigang lu - Sun Microsystems - Beijing China * Existence of "no-prom-cdma-sync" property means consistent
4899b58c2adSzhigang lu - Sun Microsystems - Beijing China * dma sync should not be done while in prom or polled mode.
4909b58c2adSzhigang lu - Sun Microsystems - Beijing China */
4919b58c2adSzhigang lu - Sun Microsystems - Beijing China if (ddi_prop_exists(DDI_DEV_T_ANY, ehcip->ehci_dip,
4929b58c2adSzhigang lu - Sun Microsystems - Beijing China DDI_PROP_NOTPROM, "no-prom-cdma-sync")) {
4939b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polledp->ehci_polled_no_sync_flag = B_TRUE;
4949b58c2adSzhigang lu - Sun Microsystems - Beijing China }
4959b58c2adSzhigang lu - Sun Microsystems - Beijing China
4969b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Allow interrupts to continue */
4979b58c2adSzhigang lu - Sun Microsystems - Beijing China mutex_exit(&ehcip->ehci_int_mutex);
4989b58c2adSzhigang lu - Sun Microsystems - Beijing China
4999b58c2adSzhigang lu - Sun Microsystems - Beijing China return (USB_SUCCESS);
5009b58c2adSzhigang lu - Sun Microsystems - Beijing China }
5019b58c2adSzhigang lu - Sun Microsystems - Beijing China
5029b58c2adSzhigang lu - Sun Microsystems - Beijing China
5039b58c2adSzhigang lu - Sun Microsystems - Beijing China /*
5049b58c2adSzhigang lu - Sun Microsystems - Beijing China * ehci_hcdi_polled_output_fini:
5059b58c2adSzhigang lu - Sun Microsystems - Beijing China */
5069b58c2adSzhigang lu - Sun Microsystems - Beijing China int
ehci_hcdi_polled_output_fini(usb_console_info_impl_t * info)5079b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_hcdi_polled_output_fini(usb_console_info_impl_t *info)
5089b58c2adSzhigang lu - Sun Microsystems - Beijing China {
5099b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_t *ehci_polledp;
5109b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_state_t *ehcip;
5119b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_pipe_private_t *pp;
5129b58c2adSzhigang lu - Sun Microsystems - Beijing China int ret;
5139b58c2adSzhigang lu - Sun Microsystems - Beijing China
5149b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polledp = (ehci_polled_t *)info->uci_private;
5159b58c2adSzhigang lu - Sun Microsystems - Beijing China
5169b58c2adSzhigang lu - Sun Microsystems - Beijing China ehcip = ehci_polledp->ehci_polled_ehcip;
5179b58c2adSzhigang lu - Sun Microsystems - Beijing China
5189b58c2adSzhigang lu - Sun Microsystems - Beijing China mutex_enter(&ehcip->ehci_int_mutex);
5199b58c2adSzhigang lu - Sun Microsystems - Beijing China
5209b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Remove the Endpoint Descriptor. */
5219b58c2adSzhigang lu - Sun Microsystems - Beijing China pp = (ehci_pipe_private_t *)ehci_polledp->
5229b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_input_pipe_handle->p_hcd_private;
5239b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_remove_async_qh(ehcip, pp);
5249b58c2adSzhigang lu - Sun Microsystems - Beijing China
5259b58c2adSzhigang lu - Sun Microsystems - Beijing China /*
5269b58c2adSzhigang lu - Sun Microsystems - Beijing China * Reset the POLLED_INPUT_MODE flag so that we can tell if
5279b58c2adSzhigang lu - Sun Microsystems - Beijing China * this structure is in use in the ehci_polled_fini routine.
5289b58c2adSzhigang lu - Sun Microsystems - Beijing China */
5299b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polledp->ehci_polled_flags &= ~POLLED_OUTPUT_MODE;
5309b58c2adSzhigang lu - Sun Microsystems - Beijing China
5319b58c2adSzhigang lu - Sun Microsystems - Beijing China ret = ehci_polled_fini(ehci_polledp);
5329b58c2adSzhigang lu - Sun Microsystems - Beijing China
5339b58c2adSzhigang lu - Sun Microsystems - Beijing China info->uci_private = NULL;
5349b58c2adSzhigang lu - Sun Microsystems - Beijing China
5359b58c2adSzhigang lu - Sun Microsystems - Beijing China mutex_exit(&ehcip->ehci_int_mutex);
5369b58c2adSzhigang lu - Sun Microsystems - Beijing China
5379b58c2adSzhigang lu - Sun Microsystems - Beijing China return (ret);
5389b58c2adSzhigang lu - Sun Microsystems - Beijing China }
5399b58c2adSzhigang lu - Sun Microsystems - Beijing China
5409b58c2adSzhigang lu - Sun Microsystems - Beijing China
5419b58c2adSzhigang lu - Sun Microsystems - Beijing China /*
5429b58c2adSzhigang lu - Sun Microsystems - Beijing China * ehci_hcdi_polled_output_enter:
5439b58c2adSzhigang lu - Sun Microsystems - Beijing China *
5449b58c2adSzhigang lu - Sun Microsystems - Beijing China * everything is done in input enter
5459b58c2adSzhigang lu - Sun Microsystems - Beijing China */
5469b58c2adSzhigang lu - Sun Microsystems - Beijing China /*ARGSUSED*/
5479b58c2adSzhigang lu - Sun Microsystems - Beijing China int
ehci_hcdi_polled_output_enter(usb_console_info_impl_t * info)5489b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_hcdi_polled_output_enter(usb_console_info_impl_t *info)
5499b58c2adSzhigang lu - Sun Microsystems - Beijing China {
5509b58c2adSzhigang lu - Sun Microsystems - Beijing China return (USB_SUCCESS);
5519b58c2adSzhigang lu - Sun Microsystems - Beijing China }
5529b58c2adSzhigang lu - Sun Microsystems - Beijing China
5539b58c2adSzhigang lu - Sun Microsystems - Beijing China
5549b58c2adSzhigang lu - Sun Microsystems - Beijing China /*
5559b58c2adSzhigang lu - Sun Microsystems - Beijing China * ehci_hcdi_polled_output_exit:
5569b58c2adSzhigang lu - Sun Microsystems - Beijing China *
5579b58c2adSzhigang lu - Sun Microsystems - Beijing China * everything is done in input exit
5589b58c2adSzhigang lu - Sun Microsystems - Beijing China */
5599b58c2adSzhigang lu - Sun Microsystems - Beijing China /*ARGSUSED*/
5609b58c2adSzhigang lu - Sun Microsystems - Beijing China int
ehci_hcdi_polled_output_exit(usb_console_info_impl_t * info)5619b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_hcdi_polled_output_exit(usb_console_info_impl_t *info)
5629b58c2adSzhigang lu - Sun Microsystems - Beijing China {
5639b58c2adSzhigang lu - Sun Microsystems - Beijing China return (USB_SUCCESS);
5649b58c2adSzhigang lu - Sun Microsystems - Beijing China }
5659b58c2adSzhigang lu - Sun Microsystems - Beijing China
5669b58c2adSzhigang lu - Sun Microsystems - Beijing China
5679b58c2adSzhigang lu - Sun Microsystems - Beijing China /*
5689b58c2adSzhigang lu - Sun Microsystems - Beijing China * ehci_hcdi_polled_write:
5699b58c2adSzhigang lu - Sun Microsystems - Beijing China * Put a key character.
5709b58c2adSzhigang lu - Sun Microsystems - Beijing China */
5719b58c2adSzhigang lu - Sun Microsystems - Beijing China int
ehci_hcdi_polled_write(usb_console_info_impl_t * info,uchar_t * buf,uint_t num_characters,uint_t * num_characters_written)5729b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_hcdi_polled_write(usb_console_info_impl_t *info, uchar_t *buf,
5739b58c2adSzhigang lu - Sun Microsystems - Beijing China uint_t num_characters, uint_t *num_characters_written)
5749b58c2adSzhigang lu - Sun Microsystems - Beijing China {
5759b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_state_t *ehcip;
5769b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_t *ehci_polledp;
5779b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_trans_wrapper_t *tw;
5789b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_pipe_private_t *pp;
5799b58c2adSzhigang lu - Sun Microsystems - Beijing China usba_pipe_handle_data_t *ph;
5809b58c2adSzhigang lu - Sun Microsystems - Beijing China int intr;
5819b58c2adSzhigang lu - Sun Microsystems - Beijing China
5829b58c2adSzhigang lu - Sun Microsystems - Beijing China #ifndef lint
5839b58c2adSzhigang lu - Sun Microsystems - Beijing China _NOTE(NO_COMPETING_THREADS_NOW);
5849b58c2adSzhigang lu - Sun Microsystems - Beijing China #endif
5859b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polledp = (ehci_polled_t *)info->uci_private;
5869b58c2adSzhigang lu - Sun Microsystems - Beijing China ehcip = ehci_polledp->ehci_polled_ehcip;
5879b58c2adSzhigang lu - Sun Microsystems - Beijing China ph = ehci_polledp->ehci_polled_input_pipe_handle;
5889b58c2adSzhigang lu - Sun Microsystems - Beijing China pp = (ehci_pipe_private_t *)ph->p_hcd_private;
5899b58c2adSzhigang lu - Sun Microsystems - Beijing China
5909b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Disable all list processing */
5919b58c2adSzhigang lu - Sun Microsystems - Beijing China Set_OpReg(ehci_command, Get_OpReg(ehci_command) &
5929b58c2adSzhigang lu - Sun Microsystems - Beijing China ~(EHCI_CMD_ASYNC_SCHED_ENABLE |
5939b58c2adSzhigang lu - Sun Microsystems - Beijing China EHCI_CMD_PERIODIC_SCHED_ENABLE));
5949b58c2adSzhigang lu - Sun Microsystems - Beijing China
5959b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Wait for few milliseconds */
5969b58c2adSzhigang lu - Sun Microsystems - Beijing China drv_usecwait(EHCI_POLLED_TIMEWAIT);
5979b58c2adSzhigang lu - Sun Microsystems - Beijing China
5989b58c2adSzhigang lu - Sun Microsystems - Beijing China tw = pp->pp_tw_head;
5999b58c2adSzhigang lu - Sun Microsystems - Beijing China ASSERT(tw != NULL);
6009b58c2adSzhigang lu - Sun Microsystems - Beijing China
6019b58c2adSzhigang lu - Sun Microsystems - Beijing China /* copy transmit buffer */
6029b58c2adSzhigang lu - Sun Microsystems - Beijing China if (num_characters > POLLED_RAW_BUF_SIZE) {
6039b58c2adSzhigang lu - Sun Microsystems - Beijing China cmn_err(CE_NOTE, "polled write size %d bigger than %d",
6049b58c2adSzhigang lu - Sun Microsystems - Beijing China num_characters, POLLED_RAW_BUF_SIZE);
6059b58c2adSzhigang lu - Sun Microsystems - Beijing China num_characters = POLLED_RAW_BUF_SIZE;
6069b58c2adSzhigang lu - Sun Microsystems - Beijing China }
6079b58c2adSzhigang lu - Sun Microsystems - Beijing China tw->tw_length = num_characters;
6089b58c2adSzhigang lu - Sun Microsystems - Beijing China ddi_rep_put8(tw->tw_accesshandle,
6099b58c2adSzhigang lu - Sun Microsystems - Beijing China buf, (uint8_t *)tw->tw_buf,
6109b58c2adSzhigang lu - Sun Microsystems - Beijing China tw->tw_length, DDI_DEV_AUTOINCR);
6119b58c2adSzhigang lu - Sun Microsystems - Beijing China Sync_IO_Buffer_for_device(tw->tw_dmahandle, tw->tw_length);
6129b58c2adSzhigang lu - Sun Microsystems - Beijing China
6139b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_insert_bulk_qtd(ehci_polledp);
6149b58c2adSzhigang lu - Sun Microsystems - Beijing China
6159b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Enable async list processing */
6169b58c2adSzhigang lu - Sun Microsystems - Beijing China Set_OpReg(ehci_command, (Get_OpReg(ehci_command) |
6179b58c2adSzhigang lu - Sun Microsystems - Beijing China EHCI_CMD_ASYNC_SCHED_ENABLE));
6189b58c2adSzhigang lu - Sun Microsystems - Beijing China
6199b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Wait for few milliseconds */
6209b58c2adSzhigang lu - Sun Microsystems - Beijing China drv_usecwait(EHCI_POLLED_TIMEWAIT);
6219b58c2adSzhigang lu - Sun Microsystems - Beijing China
6229b58c2adSzhigang lu - Sun Microsystems - Beijing China while (!((Get_OpReg(ehci_status)) & (EHCI_INTR_USB
6239b58c2adSzhigang lu - Sun Microsystems - Beijing China |EHCI_INTR_FRAME_LIST_ROLLOVER | EHCI_INTR_USB_ERROR))) {
6249b58c2adSzhigang lu - Sun Microsystems - Beijing China #ifndef __sparc
6259b58c2adSzhigang lu - Sun Microsystems - Beijing China invalidate_cache();
6269b58c2adSzhigang lu - Sun Microsystems - Beijing China #else
6279b58c2adSzhigang lu - Sun Microsystems - Beijing China ;
6289b58c2adSzhigang lu - Sun Microsystems - Beijing China #endif
6299b58c2adSzhigang lu - Sun Microsystems - Beijing China }
6309b58c2adSzhigang lu - Sun Microsystems - Beijing China
6319b58c2adSzhigang lu - Sun Microsystems - Beijing China intr = (Get_OpReg(ehci_status)) &
6329b58c2adSzhigang lu - Sun Microsystems - Beijing China (EHCI_INTR_FRAME_LIST_ROLLOVER |
6339b58c2adSzhigang lu - Sun Microsystems - Beijing China EHCI_INTR_USB | EHCI_INTR_USB_ERROR);
6349b58c2adSzhigang lu - Sun Microsystems - Beijing China
6359b58c2adSzhigang lu - Sun Microsystems - Beijing China /*
6369b58c2adSzhigang lu - Sun Microsystems - Beijing China * Check whether any frame list rollover interrupt is pending
6379b58c2adSzhigang lu - Sun Microsystems - Beijing China * and if it is pending, process this interrupt.
6389b58c2adSzhigang lu - Sun Microsystems - Beijing China */
6399b58c2adSzhigang lu - Sun Microsystems - Beijing China if (intr & EHCI_INTR_FRAME_LIST_ROLLOVER) {
6409b58c2adSzhigang lu - Sun Microsystems - Beijing China
6419b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_handle_frame_list_rollover(ehcip);
6429b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_finish_interrupt(ehcip,
6439b58c2adSzhigang lu - Sun Microsystems - Beijing China EHCI_INTR_FRAME_LIST_ROLLOVER);
6449b58c2adSzhigang lu - Sun Microsystems - Beijing China }
6459b58c2adSzhigang lu - Sun Microsystems - Beijing China
6467c478bd9Sstevel@tonic-gate /* Check for any USB transaction completion notification */
6477c478bd9Sstevel@tonic-gate if (intr & (EHCI_INTR_USB | EHCI_INTR_USB_ERROR)) {
6489b58c2adSzhigang lu - Sun Microsystems - Beijing China
6499b58c2adSzhigang lu - Sun Microsystems - Beijing China (void) ehci_polled_process_active_intr_qtd_list(ehci_polledp);
6509b58c2adSzhigang lu - Sun Microsystems - Beijing China
6519b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Acknowledge the USB and USB error interrupt */
6529b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_finish_interrupt(ehcip,
6539b58c2adSzhigang lu - Sun Microsystems - Beijing China intr & (EHCI_INTR_USB | EHCI_INTR_USB_ERROR));
6549b58c2adSzhigang lu - Sun Microsystems - Beijing China
6557c478bd9Sstevel@tonic-gate }
6567c478bd9Sstevel@tonic-gate
6579b58c2adSzhigang lu - Sun Microsystems - Beijing China *num_characters_written = num_characters;
6589b58c2adSzhigang lu - Sun Microsystems - Beijing China
6597c478bd9Sstevel@tonic-gate #ifndef lint
6607c478bd9Sstevel@tonic-gate _NOTE(COMPETING_THREADS_NOW);
6617c478bd9Sstevel@tonic-gate #endif
6627c478bd9Sstevel@tonic-gate
6637c478bd9Sstevel@tonic-gate return (USB_SUCCESS);
6647c478bd9Sstevel@tonic-gate }
6657c478bd9Sstevel@tonic-gate
6667c478bd9Sstevel@tonic-gate
6677c478bd9Sstevel@tonic-gate /*
6687c478bd9Sstevel@tonic-gate * Internal Functions
6697c478bd9Sstevel@tonic-gate */
6707c478bd9Sstevel@tonic-gate
6717c478bd9Sstevel@tonic-gate /*
6727c478bd9Sstevel@tonic-gate * Polled initialization routines
6737c478bd9Sstevel@tonic-gate */
6747c478bd9Sstevel@tonic-gate
6757c478bd9Sstevel@tonic-gate
6767c478bd9Sstevel@tonic-gate /*
6777c478bd9Sstevel@tonic-gate * ehci_polled_init:
6787c478bd9Sstevel@tonic-gate *
6797c478bd9Sstevel@tonic-gate * Initialize generic information Uthat is needed to provide USB/POLLED
6807c478bd9Sstevel@tonic-gate * support.
6817c478bd9Sstevel@tonic-gate */
6827c478bd9Sstevel@tonic-gate static int
ehci_polled_init(usba_pipe_handle_data_t * ph,ehci_state_t * ehcip,usb_console_info_impl_t * console_info)6837c478bd9Sstevel@tonic-gate ehci_polled_init(
6847c478bd9Sstevel@tonic-gate usba_pipe_handle_data_t *ph,
6857c478bd9Sstevel@tonic-gate ehci_state_t *ehcip,
6867c478bd9Sstevel@tonic-gate usb_console_info_impl_t *console_info)
6877c478bd9Sstevel@tonic-gate {
6887c478bd9Sstevel@tonic-gate ehci_polled_t *ehci_polledp;
6897c478bd9Sstevel@tonic-gate ehci_pipe_private_t *pp;
6907c478bd9Sstevel@tonic-gate ehci_qtd_t *qtd;
6919b58c2adSzhigang lu - Sun Microsystems - Beijing China int pipe_attr;
6927c478bd9Sstevel@tonic-gate
6937c478bd9Sstevel@tonic-gate ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
6947c478bd9Sstevel@tonic-gate
6957c478bd9Sstevel@tonic-gate /*
6967c478bd9Sstevel@tonic-gate * We have already initialized this structure. If the structure
6977c478bd9Sstevel@tonic-gate * has already been initialized, then we don't need to redo it.
6987c478bd9Sstevel@tonic-gate */
6997c478bd9Sstevel@tonic-gate if (console_info->uci_private) {
7007c478bd9Sstevel@tonic-gate
7017c478bd9Sstevel@tonic-gate return (USB_SUCCESS);
7027c478bd9Sstevel@tonic-gate }
7037c478bd9Sstevel@tonic-gate
7047c478bd9Sstevel@tonic-gate /* Allocate and intitialize a state structure */
7057c478bd9Sstevel@tonic-gate ehci_polledp = (ehci_polled_t *)
7067c478bd9Sstevel@tonic-gate kmem_zalloc(sizeof (ehci_polled_t), KM_SLEEP);
7077c478bd9Sstevel@tonic-gate
7087c478bd9Sstevel@tonic-gate console_info->uci_private = (usb_console_info_private_t)ehci_polledp;
7097c478bd9Sstevel@tonic-gate
7107c478bd9Sstevel@tonic-gate /*
7117c478bd9Sstevel@tonic-gate * Store away the ehcip so that we can get to it when we are in
7127c478bd9Sstevel@tonic-gate * POLLED mode. We don't want to have to call ehci_obtain_state
7137c478bd9Sstevel@tonic-gate * every time we want to access this structure.
7147c478bd9Sstevel@tonic-gate */
7157c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_ehcip = ehcip;
7167c478bd9Sstevel@tonic-gate /*
7177c478bd9Sstevel@tonic-gate * Save usb device and endpoint number information from the usb
7187c478bd9Sstevel@tonic-gate * pipe handle.
7197c478bd9Sstevel@tonic-gate */
7207c478bd9Sstevel@tonic-gate mutex_enter(&ph->p_mutex);
7217c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_usb_dev = ph->p_usba_device;
7227c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_ep_addr = ph->p_ep.bEndpointAddress;
7237c478bd9Sstevel@tonic-gate mutex_exit(&ph->p_mutex);
7247c478bd9Sstevel@tonic-gate
7257c478bd9Sstevel@tonic-gate /*
7267c478bd9Sstevel@tonic-gate * Allocate memory to make duplicate of original usb pipe handle.
7277c478bd9Sstevel@tonic-gate */
7287c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_input_pipe_handle =
7297c478bd9Sstevel@tonic-gate kmem_zalloc(sizeof (usba_pipe_handle_data_t), KM_SLEEP);
7307c478bd9Sstevel@tonic-gate
7317c478bd9Sstevel@tonic-gate /*
7327c478bd9Sstevel@tonic-gate * Copy the USB handle into the new pipe handle. Also
7337c478bd9Sstevel@tonic-gate * create new lock for the new pipe handle.
7347c478bd9Sstevel@tonic-gate */
7357c478bd9Sstevel@tonic-gate bcopy((void *)ph,
7367c478bd9Sstevel@tonic-gate (void *)ehci_polledp->ehci_polled_input_pipe_handle,
7377c478bd9Sstevel@tonic-gate sizeof (usba_pipe_handle_data_t));
7387c478bd9Sstevel@tonic-gate
7397c478bd9Sstevel@tonic-gate /*
7407c478bd9Sstevel@tonic-gate * uint64_t typecast to make sure amd64 can compile
7417c478bd9Sstevel@tonic-gate */
7427c478bd9Sstevel@tonic-gate mutex_init(&ehci_polledp->ehci_polled_input_pipe_handle->p_mutex,
743a195726fSgovinda NULL, MUTEX_DRIVER, DDI_INTR_PRI(ehcip->ehci_intr_pri));
7447c478bd9Sstevel@tonic-gate
7457c478bd9Sstevel@tonic-gate /*
7467c478bd9Sstevel@tonic-gate * Create a new ehci pipe private structure
7477c478bd9Sstevel@tonic-gate */
7487c478bd9Sstevel@tonic-gate pp = (ehci_pipe_private_t *)
7497c478bd9Sstevel@tonic-gate kmem_zalloc(sizeof (ehci_pipe_private_t), KM_SLEEP);
7507c478bd9Sstevel@tonic-gate
7517c478bd9Sstevel@tonic-gate /*
7527c478bd9Sstevel@tonic-gate * Store the pointer in the pipe handle. This structure was also
7537c478bd9Sstevel@tonic-gate * just allocated.
7547c478bd9Sstevel@tonic-gate */
7557c478bd9Sstevel@tonic-gate mutex_enter(&ehci_polledp->ehci_polled_input_pipe_handle->p_mutex);
7567c478bd9Sstevel@tonic-gate
7577c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_input_pipe_handle->
7587c478bd9Sstevel@tonic-gate p_hcd_private = (usb_opaque_t)pp;
7597c478bd9Sstevel@tonic-gate
7607c478bd9Sstevel@tonic-gate mutex_exit(&ehci_polledp->ehci_polled_input_pipe_handle->p_mutex);
7617c478bd9Sstevel@tonic-gate
7627c478bd9Sstevel@tonic-gate /*
7637c478bd9Sstevel@tonic-gate * Store a pointer to the pipe handle. This structure was just
7647c478bd9Sstevel@tonic-gate * allocated and it is not in use yet. The locking is there to
7657c478bd9Sstevel@tonic-gate * satisfy warlock.
7667c478bd9Sstevel@tonic-gate */
7677c478bd9Sstevel@tonic-gate mutex_enter(&ph->p_mutex);
7687c478bd9Sstevel@tonic-gate
7697c478bd9Sstevel@tonic-gate bcopy(&ph->p_policy, &pp->pp_policy, sizeof (usb_pipe_policy_t));
7707c478bd9Sstevel@tonic-gate
7717c478bd9Sstevel@tonic-gate mutex_exit(&ph->p_mutex);
7727c478bd9Sstevel@tonic-gate
7737c478bd9Sstevel@tonic-gate pp->pp_pipe_handle = ehci_polledp->ehci_polled_input_pipe_handle;
7747c478bd9Sstevel@tonic-gate
7757c478bd9Sstevel@tonic-gate /*
7767c478bd9Sstevel@tonic-gate * Allocate a dummy for the interrupt table. This dummy will be
7777c478bd9Sstevel@tonic-gate * put into the action when we switch interrupt tables during
7787c478bd9Sstevel@tonic-gate * ehci_hcdi_polled_enter. Dummy is placed on the unused lattice
7797c478bd9Sstevel@tonic-gate * entries. When the QH is allocated we will replace dummy QH by
7807c478bd9Sstevel@tonic-gate * valid interrupt QH in one or more locations in the interrupt
7817c478bd9Sstevel@tonic-gate * lattice depending on the requested polling interval. Also we
7827c478bd9Sstevel@tonic-gate * will hang a dummy QTD to the QH & dummy QTD is used to indicate
7837c478bd9Sstevel@tonic-gate * the end of the QTD chain.
7847c478bd9Sstevel@tonic-gate */
7857c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_dummy_qh =
7867c478bd9Sstevel@tonic-gate ehci_alloc_qh(ehcip, NULL, EHCI_POLLED_MODE_FLAG);
7877c478bd9Sstevel@tonic-gate
7887c478bd9Sstevel@tonic-gate if (ehci_polledp->ehci_polled_dummy_qh == NULL) {
7897c478bd9Sstevel@tonic-gate
7907c478bd9Sstevel@tonic-gate return (USB_NO_RESOURCES);
7917c478bd9Sstevel@tonic-gate }
7927c478bd9Sstevel@tonic-gate
7937c478bd9Sstevel@tonic-gate /*
7949b58c2adSzhigang lu - Sun Microsystems - Beijing China * Allocate the endpoint. This QH will be inserted in
7959b58c2adSzhigang lu - Sun Microsystems - Beijing China * to the lattice chain for the device. This endpoint
7967c478bd9Sstevel@tonic-gate * will have the QTDs hanging off of it for the processing.
7977c478bd9Sstevel@tonic-gate */
7987c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_qh = ehci_alloc_qh(
7997c478bd9Sstevel@tonic-gate ehcip, ph, EHCI_POLLED_MODE_FLAG);
8007c478bd9Sstevel@tonic-gate
8017c478bd9Sstevel@tonic-gate if (ehci_polledp->ehci_polled_qh == NULL) {
8027c478bd9Sstevel@tonic-gate
8037c478bd9Sstevel@tonic-gate return (USB_NO_RESOURCES);
8047c478bd9Sstevel@tonic-gate }
8057c478bd9Sstevel@tonic-gate
8067c478bd9Sstevel@tonic-gate /* Set the state of pipe as idle */
8077c478bd9Sstevel@tonic-gate pp->pp_state = EHCI_PIPE_STATE_IDLE;
8087c478bd9Sstevel@tonic-gate
8097c478bd9Sstevel@tonic-gate /* Set polled mode flag */
8107c478bd9Sstevel@tonic-gate pp->pp_flag = EHCI_POLLED_MODE_FLAG;
8117c478bd9Sstevel@tonic-gate
8127c478bd9Sstevel@tonic-gate /* Insert the endpoint onto the pipe handle */
8137c478bd9Sstevel@tonic-gate pp->pp_qh = ehci_polledp->ehci_polled_qh;
8147c478bd9Sstevel@tonic-gate
8159b58c2adSzhigang lu - Sun Microsystems - Beijing China pipe_attr = ph->p_ep.bmAttributes & USB_EP_ATTR_MASK;
8167c478bd9Sstevel@tonic-gate
8179b58c2adSzhigang lu - Sun Microsystems - Beijing China switch (pipe_attr) {
8189b58c2adSzhigang lu - Sun Microsystems - Beijing China case USB_EP_ATTR_INTR:
8199b58c2adSzhigang lu - Sun Microsystems - Beijing China /*
8209b58c2adSzhigang lu - Sun Microsystems - Beijing China * Set soft interrupt handler flag in the normal mode usb
8219b58c2adSzhigang lu - Sun Microsystems - Beijing China * pipe handle.
8229b58c2adSzhigang lu - Sun Microsystems - Beijing China */
8239b58c2adSzhigang lu - Sun Microsystems - Beijing China mutex_enter(&ph->p_mutex);
8249b58c2adSzhigang lu - Sun Microsystems - Beijing China ph->p_spec_flag |= USBA_PH_FLAG_USE_SOFT_INTR;
8259b58c2adSzhigang lu - Sun Microsystems - Beijing China mutex_exit(&ph->p_mutex);
8267c478bd9Sstevel@tonic-gate
8279b58c2adSzhigang lu - Sun Microsystems - Beijing China /*
8289b58c2adSzhigang lu - Sun Microsystems - Beijing China * Insert a Interrupt polling request onto the endpoint.
8299b58c2adSzhigang lu - Sun Microsystems - Beijing China *
8309b58c2adSzhigang lu - Sun Microsystems - Beijing China * There will now be two QTDs on the QH, one is the dummy QTD
8319b58c2adSzhigang lu - Sun Microsystems - Beijing China * that was allocated above in the ehci_alloc_qh and this
8329b58c2adSzhigang lu - Sun Microsystems - Beijing China * new one.
8339b58c2adSzhigang lu - Sun Microsystems - Beijing China */
8349b58c2adSzhigang lu - Sun Microsystems - Beijing China if ((ehci_start_periodic_pipe_polling(ehcip,
8359b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polledp->ehci_polled_input_pipe_handle,
8369b58c2adSzhigang lu - Sun Microsystems - Beijing China NULL, USB_FLAGS_SLEEP)) != USB_SUCCESS) {
8377c478bd9Sstevel@tonic-gate
8389b58c2adSzhigang lu - Sun Microsystems - Beijing China return (USB_NO_RESOURCES);
8399b58c2adSzhigang lu - Sun Microsystems - Beijing China }
8409b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Get the given new interrupt qtd */
8419b58c2adSzhigang lu - Sun Microsystems - Beijing China qtd = (ehci_qtd_t *)(ehci_qtd_iommu_to_cpu(ehcip,
8429b58c2adSzhigang lu - Sun Microsystems - Beijing China (Get_QH(pp->pp_qh->qh_next_qtd) & EHCI_QH_NEXT_QTD_PTR)));
8439b58c2adSzhigang lu - Sun Microsystems - Beijing China
8449b58c2adSzhigang lu - Sun Microsystems - Beijing China /* Insert this qtd into active interrupt QTD list */
8459b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polled_insert_qtd_into_active_intr_qtd_list(ehci_polledp,
8469b58c2adSzhigang lu - Sun Microsystems - Beijing China qtd);
8479b58c2adSzhigang lu - Sun Microsystems - Beijing China break;
8489b58c2adSzhigang lu - Sun Microsystems - Beijing China case USB_EP_ATTR_BULK:
8499b58c2adSzhigang lu - Sun Microsystems - Beijing China if ((ehci_polled_create_tw(ehci_polledp,
8509b58c2adSzhigang lu - Sun Microsystems - Beijing China ehci_polledp->ehci_polled_input_pipe_handle,
8519b58c2adSzhigang lu - Sun Microsystems - Beijing China USB_FLAGS_SLEEP)) != USB_SUCCESS) {
8529b58c2adSzhigang lu - Sun Microsystems - Beijing China
8539b58c2adSzhigang lu - Sun Microsystems - Beijing China return (USB_NO_RESOURCES);
8549b58c2adSzhigang lu - Sun Microsystems - Beijing China }
8559b58c2adSzhigang lu - Sun Microsystems - Beijing China break;
8569b58c2adSzhigang lu - Sun Microsystems - Beijing China default:
8579b58c2adSzhigang lu - Sun Microsystems - Beijing China return (USB_FAILURE);
8589b58c2adSzhigang lu - Sun Microsystems - Beijing China }
8597c478bd9Sstevel@tonic-gate
8607c478bd9Sstevel@tonic-gate return (USB_SUCCESS);
8617c478bd9Sstevel@tonic-gate }
8627c478bd9Sstevel@tonic-gate
8637c478bd9Sstevel@tonic-gate
8647c478bd9Sstevel@tonic-gate /*
8657c478bd9Sstevel@tonic-gate * Polled deinitialization routines
8667c478bd9Sstevel@tonic-gate */
8677c478bd9Sstevel@tonic-gate
8687c478bd9Sstevel@tonic-gate
8697c478bd9Sstevel@tonic-gate /*
8707c478bd9Sstevel@tonic-gate * ehci_polled_fini:
8717c478bd9Sstevel@tonic-gate */
8727c478bd9Sstevel@tonic-gate static int
ehci_polled_fini(ehci_polled_t * ehci_polledp)8737c478bd9Sstevel@tonic-gate ehci_polled_fini(ehci_polled_t *ehci_polledp)
8747c478bd9Sstevel@tonic-gate {
8757c478bd9Sstevel@tonic-gate ehci_state_t *ehcip = ehci_polledp->ehci_polled_ehcip;
8767c478bd9Sstevel@tonic-gate ehci_pipe_private_t *pp;
8777c478bd9Sstevel@tonic-gate
8787c478bd9Sstevel@tonic-gate ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
8797c478bd9Sstevel@tonic-gate
8807c478bd9Sstevel@tonic-gate /* If the structure is already in use, then don't free it */
8817c478bd9Sstevel@tonic-gate if (ehci_polledp->ehci_polled_flags & POLLED_INPUT_MODE) {
8827c478bd9Sstevel@tonic-gate
8837c478bd9Sstevel@tonic-gate return (USB_SUCCESS);
8847c478bd9Sstevel@tonic-gate }
8857c478bd9Sstevel@tonic-gate
8867c478bd9Sstevel@tonic-gate pp = (ehci_pipe_private_t *)
8877c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_input_pipe_handle->p_hcd_private;
8887c478bd9Sstevel@tonic-gate
8897c478bd9Sstevel@tonic-gate /* Deallocate all the pre-allocated interrupt requests */
8907c478bd9Sstevel@tonic-gate ehci_handle_outstanding_requests(ehcip, pp);
8917c478bd9Sstevel@tonic-gate
8927c478bd9Sstevel@tonic-gate /*
8937c478bd9Sstevel@tonic-gate * Traverse the list of QTD's on this endpoint and these QTD's
8947c478bd9Sstevel@tonic-gate * have outstanding transfer requests. Since list processing
8957c478bd9Sstevel@tonic-gate * is stopped, these QTDs can be deallocated.
8967c478bd9Sstevel@tonic-gate */
8977c478bd9Sstevel@tonic-gate ehci_polled_traverse_qtds(ehci_polledp, pp->pp_pipe_handle);
8987c478bd9Sstevel@tonic-gate
8997c478bd9Sstevel@tonic-gate /* Free DMA resources */
9007c478bd9Sstevel@tonic-gate ehci_free_dma_resources(ehcip, pp->pp_pipe_handle);
9017c478bd9Sstevel@tonic-gate
9027c478bd9Sstevel@tonic-gate /*
9037c478bd9Sstevel@tonic-gate * Deallocate the endpoint descriptors that we allocated
9047c478bd9Sstevel@tonic-gate * with ehci_alloc_qh.
9057c478bd9Sstevel@tonic-gate */
9067c478bd9Sstevel@tonic-gate if (ehci_polledp->ehci_polled_dummy_qh) {
9077c478bd9Sstevel@tonic-gate ehci_deallocate_qh(ehcip, ehci_polledp->ehci_polled_dummy_qh);
9087c478bd9Sstevel@tonic-gate }
9097c478bd9Sstevel@tonic-gate
9107c478bd9Sstevel@tonic-gate if (ehci_polledp->ehci_polled_qh) {
9117c478bd9Sstevel@tonic-gate ehci_deallocate_qh(ehcip, ehci_polledp->ehci_polled_qh);
9127c478bd9Sstevel@tonic-gate }
9137c478bd9Sstevel@tonic-gate
9147c478bd9Sstevel@tonic-gate mutex_destroy(&ehci_polledp->ehci_polled_input_pipe_handle->p_mutex);
9157c478bd9Sstevel@tonic-gate
9167c478bd9Sstevel@tonic-gate /*
9177c478bd9Sstevel@tonic-gate * Destroy everything about the pipe that we allocated in
9187c478bd9Sstevel@tonic-gate * ehci_polled_duplicate_pipe_handle
9197c478bd9Sstevel@tonic-gate */
9207c478bd9Sstevel@tonic-gate kmem_free(pp, sizeof (ehci_pipe_private_t));
9217c478bd9Sstevel@tonic-gate
9227c478bd9Sstevel@tonic-gate kmem_free(ehci_polledp->ehci_polled_input_pipe_handle,
9237c478bd9Sstevel@tonic-gate sizeof (usba_pipe_handle_data_t));
9247c478bd9Sstevel@tonic-gate
9257c478bd9Sstevel@tonic-gate /*
9267c478bd9Sstevel@tonic-gate * We use this field to determine if a QTD is for input or not,
9277c478bd9Sstevel@tonic-gate * so NULL the pointer so we don't check deallocated data.
9287c478bd9Sstevel@tonic-gate */
9297c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_input_pipe_handle = NULL;
9307c478bd9Sstevel@tonic-gate
9317c478bd9Sstevel@tonic-gate /*
9327c478bd9Sstevel@tonic-gate * Finally, free off the structure that we use to keep track
9337c478bd9Sstevel@tonic-gate * of all this.
9347c478bd9Sstevel@tonic-gate */
9357c478bd9Sstevel@tonic-gate kmem_free(ehci_polledp, sizeof (ehci_polled_t));
9367c478bd9Sstevel@tonic-gate
9377c478bd9Sstevel@tonic-gate return (USB_SUCCESS);
9387c478bd9Sstevel@tonic-gate }
9397c478bd9Sstevel@tonic-gate
9407c478bd9Sstevel@tonic-gate
9417c478bd9Sstevel@tonic-gate /*
9427c478bd9Sstevel@tonic-gate * Polled save state routines
9437c478bd9Sstevel@tonic-gate */
9447c478bd9Sstevel@tonic-gate
9457c478bd9Sstevel@tonic-gate
9467c478bd9Sstevel@tonic-gate /*
9477c478bd9Sstevel@tonic-gate * ehci_polled_save_state:
9487c478bd9Sstevel@tonic-gate */
9497c478bd9Sstevel@tonic-gate static void
ehci_polled_save_state(ehci_polled_t * ehci_polledp)9507c478bd9Sstevel@tonic-gate ehci_polled_save_state(ehci_polled_t *ehci_polledp)
9517c478bd9Sstevel@tonic-gate {
9527c478bd9Sstevel@tonic-gate int i;
9537c478bd9Sstevel@tonic-gate ehci_state_t *ehcip;
9547c478bd9Sstevel@tonic-gate uint_t polled_toggle;
9557c478bd9Sstevel@tonic-gate uint_t real_toggle;
9567c478bd9Sstevel@tonic-gate ehci_pipe_private_t *pp = NULL; /* Normal mode Pipe */
9577c478bd9Sstevel@tonic-gate ehci_pipe_private_t *polled_pp; /* Polled mode Pipe */
9587c478bd9Sstevel@tonic-gate usba_pipe_handle_data_t *ph;
9597c478bd9Sstevel@tonic-gate uint8_t ep_addr;
9607c478bd9Sstevel@tonic-gate ehci_regs_t *ehci_polled_regsp;
9617c478bd9Sstevel@tonic-gate ehci_qh_t *qh;
9627c478bd9Sstevel@tonic-gate
9637c478bd9Sstevel@tonic-gate #ifndef lint
9647c478bd9Sstevel@tonic-gate _NOTE(NO_COMPETING_THREADS_NOW);
9657c478bd9Sstevel@tonic-gate #endif
9667c478bd9Sstevel@tonic-gate
9677c478bd9Sstevel@tonic-gate /*
9687c478bd9Sstevel@tonic-gate * If either of these two flags are set, then we have already
9697c478bd9Sstevel@tonic-gate * saved off the state information and setup the controller.
9707c478bd9Sstevel@tonic-gate */
9717c478bd9Sstevel@tonic-gate if (ehci_polledp->ehci_polled_flags & POLLED_INPUT_MODE_INUSE) {
9727c478bd9Sstevel@tonic-gate #ifndef lint
9737c478bd9Sstevel@tonic-gate _NOTE(COMPETING_THREADS_NOW);
9747c478bd9Sstevel@tonic-gate #endif
9757c478bd9Sstevel@tonic-gate return;
9767c478bd9Sstevel@tonic-gate }
9777c478bd9Sstevel@tonic-gate
9787c478bd9Sstevel@tonic-gate ehcip = ehci_polledp->ehci_polled_ehcip;
9797c478bd9Sstevel@tonic-gate
9807c478bd9Sstevel@tonic-gate /*
9817c478bd9Sstevel@tonic-gate * Check if the number of keyboard reach the max number we can
9827c478bd9Sstevel@tonic-gate * support in polled mode
9837c478bd9Sstevel@tonic-gate */
9847c478bd9Sstevel@tonic-gate if (++ ehcip->ehci_polled_enter_count > MAX_NUM_FOR_KEYBOARD) {
9857c478bd9Sstevel@tonic-gate #ifndef lint
9867c478bd9Sstevel@tonic-gate _NOTE(COMPETING_THREADS_NOW);
9877c478bd9Sstevel@tonic-gate #endif
9887c478bd9Sstevel@tonic-gate return;
9897c478bd9Sstevel@tonic-gate }
9907c478bd9Sstevel@tonic-gate ehci_polled_regsp = &ehcip->ehci_polled_save_regs;
9917c478bd9Sstevel@tonic-gate
9927c478bd9Sstevel@tonic-gate /* Get the endpoint addr. */
9937c478bd9Sstevel@tonic-gate ep_addr = ehci_polledp->ehci_polled_ep_addr;
9947c478bd9Sstevel@tonic-gate
9957c478bd9Sstevel@tonic-gate /* Get the normal mode usb pipe handle */
9967c478bd9Sstevel@tonic-gate ph = usba_hcdi_get_ph_data(ehci_polledp->ehci_polled_usb_dev, ep_addr);
9977c478bd9Sstevel@tonic-gate
9987c478bd9Sstevel@tonic-gate /*
9997c478bd9Sstevel@tonic-gate * The first enter keyboard entry should save info of the normal mode,
10007c478bd9Sstevel@tonic-gate * disable all list processing and interrupt, initialize the
10017c478bd9Sstevel@tonic-gate * frame list table with dummy QHs.
10027c478bd9Sstevel@tonic-gate */
10037c478bd9Sstevel@tonic-gate if (ehcip->ehci_polled_enter_count == 1) {
10047c478bd9Sstevel@tonic-gate /*
10057c478bd9Sstevel@tonic-gate * Save the current normal mode ehci registers and later this
10067c478bd9Sstevel@tonic-gate * saved register copy is used to replace some of required ehci
10077c478bd9Sstevel@tonic-gate * registers before switching from polled mode to normal mode.
10087c478bd9Sstevel@tonic-gate */
10097c478bd9Sstevel@tonic-gate
10107c478bd9Sstevel@tonic-gate bzero((void *)ehci_polled_regsp, sizeof (ehci_regs_t));
10117c478bd9Sstevel@tonic-gate
10127c478bd9Sstevel@tonic-gate /* Save current ehci registers */
10137c478bd9Sstevel@tonic-gate ehci_polled_regsp->ehci_command = Get_OpReg(ehci_command);
10147c478bd9Sstevel@tonic-gate ehci_polled_regsp->ehci_interrupt = Get_OpReg(ehci_interrupt);
10157c478bd9Sstevel@tonic-gate ehci_polled_regsp->ehci_ctrl_segment =
10167c478bd9Sstevel@tonic-gate Get_OpReg(ehci_ctrl_segment);
10177c478bd9Sstevel@tonic-gate ehci_polled_regsp->
10187c478bd9Sstevel@tonic-gate ehci_async_list_addr = Get_OpReg(ehci_async_list_addr);
10197c478bd9Sstevel@tonic-gate ehci_polled_regsp->ehci_config_flag =
10207c478bd9Sstevel@tonic-gate Get_OpReg(ehci_config_flag);
10217c478bd9Sstevel@tonic-gate ehci_polled_regsp->ehci_periodic_list_base =
10227c478bd9Sstevel@tonic-gate Get_OpReg(ehci_periodic_list_base);
10237c478bd9Sstevel@tonic-gate
10247c478bd9Sstevel@tonic-gate /* Disable all list processing and interrupts */
10257c478bd9Sstevel@tonic-gate Set_OpReg(ehci_command, Get_OpReg(ehci_command) &
10267c478bd9Sstevel@tonic-gate ~(EHCI_CMD_ASYNC_SCHED_ENABLE |
10277c478bd9Sstevel@tonic-gate EHCI_CMD_PERIODIC_SCHED_ENABLE));
10287c478bd9Sstevel@tonic-gate
10297c478bd9Sstevel@tonic-gate /* Wait for few milliseconds */
10307c478bd9Sstevel@tonic-gate drv_usecwait(EHCI_POLLED_TIMEWAIT);
10317c478bd9Sstevel@tonic-gate
10327c478bd9Sstevel@tonic-gate /* Save any unprocessed normal mode ehci interrupts */
10337c478bd9Sstevel@tonic-gate ehcip->ehci_missed_intr_sts = EHCI_INTR_USB;
10347c478bd9Sstevel@tonic-gate
10357c478bd9Sstevel@tonic-gate /*
10367c478bd9Sstevel@tonic-gate * Save the current interrupt lattice and replace this lattice
10377c478bd9Sstevel@tonic-gate * with an lattice used in POLLED mode. We will restore lattice
10387c478bd9Sstevel@tonic-gate * back when we exit from the POLLED mode.
10397c478bd9Sstevel@tonic-gate */
10407c478bd9Sstevel@tonic-gate for (i = 0; i < EHCI_NUM_PERIODIC_FRAME_LISTS; i++) {
10417c478bd9Sstevel@tonic-gate ehcip->ehci_polled_frame_list_table[i] =
10427c478bd9Sstevel@tonic-gate (ehci_qh_t *)(uintptr_t)Get_PFLT(ehcip->
10437c478bd9Sstevel@tonic-gate ehci_periodic_frame_list_tablep->
10447c478bd9Sstevel@tonic-gate ehci_periodic_frame_list_table[i]);
10457c478bd9Sstevel@tonic-gate }
10467c478bd9Sstevel@tonic-gate
10477c478bd9Sstevel@tonic-gate /*
10487c478bd9Sstevel@tonic-gate * Fill in the lattice with dummy QHs. These QHs are used so the
10497c478bd9Sstevel@tonic-gate * controller can tell that it is at the end of the QH list.
10507c478bd9Sstevel@tonic-gate */
10517c478bd9Sstevel@tonic-gate for (i = 0; i < EHCI_NUM_PERIODIC_FRAME_LISTS; i++) {
10527c478bd9Sstevel@tonic-gate Set_PFLT(ehcip->ehci_periodic_frame_list_tablep->
10537c478bd9Sstevel@tonic-gate ehci_periodic_frame_list_table[i],
10547c478bd9Sstevel@tonic-gate ehci_qh_cpu_to_iommu(ehcip,
10557c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_dummy_qh) |
10567c478bd9Sstevel@tonic-gate (EHCI_QH_LINK_REF_QH | EHCI_QH_LINK_PTR_VALID));
10577c478bd9Sstevel@tonic-gate }
10587c478bd9Sstevel@tonic-gate
10597c478bd9Sstevel@tonic-gate }
10607c478bd9Sstevel@tonic-gate
10617c478bd9Sstevel@tonic-gate /* Get the polled mode ehci pipe private structure */
10627c478bd9Sstevel@tonic-gate polled_pp = (ehci_pipe_private_t *)
10637c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_input_pipe_handle->p_hcd_private;
10647c478bd9Sstevel@tonic-gate
10657c478bd9Sstevel@tonic-gate /*
10667c478bd9Sstevel@tonic-gate * Before replacing the lattice, adjust the data togggle on the
10677c478bd9Sstevel@tonic-gate * on the ehci's interrupt ed
10687c478bd9Sstevel@tonic-gate */
10697c478bd9Sstevel@tonic-gate polled_toggle = (Get_QH(polled_pp->pp_qh->qh_status) &
10707c478bd9Sstevel@tonic-gate EHCI_QH_STS_DATA_TOGGLE) ? DATA1:DATA0;
10717c478bd9Sstevel@tonic-gate
10727c478bd9Sstevel@tonic-gate /*
10737c478bd9Sstevel@tonic-gate * If normal mode interrupt pipe endpoint is active, get the data
10747c478bd9Sstevel@tonic-gate * toggle from the this interrupt endpoint through the corresponding
10757c478bd9Sstevel@tonic-gate * interrupt pipe handle. Else get the data toggle information from
10767c478bd9Sstevel@tonic-gate * the usb device structure and this information is saved during the
10777c478bd9Sstevel@tonic-gate * normal mode interrupt pipe close. Use this data toggle information
10787c478bd9Sstevel@tonic-gate * to fix the data toggle of polled mode interrupt endpoint.
10797c478bd9Sstevel@tonic-gate */
10807c478bd9Sstevel@tonic-gate if (ph) {
10817c478bd9Sstevel@tonic-gate /* Get the normal mode ehci pipe private structure */
10827c478bd9Sstevel@tonic-gate pp = (ehci_pipe_private_t *)ph->p_hcd_private;
10837c478bd9Sstevel@tonic-gate
10847c478bd9Sstevel@tonic-gate real_toggle = (Get_QH(pp->pp_qh->qh_status) &
10857c478bd9Sstevel@tonic-gate EHCI_QH_STS_DATA_TOGGLE) ? DATA1:DATA0;
10867c478bd9Sstevel@tonic-gate } else {
10877c478bd9Sstevel@tonic-gate real_toggle = usba_hcdi_get_data_toggle(
10887c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_usb_dev, ep_addr);
10897c478bd9Sstevel@tonic-gate }
10907c478bd9Sstevel@tonic-gate
10917c478bd9Sstevel@tonic-gate if (polled_toggle != real_toggle) {
10927c478bd9Sstevel@tonic-gate if (real_toggle == DATA0) {
10937c478bd9Sstevel@tonic-gate Set_QH(polled_pp->pp_qh->qh_status,
10947c478bd9Sstevel@tonic-gate Get_QH(polled_pp->pp_qh->qh_status) &
10957c478bd9Sstevel@tonic-gate ~EHCI_QH_STS_DATA_TOGGLE);
10967c478bd9Sstevel@tonic-gate } else {
10977c478bd9Sstevel@tonic-gate Set_QH(polled_pp->pp_qh->qh_status,
10987c478bd9Sstevel@tonic-gate Get_QH(polled_pp->pp_qh->qh_status) |
10997c478bd9Sstevel@tonic-gate EHCI_QH_STS_DATA_TOGGLE);
11007c478bd9Sstevel@tonic-gate }
11017c478bd9Sstevel@tonic-gate }
11027c478bd9Sstevel@tonic-gate
11037c478bd9Sstevel@tonic-gate /*
11047c478bd9Sstevel@tonic-gate * Check whether Halt bit is set in the QH and if so clear the
11057c478bd9Sstevel@tonic-gate * halt bit.
11067c478bd9Sstevel@tonic-gate */
11077c478bd9Sstevel@tonic-gate if (polled_pp->pp_qh->qh_status & EHCI_QH_STS_HALTED) {
11087c478bd9Sstevel@tonic-gate
11097c478bd9Sstevel@tonic-gate /* Clear the halt bit */
11107c478bd9Sstevel@tonic-gate Set_QH(polled_pp->pp_qh->qh_status,
11117c478bd9Sstevel@tonic-gate (Get_QH(polled_pp->pp_qh->qh_status) &
11127c478bd9Sstevel@tonic-gate ~EHCI_QH_STS_HALTED));
11137c478bd9Sstevel@tonic-gate }
11147c478bd9Sstevel@tonic-gate
11157c478bd9Sstevel@tonic-gate /*
11167c478bd9Sstevel@tonic-gate * Initialize the qh overlay area
11177c478bd9Sstevel@tonic-gate */
11187c478bd9Sstevel@tonic-gate qh = ehci_polledp->ehci_polled_qh;
11197c478bd9Sstevel@tonic-gate for (i = 0; i < 5; i++) {
11206aef9e11SToomas Soome Set_QH(qh->qh_buf[i], 0);
11216aef9e11SToomas Soome Set_QH(qh->qh_buf_high[i], 0);
11227c478bd9Sstevel@tonic-gate }
11237c478bd9Sstevel@tonic-gate Set_QH(qh->qh_next_qtd, ehci_qtd_cpu_to_iommu(ehcip,
11247c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_active_intr_qtd_list));
11257c478bd9Sstevel@tonic-gate
11267c478bd9Sstevel@tonic-gate /*
11277c478bd9Sstevel@tonic-gate * Now, add the endpoint to the lattice that we will hang our
11287c478bd9Sstevel@tonic-gate * QTD's off of. We need to poll this device at every 8 ms and
11297c478bd9Sstevel@tonic-gate * hence add this QH needs 4 entries in interrupt lattice.
11307c478bd9Sstevel@tonic-gate */
11317c478bd9Sstevel@tonic-gate for (i = ehcip->ehci_polled_enter_count - 1;
11327c478bd9Sstevel@tonic-gate i < EHCI_NUM_PERIODIC_FRAME_LISTS;
11337c478bd9Sstevel@tonic-gate i = i + LS_MIN_POLL_INTERVAL) {
11347c478bd9Sstevel@tonic-gate Set_PFLT(ehcip->ehci_periodic_frame_list_tablep->
11357c478bd9Sstevel@tonic-gate ehci_periodic_frame_list_table[i],
11367c478bd9Sstevel@tonic-gate ehci_qh_cpu_to_iommu(ehcip,
11377c478bd9Sstevel@tonic-gate ehci_polledp->ehci_polled_qh) | EHCI_QH_LINK_REF_QH);
11387c478bd9Sstevel@tonic-gate }
11397c478bd9Sstevel@tonic-gate /* The first enter keyboard entry enable interrupts and periodic list */
11407c478bd9Sstevel@tonic-gate if (ehcip->ehci_polled_enter_count == 1) {
11417c478bd9Sstevel@tonic-gate /* Enable USB and Frame list rollover interrupts */
11427c478bd9Sstevel@tonic-gate Set_OpReg(ehci_interrupt, (EHCI_INTR_USB |
11437c478bd9Sstevel@tonic-gate EHCI_INTR_USB_ERROR | EHCI_INTR_FRAME_LIST_ROLLOVER));
1144