37#ifdef USB_GLOBAL_INCLUDE_FILE
38#include USB_GLOBAL_INCLUDE_FILE
40#include <sys/stdint.h>
41#include <sys/stddef.h>
46#include <sys/kernel.h>
48#include <sys/module.h>
51#include <sys/condvar.h>
52#include <sys/sysctl.h>
54#include <sys/unistd.h>
55#include <sys/callout.h>
56#include <sys/malloc.h>
62#define USB_DEBUG_VAR uss820dcidebug
79#define USS820_DCI_BUS2SC(bus) \
80 __containerof(bus, struct uss820dci_softc, sc_bus)
82#define USS820_DCI_PC2SC(pc) \
83 USS820_DCI_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus)
85#define USS820_DCI_THREAD_IRQ \
86 (USS820_SSR_SUSPEND | USS820_SSR_RESUME | USS820_SSR_RESET)
89static int uss820dcidebug = 0;
91static SYSCTL_NODE(_hw_usb, OID_AUTO, uss820dci, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
94 &uss820dcidebug, 0,
"uss820dci debug level");
97#define USS820_DCI_INTR_ENDPT 1
128 .max_out_frame_size = 32,
130 .support_control = 1,
133 .max_in_frame_size = 64,
134 .max_out_frame_size = 64,
136 .support_multi_buffer = 1,
138 .support_interrupt = 1,
143 .max_in_frame_size = 8,
144 .max_out_frame_size = 8,
146 .support_multi_buffer = 1,
148 .support_interrupt = 1,
153 .max_in_frame_size = 256,
154 .max_out_frame_size = 256,
156 .support_multi_buffer = 1,
157 .support_isochronous = 1,
165 uint8_t keep_mask, uint8_t set_mask)
183 }
else if (ep_addr < 5) {
185 }
else if (ep_addr < 7) {
187 }
else if (ep_addr == 7) {
226 temp &= ~USS820_MCSR_DPEN;
237 DPRINTFN(0,
"not supported\n");
243 DPRINTFN(5,
"addr=%d\n",
addr);
262 DPRINTFN(5,
"rx_stat=0x%02x rem=%u\n", rx_stat, td->
remainder);
288 DPRINTFN(0,
"Invalid SETUP packet "
289 "length, %d bytes\n",
count);
290 goto setup_not_complete;
293 DPRINTFN(0,
"Unsupported SETUP packet "
294 "length, %d bytes\n",
count);
295 goto setup_not_complete;
306 DPRINTF(
"new SETUP packet received\n");
338 temp &= ~USS820_TXCON_TXCLR;
355 DPRINTFN(5,
"stalling\n");
397 DPRINTFN(5,
"rx_stat=0x%02x rx_flag=0x%02x rem=%u\n",
408 DPRINTFN(5,
"faking complete\n");
420 DPRINTFN(5,
"overflow or underflow\n");
442 DPRINTFN(5,
"count=0x%04x\n",
count);
446 if (count < td->max_packet_size) {
517 DPRINTFN(5,
"tx_flag=0x%02x rem=%u\n", tx_flag, td->
remainder);
523 DPRINTFN(5,
"rx_stat=0x%02x\n", rx_stat);
619 DPRINTFN(5,
"rx_stat=0x%02x rem=%u\n", rx_stat, td->
remainder);
624 DPRINTFN(5,
"faking complete\n");
629 DPRINTFN(5,
"tx_flag=0x%02x rem=%u\n", tx_flag, td->
remainder);
660 if ((td->
func) (sc, td)) {
669 }
else if (td->remainder > 0) {
713 TAILQ_FOREACH(xfer, &sc->
sc_bus.
intr_q.head, wait_entry)
722 TAILQ_FOREACH(xfer, &sc->
sc_bus.
intr_q.head, wait_entry) {
739 scratch &= ~USS820_SCRATCH_IE_RESUME;
741 scr &= ~USS820_SCR_IE_SUSP;
753 int retval = FILTER_HANDLED;
762 retval = FILTER_SCHEDULE_THREAD;
768 retval = FILTER_SCHEDULE_THREAD;
831 DPRINTF(
"real bus interrupt 0x%02x\n", ssr);
886 DPRINTFN(9,
"addr=%d endpt=%d sumlen=%d speed=%d\n",
1038 DPRINTFN(15,
"endpoint 0x%02x\n", xfer->
endpointno);
1047 ep_no = 1 << (2 * ep_no);
1053 ep_no |= (ep_no << 1);
1185 DPRINTFN(13,
"xfer=%p endpoint=%p transfer done\n",
1232 DPRINTFN(2,
"xfer=%p, endpoint=%p, error=%d\n",
1264 DPRINTFN(5,
"endpoint=%p\n", ep);
1290 uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
1322 temp &= ~USS820_TXCON_TXCLR;
1332 temp &= ~USS820_RXCON_RXFFRC;
1334 temp &= ~USS820_RXCON_RXCLR;
1348 DPRINTFN(5,
"endpoint=%p\n", ep);
1461 if (
pf->max_in_frame_size !=
pf->max_out_frame_size) {
1462 DPRINTF(
"Max frame size mismatch %u != %u\n",
1463 pf->max_in_frame_size,
pf->max_out_frame_size);
1465 if (
pf->support_isochronous) {
1466 if (
pf->max_in_frame_size <= 64) {
1470 }
else if (
pf->max_in_frame_size <= 256) {
1474 }
else if (
pf->max_in_frame_size <= 512) {
1484 if ((
pf->max_in_frame_size <= 8) &&
1488 }
else if (
pf->max_in_frame_size <= 16) {
1491 }
else if ((
pf->max_in_frame_size <= 32) &&
1507 if (
pf->support_control) {
1539 temp &= ~USS820_SCR_T_IRQ;
1710 DPRINTFN(6,
"xfer=%p next=%d nframes=%d\n",
1749 .bcdUSB = {0x00, 0x02},
1753 .bMaxPacketSize = 64,
1754 .bcdDevice = {0x00, 0x01},
1757 .bNumConfigurations = 1,
1763 .bcdUSB = {0x00, 0x02},
1767 .bMaxPacketSize0 = 0,
1768 .bNumConfigurations = 0,
1788 .bInterfaceProtocol = 0,
1800#define HSETW(ptr, val) ptr = { (uint8_t)(val), (uint8_t)((val) >> 8) }
1812#define STRING_VENDOR \
1815#define STRING_PRODUCT \
1816 "D\0C\0I\0 \0R\0o\0o\0t\0 \0H\0U\0B"
1844 switch (
req->bmRequestType) {
1846 switch (
req->bRequest) {
1848 goto tr_handle_get_descriptor;
1850 goto tr_handle_get_config;
1852 goto tr_handle_get_status;
1859 switch (
req->bRequest) {
1861 goto tr_handle_set_address;
1863 goto tr_handle_set_config;
1875 switch (
req->bRequest) {
1879 goto tr_handle_clear_halt;
1881 goto tr_handle_clear_wakeup;
1889 goto tr_handle_set_halt;
1891 goto tr_handle_set_wakeup;
1904 switch (
req->bRequest) {
1906 goto tr_handle_get_ep_status;
1913 switch (
req->bRequest) {
1915 goto tr_handle_set_interface;
1925 switch (
req->bRequest) {
1927 goto tr_handle_get_interface;
1929 goto tr_handle_get_iface_status;
1946 switch (
req->bRequest) {
1958 switch (
req->bRequest) {
1960 goto tr_handle_clear_port_feature;
1962 goto tr_handle_set_port_feature;
1974 switch (
req->bRequest) {
1976 goto tr_handle_get_tt_state;
1978 goto tr_handle_get_port_status;
1985 switch (
req->bRequest) {
1987 goto tr_handle_get_class_descriptor;
1989 goto tr_handle_get_class_status;
2000tr_handle_get_descriptor:
2001 switch (
value >> 8) {
2024 switch (
value & 0xff) {
2031 len =
sizeof(uss820dci_vendor);
2032 ptr = (
const void *)&uss820dci_vendor;
2036 len =
sizeof(uss820dci_product);
2037 ptr = (
const void *)&uss820dci_product;
2048tr_handle_get_config:
2053tr_handle_get_status:
2058tr_handle_set_address:
2059 if (
value & 0xFF00) {
2065tr_handle_set_config:
2072tr_handle_get_interface:
2077tr_handle_get_tt_state:
2078tr_handle_get_class_status:
2079tr_handle_get_iface_status:
2080tr_handle_get_ep_status:
2086tr_handle_set_interface:
2087tr_handle_set_wakeup:
2088tr_handle_clear_wakeup:
2089tr_handle_clear_halt:
2092tr_handle_clear_port_feature:
2096 DPRINTFN(9,
"UR_CLEAR_PORT_FEATURE on port %d\n",
index);
2130tr_handle_set_port_feature:
2134 DPRINTFN(9,
"UR_SET_PORT_FEATURE\n");
2155tr_handle_get_port_status:
2157 DPRINTFN(9,
"UR_GET_PORT_STATUS\n");
2199tr_handle_get_class_descriptor:
2291 for (
n = 0;
n != ntd;
n++) {
2300 if (
pf->support_multi_buffer &&
2308 parm->
size[0] +=
sizeof(*td);
2326 DPRINTFN(2,
"endpoint=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
static SYSCTL_NODE(_hw_usb, OID_AUTO, dwc_otg, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "USB DWC OTG")
SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, phy_type, CTLFLAG_RDTUN, &dwc_otg_phy_type, 0, "DWC OTG PHY TYPE - 0/1/2/3 - ULPI/HSIC/INTERNAL/UTMI+")
void(* endpoint_init)(struct usb_device *, struct usb_endpoint_descriptor *, struct usb_endpoint *)
const struct usb_bus_methods * methods
struct usb_xfer_queue intr_q
uByte bConfigurationValue
enum usb_hc_mode usb_mode
struct usb_device_flags flags
const struct usb_pipe_methods * methods
struct usb_endpoint_descriptor * edesc
uWord wHubCharacteristics
uint16_t max_in_frame_size
void(* open)(struct usb_xfer *)
uint32_t hc_max_frame_size
uint8_t hc_max_packet_count
struct usb_xfer * curr_xfer
uint16_t hc_max_packet_size
const struct usb_pipe_methods * methods
enum usb_hc_mode usb_mode
usb_frlength_t * frlengths
struct usb_page_cache * frbuffers
struct usb_endpoint * endpoint
struct usb_xfer_flags_int flags_int
struct usb_xfer_flags flags
struct usb_xfer_root * xroot
struct usb_page_cache * pc
struct uss820dci_td * td_next
struct usb_config_descriptor confd
bus_space_tag_t sc_io_tag
uint32_t sc_xfer_complete
bus_space_handle_t sc_io_hdl
struct uss820_flags sc_flags
union uss820_hub_temp sc_hub_temp
struct usb_page_cache * pc
uint8_t support_multi_buffer
struct uss820dci_td * obj_next
struct usb_port_status ps
#define UT_WRITE_INTERFACE
#define UR_SET_DESCRIPTOR
#define UT_WRITE_CLASS_OTHER
#define UT_WRITE_CLASS_DEVICE
#define UR_CLEAR_TT_BUFFER
#define UHF_C_PORT_SUSPEND
#define UT_READ_CLASS_INTERFACE
#define UDESC_DEVICE_QUALIFIER
#define UF_DEVICE_REMOTE_WAKEUP
#define UT_READ_VENDOR_INTERFACE
#define UHF_C_PORT_OVER_CURRENT
#define UPS_PORT_MODE_DEVICE
#define UHD_OC_INDIVIDUAL
#define UT_WRITE_ENDPOINT
#define UT_READ_CLASS_DEVICE
#define UT_WRITE_CLASS_INTERFACE
#define UT_READ_CLASS_OTHER
#define UHF_PORT_INDICATOR
#define UHD_PWR_NO_SWITCH
#define UPS_C_CONNECT_STATUS
#define UPS_CURRENT_CONNECT_STATUS
#define UHF_C_PORT_ENABLE
#define UT_WRITE_VENDOR_INTERFACE
#define UT_READ_INTERFACE
#define UR_GET_DESCRIPTOR
#define UHF_C_PORT_CONNECTION
void usbd_get_page(struct usb_page_cache *pc, usb_frlength_t offset, struct usb_page_search *res)
void usbd_copy_in(struct usb_page_cache *cache, usb_frlength_t offset, const void *ptr, usb_frlength_t len)
#define USB_HW_POWER_RESUME
#define USB_HW_POWER_SUSPEND
#define USB_HW_POWER_SHUTDOWN
const struct usb_string_lang usb_string_lang_en
#define USB_ADD_BYTES(ptr, size)
#define USB_BUS_SPIN_UNLOCK(_b)
#define USB_BUS_UNLOCK(_b)
#define USB_BUS_SPIN_LOCK(_b)
#define USB_BUS_LOCK_ASSERT(_b, _t)
enum usb_dev_speed usbd_get_speed(struct usb_device *udev)
void uhub_root_intr(struct usb_bus *bus, const uint8_t *ptr, uint8_t len)
void usbd_transfer_setup_sub(struct usb_setup_params *parm)
void usbd_transfer_done(struct usb_xfer *xfer, usb_error_t error)
void usbd_transfer_enqueue(struct usb_xfer_queue *pq, struct usb_xfer *xfer)
uint8_t usbd_xfer_get_isochronous_start_frame(struct usb_xfer *xfer, uint32_t frame_curr, uint32_t frame_min, uint32_t frame_ms, uint32_t frame_mask, uint32_t *p_frame_start)
void usbd_transfer_timeout_ms(struct usb_xfer *xfer, void(*cb)(void *arg), usb_timeout_t ms)
void usb_pause_mtx(struct mtx *mtx, int timo)
@ USB_ERR_NORMAL_COMPLETION
static void uss820dci_xfer_stall(struct usb_xfer *xfer)
static void uss820dci_clear_stall(struct usb_device *udev, struct usb_endpoint *ep)
static void uss820dci_pull_up(struct uss820dci_softc *sc)
#define USS820_DCI_INTR_ENDPT
static void uss820dci_device_intr_open(struct usb_xfer *xfer)
static void uss820dci_set_address(struct uss820dci_softc *sc, uint8_t addr)
static void uss820dci_timeout(void *arg)
static void uss820dci_suspend(struct uss820dci_softc *sc)
static void uss820dci_device_bulk_open(struct usb_xfer *xfer)
static void uss820dci_set_stall(struct usb_device *udev, struct usb_endpoint *ep, uint8_t *did_stall)
static const struct usb_device_descriptor uss820dci_devd
static const struct usb_pipe_methods uss820dci_device_ctrl_methods
static void uss820dci_device_isoc_fs_open(struct usb_xfer *xfer)
static void uss820dci_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc, struct usb_endpoint *ep)
static void uss820dci_do_poll(struct usb_bus *)
static usb_error_t uss820dci_roothub_exec(struct usb_device *udev, struct usb_device_request *req, const void **pptr, uint16_t *plength)
static const struct usb_pipe_methods uss820dci_device_bulk_methods
static const struct usb_bus_methods uss820dci_bus_methods
static void uss820dci_xfer_setup(struct usb_setup_params *parm)
static void uss820dci_setup_standard_chain_sub(struct uss820_std_temp *temp)
static const struct usb_pipe_methods uss820dci_device_isoc_fs_methods
static void uss820dci_device_ctrl_start(struct usb_xfer *xfer)
static void uss820dci_wait_suspend(struct uss820dci_softc *sc, uint8_t on)
static void uss820dci_device_bulk_start(struct usb_xfer *xfer)
static void uss820dci_device_done(struct usb_xfer *, usb_error_t)
static void uss820dci_device_isoc_fs_start(struct usb_xfer *xfer)
static void uss820dci_device_bulk_enter(struct usb_xfer *xfer)
static const struct usb_hub_descriptor_min uss820dci_hubd
static void uss820dci_start_standard_chain(struct usb_xfer *xfer)
static void uss820dci_interrupt_complete_locked(struct uss820dci_softc *sc)
static void uss820dci_pull_down(struct uss820dci_softc *sc)
USB_MAKE_STRING_DESC(STRING_VENDOR, uss820dci_vendor)
static void uss820dci_intr_set(struct usb_xfer *, uint8_t)
static void uss820dci_device_isoc_fs_close(struct usb_xfer *xfer)
static void uss820dci_clear_stall_sub(struct uss820dci_softc *sc, uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
static void uss820dci_device_ctrl_enter(struct usb_xfer *xfer)
static const struct usb_pipe_methods uss820dci_device_intr_methods
void uss820dci_uninit(struct uss820dci_softc *sc)
static void uss820dci_device_intr_enter(struct usb_xfer *xfer)
usb_error_t uss820dci_init(struct uss820dci_softc *sc)
static void uss820dci_update_shared_1(struct uss820dci_softc *, uint8_t, uint8_t, uint8_t)
static void uss820dci_device_intr_start(struct usb_xfer *xfer)
static void uss820dci_device_ctrl_close(struct usb_xfer *xfer)
static uss820dci_cmd_t uss820dci_data_rx
static uss820dci_cmd_t uss820dci_data_tx_sync
static void uss820dci_get_hw_ep_profile(struct usb_device *udev, const struct usb_hw_ep_profile **ppf, uint8_t ep_addr)
static void uss820dci_xfer_do_fifo(struct usb_xfer *xfer)
static void uss820dci_resume(struct uss820dci_softc *sc)
static void uss820dci_standard_done(struct usb_xfer *)
static uint8_t uss820dci_xfer_do_complete(struct usb_xfer *xfer)
void uss820dci_interrupt(void *arg)
static void uss820dci_device_bulk_close(struct usb_xfer *xfer)
static void uss820dci_device_intr_close(struct usb_xfer *xfer)
static void uss820dci_device_ctrl_open(struct usb_xfer *xfer)
static const struct usb_device_qualifier uss820dci_odevd
static usb_error_t uss820dci_standard_done_sub(struct usb_xfer *xfer)
static void uss820dci_interrupt_poll_locked(struct uss820dci_softc *sc)
static void uss820dci_setup_standard_chain(struct usb_xfer *xfer)
static void uss820dci_xfer_unsetup(struct usb_xfer *xfer)
#define USS820_DCI_BUS2SC(bus)
static void uss820dci_wakeup_peer(struct uss820dci_softc *sc)
static void uss820dci_device_isoc_fs_enter(struct usb_xfer *xfer)
int uss820dci_filter_interrupt(void *arg)
static uss820dci_cmd_t uss820dci_setup_rx
#define USS820_DCI_THREAD_IRQ
static void uss820dci_root_intr(struct uss820dci_softc *)
static const struct uss820dci_config_desc uss820dci_confd
#define USS820_DCI_PC2SC(pc)
static void uss820dci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
static uss820dci_cmd_t uss820dci_data_tx
static const struct usb_hw_ep_profile uss820dci_ep_profile[]
#define USS820_RXSTAT_RXSOVW
#define USS820_REG_STRIDE
#define USS820_SCR_IRQPOL
#define USS820_SCR_IE_SUSP
#define USS820_TXCON_FFSZ_16_64
#define USS820_TXCON_FFSZ_8_512
#define USS820_RXSTAT_RXSETUP
#define USS820_TXCON_TXISO
#define USS820_TXFLG_TXFIF1
#define USS820_SSR_RESUME
#define USS820_SCRATCH_IE_RESUME
#define USS820_SSR_SUSPEND
#define USS820_EPCON_TXEPEN
uint8_t() uss820dci_cmd_t(struct uss820dci_softc *, struct uss820dci_td *td)
#define USS820_MCSR_BDFEAT
#define USS820_RXCON_RXCLR
#define USS820_EPCON_TXOE
#define USS820_RXCON_RXFFRC
#define USS820_RXFLG_RXOVF
#define USS820_RXFLG_RXFIF1
#define USS820_RXFLG_RXURF
#define USS820_TXCON_FFSZ_32_1024
#define USS820_EPCON_TXSTL
#define USS820_RXSTAT_STOVW
#define USS820_RXFLG_RXFIF0
#define USS820_TXSTAT_TXSOVW
#define USS820_SCR_IE_RESET
#define USS820_EPCON_RXSTL
#define USS820_EPCON_RXEPEN
#define USS820_EPCON_RXSPM
#define USS820_WRITE_1(sc, reg, data)
#define USS820_RXSTAT_EDOVW
#define USS820_EPCON_CTLEP
#define USS820_READ_1(sc, reg)
#define USS820_TXFLG_TXFIF0
#define USS820_SCR_SRESET
#define USS820_TXCON_FFSZ_64_256
#define USS820_TXFLG_TXOVF
#define USS820_TXFLG_TXURF
#define USS820_TXCON_TXCLR
#define USS820_EPCON_RXIE