freebsd-skq/sys/dev/usb2/controller/uss820dci.h
alfred effcf5d59c Bring in USB4BSD, Hans Petter Selasky rework of the USB stack
that includes significant features and SMP safety.

This commit includes a more or less complete rewrite of the *BSD USB
stack, including Host Controller and Device Controller drivers and
updating all existing USB drivers to use the new USB API:

1) A brief feature list:

  - A new and mutex enabled USB API.

  - Many USB drivers are now running Giant free.

  - Linux USB kernel compatibility layer.

  - New UGEN backend and libusb library, finally solves the "driver
    unloading" problem. The new BSD licensed libusb20 library is fully
    compatible with libusb-0.1.12 from sourceforge.

  - New "usbconfig" utility, for easy configuration of USB.

  - Full support for Split transactions, which means you can use your
    full speed USB audio device on a high speed USB HUB.

  - Full support for HS ISOC transactions, which makes writing drivers
    for various HS webcams possible, for example.

  - Full support for USB on embedded platforms, mostly cache flushing
    and buffer invalidating stuff.

  - Safer parsing of USB descriptors.

  - Autodetect of annoying USB install disks.

  - Support for USB device side mode, also called USB gadget mode,
    using the same API like the USB host side. In other words the new
    USB stack is symmetric with regard to host and device side.

  - Support for USB transfers like I/O vectors, means more throughput
    and less interrupts.

  - ... see the FreeBSD quarterly status reports under "USB project"

2) To enable the driver in the default kernel build:

2.a) Remove all existing USB device options from your kernel config
file.

2.b) Add the following USB device options to your kernel configuration
file:

# USB core support
device          usb2_core

# USB controller support
device		usb2_controller
device		usb2_controller_ehci
device		usb2_controller_ohci
device		usb2_controller_uhci

# USB mass storage support
device		usb2_storage
device		usb2_storage_mass

# USB ethernet support, requires miibus
device		usb2_ethernet
device		usb2_ethernet_aue
device		usb2_ethernet_axe
device		usb2_ethernet_cdce
device		usb2_ethernet_cue
device		usb2_ethernet_kue
device		usb2_ethernet_rue
device		usb2_ethernet_dav

# USB wireless LAN support
device		usb2_wlan
device		usb2_wlan_rum
device		usb2_wlan_ral
device		usb2_wlan_zyd

# USB serial device support
device		usb2_serial
device		usb2_serial_ark
device		usb2_serial_bsa
device		usb2_serial_bser
device		usb2_serial_chcom
device		usb2_serial_cycom
device		usb2_serial_foma
device		usb2_serial_ftdi
device		usb2_serial_gensa
device		usb2_serial_ipaq
device		usb2_serial_lpt
device		usb2_serial_mct
device		usb2_serial_modem
device		usb2_serial_moscom
device		usb2_serial_plcom
device		usb2_serial_visor
device		usb2_serial_vscom

# USB bluetooth support
device		usb2_bluetooth
device		usb2_bluetooth_ng

# USB input device support
device		usb2_input
device		usb2_input_hid
device		usb2_input_kbd
device		usb2_input_ms

# USB sound and MIDI device support
device		usb2_sound

2) To enable the driver at runtime:

2.a) Unload all existing USB modules. If USB is compiled into the
kernel then you might have to build a new kernel.

2.b) Load the "usb2_xxx.ko" modules under /boot/kernel having the same
base name like the kernel device option.

Submitted by: Hans Petter Selasky hselasky at c2i dot net
Reviewed by: imp, alfred
2008-11-04 02:31:03 +00:00

376 lines
13 KiB
C

