Re: HC died

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

 



On 23.2.2023 18.05, Seth Bollinger wrote:
Note that the USB-2.0 spec says (section 9.2.6.3, Set Address
Processing):

         After the reset/resume recovery interval, if a device receives a
         SetAddress() request, the device must be able to complete
         processing of the request and be able to successfully complete
         the Status stage of the request within 50 ms.

These devices' 9.6 seconds to process a Set-Address request is a _lot_
longer than 50 ms.  No wonder they don't work properly.  Why on earth do
they take so long?

The device can't actually respond as it's no longer present on the
bus.  The hardware is taking this long to complete the TRB when the
device disappears in the middle of the transaction (at least this is
the theory).

I'm not trying to argue that these devices aren't crappy.  However, it
does seem like there are quite a lot of crappy devices in the field.
It would be nice if the driver didn't die when encountering these
devices.

Of course, xHCI controller drivers should be able to cancel an
Address-Device TRB without waiting for it to complete.

Agreed.  Is there some way I could try to cancel this command ring
TRB?  The hardware seems hung enough that it's not responding to
whatever we're trying to do in the cleanup routine when the timeout
handler fires though.

xhci driver does exactly this, but fails to stop the command ring while
trying to abort the command TRB.

Does increasing the timeout for stopping command ring help?

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f5b0e1ce22af..6cecbca34cca 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -397,7 +397,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
         * and try to recover a -ETIMEDOUT with a host controller reset.
         */
        ret = xhci_handshake(&xhci->op_regs->cmd_ring,
-                       CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
+                       CMD_RING_RUNNING, 0, 10 * 1000 * 1000);
        if (ret < 0) {
                xhci_err(xhci, "Abort failed to stop command ring: %d\n", ret);
                xhci_halt(xhci);
Thanks
-Mathias



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

  Powered by Linux