uhci.h revision d29f5a711240f866521445b1656d114da090335e
2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A#ifndef _SYS_USB_UHCI_H
2N/A#define _SYS_USB_UHCI_H
2N/A
2N/A
2N/A#include <sys/types.h>
2N/A
2N/A#ifdef __cplusplus
2N/Aextern "C" {
2N/A#endif
2N/A
2N/A/*
2N/A * Universal Host Controller Driver (UHCI)
2N/A *
2N/A * The UHCI driver is a driver which interfaces to the Universal
2N/A * Serial Bus Driver (USBA) and the Host Controller (HC). The interface to
2N/A * the Host Controller is defined by the Universal Host Controller
2N/A * Interface spec.
2N/A */
2N/A
2N/A
2N/A#define LEGACYMODE_REG_OFFSET 0xc0
2N/A#define LEGACYMODE_REG_INIT_VALUE 0xaf00
2N/A
2N/A/*
2N/A * The register set of the UCHI controller
2N/A * This structure is laid out for proper alignment so no need to pack(1).
2N/A */
2N/Atypedef volatile struct hcr_regs {
2N/A uint16_t USBCMD;
2N/A uint16_t USBSTS;
2N/A uint16_t USBINTR;
2N/A uint16_t FRNUM;
2N/A uint32_t FRBASEADD;
2N/A uchar_t SOFMOD;
2N/A uchar_t rsvd[3];
2N/A uint16_t PORTSC[2];
2N/A} hc_regs_t;
2N/A
2N/A/*
2N/A * #defines for the USB Command Register
2N/A */
2N/A#define USBCMD_REG_MAXPKT_64 0x0080
2N/A#define USBCMD_REG_CONFIG_FLAG 0x0040
2N/A#define USBCMD_REG_SW_DEBUG 0x0020
2N/A#define USBCMD_REG_FGBL_RESUME 0x0010
2N/A#define USBCMD_REG_ENER_GBL_SUSPEND 0x0008
2N/A#define USBCMD_REG_GBL_RESET 0x0004
2N/A#define USBCMD_REG_HC_RESET 0x0002
2N/A#define USBCMD_REG_HC_RUN 0x0001
2N/A
2N/A
2N/A/*
2N/A * #defines for the USB Status Register
2N/A */
2N/A#define USBSTS_REG_HC_HALTED 0x0020
2N/A#define USBSTS_REG_HC_PROCESS_ERR 0x0010
2N/A#define USBSTS_REG_HOST_SYS_ERR 0x0008
2N/A#define USBSTS_REG_RESUME_DETECT 0x0004
2N/A#define USBSTS_REG_USB_ERR_INTR 0x0002
2N/A#define USBSTS_REG_USB_INTR 0x0001
2N/A
2N/A/*
2N/A * #defines for the USB Root Hub Port Register
2N/A */
2N/A#define HCR_PORT_CCS 0x1
2N/A#define HCR_PORT_CSC 0x2
2N/A#define HCR_PORT_ENABLE 0x4
2N/A#define HCR_PORT_ENDIS_CHG 0x8
2N/A#define HCR_PORT_LINE_STATSU 0x30
2N/A#define HCR_PORT_RESUME_DETECT 0x40
2N/A#define HCR_PORT_LSDA 0x100
2N/A#define HCR_PORT_RESET 0x200
2N/A#define HCR_PORT_SUSPEND 0x1000
2N/A
2N/A/*
2N/A * #defines for USB Interrupt Enable Register
2N/A */
2N/A#define USBINTR_REG_SPINT_EN 0x0008
2N/A#define USBINTR_REG_IOC_EN 0x0004
2N/A#define USBINTR_REG_RESUME_INT_EN 0x0002
2N/A#define USBINTR_REG_TOCRC_INT_EN 0x0001
2N/A
2N/A#define ENABLE_ALL_INTRS 0x000F
2N/A#define DISABLE_ALL_INTRS 0x0000
2N/A#define UHCI_INTR_MASK 0x1f
2N/A
2N/A
2N/A#define SetReg32(hndl, addr, val) ddi_put32((hndl), \
2N/A &(addr), (val))
2N/A#define GetReg32(hndl, addr) ddi_get32((hndl), &(addr))
2N/A
2N/A#define SetQH32(ucp, addr, val) \
2N/A SetReg32((ucp)->uhci_qh_pool_mem_handle, (addr), (val))
2N/A#define GetQH32(ucp, addr) \
2N/A GetReg32((ucp)->uhci_qh_pool_mem_handle, (addr))
2N/A
2N/A#define SetTD32(ucp, addr, val) \
2N/A SetReg32((ucp)->uhci_td_pool_mem_handle, (addr), (val))
2N/A#define GetTD32(ucp, addr) \
2N/A GetReg32((ucp)->uhci_td_pool_mem_handle, (addr))
2N/A
2N/A#define SetFL32(ucp, addr, val) \
2N/A SetReg32((ucp)->uhci_flt_mem_handle, (addr), (val))
2N/A#define GetFL32(ucp, addr) \
2N/A GetReg32((ucp)->uhci_flt_mem_handle, (addr))
2N/A
2N/A
2N/A/*
2N/A * UHCI Queue Head structure, aligned on 16 byte boundary
2N/A */
2N/Atypedef struct uhci_qh {
2N/A /* Hardware controlled bits */
2N/A uint32_t link_ptr; /* Next Queue Head / TD */
2N/A uint32_t element_ptr; /* Next queue head / TD */
2N/A
2N/A /* Software controlled bits */
2N/A uint16_t node; /* Node that its attached */
2N/A uint16_t qh_flag; /* See below */
2N/A
2N/A struct uhci_qh *prev_qh; /* Pointer to Prev queue head */
2N/A struct uhci_td *td_tailp; /* Pointer to the last TD of QH */
2N/A struct uhci_bulk_isoc_xfer_info *bulk_xfer_info;
2N/A uint64_t __pad1; /* align to 16 bytes */
2N/A} queue_head_t;
2N/A
2N/A#define NUM_STATIC_NODES 63
2N/A#define NUM_INTR_QH_LISTS 64
2N/A#define NUM_FRAME_LST_ENTRIES 1024
2N/A#define TREE_HEIGHT 5
2N/A#define VIRTUAL_TREE_HEIGHT 5
2N/A#define SIZE_OF_FRAME_LST_TABLE 1024 * 4
2N/A
2N/A#define HC_TD_HEAD 0x0
2N/A#define HC_QUEUE_HEAD 0x2
2N/A#define HC_DEPTH_FIRST 0x4
2N/A#define HC_END_OF_LIST 0x1
2N/A
2N/A#define QUEUE_HEAD_FLAG_STATIC 0x1
2N/A#define QUEUE_HEAD_FLAG_FREE 0x2
2N/A#define QUEUE_HEAD_FLAG_BUSY 0x3
2N/A
2N/A#define QH_LINK_PTR_MASK 0xFFFFFFF0
2N/A#define QH_ELEMENT_PTR_MASK 0xFFFFFFF0
2N/A#define FRAME_LST_PTR_MASK 0xFFFFFFF0
2N/A
2N/A
2N/A#define GetField(u, td, f, o, l) \
2N/A ((GetTD32(u, (td)->f) >> (o)) & ((1U<<l)-1))
2N/A
2N/A#define SetField(u, td, f, o, l, v) \
2N/A SetTD32(u, (td)->f, \
2N/A (GetTD32(u, (td)->f) & ~(((1U<<l)-1) << o)) | \
2N/A (((v) & ((1U<<l)-1)) << o))
2N/A
2N/A#define GetTD_alen(u, td) GetField((u), (td), dw2, 0, 11)
2N/A#define GetTD_status(u, td) GetField((u), (td), dw2, 16, 8)
2N/A#define GetTD_ioc(u, td) GetField((u), (td), dw2, 24, 1)
2N/A#define GetTD_iso(u, td) GetField((u), (td), dw2, 25, 1)
2N/A#define GetTD_ls(u, td) GetField((u), (td), dw2, 26, 1)
2N/A#define GetTD_c_err(u, td) GetField((u), (td), dw2, 27, 2)
2N/A#define GetTD_spd(u, td) GetField((u), (td), dw2, 29, 1)
2N/A#define GetTD_PID(u, td) GetField((u), (td), dw3, 0, 8)
2N/A#define GetTD_devaddr(u, td) GetField((u), (td), dw3, 8, 7)
2N/A#define GetTD_endpt(u, td) GetField((u), (td), dw3, 15, 4)
2N/A#define GetTD_dtogg(u, td) GetField((u), (td), dw3, 19, 1)
2N/A#define GetTD_mlen(u, td) GetField((u), (td), dw3, 21, 11)
2N/A
2N/A#define SetTD_alen(u, td, v) SetField((u), (td), dw2, 0, 11, (v))
2N/A#define SetTD_status(u, td, v) SetField((u), (td), dw2, 16, 8, (v))
2N/A#define SetTD_ioc(u, td, v) SetField((u), (td), dw2, 24, 1, (v))
2N/A#define SetTD_iso(u, td, v) SetField((u), (td), dw2, 25, 1, (v))
2N/A#define SetTD_ls(u, td, v) SetField((u), (td), dw2, 26, 1, (v))
2N/A#define SetTD_c_err(u, td, v) SetField((u), (td), dw2, 27, 2, (v))
2N/A#define SetTD_spd(u, td, v) SetField((u), (td), dw2, 29, 1, (v))
2N/A#define SetTD_PID(u, td, v) SetField((u), (td), dw3, 0, 8, (v))
2N/A#define SetTD_devaddr(u, td, v) SetField((u), (td), dw3, 8, 7, (v))
2N/A#define SetTD_endpt(u, td, v) SetField((u), (td), dw3, 15, 4, (v))
2N/A#define SetTD_dtogg(u, td, v) SetField((u), (td), dw3, 19, 1, (v))
2N/A#define SetTD_mlen(u, td, v) SetField((u), (td), dw3, 21, 11, (v))
2N/A
2N/A/*
2N/A * UHCI Transfer Descriptor structure, aligned on 16 byte boundary
2N/A */
2N/Atypedef struct uhci_td {
2N/A
2N/A /* Information required by HC for executing the request */
2N/A /* Pointer to the next TD/QH */
2N/A uint32_t link_ptr;
2N/A uint32_t dw2;
2N/A uint32_t dw3;
2N/A /* Data buffer address */
2N/A uint32_t buffer_address;
2N/A
2N/A /* Information required by HCD for managing the request */
2N/A struct uhci_td *qh_td_prev;
2N/A struct uhci_td *tw_td_next;
2N/A struct uhci_td *outst_td_next;
2N/A struct uhci_td *outst_td_prev;
2N/A struct uhci_trans_wrapper *tw;
2N/A struct uhci_td *isoc_next;
2N/A struct uhci_td *isoc_prev;
2N/A ushort_t isoc_pkt_index;
2N/A ushort_t flag;
2N/A uint_t starting_frame;
2N/A uint_t _pad[3]; /* 16 byte alignment */
2N/A} uhci_td_t;
2N/A
2N/A#define TD_FLAG_FREE 0x1
2N/A#define TD_FLAG_BUSY 0x2
2N/A#define TD_FLAG_DUMMY 0x3
2N/A
2N/A#define INTERRUPT_ON_COMPLETION 0x1
2N/A#define END_POINT_ADDRESS_MASK 0xF
2N/A#define UHCI_MAX_ERR_COUNT 3
2N/A#define MAX_NUM_BULK_TDS_PER_XFER 128
2N/A
2N/A/* section 3.2.2 of UHCI1.1 spec, bits 23:16 of status field */
2N/A#define UHCI_TD_ACTIVE 0x80
2N/A#define UHCI_TD_STALLED 0x40
2N/A#define UHCI_TD_DATA_BUFFER_ERR 0x20
2N/A#define UHCI_TD_BABBLE_ERR 0x10
2N/A#define UHCI_TD_NAK_RECEIVED 0x08
2N/A#define UHCI_TD_CRC_TIMEOUT 0x04
2N/A#define UHCI_TD_BITSTUFF_ERR 0x02
2N/A
2N/A#define TD_INACTIVE 0x7F
2N/A#define TD_STATUS_MASK 0x76
2N/A#define ZERO_LENGTH 0x7FF
2N/A
2N/A#define PID_SETUP 0x2D
2N/A#define PID_IN 0x69
2N/A#define PID_OUT 0xe1
2N/A
2N/A#define SETUP_SIZE 8
2N/A
2N/A#define SETUP 0x11
2N/A#define DATA 0x12
2N/A#define STATUS 0x13
2N/A
2N/A#define UHCI_INVALID_PTR NULL
2N/A#define LOW_SPEED_DEVICE 1
2N/A
2N/A/*
2N/A * These provide synchronization between TD deletions.
2N/A */
2N/A#define UHCI_NOT_CLAIMED 0x0
2N/A#define UHCI_INTR_HDLR_CLAIMED 0x1
2N/A#define UHCI_MODIFY_TD_BITS_CLAIMED 0x2
2N/A#define UHCI_TIMEOUT_HDLR_CLAIMED 0x3
2N/A
2N/A
2N/A/*
2N/A * Structure for Bulk and Isoc TD pools
2N/A */
2N/Atypedef struct uhci_bulk_isoc_td_pool {
2N/A caddr_t pool_addr;
2N/A ddi_dma_cookie_t cookie; /* DMA cookie */
2N/A ddi_dma_handle_t dma_handle; /* DMA handle */
2N/A ddi_acc_handle_t mem_handle; /* Memory handle */
2N/A ushort_t num_tds;
2N/A} uhci_bulk_isoc_td_pool_t;
2N/A
2N/A/*
2N/A * Structure for Bulk and Isoc transfers
2N/A */
2N/Atypedef struct uhci_bulk_isoc_xfer_info {
2N/A uhci_bulk_isoc_td_pool_t *td_pools;
2N/A ushort_t num_pools;
2N/A ushort_t num_tds;
2N/A} uhci_bulk_isoc_xfer_t;
2N/A
2N/A/*
2N/A * Structure for Isoc DMA buffer
2N/A * One Isoc transfer includes multiple Isoc packets.
2N/A * One DMA buffer is allocated for one packet each.
2N/A */
2N/Atypedef struct uhci_isoc_buf {
2N/A caddr_t buf_addr; /* Starting buffer address */
2N/A ddi_dma_cookie_t cookie; /* DMA cookie */
2N/A ddi_dma_handle_t dma_handle; /* DMA handle */
2N/A ddi_acc_handle_t mem_handle; /* Memory handle */
2N/A size_t length; /* Buffer length */
2N/A ushort_t index;
2N/A} uhci_isoc_buf_t;
2N/A
2N/A/*
2N/A * Macros related to ISOC transfers
2N/A */
2N/A#define UHCI_SIZE_OF_HW_FRNUM 11
2N/A#define UHCI_BIT_10_MASK 0x400
2N/A#define UHCI_MAX_ISOC_FRAMES 1024
2N/A#define UHCI_MAX_ISOC_PKTS 256
2N/A#define UHCI_DEFAULT_ISOC_RCV_PKTS 1 /* isoc pkts per req */
2N/A
2N/A#define FRNUM_MASK 0x3FF
2N/A#define SW_FRNUM_MASK 0xFFFFFFFFFFFFF800
2N/A#define INVALID_FRNUM 0
2N/A#define FRNUM_OFFSET 5
2N/A#define MAX_FRAME_NUM 1023
2N/A
2N/Atypedef uint32_t frame_lst_table_t;
2N/A
2N/A/*
2N/A * Bandwidth allocation
2N/A * The following definitions are used during bandwidth
2N/A * calculations for a given endpoint maximum packet size.
2N/A */
2N/A#define MAX_BUS_BANDWIDTH 1500 /* Up to 1500 bytes per frame */
2N/A#define MAX_POLL_INTERVAL 255 /* Maximum polling interval */
2N/A#define MIN_POLL_INTERVAL 1 /* Minimum polling interval */
2N/A#define SOF 6 /* Length in bytes of SOF */
2N/A#define EOF 2 /* Length in bytes of EOF */
2N/A
2N/A/*
2N/A * Minimum polling interval for low speed endpoint
2N/A *
2N/A * According USB Specifications, a full-speed endpoint can specify
2N/A * a desired polling interval 1ms to 255ms and a low speed endpoints
2N/A * are limited to specifying only 10ms to 255ms. But some old keyboards
2N/A * and mice uses polling interval of 8ms. For compatibility purpose,
2N/A * we are using polling interval between 8ms and 255ms for low speed
2N/A * endpoints.
2N/A */
2N/A#define MIN_LOW_SPEED_POLL_INTERVAL 8
2N/A
2N/A/*
2N/A * For non-periodic transfers, reserve at least for one low-speed device
2N/A * transaction and according to USB Bandwidth Analysis white paper, it
2N/A * comes around 12% of USB frame time. Then periodic transfers will get
2N/A * 88% of USB frame time.
2N/A */
2N/A#define MAX_PERIODIC_BANDWIDTH (((MAX_BUS_BANDWIDTH - SOF - EOF)*88)/100)
2N/A
2N/A/*
2N/A * The following are the protocol overheads in terms of Bytes for the
2N/A * different transfer types. All these protocol overhead values are
2N/A * derived from the 5.9.3 section of USB Specification and with the
2N/A * help of Bandwidth Analysis white paper which is posted on the USB
2N/A * developer forum.
2N/A */
2N/A#define FS_NON_ISOC_PROTO_OVERHEAD 14
2N/A#define FS_ISOC_INPUT_PROTO_OVERHEAD 11
2N/A#define FS_ISOC_OUTPUT_PROTO_OVERHEAD 10
2N/A#define LOW_SPEED_PROTO_OVERHEAD 97
2N/A#define HUB_LOW_SPEED_PROTO_OVERHEAD 01
2N/A
2N/A/*
2N/A * The Host Controller (HC) delays are the USB host controller specific
2N/A * delays. The value shown below is the host controller delay for the
2N/A * Sand core USB host controller.
2N/A */
2N/A#define HOST_CONTROLLER_DELAY 18
2N/A
2N/A/*
2N/A * The low speed clock below represents that to transmit one low-speed
2N/A * bit takes eight times more than one full speed bit time.
2N/A */
2N/A#define LOW_SPEED_CLOCK 8
2N/A
2N/A/* the 16 byte alignment is required for every TD and QH start addr */
2N/A#define UHCI_QH_ALIGN_SZ 16
2N/A#define UHCI_TD_ALIGN_SZ 16
2N/A
2N/A#ifdef __cplusplus
2N/A}
2N/A#endif
2N/A
2N/A#endif /* _SYS_USB_UHCI_H */
2N/A