ohcid.h revision 9c75c6bf17b72bb057d7a8879feba77ece65241a
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_USB_OHCID_H
#define _SYS_USB_OHCID_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Open Host Controller Driver (OHCI)
*
* The USB Open Host Controller driver is a software driver which interfaces
* to the Universal Serial Bus layer (USBA) and the USB Open Host Controller.
* The interface to USB Open Host Controller is defined by the OpenHCI Host
* Controller Interface.
*
* This header file describes the data structures required for the USB Open
* Host Controller Driver to maintain state of USB Open Host Controller, to
* perform different USB transfers and for the bandwidth allocations.
*/
/*
* OpenHCI interrupt status information structure
*
* The Host Controller Driver (HCD) has to maintain two different sets of
* Host Controller (HC) state information that includes HC registers, the
* interrupt tables etc.. for the normal and polled modes. In addition,
* suppose if we switched to polled mode while ohci interrupt handler is
* executing in the normal mode then we need to save the interrupt status
* information that includes interrupts for which ohci interrupt handler
* is called and HCCA done head list in the polled mode. This infromation
* will be used later in normal mode to service those missed interrupts.
* This will avoid race conditions like missing of normal mode's ohci SOF
* and WriteDoneHead interrupts because of this polled switch.
*/
typedef struct ohci_save_intr_sts {
/*
* The following field has set of flags & these flags will be set
* in the ohci interrupt handler to indicate that currently ohci
* interrupt handler is in execution and also while critical code
* execution within the ohci interrupt handler. These flags will
* be verified in polled mode while saving the normal mode's ohci
* interrupt status information.
*/
/*
* The following fields will be used to save the interrupt status
* and the HCCA done head list that the ohci interrupt handler is
* currently handling.
*/
/*
* The following fields will be used to save the interrupt status
* and the HCCA done list currently being handled by the critical
* section of the ohci interrupt handler..
*/
/*
* The following fields will be used to save the interrupt status
* and HCCA done head list by the polled code if an interrupt is
* pending when polled code is entered. These missed interrupts &
* done list will be serviced either in current normal mode ohci
* interrupt handler execution or during the next ohci interrupt
* handler execution.
*/
/*
* These flags will be set in the the normal mode ohci interrupt handler
* to indicate that currently ohci interrupt handler is in execution and
* also while critical code execution within the ohci interrupt handler.
* These flags will be verified in the polled mode while saving the normal
* mode's ohci interrupt status infromation.
*/
/*
* OpenHCI Host Controller state structure
*
* The Host Controller Driver (HCD) maintains the state of Host Controller
* (HC). There is an ohci_state structure per instance of the OpenHCI
* host controller.
*/
typedef struct ohci_state {
int ohci_intr_type; /* intr type used */
int ohci_intr_cnt; /* # of intrs inuse */
int ohci_intr_cap; /* intr capabilities */
/* HCCA area */
/*
* There are two pools of memory. One pool contains the memory for
* the transfer descriptors and other pool contains the memory for
* the endpoint descriptors. The advantage of the pools is that it's
* easy to go back and forth between the iommu and the cpu addresses.
*
* The pools are protected by the ohci_int_mutex because the memory
* in the pools may be accessed by either the host controller or the
* host controller driver.
*/
/* General transfer descriptor pool */
/* Endpoint descriptor pool */
/* Condition variables */
/* Semaphore to serialize opens and closes */
/*
* Bandwidth fields
*
* The ohci_bandwidth array keeps track of the allocated bandwidth
* for this host controller. The total bandwidth allocated for least
* allocated list out of the 32 periodic lists is represented by the
* ohci_periodic_minimum_bandwidth field.
*/
/* Different transfer open pipe counts */
/*
* Endpoint Reclamation List
*
* The interrupt or isochronous list processing cannot be stopped
* when a periodic endpoint is removed from the list. The endpoints
* are detached from the interrupt lattice tree and put on to the
* reclaimation list. On next SOF interrupt all those endpoints,
* which are on the reclaimation list will be deallocated.
*/
/*
* Global transfer timeout handling & this transfer timeout handling
* will be per USB Host Controller.
*/
/* Frame number overflow information */
/* For Schedule Overrun error counter */
/* For host controller error counter */
/* For SOF interrupt event */
/* Openhci Host Controller Software State information */
/*
* ohci_save_intr_stats is used to save the normal mode interrupt
* status information while executing interrupt handler & also by
* the polled code if an interrupt is pending for the normal mode
* when polled code is entered.
*/
/*
* Saved copy of the ohci registers of the normal mode & change
* required ohci registers values for the polled mode operation.
* Before returning from the polled mode to normal mode replace
* the required current registers with this saved ohci registers
* copy.
*/
/*
* Saved copy of the interrupt table used in normal ohci mode and
* replace this table by another interrupt table that used in the
* POLLED mode.
*/
/* ohci polled mode enter counter for the input devices */
/*
* Counter for polled mode and used in suspend mode to see if
* there is a input device connected.
*/
/* Done list for the Polled mode */
/* Log handle for debug, console, log messages */
/* Kstat structures */
} ohci_state_t;
typedef struct ohci_intrs_stats {
struct kstat_named ohci_hcr_intr_so;
struct kstat_named ohci_hcr_intr_wdh;
struct kstat_named ohci_hcr_intr_sof;
struct kstat_named ohci_hcr_intr_rd;
struct kstat_named ohci_hcr_intr_ue;
struct kstat_named ohci_hcr_intr_fno;
struct kstat_named ohci_hcr_intr_rhsc;
struct kstat_named ohci_hcr_intr_oc;
struct kstat_named ohci_hcr_intr_not_claimed;
struct kstat_named ohci_hcr_intr_total;
/*
* ohci kstat defines
*/
#define OHCI_INTRS_STATS_DATA(ohci) \
#define OHCI_CTRL_STATS(ohci) \
#define OHCI_BULK_STATS(ohci) \
#define OHCI_INTR_STATS(ohci) \
#define OHCI_ISOC_STATS(ohci) \
/* warlock directives, stable data */
/* this may not be stable data in the future */
/*
* Host Contoller Software States
*
* OHCI_CTLR_INIT_STATE:
* The host controller soft state will be set to this during the
* ohci_attach.
*
* OHCI_CTLR_SUSPEND_STATE:
* The host controller soft state will be set to this during the
* ohci_cpr_suspend.
*
* OHCI_CTLR_OPERATIONAL_STATE:
* The host controller soft state will be set to this after moving
* host controller to operational state and host controller start
* generating SOF successfully.
*
* OHCI_CTLR_ERROR_STATE:
* The host controller soft state will be set to this during the
* no SOF or UE error conditions.
*
* Under this state or condition, only pipe stop polling, pipe reset
* and pipe close are allowed. But all other entry points like pipe
*
* State Diagram for the host controller software state
*
*
* ohci_attach->[INIT_STATE]
* |
* | -------->----[ERROR_STATE]--<-----------<---
* | ^ ^
* V | Success |
* ^ |
* | |
* | V
* -<-ohci_cpr_resume--[SUSPEND_STATE]-<-ohci_cpr_suspend
*/
#define OHCI_CTLR_INIT_STATE 0 /* Initilization state */
/*
* Define all ohci's Vendor-id and Device-id Here
*/
#define RIO_VENDOR 0x108e
#define RIO_DEVICE 0x1103
/*
* Periodic and non-periodic macros
*/
USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) ||\
((endpoint->bmAttributes &\
USB_EP_ATTR_MASK) == USB_EP_ATTR_CONTROL) ||\
((endpoint->bmAttributes &\
/*
* OHCI ED and TD Pool sizes.
*/
#define OHCI_ED_POOL_SIZE 100
#define OHCI_TD_POOL_SIZE 200
/*
* ohci_dma_addr_bind_flag values
*
* This flag indicates if the various DMA addresses allocated by the OHCI
* have been bound to their respective handles. This is needed to recover
* without errors from ohci_cleanup when it calls ddi_dma_unbind_handle()
*/
/*
* Maximum SOF wait count
*/
/*
* Pipe private structure
*
* There is an instance of this structure per pipe. This structure holds
* HCD specific pipe information. A pointer to this structure is kept in
* the USBA pipe handle (usba_pipe_handle_data_t).
*/
typedef struct ohci_pipe_private {
/* State of the pipe */
/* Local copy of the pipe policy */
/* For Periodic Pipes Only */
/* For isochronous pipe only */
/*
* Each pipe may have multiple transfer wrappers. Each transfer
* wrapper represents a USB transfer on the bus. A transfer is
* made up of one or more transactions.
*/
/* Done td count */
/* Errors */
/* Flags */
/* Condition variable for transfers completion event */
/*
* HCD gets Interrupt/Isochronous IN polling request only once and
* it has to insert next polling requests after completion of first
* has to take copy of the original Interrupt/Isochronous IN request.
*/
/* warlock directives, stable data */
/*
* Pipe states
*
* ohci pipe states will be similar to usba. Refer usbai.h.
*/
/* Additional ohci pipe states for the ohci_pipe_cleanup */
/*
* Pipe specific Flags
*/
/*
* The maximum allowable usb isochronous data transfer size or maximum
* number of isochronous data packets.
*
* Each usb isochronous request must not exceed multiples of isochronous
* endpoint packet size and OHCI_MAX_ISOC_PKTS_PER_XFER.
*
* Ex: usb isochronous endpoint maximum packet size is 64 bytes
* maximum usb isochronous request will be OHCI_MAX_ISOC_PKTS_PER_XFER
* * 64 bytes
*/
/*
* The ohci supports maximum of eight isochronous data packets per transfer
* descriptor.
*/
/*
* USB frame offset
*
* Add appropriate frame offset to the current usb frame number and use it
* as a starting frame number for a given usb isochronous request.
*/
/*
* Default usb isochronous receive packets per request before ohci will do
* callback.
*/
/*
* Different interrupt polling intervals supported
*/
#define INTR_1MS_POLL 1
#define INTR_2MS_POLL 2
#define INTR_4MS_POLL 4
#define INTR_8MS_POLL 8
#define INTR_16MS_POLL 16
#define INTR_32MS_POLL 32
/*
* Number of interrupt/isochronous transfer requests that should
* be maintained on the interrupt/isochronous endpoint corresponding
* to different polling intervals supported.
*/
/* Function prototype */
typedef void (*ohci_handler_function_t)(
struct ohci_trans_wrapper *tw,
void *ohci_handle_callback_value);
/*
* Transfer wrapper
*
* The transfer wrapper represents a USB transfer on the bus and there
* is one instance per USB transfer. A transfer is made up of one or
* more transactions.
*
* Control and bulk pipes will have one transfer wrapper per transfer
* and where as Isochronous and Interrupt pipes will only have one
* transfer wrapper. The transfers wrapper are continually reused for
* the Interrupt and Isochronous pipes as those pipes are polled.
*/
typedef struct ohci_trans_wrapper {
char *tw_buf; /* Buffer for Xfer */
/* We preallocate all the td's for each tw and place them here */
/* Current transfer request pointer */
/* Current isochronous packet descriptor pointer */
/* Transfer timeout information */
/*
* This is the function to call when this td is done. This way
* we don't have to look in the td to figure out what kind it is.
*/
/*
* This is the callback value used when processing a done td.
*/
/*
* Time waits for the different OHCI specific operations.
* These timeout values are specified in terms of microseconds.
*/
/* These timeout values are specified in seconds */
/* OHCI flags for general use */
/*
* Maximum allowable data transfer size per transaction as supported
* by OHCI is 8k. (See Open Host Controller Interface Spec rev 1.0a)
*/
/*
* The maximum allowable bulk data transfer size. It can be different
* from OHCI_MAX_TD_XFER_SIZE and if it is more then ohci driver will
* take care of breaking a bulk data request into multiples of ohci
* OHCI_MAX_TD_XFER_SIZE until request is satisfied. Currently this
* value is set to 256k bytes.
*/
/*
* Timeout flags
*
* These flags will be used to stop the timer before timeout handler
* gets executed.
*/
/*
* Bandwidth allocation
*
* The following definitions are used during bandwidth calculations
* for a given endpoint maximum packet size.
*/
/*
* Minimum polling interval for low speed endpoint
*
* According USB Specifications, a full-speed endpoint can specify
* a desired polling interval 1ms to 255ms and a low speed endpoints
* are limited to specifying only 10ms to 255ms. But some old keyboards
* and mice uses polling interval of 8ms. For compatibility purpose,
* we are using polling interval between 8ms and 255ms for low speed
* endpoints. But ohci driver will reject any low speed endpoints which
* request polling interval less than 8ms.
*/
#define MIN_LOW_SPEED_POLL_INTERVAL 8
/*
* For non-periodic transfers, reserve atleast for one low-speed device
* transaction. According to USB Bandwidth Analysis white paper and also
* as per OHCI Specification 1.0a, section 7.3.5, page 123, one low-speed
* transaction takes 0x628h full speed bits (197 bytes), which comes to
* around 13% of USB frame time.
*
* The periodic transfers will get around 87% of USB frame time.
*/
#define MAX_NON_PERIODIC_BANDWIDTH 197
/*
* The USB periodic transfers like interrupt and isochronous transfers
* after completion of SOF and USB non-periodic transfers.
*/
#define PERIODIC_XFER_STARTS (MAX_USB_BUS_BANDWIDTH - \
/* Number of Bits Per Byte */
#define BITS_PER_BYTE 8
/*
* The following are the protocol overheads in terms of Bytes for the
* different transfer types. All these protocol overhead values are
* derived from the 5.9.3 section of USB Specification and with the
* help of Bandwidth Analysis white paper which is posted on the USB
* developer forum.
*/
#define FS_NON_ISOC_PROTO_OVERHEAD 14
#define FS_ISOC_INPUT_PROTO_OVERHEAD 11
#define FS_ISOC_OUTPUT_PROTO_OVERHEAD 10
#define LOW_SPEED_PROTO_OVERHEAD 97
#define HUB_LOW_SPEED_PROTO_OVERHEAD 01
/*
* The Host Controller (HC) delays are the USB host controller specific
* delays. The value shown below is the host controller delay for the
* RIO USB host controller. This value was calculated and given by the
* Sun USB hardware people.
*/
#define HOST_CONTROLLER_DELAY 18
/*
* The low speed clock below represents that to transmit one low-speed
* bit takes eight times more than one full speed bit time.
*/
#define LOW_SPEED_CLOCK 8
/*
*/
0, sizeof (ohci_hcca_t), \
0, OHCI_ED_POOL_SIZE * sizeof (ohci_ed_t), \
(void) ddi_dma_sync( \
0, OHCI_TD_POOL_SIZE * sizeof (ohci_td_t), \
(void) ddi_dma_sync(dma_handle, \
0, length, DDI_DMA_SYNC_FORCPU);
/*
* Macros to speed handling of 32bit IDs
*/
#define OHCI_LOOKUP_ID(x) id32_lookup((x))
#define OHCI_FREE_ID(x) id32_free((x))
/*
* Miscellaneous definitions.
*/
/* Data toggle bits */
#define DATA0 0
#define DATA1 1
/* sKip bit actions */
#define CLEAR_sKip 0
#define SET_sKip 1
typedef uint_t skip_bit_t;
/*
* Setup Packet
*/
typedef struct setup_pkt {
#define REQUEST_TYPE_OFFSET 0
#define REQUEST_OFFSET 1
#define VALUE_OFFSET 2
#define INDEX_OFFSET 4
#define LENGTH_OFFSET 6
#define TYPE_DEV_TO_HOST 0x80000000
#define DEVICE 0x00000001
#define CONFIGURATION 0x00000002
/*
* The following are used in attach to indicate
* what has been succesfully allocated, so detach
* can remove them.
*/
/*
* Debug printing
* Masks
*/
#define PRINT_MASK_ALL 0xFFFFFFFF
/* Polling support */
/* Root hub related functions */
int ohci_init_root_hub(
void ohci_handle_root_hub_status_change(void *arg);
/* Endpoint Descriptor (ED) related functions */
void ohci_deallocate_ed(
/* Transfer Descriptor (TD) related functions */
void ohci_traverse_tds(
void ohci_deallocate_td(
/* Transfer Wrapper (TW) functions */
/* Interrupt Handling functions */
/* Miscillaneous functions */
dev_info_t *dip);
int ohci_do_soft_reset(
#ifdef __cplusplus
}
#endif
#endif /* _SYS_USB_OHCID_H */