mirror of
https://github.com/apache/nuttx.git
synced 2026-10-03 20:27:53 +00:00
drivers/usbhost: Acknowledge xHCI events before walking the ring.
The event ring was acknowledged after being walked. An event arriving during the walk sets the pending bit again, and clearing the bit afterwards discards it. Transfers have no timeout, so the transfer that event belonged to waits forever. Acknowledge first. A spurious second pass over an empty ring costs nothing. Assisted-by: Claude:claude-opus-5 Signed-off-by: Justin Hammond <justin@dynam.ac>
This commit is contained in:
parent
e03c23c4ae
commit
f78decb390
1 changed files with 14 additions and 12 deletions
|
|
@ -2907,6 +2907,20 @@ static void xhci_interrupt_work(FAR void *arg)
|
|||
FAR struct usbhost_xhci_s *priv = arg;
|
||||
uint32_t iman;
|
||||
|
||||
/* Acknowledge before walking the ring, not after. An event arriving
|
||||
* during the walk sets the pending bit again, and clearing after the
|
||||
* walk discards it. Transfers have no timeout, so the one it belonged
|
||||
* to would wait forever.
|
||||
*/
|
||||
|
||||
xhci_oper_putreg(priv, XHCI_USBSTS, priv->pending);
|
||||
|
||||
iman = xhci_runt_getreg(priv, XHCI_IMAN(0));
|
||||
if (iman & XHCI_IMAN_IP)
|
||||
{
|
||||
xhci_runt_putreg(priv, XHCI_IMAN(0), iman);
|
||||
}
|
||||
|
||||
xhci_events_poll(priv);
|
||||
|
||||
/* Port Change Detect */
|
||||
|
|
@ -2939,18 +2953,6 @@ static void xhci_interrupt_work(FAR void *arg)
|
|||
uinfo("Host Controller Error\n");
|
||||
}
|
||||
|
||||
/* ACK interrupts */
|
||||
|
||||
xhci_oper_putreg(priv, XHCI_USBSTS, priv->pending);
|
||||
|
||||
/* Clear interrupter pending bit */
|
||||
|
||||
iman = xhci_runt_getreg(priv, XHCI_IMAN(0));
|
||||
if (iman & XHCI_IMAN_IP)
|
||||
{
|
||||
xhci_runt_putreg(priv, XHCI_IMAN(0), iman);
|
||||
}
|
||||
|
||||
/* Clear pending bits */
|
||||
|
||||
priv->pending = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue