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 c288d9f9e470fa08ce833beb94e066f4fe77223b Author: Justin Hammond <[email protected]> AuthorDate: Sun Aug 16 17:15:08 2026 +0800 drivers/usbhost: Compute the event ring segment count at full width. The number of event ring segments a controller allows is a power of two reported as its exponent, and the exponent can reach 15. Computing 1 << exponent into the uint8_t that holds it wraps to zero on any controller offering more than 128 segments, and a controller told its event ring table holds no entries has nowhere to report anything: every command times out. Work it out at full width and narrow afterwards. Assisted-by: Claude:claude-opus-5 Signed-off-by: Justin Hammond <[email protected]> --- drivers/usbhost/usbhost_xhci.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/usbhost/usbhost_xhci.c b/drivers/usbhost/usbhost_xhci.c index b1f05a3385b..144a4b66faa 100644 --- a/drivers/usbhost/usbhost_xhci.c +++ b/drivers/usbhost/usbhost_xhci.c @@ -4611,6 +4611,7 @@ static void xhci_disconnect(FAR struct usbhost_driver_s *drvr, static int xhci_hw_getparams(FAR struct usbhost_xhci_s *priv) { uint32_t regval; + uint32_t erst; /* Get data form Host Controller Capability 1 Parameters */ @@ -4651,16 +4652,21 @@ static int xhci_hw_getparams(FAR struct usbhost_xhci_s *priv) uinfo("no scratch = %d\n", priv->no_scratch); - priv->no_erst = 1 << XHCI_HCSPARAMS2_ERST(regval); + /* How many event ring segments the controller will allow, which is a + * power of two and can reach 32768, so it is worked out at full width + * and only then narrowed to what this driver actually uses. Computed + * into the field directly it would wrap to zero on any controller + * offering more than 128 segments, and a table declared to hold no + * entries gives a controller with nowhere to report anything. + */ + + erst = 1ul << XHCI_HCSPARAMS2_ERST(regval); - uinfo("no_erst = %d\n", priv->no_erst); + uinfo("erst max = %" PRIu32 "\n", erst); /* Limit event ring segment table to 1 */ - if (priv->no_erst > XHCI_MAX_ERST) - { - priv->no_erst = XHCI_MAX_ERST; - } + priv->no_erst = (erst > XHCI_MAX_ERST) ? XHCI_MAX_ERST : erst; uinfo("no erst = %d\n", priv->no_erst);
