diff --git a/README.md b/README.md index d79df887..10ed83a8 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ The CherryUSB Host Stack has a standard enumeration implementation for devices m CherryUSB Host Stack has the following functions: +- Support low speed, full speed, high speed and super speed devices - Automatic loading of supported Class drivers - Support blocking transfers and asynchronous transfers - Support Composite Device diff --git a/README_zh.md b/README_zh.md index 0aee5a75..cce81939 100644 --- a/README_zh.md +++ b/README_zh.md @@ -87,6 +87,7 @@ CherryUSB Host 协议栈对挂载在 roothub、外部 hub 上的设备规范了 CherryUSB Host 协议栈当前实现以下功能: +- 支持 low speed, full speed, high speed 和 super speed 设备 - 自动加载支持的Class 驱动 - 支持阻塞式传输和异步传输 - 支持复合设备 diff --git a/class/hub/usb_hub.h b/class/hub/usb_hub.h index 7956b163..68e0ecf1 100644 --- a/class/hub/usb_hub.h +++ b/class/hub/usb_hub.h @@ -10,6 +10,12 @@ #define HUB_DESCRIPTOR_TYPE_HUB 0x29 #define HUB_DESCRIPTOR_TYPE_HUB3 0x2A +#define HUB_MAX_DEPTH 5 + +#define HUB_SUBCLASS 0x00 +#define HUB_PROTOCOL_STT 0x01 +#define HUB_PROTOCOL_MTT 0x02 + /* Hub class requests */ #define HUB_REQUEST_GET_STATUS USB_REQUEST_GET_STATUS #define HUB_REQUEST_CLEAR_FEATURE USB_REQUEST_CLEAR_FEATURE @@ -27,23 +33,31 @@ #define HUB_FEATURE_HUB_C_OVERCURRENT (0x1) /* Port features */ -#define HUB_PORT_FEATURE_CONNECTION (0x00) -#define HUB_PORT_FEATURE_ENABLE (0x01) -#define HUB_PORT_FEATURE_SUSPEND (0x02) -#define HUB_PORT_FEATURE_OVERCURRENT (0x03) -#define HUB_PORT_FEATURE_RESET (0x04) -#define HUB_PORT_FEATURE_L1 (0x05) -#define HUB_PORT_FEATURE_POWER (0x08) -#define HUB_PORT_FEATURE_LOWSPEED (0x09) -#define HUB_PORT_FEATURE_HIGHSPEED (0x0a) +#define HUB_PORT_FEATURE_CONNECTION (0x00) +#define HUB_PORT_FEATURE_ENABLE (0x01) +#define HUB_PORT_FEATURE_SUSPEND (0x02) +#define HUB_PORT_FEATURE_OVERCURRENT (0x03) +#define HUB_PORT_FEATURE_RESET (0x04) +#define HUB_PORT_FEATURE_L1 (0x05) /* USB 2.0 only */ + +#define HUB_PORT_FEATURE_POWER (0x08) /* USB 2.0 only */ +#define HUB_PORT_FEATURE_POWER_SS (0x09) /* USB 3.0 only */ +/* This is a bit tricky because HUB_PORT_FEATURE_POWER_SS and + HUB_PORT_FEATURE_LOWSPEED share the same bit. */ +#define HUB_PORT_FEATURE_LOWSPEED (0x09) /* USB 2.0 only */ +#define HUB_PORT_FEATURE_HIGHSPEED (0x0a) /* USB 2.0 only */ +#define HUB_PORT_FEATURE_TEST (0x0b) /* USB 2.0 only */ +#define HUB_PORT_FEATURE_INDICATOR (0x0c) /* USB 2.0 only */ + +/* Port status change (wPortChange) */ #define HUB_PORT_FEATURE_C_CONNECTION (0x10) -#define HUB_PORT_FEATURE_C_ENABLE (0x11) -#define HUB_PORT_FEATURE_C_SUSPEND (0x12) +#define HUB_PORT_FEATURE_C_ENABLE (0x11) /* USB 2.0 only */ +#define HUB_PORT_FEATURE_C_SUSPEND (0x12) /* USB 2.0 only */ #define HUB_PORT_FEATURE_C_OVER_CURREN (0x13) #define HUB_PORT_FEATURE_C_RESET (0x14) -#define HUB_PORT_FEATURE_TEST (0x15) -#define HUB_PORT_FEATURE_INDICATOR (0x16) -#define HUB_PORT_FEATURE_C_PORTL1 (0x17) +#define HUB_PORT_FEATURE_C_BH_RESET (0x15) /* USB 3.0 only */ +#define HUB_PORT_FEATURE_C_LINK_STATE (0x16) /* USB 3.0 only */ +#define HUB_PORT_FEATURE_C_CONFIG_ERR (0x17) /* USB 3.0 only */ /* Hub status */ #define HUB_STATUS_LOCALPOWER (1 << 0) @@ -56,23 +70,42 @@ /* Hub port status */ #define HUB_PORT_STATUS_CONNECTION (1 << 0) #define HUB_PORT_STATUS_ENABLE (1 << 1) -#define HUB_PORT_STATUS_SUSPEND (1 << 2) +#define HUB_PORT_STATUS_SUSPEND (1 << 2) /* USB 2.0 only */ #define HUB_PORT_STATUS_OVERCURRENT (1 << 3) #define HUB_PORT_STATUS_RESET (1 << 4) -#define HUB_PORT_STATUS_L1 (1 << 5) -#define HUB_PORT_STATUS_POWER (1 << 8) -#define HUB_PORT_STATUS_LOW_SPEED (1 << 9) -#define HUB_PORT_STATUS_HIGH_SPEED (1 << 10) -#define HUB_PORT_STATUS_TEST (1 << 11) -#define HUB_PORT_STATUS_INDICATOR (1 << 12) +#define HUB_PORT_STATUS_L1 (1 << 5) /* USB 2.0 only */ + +/* Port Link State (PORT_LINK_STATE), USB 3.0 only */ +#define HUB_PORT_STATUS_LS_U0 (0x00 << 5) +#define HUB_PORT_STATUS_LS_U1 (0x01 << 5) +#define HUB_PORT_STATUS_LS_U2 (0x02 << 5) +#define HUB_PORT_STATUS_LS_U3 (0x03 << 5) +#define HUB_PORT_STATUS_LS_SS_DISABLED (0x04 << 5) +#define HUB_PORT_STATUS_LS_RX_DETECT (0x05 << 5) +#define HUB_PORT_STATUS_LS_SS_INACTIVE (0x06 << 5) +#define HUB_PORT_STATUS_LS_POLLING (0x07 << 5) +#define HUB_PORT_STATUS_LS_RECOVERY (0x08 << 5) +#define HUB_PORT_STATUS_LS_HOT_RESET (0x09 << 5) +#define HUB_PORT_STATUS_LS_COMP_MOD (0x0a << 5) +#define HUB_PORT_STATUS_LS_LOOPBACK (0x0b << 5) + +#define HUB_PORT_STATUS_POWER (1 << 8) +#define HUB_PORT_STATUS_POWER_SS (1 << 9) /* USB 3.0 only */ +#define HUB_PORT_STATUS_LOW_SPEED (1 << 9) /* USB 2.0 only */ +#define HUB_PORT_STATUS_HIGH_SPEED (1 << 10) /* USB 2.0 only */ +#define HUB_PORT_STATUS_TEST (1 << 11) /* USB 2.0 only */ +#define HUB_PORT_STATUS_INDICATOR (1 << 12) /* USB 2.0 only */ /* Hub port status change */ #define HUB_PORT_STATUS_C_CONNECTION (1 << 0) -#define HUB_PORT_STATUS_C_ENABLE (1 << 1) -#define HUB_PORT_STATUS_C_SUSPEND (1 << 2) +#define HUB_PORT_STATUS_C_ENABLE (1 << 1) /* USB 2.0 only */ +#define HUB_PORT_STATUS_C_SUSPEND (1 << 2) /* USB 2.0 only */ #define HUB_PORT_STATUS_C_OVERCURRENT (1 << 3) #define HUB_PORT_STATUS_C_RESET (1 << 4) -#define HUB_PORT_STATUS_C_L1 (1 << 5) +#define HUB_PORT_STATUS_C_L1 (1 << 5) /* USB 2.0 only */ +#define HUB_PORT_STATUS_C_BH_RESET (1 << 5) /* USB 3.0 only */ +#define HUB_PORT_STATUS_C_PORTLINK (1 << 6) /* USB 3.0 only */ +#define HUB_PORT_STATUS_C_CONFIGERR (1 << 7) /* USB 3.0 only */ /* Hub characteristics */ #define HUB_CHAR_LPSM_SHIFT (0) /* Bits 0-1: Logical Power Switching Mode */ @@ -106,6 +139,21 @@ struct usb_hub_descriptor { #define USB_SIZEOF_HUB_DESC 9 +/* Super speed Hub descriptor */ +struct usb_hub_ss_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bNbrPorts; + uint16_t wHubCharacteristics; + uint8_t bPwrOn2PwrGood; + uint8_t bHubContrCurrent; + uint8_t bHubHdrDecLat; + uint16_t wHubDelay; + uint8_t DeviceRemovable; +} __PACKED; + +#define USB_SIZEOF_HUB_SS_DESC 11 + /* Hub status */ struct hub_status { uint16_t wPortStatus; diff --git a/class/hub/usbh_hub.c b/class/hub/usbh_hub.c index 1745d8c0..d0974a02 100644 --- a/class/hub/usbh_hub.c +++ b/class/hub/usbh_hub.c @@ -55,9 +55,7 @@ static void usbh_hub_class_free(struct usbh_hub *hub_class) } memset(hub_class, 0, sizeof(struct usbh_hub)); } -#endif -#if CONFIG_USBHOST_MAX_EXTHUBS > 0 static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer) { struct usb_setup_packet *setup; @@ -67,15 +65,7 @@ static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer) setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE; setup->bRequest = USB_REQUEST_GET_DESCRIPTOR; - - /* TODO: hub descriptor has some difference between USB 2.0 and USB 3.x, - and we havn't handle the difference here */ - if ((hub->parent->speed == USB_SPEED_SUPER) || - (hub->parent->speed == USB_SPEED_SUPER_PLUS)) { - setup->wValue = HUB_DESCRIPTOR_TYPE_HUB3 << 8; - } else { - setup->wValue = HUB_DESCRIPTOR_TYPE_HUB << 8; - } + setup->wValue = HUB_DESCRIPTOR_TYPE_HUB << 8; setup->wIndex = 0; setup->wLength = USB_SIZEOF_HUB_DESC; @@ -87,8 +77,8 @@ static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer) memcpy(buffer, g_hub_buf[hub->bus->busid], USB_SIZEOF_HUB_DESC); return ret; } -#if 0 -static int _usbh_hub_get_status(struct usbh_hub *hub, uint8_t *buffer) + +static int _usbh_hub_get_hub_ss_descriptor(struct usbh_hub *hub, uint8_t *buffer) { struct usb_setup_packet *setup; int ret; @@ -96,20 +86,20 @@ static int _usbh_hub_get_status(struct usbh_hub *hub, uint8_t *buffer) setup = hub->parent->setup; setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = HUB_REQUEST_GET_STATUS; - setup->wValue = 0; + setup->bRequest = USB_REQUEST_GET_DESCRIPTOR; + setup->wValue = HUB_DESCRIPTOR_TYPE_HUB3 << 8; + setup->wIndex = 0; - setup->wLength = 2; + setup->wLength = USB_SIZEOF_HUB_SS_DESC; ret = usbh_control_transfer(hub->parent, setup, g_hub_buf[hub->bus->busid]); if (ret < 0) { return ret; } - memcpy(buffer, g_hub_buf[hub->bus->busid], 2); + memcpy(buffer, g_hub_buf[hub->bus->busid], USB_SIZEOF_HUB_SS_DESC); return ret; } #endif -#endif static int _usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct hub_port_status *port_status) { @@ -199,6 +189,27 @@ static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length } return 0; } + +static int parse_hub_ss_descriptor(struct usb_hub_ss_descriptor *desc, uint16_t length) +{ + if (desc->bLength < USB_SIZEOF_HUB_SS_DESC) { + USB_LOG_ERR("invalid device bLength 0x%02x\r\n", desc->bLength); + return -1; + } else if (desc->bDescriptorType != HUB_DESCRIPTOR_TYPE_HUB3) { + USB_LOG_ERR("unexpected descriptor 0x%02x\r\n", desc->bDescriptorType); + return -2; + } else { + USB_LOG_RAW("SuperSpeed Hub Descriptor:\r\n"); + USB_LOG_RAW("bLength: 0x%02x \r\n", desc->bLength); + USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType); + USB_LOG_RAW("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts); + USB_LOG_RAW("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics); + USB_LOG_RAW("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood); + USB_LOG_RAW("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent); + USB_LOG_RAW("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable); + } + return 0; +} #endif static int usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct hub_port_status *port_status) @@ -311,22 +322,65 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf) hub->hub_addr = hport->dev_addr; hub->parent = hport; hub->bus = hport->bus; + hub->speed = hport->speed; + hport->self = hub; hport->config.intf[intf].priv = hub; - ret = _usbh_hub_get_hub_descriptor(hub, (uint8_t *)&hub->hub_desc); - if (ret < 0) { - return ret; + if (hport->depth > HUB_MAX_DEPTH) { + USB_LOG_ERR("Hub depth(%d) is overflow\r\n", hport->depth); + return -USB_ERR_INVAL; } - parse_hub_descriptor(&hub->hub_desc, USB_SIZEOF_HUB_DESC); + /* + * Super-Speed hubs need to know their depth to be able to + * parse the bits of the route-string that correspond to + * their downstream port number. + * + */ + if ((hport->depth != 0) && (hport->speed == USB_SPEED_SUPER)) { + ret = usbh_hub_set_depth(hub, hport->depth - 1); + if (ret < 0) { + USB_LOG_ERR("Unable to set hub depth \r\n"); + return ret; + } + } - for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { + /* Get hub descriptor. */ + if (hport->speed == USB_SPEED_SUPER) { + ret = _usbh_hub_get_hub_ss_descriptor(hub, (uint8_t *)&hub->hub_ss_desc); + if (ret < 0) { + return ret; + } + + parse_hub_ss_descriptor(&hub->hub_ss_desc, USB_SIZEOF_HUB_SS_DESC); + hub->nports = hub->hub_ss_desc.bNbrPorts; + hub->powerdelay = hub->hub_ss_desc.bPwrOn2PwrGood * 2; + hub->tt_think = 0U; + } else { + ret = _usbh_hub_get_hub_descriptor(hub, (uint8_t *)&hub->hub_desc); + if (ret < 0) { + return ret; + } + + parse_hub_descriptor(&hub->hub_desc, USB_SIZEOF_HUB_DESC); + hub->nports = hub->hub_desc.bNbrPorts; + hub->powerdelay = hub->hub_desc.bPwrOn2PwrGood * 2; + hub->tt_think = ((hub->hub_desc.wHubCharacteristics & HUB_CHAR_TTTT_MASK) >> 5); + } + + for (uint8_t port = 0; port < hub->nports; port++) { hub->child[port].port = port + 1; hub->child[port].parent = hub; hub->child[port].bus = hport->bus; } + if (hport->device_desc.bDeviceProtocol == HUB_PROTOCOL_MTT) { + hub->ismtt = 1; + } else { + hub->ismtt = 0; + } + ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc; if (ep_desc->bEndpointAddress & 0x80) { USBH_EP_INIT(hub->intin, ep_desc); @@ -334,28 +388,16 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf) return -1; } - if (hport->speed == USB_SPEED_SUPER) { - uint16_t depth = 0; - struct usbh_hubport *parent = hport->parent->parent; - while (parent) { - depth++; - parent = parent->parent->parent; - } - - ret = usbh_hub_set_depth(hub, depth); - if (ret < 0) { - return ret; - } - } - - for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { + for (uint8_t port = 0; port < hub->nports; port++) { ret = usbh_hub_set_feature(hub, port + 1, HUB_PORT_FEATURE_POWER); if (ret < 0) { return ret; } } - for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { + usb_osal_msleep(hub->powerdelay); + + for (uint8_t port = 0; port < hub->nports; port++) { ret = usbh_hub_get_portstatus(hub, port + 1, &port_status); USB_LOG_INFO("port %u, status:0x%02x, change:0x%02x\r\n", port + 1, port_status.wPortStatus, port_status.wPortChange); if (ret < 0) { @@ -395,7 +437,7 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf) usb_osal_timer_delete(hub->int_timer); } - for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { + for (uint8_t port = 0; port < hub->nports; port++) { child = &hub->child[port]; usbh_hubport_release(child); child->parent = NULL; @@ -415,7 +457,7 @@ static void usbh_hub_events(struct usbh_hub *hub) { struct usbh_hubport *child; struct hub_port_status port_status; - uint8_t portchange_index; + uint16_t portchange_index; uint16_t portstatus; uint16_t portchange; uint16_t mask; @@ -429,11 +471,10 @@ static void usbh_hub_events(struct usbh_hub *hub) } flags = usb_osal_enter_critical_section(); - portchange_index = hub->int_buffer[0]; - hub->int_buffer[0] &= ~portchange_index; + memcpy(&portchange_index, hub->int_buffer, 2); usb_osal_leave_critical_section(flags); - for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { + for (uint8_t port = 0; port < hub->nports; port++) { USB_LOG_DBG("Port change:0x%02x\r\n", portchange_index); if (!(portchange_index & (1 << (port + 1)))) { @@ -539,12 +580,23 @@ static void usbh_hub_events(struct usbh_hub *hub) } } - if (portstatus & HUB_PORT_STATUS_HIGH_SPEED) { - speed = USB_SPEED_HIGH; - } else if (portstatus & HUB_PORT_STATUS_LOW_SPEED) { - speed = USB_SPEED_LOW; + /* + * Figure out device speed. This is a bit tricky because + * HUB_PORT_STATUS_POWER_SS and HUB_PORT_STATUS_LOW_SPEED share the same bit. + */ + if (portstatus & HUB_PORT_STATUS_POWER) { + if (portstatus & HUB_PORT_STATUS_HIGH_SPEED) { + speed = USB_SPEED_HIGH; + } else if (portstatus & HUB_PORT_STATUS_LOW_SPEED) { + speed = USB_SPEED_LOW; + } else { + speed = USB_SPEED_FULL; + } + } else if (portstatus & HUB_PORT_STATUS_POWER_SS) { + speed = USB_SPEED_SUPER; } else { - speed = USB_SPEED_FULL; + USB_LOG_WRN("Port %u does not enable power\r\n", port + 1); + continue; } child = &hub->child[port]; @@ -553,6 +605,7 @@ static void usbh_hub_events(struct usbh_hub *hub) memset(child, 0, sizeof(struct usbh_hubport)); child->parent = hub; + child->depth = (hub->parent ? hub->parent->depth : 0) + 1; child->connected = true; child->port = port + 1; child->speed = speed; @@ -624,7 +677,7 @@ int usbh_hub_initialize(struct usbh_bus *bus) hub->is_roothub = true; hub->parent = NULL; hub->hub_addr = 1; - hub->hub_desc.bNbrPorts = CONFIG_USBHOST_MAX_RHPORTS; + hub->nports = CONFIG_USBHOST_MAX_RHPORTS; hub->int_buffer = bus->hcd.roothub_intbuf; hub->bus = bus; @@ -652,7 +705,7 @@ int usbh_hub_deinitialize(struct usbh_bus *bus) flags = usb_osal_enter_critical_section(); hub = &bus->hcd.roothub; - for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { + for (uint8_t port = 0; port < hub->nports; port++) { hport = &hub->child[port]; usbh_hubport_release(hport); diff --git a/class/hub/usbh_hub.h b/class/hub/usbh_hub.h index 1f34c53b..dcce6606 100644 --- a/class/hub/usbh_hub.h +++ b/class/hub/usbh_hub.h @@ -10,10 +10,6 @@ struct usbh_hub; -#define USBH_HUB_MAX_PORTS 4 -/* Maximum size of an interrupt IN transfer */ -#define USBH_HUB_INTIN_BUFSIZE ((USBH_HUB_MAX_PORTS + 8) >> 3) - #ifdef __cplusplus extern "C" { #endif diff --git a/core/usbh_core.c b/core/usbh_core.c index d1fc769d..24964137 100644 --- a/core/usbh_core.c +++ b/core/usbh_core.c @@ -731,7 +731,7 @@ static void *usbh_list_all_interface_name(struct usbh_hub *hub, const char *devn struct usbh_hub *hub_next; void *priv; - for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { + for (uint8_t port = 0; port < hub->nports; port++) { hport = &hub->child[port]; if (hport->connected) { for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) { @@ -760,8 +760,9 @@ static void usbh_list_all_interface_driver(struct usbh_hub *hub) { struct usbh_hubport *hport; struct usbh_hub *hub_next; + const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" }; - for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { + for (uint8_t port = 0; port < hub->nports; port++) { hport = &hub->child[port]; if (hport->connected) { for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) { @@ -770,11 +771,12 @@ static void usbh_list_all_interface_driver(struct usbh_hub *hub) USB_LOG_RAW("\t"); } - USB_LOG_RAW("|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s\r\n", + USB_LOG_RAW("|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s, %s\r\n", hport->port, hport->dev_addr, itf, - hport->config.intf[itf].class_driver->driver_name); + hport->config.intf[itf].class_driver->driver_name, + speed_table[hport->speed]); if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) { hub_next = hport->config.intf[itf].priv; @@ -794,7 +796,7 @@ static void usbh_list_all_interface_desc(struct usbh_bus *bus, struct usbh_hub * struct usbh_hubport *hport; struct usbh_hub *hub_next; - for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { + for (uint8_t port = 0; port < hub->nports; port++) { hport = &hub->child[port]; if (hport->connected) { USB_LOG_RAW("\r\nBus %u, Hub %u, Port %u, dev addr:0x%02x, VID:PID 0x%04x:0x%04x\r\n", @@ -888,7 +890,7 @@ int lsusb(int argc, char **argv) USB_LOG_RAW("/: Bus %u, Hub %u, ports=%u, is roothub\r\n", bus->busid, hub->index, - hub->hub_desc.bNbrPorts); + hub->nports); usbh_list_all_interface_driver(hub); } } diff --git a/core/usbh_core.h b/core/usbh_core.h index 32109885..ab805ec7 100644 --- a/core/usbh_core.h +++ b/core/usbh_core.h @@ -101,6 +101,9 @@ struct usbh_hubport { uint8_t port; /* Hub port index */ uint8_t dev_addr; /* device address */ uint8_t speed; /* device speed */ + uint8_t depth; /* distance from root hub */ + uint8_t route; /* route string */ + uint8_t slot_id; /* slot id */ struct usb_device_descriptor device_desc; struct usbh_configuration config; const char *iManufacturer; @@ -109,6 +112,7 @@ struct usbh_hubport { uint8_t *raw_config_desc; struct usb_setup_packet *setup; struct usbh_hub *parent; + struct usbh_hub *self; /* if this hubport is a hub */ struct usbh_bus *bus; struct usb_endpoint_descriptor ep0; struct usbh_urb ep0_urb; @@ -120,7 +124,13 @@ struct usbh_hub { bool is_roothub; uint8_t index; uint8_t hub_addr; - struct usb_hub_descriptor hub_desc; + uint8_t speed; + uint8_t nports; + uint8_t powerdelay; + uint8_t tt_think; + bool ismtt; + struct usb_hub_descriptor hub_desc; /* USB 2.0 only */ + struct usb_hub_ss_descriptor hub_ss_desc; /* USB 3.0 only */ struct usbh_hubport child[CONFIG_USBHOST_MAX_EHPORTS]; struct usbh_hubport *parent; struct usbh_bus *bus; @@ -145,7 +155,7 @@ struct usbh_devaddr_map { struct usbh_hcd { uint32_t reg_base; uint8_t hcd_id; - uint8_t roothub_intbuf[1]; + uint8_t roothub_intbuf[2]; /* at most 15 roothub ports */ struct usbh_hub roothub; };