39#ifdef USB_GLOBAL_INCLUDE_FILE
40#include USB_GLOBAL_INCLUDE_FILE
42#include <sys/stdint.h>
43#include <sys/stddef.h>
48#include <sys/kernel.h>
50#include <sys/module.h>
53#include <sys/condvar.h>
54#include <sys/sysctl.h>
56#include <sys/unistd.h>
57#include <sys/callout.h>
58#include <sys/malloc.h>
64#define USB_DEBUG_VAR atmegadci_debug
81#define ATMEGA_BUS2SC(bus) \
82 __containerof(bus, struct atmegadci_softc, sc_bus)
84#define ATMEGA_PC2SC(pc) \
85 ATMEGA_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus)
88static int atmegadci_debug = 0;
90static SYSCTL_NODE(_hw_usb, OID_AUTO, atmegadci, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
93 &atmegadci_debug, 0,
"ATMEGA DCI debug level");
96#define ATMEGA_INTR_ENDPT 1
120 .max_out_frame_size = 64,
122 .support_control = 1,
125 .max_in_frame_size = 64,
126 .max_out_frame_size = 64,
129 .support_interrupt = 1,
130 .support_isochronous = 1,
235 DPRINTFN(5,
"addr=%d\n",
addr);
259 DPRINTFN(5,
"UEINTX=0x%02x\n", temp);
276 DPRINTFN(0,
"Invalid SETUP packet "
277 "length, %d bytes\n",
count);
281 DPRINTFN(0,
"Unsupported SETUP packet "
282 "length, %d bytes\n",
count);
287 (
void *)&
req,
sizeof(
req));
312 DPRINTFN(5,
"stalling\n");
351 DPRINTFN(5,
"temp=0x%02x rem=%u\n", temp, td->
remainder);
359 DPRINTFN(5,
"faking complete\n");
384 if (count < td->max_packet_size) {
463 DPRINTFN(5,
"temp=0x%02x rem=%u\n", temp, td->
remainder);
541 DPRINTFN(5,
"temp=0x%02x\n", temp);
544 DPRINTFN(5,
"faking complete\n");
579 if ((td->
func) (td)) {
588 }
else if (td->remainder > 0) {
619 TAILQ_FOREACH(xfer, &sc->
sc_bus.
intr_q.head, wait_entry) {
630 DPRINTFN(5,
"vbus = %u\n", is_on);
668 DPRINTFN(14,
"UDINT=0x%02x\n",
status);
672 DPRINTFN(5,
"end of reset\n");
694 DPRINTFN(5,
"resume interrupt\n");
710 DPRINTFN(5,
"suspend interrupt\n");
735 DPRINTFN(5,
"USBINT=0x%02x\n",
status);
744 DPRINTFN(5,
"real endpoint interrupt UEINT=0x%02x\n",
status);
784 DPRINTFN(9,
"addr=%d endpt=%d sumlen=%d speed=%d\n",
1036 DPRINTFN(13,
"xfer=%p endpoint=%p transfer done\n",
1084 DPRINTFN(9,
"xfer=%p, endpoint=%p, error=%d\n",
1096 DPRINTFN(15,
"disabled interrupts!\n");
1117 DPRINTFN(5,
"endpoint=%p\n", ep);
1132 uint8_t ep_type, uint8_t ep_dir)
1185 "Chip rejected configuration\n");
1196 DPRINTFN(5,
"endpoint=%p\n", ep);
1245 for (
n = 0;
n != 20;
n++) {
1425 DPRINTFN(6,
"xfer=%p next=%d nframes=%d\n",
1466 .bcdUSB = {0x00, 0x02},
1470 .bMaxPacketSize = 64,
1471 .bcdDevice = {0x00, 0x01},
1474 .bNumConfigurations = 1,
1494 .bInterfaceProtocol = 0,
1505#define HSETW(ptr, val) ptr = { (uint8_t)(val), (uint8_t)((val) >> 8) }
1517#define STRING_VENDOR \
1520#define STRING_PRODUCT \
1521 "D\0C\0I\0 \0R\0o\0o\0t\0 \0H\0U\0B"
1550 switch (
req->bmRequestType) {
1552 switch (
req->bRequest) {
1554 goto tr_handle_get_descriptor;
1556 goto tr_handle_get_config;
1558 goto tr_handle_get_status;
1565 switch (
req->bRequest) {
1567 goto tr_handle_set_address;
1569 goto tr_handle_set_config;
1581 switch (
req->bRequest) {
1585 goto tr_handle_clear_halt;
1587 goto tr_handle_clear_wakeup;
1595 goto tr_handle_set_halt;
1597 goto tr_handle_set_wakeup;
1610 switch (
req->bRequest) {
1612 goto tr_handle_get_ep_status;
1619 switch (
req->bRequest) {
1621 goto tr_handle_set_interface;
1631 switch (
req->bRequest) {
1633 goto tr_handle_get_interface;
1635 goto tr_handle_get_iface_status;
1652 switch (
req->bRequest) {
1664 switch (
req->bRequest) {
1666 goto tr_handle_clear_port_feature;
1668 goto tr_handle_set_port_feature;
1680 switch (
req->bRequest) {
1682 goto tr_handle_get_tt_state;
1684 goto tr_handle_get_port_status;
1691 switch (
req->bRequest) {
1693 goto tr_handle_get_class_descriptor;
1695 goto tr_handle_get_class_status;
1706tr_handle_get_descriptor:
1707 switch (
value >> 8) {
1723 switch (
value & 0xff) {
1730 len =
sizeof(atmegadci_vendor);
1731 ptr = (
const void *)&atmegadci_vendor;
1735 len =
sizeof(atmegadci_product);
1736 ptr = (
const void *)&atmegadci_product;
1747tr_handle_get_config:
1752tr_handle_get_status:
1757tr_handle_set_address:
1758 if (
value & 0xFF00) {
1764tr_handle_set_config:
1771tr_handle_get_interface:
1776tr_handle_get_tt_state:
1777tr_handle_get_class_status:
1778tr_handle_get_iface_status:
1779tr_handle_get_ep_status:
1785tr_handle_set_interface:
1786tr_handle_set_wakeup:
1787tr_handle_clear_wakeup:
1788tr_handle_clear_halt:
1791tr_handle_clear_port_feature:
1795 DPRINTFN(9,
"UR_CLEAR_PORT_FEATURE on port %d\n",
index);
1855 "Chip rejected EP0 configuration\n");
1867tr_handle_set_port_feature:
1871 DPRINTFN(9,
"UR_SET_PORT_FEATURE\n");
1892tr_handle_get_port_status:
1894 DPRINTFN(9,
"UR_GET_PORT_STATUS\n");
1938tr_handle_get_class_descriptor:
2016 for (
n = 0;
n != ntd;
n++) {
2025 if (
pf->support_multi_buffer) {
2032 parm->
size[0] +=
sizeof(*td);
2050 DPRINTFN(2,
"endpoint=%p, addr=%d, endpt=%d, mode=%d (%d,%d)\n",
static void atmegadci_device_isoc_fs_close(struct usb_xfer *xfer)
static void atmegadci_wakeup_peer(struct atmegadci_softc *sc)
static void atmegadci_xfer_unsetup(struct usb_xfer *xfer)
static void atmegadci_resume(struct atmegadci_softc *sc)
static const struct usb_device_descriptor atmegadci_devd
static const struct usb_pipe_methods atmegadci_device_non_isoc_methods
static void atmegadci_device_isoc_fs_start(struct usb_xfer *xfer)
static void atmegadci_xfer_setup(struct usb_setup_params *parm)
static atmegadci_cmd_t atmegadci_setup_rx
static void atmegadci_device_non_isoc_enter(struct usb_xfer *xfer)
void atmegadci_uninit(struct atmegadci_softc *sc)
static void atmegadci_set_stall(struct usb_device *udev, struct usb_endpoint *ep, uint8_t *did_stall)
static const struct usb_hub_descriptor_min atmegadci_hubd
static void atmegadci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
static void atmegadci_setup_standard_chain_sub(struct atmegadci_std_temp *temp)
static const struct atmegadci_config_desc atmegadci_confd
#define ATMEGA_BUS2SC(bus)
static void atmegadci_setup_standard_chain(struct usb_xfer *xfer)
static void atmegadci_interrupt_poll(struct atmegadci_softc *sc)
static void atmegadci_clocks_off(struct atmegadci_softc *sc)
static void atmegadci_pull_up(struct atmegadci_softc *sc)
static usb_error_t atmegadci_roothub_exec(struct usb_device *udev, struct usb_device_request *req, const void **pptr, uint16_t *plength)
static void atmegadci_device_non_isoc_close(struct usb_xfer *xfer)
static void atmegadci_set_address(struct atmegadci_softc *sc, uint8_t addr)
static const struct usb_pipe_methods atmegadci_device_isoc_fs_methods
static void atmegadci_device_non_isoc_start(struct usb_xfer *xfer)
static const struct usb_bus_methods atmegadci_bus_methods
usb_error_t atmegadci_init(struct atmegadci_softc *sc)
static void atmegadci_clear_stall(struct usb_device *udev, struct usb_endpoint *ep)
#define ATMEGA_INTR_ENDPT
static void atmegadci_standard_done(struct usb_xfer *)
static atmegadci_cmd_t atmegadci_data_tx
static atmegadci_cmd_t atmegadci_data_tx_sync
static void atmegadci_timeout(void *arg)
static atmegadci_cmd_t atmegadci_data_rx
static const struct usb_hw_ep_profile atmegadci_ep_profile[2]
void atmegadci_interrupt(struct atmegadci_softc *sc)
static void atmegadci_root_intr(struct atmegadci_softc *sc)
static void atmegadci_clear_stall_sub(struct atmegadci_softc *sc, uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
static void atmegadci_get_hw_ep_profile(struct usb_device *udev, const struct usb_hw_ep_profile **ppf, uint8_t ep_addr)
static void atmegadci_do_poll(struct usb_bus *)
static void atmegadci_device_non_isoc_open(struct usb_xfer *xfer)
USB_MAKE_STRING_DESC(STRING_VENDOR, atmegadci_vendor)
static void atmegadci_device_isoc_fs_open(struct usb_xfer *xfer)
static void atmegadci_suspend(struct atmegadci_softc *sc)
static void atmegadci_start_standard_chain(struct usb_xfer *xfer)
static void atmegadci_xfer_stall(struct usb_xfer *xfer)
static void atmegadci_pull_down(struct atmegadci_softc *sc)
static void atmegadci_device_isoc_fs_enter(struct usb_xfer *xfer)
static void atmegadci_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc, struct usb_endpoint *ep)
static uint8_t atmegadci_xfer_do_fifo(struct usb_xfer *xfer)
static void atmegadci_device_done(struct usb_xfer *, usb_error_t)
static usb_error_t atmegadci_standard_done_sub(struct usb_xfer *xfer)
static void atmegadci_clocks_on(struct atmegadci_softc *sc)
static void atmegadci_vbus_interrupt(struct atmegadci_softc *sc, uint8_t is_on)
#define ATMEGA_UESTA0X_CFGOK
#define ATMEGA_UHWCON_UVREGE
#define ATMEGA_WRITE_1(sc, reg, data)
#define ATMEGA_USBCON_FRZCLK
#define ATMEGA_UEINTX_RXSTPI
#define ATMEGA_READ_1(sc, reg)
#define ATMEGA_UECONX_RSTDT
#define ATMEGA_UEIENX_TXINE
#define ATMEGA_USBINT_VBUSTI
#define ATMEGA_UEINTX_FIFOCON
#define ATMEGA_UDCON_RMWKUP
#define ATMEGA_USBCON_USBE
#define ATMEGA_UDINT_WAKEUPE
#define ATMEGA_UECFG0X_EPTYPE2
#define ATMEGA_WRITE_MULTI_1(sc, reg, ptr, len)
#define ATMEGA_UEINTX_TXINI
#define ATMEGA_USBCON_VBUSTE
#define ATMEGA_UHWCON_UIMOD
#define ATMEGA_UECONX_EPEN
uint8_t() atmegadci_cmd_t(struct atmegadci_td *td)
#define ATMEGA_UECFG0X_EPTYPE3
#define ATMEGA_UECONX_STALLRQ
#define ATMEGA_UERST_MASK(n)
#define ATMEGA_UECFG0X_EPTYPE1
#define ATMEGA_UDINT_SUSPI
#define ATMEGA_UEIENX_RXOUTE
#define ATMEGA_FRAME_MASK
#define ATMEGA_UECFG1X_ALLOC
#define ATMEGA_UDINT_WAKEUPI
#define ATMEGA_UEINTX_RXOUTI
#define ATMEGA_UDCON_DETACH
#define ATMEGA_UECFG0X_EPDIR
#define ATMEGA_UDINT_EORSTE
#define ATMEGA_UDINT_SUSPE
#define ATMEGA_UDADDR_ADDEN
#define ATMEGA_UECONX_STALLRQC
#define ATMEGA_UEIENX_RXSTPE
#define ATMEGA_USBCON_OTGPADE
#define ATMEGA_UECFG1X_EPSIZE(n)
#define ATMEGA_USBSTA_VBUS
#define ATMEGA_READ_MULTI_1(sc, reg, ptr, len)
#define ATMEGA_UECFG1X_EPBK0
#define ATMEGA_UDINT_EORSTI
#define ATMEGA_UECFG0X_EPTYPE0
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+")
struct usb_config_descriptor confd
union atmegadci_hub_temp sc_hub_temp
atmegadci_clocks_t * sc_clocks_on
struct atmegadci_flags sc_flags
atmegadci_clocks_t * sc_clocks_off
struct usb_page_cache * pc
struct atmegadci_td * td_next
uint8_t support_multi_buffer
struct usb_page_cache * pc
struct atmegadci_td * obj_next
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
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_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 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_UNLOCK(_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