On Fri, 3 Jan 2014, Sarah Sharp wrote: > Occasionally when a USB 3.0 device is disconnected, the roothub port > goes into the SS.Inactive state, rather than reporting a disconnect. A > warm reset is the only way to get out of this state. khubd notices the > link state in hub_port_events(), Do you mean hub_events()? There is no hub_port_events() routine. > and since a udev is active on that > port, it calls into usb_reset_and_verify_device(). > > USB 3.0 Link PM is disabled before the device is reset, in order to > balance out the LPM ref counts. That code will also issue two control > transfers to disable the U1 and U2 timeouts. On some USB host > controllers (at least the Intel ones, possibly others), issuing a > control transfer to a disconnected port causes the transfer to timeout, > rather than immediately returning with a transfer error. Each control > transfer takes five seconds to timeout and be canceled. > > [ 89.551350] hub 2-0:1.0: state 7 ports 4 chg 0000 evt 0004 > [ 89.551642] hub 2-0:1.0: warm reset port 2 > [ 94.549887] usb 2-2: Disable of device-initiated U1 failed. > [ 99.548027] usb 2-2: Disable of device-initiated U2 failed. > > The end result is that USB device disconnect is delayed by ten seconds, > and khubd won't be able to service other ports until the disconnect is > handled. Work around this by checking the status of the device's port, > and not sending the U1/U2 disable control transfers if the device is > disconnected. The way you are doing this doesn't seem right, or at least, doesn't seem optimal. LPM is disabled before the port is reset. At that time, the port is still in the SS.Inactive state, and the port-connect bit is the same as it was when hub_events() first read the port status. So how will your new hub_is_device_disconnected() routine be able to do any better than the existing code already does? It sounds like what you really want to do is balance the LPM count but skip sending the actual request if the port is in the SS.Inactive state. Furthermore, you should already know when the port is in this state with no need for an additional hub_port_status() call, because hub_events() knows the port status. Alan Stern -- 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