/* $FreeBSD$ */
/*-
* Copyright (c) 2007 Hans Petter Selasky <hselasky@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _USS820_DCI_H_
#define _USS820_DCI_H_
#define USS820_EP_MAX 8 /* maximum number of endpoints */
#define USS820_TXDAT 0x00 /* Transmit FIFO data */
#define USS820_TXCNTL 0x01 /* Transmit FIFO byte count low */
#define USS820_TXCNTL_MASK 0xFF
#define USS820_TXCNTH 0x02 /* Transmit FIFO byte count high */
#define USS820_TXCNTH_MASK 0x03
#define USS820_TXCNTH_UNUSED 0xFC
#define USS820_TXCON 0x03 /* USB transmit FIFO control */
#define USS820_TXCON_REVRP 0x01
#define USS820_TXCON_ADVRM 0x02
#define USS820_TXCON_ATM 0x04 /* Automatic Transmit Management */
#define USS820_TXCON_TXISO 0x08 /* Transmit Isochronous Data */
#define USS820_TXCON_UNUSED 0x10
#define USS820_TXCON_FFSZ_16_64 0x00
#define USS820_TXCON_FFSZ_64_256 0x20
#define USS820_TXCON_FFSZ_8_512 0x40
#define USS820_TXCON_FFSZ_32_1024 0x60
#define USS820_TXCON_FFSZ_MASK 0x60
#define USS820_TXCON_TXCLR 0x80 /* Transmit FIFO clear */
#define USS820_TXFLG 0x04 /* Transmit FIFO flag (Read Only) */
#define USS820_TXFLG_TXOVF 0x01 /* TX overrun */
#define USS820_TXFLG_TXURF 0x02 /* TX underrun */
#define USS820_TXFLG_TXFULL 0x04 /* TX full */
#define USS820_TXFLG_TXEMP 0x08 /* TX empty */
#define USS820_TXFLG_UNUSED 0x30
#define USS820_TXFLG_TXFIF0 0x40
#define USS820_TXFLG_TXFIF1 0x80
#define USS820_RXDAT 0x05 /* Receive FIFO data */
#define USS820_RXCNTL 0x06 /* Receive FIFO byte count low */
#define USS820_RXCNTL_MASK 0xFF
#define USS820_RXCNTH 0x07 /* Receive FIFO byte count high */
#define USS820_RXCNTH_MASK 0x03
#define USS820_RXCNTH_UNUSED 0xFC
#define USS820_RXCON 0x08 /* Receive FIFO control */
#define USS820_RXCON_REVWP 0x01
#define USS820_RXCON_ADVWM 0x02
#define USS820_RXCON_ARM 0x04 /* Auto Receive Management */
#define USS820_RXCON_RXISO 0x08 /* Receive Isochronous Data */
#define USS820_RXCON_RXFFRC 0x10 /* FIFO Read Complete */
#define USS820_RXCON_FFSZ_16_64 0x00
#define USS820_RXCON_FFSZ_64_256 0x20
#define USS820_RXCON_FFSZ_8_512 0x40
#define USS820_RXCON_FFSZ_32_1024 0x60
#define USS820_RXCON_RXCLR 0x80 /* Receive FIFO clear */
#define USS820_RXFLG 0x09 /* Receive FIFO flag (Read Only) */
#define USS820_RXFLG_RXOVF 0x01 /* RX overflow */
#define USS820_RXFLG_RXURF 0x02 /* RX underflow */
#define USS820_RXFLG_RXFULL 0x04 /* RX full */
#define USS820_RXFLG_RXEMP 0x08 /* RX empty */
#define USS820_RXFLG_RXFLUSH 0x10 /* RX flush */
#define USS820_RXFLG_UNUSED 0x20
#define USS820_RXFLG_RXFIF0 0x40
#define USS820_RXFLG_RXFIF1 0x80
#define USS820_EPINDEX 0x0a /* Endpoint index selection */
#define USS820_EPINDEX_MASK 0x07
#define USS820_EPINDEX_UNUSED 0xF8
#define USS820_EPCON 0x0b /* Endpoint control */
#define USS820_EPCON_TXEPEN 0x01 /* Transmit Endpoint Enable */
#define USS820_EPCON_TXOE 0x02 /* Transmit Output Enable */
#define USS820_EPCON_RXEPEN 0x04 /* Receive Endpoint Enable */
#define USS820_EPCON_RXIE 0x08 /* Receive Input Enable */
#define USS820_EPCON_RXSPM 0x10 /* Receive Single-Packet Mode */
#define USS820_EPCON_CTLEP 0x20 /* Control Endpoint */
#define USS820_EPCON_TXSTL 0x40 /* Stall Transmit Endpoint */
#define USS820_EPCON_RXSTL 0x80 /* Stall Receive Endpoint */
#define USS820_TXSTAT 0x0c /* Transmit status */
#define USS820_TXSTAT_TXACK 0x01 /* Transmit Acknowledge */
#define USS820_TXSTAT_TXERR 0x02 /* Transmit Error */
#define USS820_TXSTAT_TXVOID 0x04 /* Transmit Void */
#define USS820_TXSTAT_TXSOVW 0x08 /* Transmit Data Sequence Overwrite
* Bit */
#define USS820_TXSTAT_TXFLUSH 0x10 /* Transmit FIFO Packet Flushed */
#define USS820_TXSTAT_TXNAKE 0x20 /* Transmit NAK Mode Enable */
#define USS820_TXSTAT_TXDSAM 0x40 /* Transmit Data-Set-Available Mode */
#define USS820_TXSTAT_TXSEQ 0x80 /* Transmitter Current Sequence Bit */
#define USS820_RXSTAT 0x0d /* Receive status */
#define USS820_RXSTAT_RXACK 0x01 /* Receive Acknowledge */
#define USS820_RXSTAT_RXERR 0x02 /* Receive Error */
#define USS820_RXSTAT_RXVOID 0x04 /* Receive Void */
#define USS820_RXSTAT_RXSOVW 0x08 /* Receive Data Sequence Overwrite Bit */
#define USS820_RXSTAT_EDOVW 0x10 /* End Overwrite Flag */
#define USS820_RXSTAT_STOVW 0x20 /* Start Overwrite Flag */
#define USS820_RXSTAT_RXSETUP 0x40 /* Received SETUP token */
#define USS820_RXSTAT_RXSEQ 0x80 /* Receiver Endpoint Sequence Bit */
#define USS820_SOFL 0x0e /* Start Of Frame counter low */
#define USS820_SOFL_MASK 0xFF
#define USS820_SOFH 0x0f /* Start Of Frame counter high */
#define USS820_SOFH_MASK 0x07
#define USS820_SOFH_SOFDIS 0x08 /* SOF Pin Output Disable */
#define USS820_SOFH_FTLOCK 0x10 /* Frame Timer Lock */
#define USS820_SOFH_SOFIE 0x20 /* SOF Interrupt Enable */
#define USS820_SOFH_ASOF 0x40 /* Any Start of Frame */
#define USS820_SOFH_SOFACK 0x80 /* SOF Token Received Without Error */
#define USS820_FADDR 0x10 /* Function Address */
#define USS820_FADDR_MASK 0x7F
#define USS820_FADDR_UNUSED 0x80
#define USS820_SCR 0x11 /* System Control */
#define USS820_SCR_UNUSED 0x01
#define USS820_SCR_T_IRQ 0x02 /* Global Interrupt Enable */
#define USS820_SCR_IRQLVL 0x04 /* Interrupt Mode */
#define USS820_SCR_SRESET 0x08 /* Software reset */
#define USS820_SCR_IE_RESET 0x10 /* Enable Reset Interrupt */
#define USS820_SCR_IE_SUSP 0x20 /* Enable Suspend Interrupt */
#define USS820_SCR_RWUPE 0x40 /* Enable Remote Wake-Up Feature */
#define USS820_SCR_IRQPOL 0x80 /* IRQ polarity */
#define USS820_SSR 0x12 /* System Status */
#define USS820_SSR_RESET 0x01 /* Reset Condition Detected on USB
* cable */
#define USS820_SSR_SUSPEND 0x02 /* Suspend Detected */
#define USS820_SSR_RESUME 0x04 /* Resume Detected */
#define USS820_SSR_SUSPDIS 0x08 /* Suspend Disable */
#define USS820_SSR_SUSPPO 0x10 /* Suspend Power Off */
#define USS820_SSR_UNUSED 0xE0
#define USS820_UNK0 0x13 /* Unknown */
#define USS820_UNK0_UNUSED 0xFF
#define USS820_SBI 0x14 /* Serial bus interrupt low */
#define USS820_SBI_FTXD0 0x01 /* Function Transmit Done, EP 0 */
#define USS820_SBI_FRXD0 0x02 /* Function Receive Done, EP 0 */
#define USS820_SBI_FTXD1 0x04
#define USS820_SBI_FRXD1 0x08
#define USS820_SBI_FTXD2 0x10
#define USS820_SBI_FRXD2 0x20
#define USS820_SBI_FTXD3 0x40
#define USS820_SBI_FRXD3 0x80
#define USS820_SBI1 0x15 /* Serial bus interrupt high */
#define USS820_SBI1_FTXD4 0x01
#define USS820_SBI1_FRXD4 0x02
#define USS820_SBI1_FTXD5 0x04
#define USS820_SBI1_FRXD5 0x08
#define USS820_SBI1_FTXD6 0x10
#define USS820_SBI1_FRXD6 0x20
#define USS820_SBI1_FTXD7 0x40
#define USS820_SBI1_FRXD7 0x80
#define USS820_SBIE 0x16 /* Serial bus interrupt enable low */
#define USS820_SBIE_FTXIE0 0x01
#define USS820_SBIE_FRXIE0 0x02
#define USS820_SBIE_FTXIE1 0x04
#define USS820_SBIE_FRXIE1 0x08
#define USS820_SBIE_FTXIE2 0x10
#define USS820_SBIE_FRXIE2 0x20
#define USS820_SBIE_FTXIE3 0x40
#define USS820_SBIE_FRXIE3 0x80
#define USS820_SBIE1 0x17 /* Serial bus interrupt enable high */
#define USS820_SBIE1_FTXIE4 0x01
#define USS820_SBIE1_FRXIE4 0x02
#define USS820_SBIE1_FTXIE5 0x04
#define USS820_SBIE1_FRXIE5 0x08
#define USS820_SBIE1_FTXIE6 0x10
#define USS820_SBIE1_FRXIE6 0x20
#define USS820_SBIE1_FTXIE7 0x40
#define USS820_SBIE1_FRXIE7 0x80
#define USS820_REV 0x18 /* Hardware revision */
#define USS820_REV_MIN 0x0F
#define USS820_REV_MAJ 0xF0
#define USS820_LOCK 0x19 /* Suspend power-off locking */
#define USS820_LOCK_UNLOCKED 0x01
#define USS820_LOCK_UNUSED 0xFE
#define USS820_PEND 0x1a /* Pend hardware status update */
#define USS820_PEND_PEND 0x01
#define USS820_PEND_UNUSED 0xFE
#define USS820_SCRATCH 0x1b /* Scratch firmware information */
#define USS820_SCRATCH_MASK 0x7F
#define USS820_SCRATCH_IE_RESUME 0x80 /* Enable Resume Interrupt */
#define USS820_MCSR 0x1c /* Miscellaneous control and status */
#define USS820_MCSR_DPEN 0x01 /* DPLS Pull-Up Enable */
#define USS820_MCSR_SUSPLOE 0x02 /* Suspend Lock Out Enable */
#define USS820_MCSR_BDFEAT 0x04 /* Board Feature Enable */
#define USS820_MCSR_FEAT 0x08 /* Feature Enable */
#define USS820_MCSR_PKGID 0x10 /* Package Identification */
#define USS820_MCSR_SUSPS 0x20 /* Suspend Status */
#define USS820_MCSR_INIT 0x40 /* Device Initialized */
#define USS820_MCSR_RWUPR 0x80 /* Remote Wakeup-Up Remember */
#define USS820_DSAV 0x1d /* Data set available low (Read Only) */
#define USS820_DSAV_TXAV0 0x01
#define USS820_DSAV_RXAV0 0x02
#define USS820_DSAV_TXAV1 0x04
#define USS820_DSAV_RXAV1 0x08
#define USS820_DSAV_TXAV2 0x10
#define USS820_DSAV_RXAV2 0x20
#define USS820_DSAV_TXAV3 0x40
#define USS820_DSAV_RXAV3 0x80
#define USS820_DSAV1 0x1e /* Data set available high */
#define USS820_DSAV1_TXAV4 0x01
#define USS820_DSAV1_RXAV4 0x02
#define USS820_DSAV1_TXAV5 0x04
#define USS820_DSAV1_RXAV5 0x08
#define USS820_DSAV1_TXAV6 0x10
#define USS820_DSAV1_RXAV6 0x20
#define USS820_DSAV1_TXAV7 0x40
#define USS820_DSAV1_RXAV7 0x80
#define USS820_UNK1 0x1f /* Unknown */
#define USS820_UNK1_UNKNOWN 0xFF
#define USS820_GET_REG(sc,reg) \
((reg) << (sc)->sc_reg_shift)
#define USS820_READ_1(sc, reg) \
bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, \
USS820_GET_REG(sc,reg))
#define USS820_WRITE_1(sc, reg, data) \
bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, \
USS820_GET_REG(sc,reg), data)
struct uss820dci_td;
typedef uint8_t (uss820dci_cmd_t)(struct uss820dci_td *td);
struct uss820dci_td {
bus_space_tag_t io_tag;
bus_space_handle_t io_hdl;
struct uss820dci_td *obj_next;
uss820dci_cmd_t *func;
struct usb2_page_cache *pc;
uint32_t offset;
uint32_t remainder;
uint16_t max_packet_size;
uint8_t rx_stat_reg;
uint8_t tx_stat_reg;
uint8_t rx_flag_reg;
uint8_t tx_flag_reg;
uint8_t rx_fifo_reg;
uint8_t tx_fifo_reg;
uint8_t rx_count_low_reg;
uint8_t rx_count_high_reg;
uint8_t tx_count_low_reg;
uint8_t tx_count_high_reg;
uint8_t rx_cntl_reg;
uint8_t tx_cntl_reg;
uint8_t ep_reg;
uint8_t pend_reg;
uint8_t ep_index;
uint8_t error:1;
uint8_t alt_next:1;
uint8_t short_pkt:1;
uint8_t support_multi_buffer:1;
uint8_t did_stall:1;
};
struct uss820_std_temp {
uss820dci_cmd_t *func;
struct usb2_page_cache *pc;
struct uss820dci_td *td;
struct uss820dci_td *td_next;
uint32_t len;
uint32_t offset;
uint16_t max_frame_size;
uint8_t short_pkt;
/*
* short_pkt = 0: transfer should be short terminated
* short_pkt = 1: transfer should not be short terminated
*/
uint8_t setup_alt_next;
};
struct uss820dci_config_desc {
struct usb2_config_descriptor confd;
struct usb2_interface_descriptor ifcd;
struct usb2_endpoint_descriptor endpd;
} __packed;
union uss820_hub_temp {
uWord wValue;
struct usb2_port_status ps;
};
struct uss820_flags {
uint8_t change_connect:1;
uint8_t change_suspend:1;
uint8_t status_suspend:1; /* set if suspended */
uint8_t status_vbus:1; /* set if present */
uint8_t status_bus_reset:1; /* set if reset complete */
uint8_t clocks_off:1;
uint8_t port_powered:1;
uint8_t port_enabled:1;
uint8_t d_pulled_up:1;
uint8_t mcsr_feat:1;
};
struct uss820dci_softc {
struct usb2_bus sc_bus;
union uss820_hub_temp sc_hub_temp;
LIST_HEAD(, usb2_xfer) sc_interrupt_list_head;
struct usb2_sw_transfer sc_root_ctrl;
struct usb2_sw_transfer sc_root_intr;
struct usb2_config_td sc_config_td;
struct resource *sc_io_res;
struct resource *sc_irq_res;
void *sc_intr_hdl;
bus_size_t sc_io_size;
bus_space_tag_t sc_io_tag;
bus_space_handle_t sc_io_hdl;
uint8_t sc_rt_addr; /* root HUB address */
uint8_t sc_dv_addr; /* device address */
uint8_t sc_conf; /* root HUB config */
uint8_t sc_reg_shift;
uint8_t sc_hub_idata[1];
struct uss820_flags sc_flags;
};
/* prototypes */
usb2_error_t uss820dci_init(struct uss820dci_softc *sc);
void uss820dci_uninit(struct uss820dci_softc *sc);
void uss820dci_suspend(struct uss820dci_softc *sc);
void uss820dci_resume(struct uss820dci_softc *sc);
void uss820dci_interrupt(struct uss820dci_softc *sc);
#endif /* _USS820_DCI_H_ */