Re: When unplug USB device, another USB device access failed

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>I don't know.  And I'm starting to think that we don't need to retry
>for such a long time -- persistent errors should be handled by the
>higher-level drivers.  Perhaps a count of 32 or so would be enough.

I think so, too.
I think that it is difficult to put out a well-grounded
numerical value even if I thinks any further. If we usually
use it, I guess that low probability of unplugging a device
while accessing to a device. Because it is thought that CPU
is not completely occupied only with retrying, I think that
no problem. I want to finish the modification by the
retrying of 32 times. I changed to 32 from 255.
How do you think?

>You did not understand my question.  What happens if ehci_hcd is
>_loaded_ and the device is running at full speed or low speed because
>it is a USB-1.1 device plugged into a high-speed hub?

I tested following case.
=== case1 ===
root hub       : plugged "USB flash" and "high-speed hub"
high-speed hub : plugged "USB mouse"
=== case2 ===
root hub       : plugged "high-speed hub"
high-speed hub : plugged "USB flash" and "USB mouse"

USB mouse unplugged while accessing USB flash. In both
cases, XactErr didn't occurred. Though it doesn't relate to
the question, when two high-speed device plugged into
high-speed hub, error didn't occur.

best regards
  KoichiroSaito

diff -uprN linux-2.6.29-rc2-git1.org/drivers/usb/host/ehci-q.c linux-2.6.29-rc2-git1/drivers/usb/host/ehci-q.c
--- linux-2.6.29-rc2-git1.org/drivers/usb/host/ehci-q.c 2008-12-25 08:26:37.000000000 +0900
+++ linux-2.6.29-rc2-git1/drivers/usb/host/ehci-q.c     2009-01-27 23:57:07.000000000 +0900
@@ -333,12 +333,39 @@ qh_completions (struct ehci_hcd *ehci, s
                token = hc32_to_cpu(ehci, qtd->hw_token);

                /* always clean up qtds the hc de-activated */
+ retry_xacterr:
                if ((token & QTD_STS_ACTIVE) == 0) {

                        /* on STALL, error, and short reads this urb must
                         * complete and all its qtds must be recycled.
                         */
                        if ((token & QTD_STS_HALT) != 0) {
+
+                               /* retry transaction errors until we
+                                * reach the software xacterr limit
+                                */
+                               if ((token & QTD_STS_XACT) &&
+                                               !QTD_CERR(token) &&
+                                               --qh->xacterrs > 0) {
+                                       ehci_dbg(ehci,
+       "detected XactErr len %d/%d retry %d\n",
+       qtd->length - QTD_LENGTH(token), qtd->length,
+       QH_XACTERR_MAX - qh->xacterrs);
+
+                                       /* reset the token in the qtd and the
+                                        * qh overlay (which still contains
+                                        * the qtd) so that we pick up from
+                                        * where we left off
+                                        */
+                                       token &= ~QTD_STS_HALT;
+                                       token |= QTD_STS_ACTIVE |
+                                                       (EHCI_TUNE_CERR << 10);
+                                       qtd->hw_token = cpu_to_hc32(ehci,
+                                                       token);
+                                       wmb();
+                                       qh->hw_token = cpu_to_hc32(ehci, token);
+                                       goto retry_xacterr;
+                               }
                                stopped = 1;

                        /* magic dummy for some short reads; qh won't advance.
@@ -355,6 +382,10 @@ qh_completions (struct ehci_hcd *ehci, s
                                                & EHCI_LIST_END(ehci))) {
                                stopped = 1;
                                goto halt;
+
+                       /* reinit the xacterr counter for the next qtd */
+                       } else {
+                               qh->xacterrs = QH_XACTERR_MAX;
                        }

                /* stop scanning when we reach qtds the hc is using */
diff -uprN linux-2.6.29-rc2-git1.org/drivers/usb/host/ehci.h linux-2.6.29-rc2-git1/drivers/usb/host/ehci.h
--- linux-2.6.29-rc2-git1.org/drivers/usb/host/ehci.h   2009-01-24 01:35:56.000000000 +0900
+++ linux-2.6.29-rc2-git1/drivers/usb/host/ehci.h       2009-01-27 20:02:08.000000000 +0900
@@ -370,6 +370,9 @@ struct ehci_qh {
 #define        QH_STATE_UNLINK_WAIT    4               /* LINKED and on reclaim q */
 #define        QH_STATE_COMPLETING     5               /* don't touch token.HALT */

+       u8                      xacterrs;       /* XactErr retry counter */
+#define        QH_XACTERR_MAX          32              /* XactErr retry limit */
+
        /* periodic schedule info */
        u8                      usecs;          /* intr bandwidth */
        u8                      gap_uf;         /* uframes split/csplit gap */
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux