]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
USB: EHCI: warn on unexpectedly active QH
authorAlan Stern <stern@rowland.harvard.edu>
Fri, 20 Nov 2015 18:53:58 +0000 (13:53 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 1 Dec 2015 18:44:19 +0000 (10:44 -0800)
This patch adds a new warning message to ehci-hcd.  The warning is
triggered whenever the driver finds that the hardware has set the
Active bit in a QH at a time when the driver expects the QH to be
completely idle.  Such bugs have been observed by users in the past,
and since they can lead to serious problems (such as inability to
unlink an URB that never completes), it would be good to know about
them when they occur.

This won't fix these bugs; that's a bigger job for a later patch.  But
success isn't guaranteed, since this depends on aspects of the
hardware which are not documented in the EHCI spec or for which the
spec's recommendations are clearly unworkable.  It therefore seems
worthwhile to check for these bugs proactively.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-by: Michael Reutman <mreutman@epiqsolutions.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci.h

index 54f5332f814ddb53bab7a58e4344e972e59c44a9..aad0777240d3b233f79b89ecd161e139647ad5d1 100644 (file)
@@ -132,10 +132,14 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
         * qtd is updated in qh_completions(). Update the QH
         * overlay here.
         */
-       if (qh->hw->hw_token & ACTIVE_BIT(ehci))
+       if (qh->hw->hw_token & ACTIVE_BIT(ehci)) {
                qh->hw->hw_qtd_next = qtd->hw_next;
-       else
+               if (qh->should_be_inactive)
+                       ehci_warn(ehci, "qh %p should be inactive!\n", qh);
+       } else {
                qh_update(ehci, qh, qtd);
+       }
+       qh->should_be_inactive = 0;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -438,6 +442,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
                                        (hw->hw_token & ACTIVE_BIT(ehci))) {
                                token = hc32_to_cpu(ehci, hw->hw_token);
                                hw->hw_token &= ~ACTIVE_BIT(ehci);
+                               qh->should_be_inactive = 1;
 
                                /* An unlink may leave an incomplete
                                 * async transaction in the TT buffer.
index 46f62e41bcde984ad2cf7d91e1461bf3f60f7e3c..ec61aedb00673db16163da24b51a442ee478aa00 100644 (file)
@@ -439,6 +439,7 @@ struct ehci_qh {
        unsigned                dequeue_during_giveback:1;
        unsigned                exception:1;    /* got a fault, or an unlink
                                                   was requested */
+       unsigned                should_be_inactive:1;
 };
 
 /*-------------------------------------------------------------------------*/