mirror of
https://github.com/apache/nuttx.git
synced 2026-10-05 21:27:49 +00:00
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 <justin@dynam.ac>
This commit is contained in:
parent
ecbd1870d3
commit
c288d9f9e4
1 changed files with 12 additions and 6 deletions
|
|
@ -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.
|
||||
*/
|
||||
|
||||
uinfo("no_erst = %d\n", priv->no_erst);
|
||||
erst = 1ul << XHCI_HCSPARAMS2_ERST(regval);
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue