uhcipolled.c revision d29f5a711240f866521445b1656d114da090335e
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* This module contains the specific uhci code used in POLLED mode.
*/
#ifndef __sparc
extern void invalidate_cache();
#endif
/*
* Internal Function Prototypes
*/
/* Polled initialization routine */
/* Polled fini routine */
/* Polled save state routine */
static void uhci_polled_save_state(uhci_polled_t *);
/* Polled restore state routine */
static void uhci_polled_restore_state(uhci_polled_t *);
/* Polled read routines */
static int uhci_polled_insert_td_on_qh(uhci_polled_t *,
static uhci_trans_wrapper_t
/*
* POLLED entry points
*
* These functions are entry points into the POLLED code.
*/
/*
* uhci_hcdi_polled_input_init:
* This is the initialization routine for handling the USB keyboard
* in POLLED mode. This routine is not called from POLLED mode, so
* it is OK to acquire mutexes.
*/
int
{
int ret;
/*
* Grab the uhci_int_mutex so that things don't change on us
* if an interrupt comes in.
*/
if (ret != USB_SUCCESS) {
return (ret);
}
/*
* Mark the structure so that if we are using it, we don't free
* the structures if one of them is unplugged.
*/
/*
* This is the buffer we will copy characters into. It will be
* copied into at this layer, so we need to keep track of it.
*/
return (USB_SUCCESS);
}
/*
* uhci_hcdi_polled_input_fini:
*/
int
{
int ret;
/* Free the buffer that we copied data into */
return (ret);
}
/*
* uhci_hcdi_polled_input_enter:
* This is where we enter into POLLED mode. This routine sets up
* everything so that calls to uhci_hcdi_polled_read will return
* characters.
*/
int
{
/*
* If the controller is already switched over, just return
*/
return (USB_SUCCESS);
}
return (USB_SUCCESS);
}
/*
* uhci_hcdi_polled_input_exit:
* This is where we exit POLLED mode. This routine restores
* everything that is needed to continue operation.
*/
int
{
/*
* If there are still outstanding "enters", just return
*/
if (uhci_polledp->uhci_polled_entry > 0) {
return (USB_SUCCESS);
}
return (USB_SUCCESS);
}
/*
* uhci_hcdi_polled_read:
* Get a key character
*/
int
{
/*
* This is a temporary work around for halt problem. The upper
* layer code does not call the right sequence of entry points
* points for reading a character in a polled mode. Once the
* upper layer code is fixed, the following code (two lines)
* must be removed.
*/
if (uhci_polledp->uhci_polled_entry == 0) {
}
}
#ifndef lint
#endif
#ifndef __sparc
#endif
/*
* Check to see if there are any TD's on the done head.
*/
*num_characters = 0;
} else {
/*
* If the TD does not complete, retry.
*/
*num_characters = 0;
} else {
/* Copy the data into the message */
}
/*
* Insert the td again into the lattice.
*/
/* Clear the interrupt status register */
}
#ifndef lint
#endif
return (USB_SUCCESS);
}
/*
* uhci_hcdi_polled_output_init:
* This is the initialization routine for handling the USB serial
* output in POLLED mode. This routine is called after input_init
* succeeded.
*/
int
{
int ret;
/*
* Grab the uhci_int_mutex so that things don't change on us
* if an interrupt comes in.
*/
if (ret != USB_SUCCESS) {
return (ret);
}
/*
* Mark the structure so that if we are using it, we don't free
* the structures if one of them is unplugged.
*/
return (USB_SUCCESS);
}
/*
* uhci_hcdi_polled_output_fini:
*/
int
{
int ret;
return (ret);
}
/*
* uhci_hcdi_polled_output_enter:
* everything is done in input enter
*/
int
{
/*
* Check if the number of devices reaches the max number
* we can support in polled mode
*/
return (USB_FAILURE);
}
return (USB_SUCCESS);
}
/*
* uhci_hcdi_polled_output_exit:
* everything is done in input exit
*/
/*ARGSUSED*/
int
{
return (USB_SUCCESS);
}
/*
* uhci_hcdi_polled_write:
* Put a key character -- rewrite this!
*/
int
{
int i;
#ifndef lint
#endif
/* copy transmit buffer */
if (num_characters > POLLED_RAW_BUF_SIZE) {
}
/*
* Now, add the endpoint to the lattice that we will hang our
* TD's off of.
*/
i += MIN_LOW_SPEED_POLL_INTERVAL) {
}
/* wait for xfer to finish */
#ifndef __sparc
#else
;
#endif
/* Now, remove the endpoint from the lattice */
i += MIN_LOW_SPEED_POLL_INTERVAL) {
}
#ifndef lint
#endif
return (USB_SUCCESS);
}
/*
* uhci_polled_init:
* support.
*/
static int
{
/*
* If the structure has already been initialized, then we don't
* need to redo it.
*/
return (USB_SUCCESS);
}
/* Allocate and intitialize a polled mode state structure */
KM_SLEEP);
/*
* Keep a copy of normal mode state structure and pipe handle.
*/
/*
* Allocate a queue head for the device. This queue head wiil be
* put in action when we switch to polled mode in _enter point.
*/
return (USB_NO_RESOURCES);
}
/*
* Insert a TD onto the queue head.
*/
return (USB_NO_RESOURCES);
}
return (USB_SUCCESS);
}
/*
* uhci_polled_fini:
*/
static int
{
/*
* Free the transfer wrapper
*/
/*
* Free the queue head and transfer descriptor allocated.
*/
/*
* Deallocate the memory for the polled mode state structure.
*/
return (USB_SUCCESS);
}
/*
* uhci_polled_save_state:
*/
static void
{
int i;
#ifndef lint
#endif
/*
* If either of these two flags are set, then we have already
* saved off the state information and setup the controller.
*/
#ifndef lint
#endif
return;
}
/*
* Check if the number of keyboard reaches the max number we can
* support in polled mode
*/
#ifndef lint
#endif
return;
}
/*
* Get the normal mode usb pipe handle.
*/
/*
* Only the first keyboard enter disable the interrutps, stop the
* host controller processing and initialize the interrupt table.
*/
/*
* Disable interrupts to prevent the interrupt handler getting
* called while we are switing to POLLed mode.
*/
/*
* Stop the HC controller from processing TD's
*/
Set_OpReg16(USBCMD, 0);
/*
* Save the current interrupt lattice and replace this lattice
* with an lattice used in POLLED mode. We will restore lattice
* back when we exit from the POLLED mode.
*/
for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) {
}
/*
* Zero out the entire interrupt lattice tree.
*/
for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) {
}
}
/*
* Now, add the endpoint to the lattice that we will hang our
* TD's off of. We (assume always) need to poll this device at
* every 8 ms.
*/
i += MIN_LOW_SPEED_POLL_INTERVAL) {
}
/*
* Adjust the data toggle
*/
} else {
}
break;
}
}
/*
* Only the first keyboard enter reset the frame number and start
* the host controler processing.
*/
/* Set the frame number to zero */
Set_OpReg16(FRNUM, 0);
/*
* Start the Host controller processing
*/
}
#ifndef lint
#endif
}
/*
* uhci_polled_restore_state:
*/
static void
{
int i;
#ifndef lint
#endif
/*
* If this flags is set, then we are still using this structure,
* so don't restore any controller state information yet.
*/
#ifndef lint
#endif
return;
}
uhcip->uhci_polled_count --;
/* Just first leave keyboard entry turn off the controller */
if (Get_OpReg16(USBCMD)) {
}
/* Only the last leave keyboard entry restore the interrupt table */
if (uhcip->uhci_polled_count == 0) {
/*
* Replace the lattice
*/
for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) {
uhcip->uhci_frame_lst_tablep[i] =
}
}
/*
* Adjust data toggle
*/
pp = (uhci_pipe_private_t *)
pp->pp_data_toggle =
(real_data_toggle == 0) ? 1 : 0;
} else {
}
}
}
/*
* Only the last leave keyboard entry enable the interrupts,
* start Host controller processing.
*/
if (uhcip->uhci_polled_count == 0) {
}
}
#ifndef lint
#endif
}
/*
* uhci_polled_insert_td:
* Initializes the transfer descriptor for polling and inserts on the
* polled queue head. This will be put in action when entered in to
* polled mode.
*/
static int
{
/* Create the transfer wrapper */
NULL) {
return (USB_FAILURE);
}
/* Use the dummy TD allocated for the queue head */
}
return (USB_SUCCESS);
}
/*
* uhci_polled_create_wrapper_t:
* Creates the transfer wrapper used in polled mode.
*/
static uhci_trans_wrapper_t *
{
/* Allocate space for the transfer wrapper */
NULL) {
return (NULL);
}
/* Allocate the DMA handle */
DDI_SUCCESS) {
return (NULL);
}
/* Allocate the memory */
DDI_SUCCESS) {
return (NULL);
}
/* Bind the handle */
return (NULL);
}
/* The cookie count should be 1 */
if (ccount != 1) {
return (NULL);
}
return (tw);
}