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 8f88d7327592011ef44a06dacb24af06251eb337
Author: Justin Hammond <[email protected]>
AuthorDate: Sun Aug 16 17:10:58 2026 +0800

    drivers/usbhost: Set the xHCI interrupter moderation interval.
    
    The interval was left at its reset value of 4000, a millisecond, which is
    how long the controller waits after an event before reporting it.  Every
    completion paid that, and mass storage spends three transfers on a
    request.
    
    Set it to 160, which is 40us, as Linux does.  Zero puts no bound on how
    often a controller may interrupt: a keyboard on an interrupt endpoint then
    takes them continuously and occupies a processor.
    
    Measured on a DWC3 with a USB 2.0 drive, doorbell to interrupt 986-1021us
    before and 13-56us after:
    
        reading 1MiB          before        after
        512 byte blocks      166 KB/s     775 KB/s
        32 KiB blocks      10666 KB/s   18618 KB/s
    
        mounting a FAT32 volume: 92.7s before, 21.1s after
    
    Assisted-by: Claude:claude-opus-5
    Signed-off-by: Justin Hammond <[email protected]>
---
 drivers/usbhost/usbhost_xhci.c |  4 ++++
 drivers/usbhost/usbhost_xhci.h | 11 +++++++++++
 2 files changed, 15 insertions(+)

diff --git a/drivers/usbhost/usbhost_xhci.c b/drivers/usbhost/usbhost_xhci.c
index ed417a92a52..2c3d3ad559a 100644
--- a/drivers/usbhost/usbhost_xhci.c
+++ b/drivers/usbhost/usbhost_xhci.c
@@ -1141,6 +1141,10 @@ static int xhci_ctrl_start(FAR struct usbhost_xhci_s 
*priv)
   xhci_oper_putreg_8b(priv, XHCI_CRCR,
                       up_addrenv_va_to_pa(priv->cmd.ring) | XHCI_CRCR_RCS);
 
+  /* Do not sit on completions; see XHCI_IMOD_INTERVAL */
+
+  xhci_runt_putreg(priv, XHCI_IMOD(0), XHCI_IMOD_DEFAULT);
+
   /* Enable interrupts */
 
   regval = xhci_runt_getreg(priv, XHCI_IMAN(0));
diff --git a/drivers/usbhost/usbhost_xhci.h b/drivers/usbhost/usbhost_xhci.h
index 8f940f8a82c..2fc2aa207ad 100644
--- a/drivers/usbhost/usbhost_xhci.h
+++ b/drivers/usbhost/usbhost_xhci.h
@@ -315,6 +315,17 @@
 #define XHCI_IMOD_IMODI_SHIFT        (0)                   /* Bits 0-15: 
Interrupt Moderation Interval */
 #define XHCI_IMOD_IMODC_SHIFT        (16)                  /* Bits 16-31: 
Interrupt Moderation Counter */
 
+/* What to set the moderation interval to, in 250ns units.
+ *
+ * The reset default is 4000, a millisecond, which is far too long to wait
+ * to be told a transfer finished.  Zero is too short: it puts no bound on
+ * how often a controller may interrupt, and a polled device such as a
+ * keyboard on an interrupt endpoint will then occupy a processor.  160 is
+ * 40us, which is what Linux uses.
+ */
+
+#define XHCI_IMOD_DEFAULT            (160)
+
 /* Event Ring Segment Table Size */
 
 #define XHCI_ERSTS_MASK              (0xffff)              /* Bit 0-15: Event 
Ring Segment Table Size */

Reply via email to