usb: xhci: correct return value in case of STS_HCE
authorOliver Neukum <oneukum@suse.com>
Thu, 4 Apr 2024 12:11:05 +0000 (15:11 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 4 Apr 2024 12:54:53 +0000 (14:54 +0200)
If we get STS_HCE we give up on the interrupt, but for the purpose
of IRQ handling that still counts as ours. We may return IRQ_NONE
only if we are positive that it wasn't ours. Hence correct the default.

Fixes: 2a25e66d676d ("xhci: print warning when HCE was set")
Cc: stable@vger.kernel.org # v6.2+
Signed-off-by: Oliver Neukum <oneukum@suse.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20240404121106.2842417-2-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-ring.c

index 52278afea94be01b9f05c71fffaca9d3da98c936..575f0fd9c9f11e3df95220dfc4be8bb62ea9fc54 100644 (file)
@@ -3133,7 +3133,7 @@ static int xhci_handle_events(struct xhci_hcd *xhci, struct xhci_interrupter *ir
 irqreturn_t xhci_irq(struct usb_hcd *hcd)
 {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-       irqreturn_t ret = IRQ_NONE;
+       irqreturn_t ret = IRQ_HANDLED;
        u32 status;
 
        spin_lock(&xhci->lock);
@@ -3141,12 +3141,13 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
        status = readl(&xhci->op_regs->status);
        if (status == ~(u32)0) {
                xhci_hc_died(xhci);
-               ret = IRQ_HANDLED;
                goto out;
        }
 
-       if (!(status & STS_EINT))
+       if (!(status & STS_EINT)) {
+               ret = IRQ_NONE;
                goto out;
+       }
 
        if (status & STS_HCE) {
                xhci_warn(xhci, "WARNING: Host Controller Error\n");
@@ -3156,7 +3157,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
        if (status & STS_FATAL) {
                xhci_warn(xhci, "WARNING: Host System Error\n");
                xhci_halt(xhci);
-               ret = IRQ_HANDLED;
                goto out;
        }
 
@@ -3167,7 +3167,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
         */
        status |= STS_EINT;
        writel(status, &xhci->op_regs->status);
-       ret = IRQ_HANDLED;
 
        /* This is the handler of the primary interrupter */
        xhci_handle_events(xhci, xhci->interrupters[0]);
This page took 0.06478 seconds and 4 git commands to generate.