On Thu, 18 Oct 2018, Kai-Heng Feng wrote: > Devices connected under Terminus Technology Inc. Hub (1a40:0101) may > fail to work after the system resumes from suspend: > [ 206.063325] usb 3-2.4: reset full-speed USB device number 4 using xhci_hcd > [ 206.143691] usb 3-2.4: device descriptor read/64, error -32 > [ 206.351671] usb 3-2.4: device descriptor read/64, error -32 > > Info for this hub: > T: Bus=03 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 2 Spd=480 MxCh= 4 > D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1 > P: Vendor=1a40 ProdID=0101 Rev=01.11 > S: Product=USB 2.0 Hub > C: #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA > I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub > > Some expirements indicate that the USB devices connected to the hub are > innocent, it's the hub itself is to blame. The hub needs extra delay > time after it resets its port. > > Hence wait for extra delay, if the device is connected to this quirky > hub. > --- a/drivers/usb/core/hub.c > +++ b/drivers/usb/core/hub.c > @@ -2891,6 +2891,11 @@ static int hub_port_reset(struct usb_hub *hub, int port1, > if (udev) { > struct usb_hcd *hcd = bus_to_hcd(udev->bus); > > + /* Hub needs extra delay after resetting its port. */ > + if (udev->parent && > + udev->parent->quirks & USB_QUIRK_HUB_SLOW_RESET) There's no need to test udev->parent, or even to put this code under the "if (udev)" test. You should simply use hub->hdev instead; it will always be defined. Alan Stern > + msleep(100); > + > update_devnum(udev, 0); > /* The xHC may think the device is already reset, > * so ignore the status.