This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 572b7a0b558a64e2e274346dda88ede7bc9f6919 Author: Justin Hammond <[email protected]> AuthorDate: Sat Aug 8 13:39:53 2026 +0800 usbhost: Report what a hub is on the port it occupies. Some host controllers must be told about the hubs in a topology, not only about the device at the end of it. xHCI is one: a hub's slot context carries a hub flag, its downstream port count and the think time of its transaction translator, and the controller routes to anything behind that hub using them. The hub class driver already reads both values from the hub descriptor and keeps them privately. Publish them on the hub's own hub port, beside the speed and function address that already describe the device attached there. A driver setting up a device behind a hub finds them on that device's parent. They are written before the hub activates any downstream port, so they are in place before there is anything behind it, and a port with no hub reports zero ports because the hub class clears each child before use. Nothing is required to read them. Fields rather than a driver method: a method would need a null check at the call site and would define an order it must be called in. Both are inside CONFIG_USBHOST_HUB, as struct usbhost_hubport_s's parent pointer already is. Multi-TT is not included; it comes from the hub's interface protocol rather than its descriptor, and driving a multi-TT hub as single-TT costs bandwidth behind it but is correct. Assisted-by: Claude:claude-opus-5 Signed-off-by: Justin Hammond <[email protected]> --- drivers/usbhost/usbhost_hub.c | 11 +++++++++++ include/nuttx/usb/usbhost.h | 15 +++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/drivers/usbhost/usbhost_hub.c b/drivers/usbhost/usbhost_hub.c index 52032ee87dd..a2ea159de00 100644 --- a/drivers/usbhost/usbhost_hub.c +++ b/drivers/usbhost/usbhost_hub.c @@ -578,6 +578,17 @@ static inline int usbhost_hubdesc(FAR struct usbhost_class_s *hubclass) priv->pwrondelay = (2 * hubdesc->pwrondelay); priv->ctrlcurrent = hubdesc->ctrlcurrent; + /* Publish what describes this hub as a hub, rather than as a device, on + * the port it occupies. A host controller that has to be told about the + * hubs in a topology reads it from there when it sets up a device behind + * this one. This runs before any downstream port is activated, so it is + * in place before there is anything behind it to set up. + */ + + hport->nports = hubdesc->nports; + hport->ttt = (hubchar & USBHUB_CHAR_TTTT_MASK) >> + USBHUB_CHAR_TTTT_SHIFT; + uinfo("Hub Descriptor:\n"); uinfo(" bDescLength: %d\n", hubdesc->len); uinfo(" bDescriptorType: 0x%02x\n", hubdesc->type); diff --git a/include/nuttx/usb/usbhost.h b/include/nuttx/usb/usbhost.h index 3a43bb3a4ae..27521f2055f 100644 --- a/include/nuttx/usb/usbhost.h +++ b/include/nuttx/usb/usbhost.h @@ -721,6 +721,21 @@ struct usbhost_hubport_s uint8_t port; /* Hub port index */ uint8_t funcaddr; /* Device function address */ uint8_t speed; /* Device speed */ +#ifdef CONFIG_USBHOST_HUB + /* Set by the hub class driver when the device attached here is itself a + * hub, describing that hub rather than this port. Both are zero + * otherwise, and zero ports is not a hub. + * + * A host controller that has to be told about the hubs in a topology, + * rather than only about the device at the end of it, reads these from + * the parent of the port it is working on. They are set before the hub + * activates any downstream port, so they are in place before anything + * behind that hub can be enumerated. + */ + + uint8_t nports; /* Downstream ports on the attached hub */ + uint8_t ttt; /* Its transaction translator think time */ +#endif }; /* The root hub port differs in that it includes a data set that is used to
