]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
xhci: Show host status when watchdog triggers and host is assumed dead.
authorMathias Nyman <mathias.nyman@linux.intel.com>
Thu, 12 Mar 2020 14:45:11 +0000 (16:45 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 Mar 2020 16:34:48 +0000 (17:34 +0100)
Additional debugging to show xHC USBSTS register when stop endpoint
command watchdog triggers and host is assumed dead.

useful to know the current status before the controller is stopped by
the xhci driver and everything is released and freed.

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20200312144517.1593-4-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.h

index efcddc0c0991a101f1ac6934c2c7ac622e4d9cdf..ba512b25901a46c4afd23d80e96e88c959e123f1 100644 (file)
@@ -955,6 +955,7 @@ void xhci_stop_endpoint_command_watchdog(struct timer_list *t)
        struct xhci_virt_ep *ep = from_timer(ep, t, stop_cmd_timer);
        struct xhci_hcd *xhci = ep->xhci;
        unsigned long flags;
+       u32 usbsts;
 
        spin_lock_irqsave(&xhci->lock, flags);
 
@@ -965,8 +966,11 @@ void xhci_stop_endpoint_command_watchdog(struct timer_list *t)
                xhci_dbg(xhci, "Stop EP timer raced with cmd completion, exit");
                return;
        }
+       usbsts = readl(&xhci->op_regs->status);
 
        xhci_warn(xhci, "xHCI host not responding to stop endpoint command.\n");
+       xhci_warn(xhci, "USBSTS:%s\n", xhci_decode_usbsts(usbsts));
+
        ep->ep_state &= ~EP_STOP_CMD_PENDING;
 
        xhci_halt(xhci);
index 685180e1b98a552d0e88cb5100446cdf48f2507d..3ff199c9aea6423f2c31f83a855d081f05fa52ec 100644 (file)
@@ -2589,6 +2589,35 @@ static inline const char *xhci_decode_portsc(u32 portsc)
        return str;
 }
 
+static inline const char *xhci_decode_usbsts(u32 usbsts)
+{
+       static char str[256];
+       int ret = 0;
+
+       if (usbsts == ~(u32)0)
+               return " 0xffffffff";
+       if (usbsts & STS_HALT)
+               ret += sprintf(str + ret, " HCHalted");
+       if (usbsts & STS_FATAL)
+               ret += sprintf(str + ret, " HSE");
+       if (usbsts & STS_EINT)
+               ret += sprintf(str + ret, " EINT");
+       if (usbsts & STS_PORT)
+               ret += sprintf(str + ret, " PCD");
+       if (usbsts & STS_SAVE)
+               ret += sprintf(str + ret, " SSS");
+       if (usbsts & STS_RESTORE)
+               ret += sprintf(str + ret, " RSS");
+       if (usbsts & STS_SRE)
+               ret += sprintf(str + ret, " SRE");
+       if (usbsts & STS_CNR)
+               ret += sprintf(str + ret, " CNR");
+       if (usbsts & STS_HCE)
+               ret += sprintf(str + ret, " HCE");
+
+       return str;
+}
+
 static inline const char *xhci_decode_doorbell(u32 slot, u32 doorbell)
 {
        static char str[256];