On Thu, 23 Dec 2010, Sarah Sharp wrote: > When there's an xHCI host power loss after a suspend from memory, the USB > core attempts to reset and verify the USB devices that are attached to the > system. The xHCI driver has to reallocate those devices, since the > hardware lost all knowledge of them during the power loss. > > When a hub is plugged in, and the host loses power, the xHCI hardware > structures are not updated to say the device is a hub. This is usually > done in hub_configure() when the USB hub is detected. That function is > skipped during a reset and verify by the USB core, since the core restores > the old configuration and alternate settings, and the hub driver has no > idea this happened. This bug makes the xHCI host controller reject the > enumeration of low speed devices under the resumed hub. What happens if you unbind the hub driver from the hub and then rebind it? Can update_hub_device() stand being called a second time? > Therefore, make the USB core re-setup the internal xHCI hub device > information by calling update_hub_device() after the alternate settings > have been re-installed. usb_reset_and_verify_device() may be called as > part of a normal hub port resume from a bus resume event (instead of a > system resume event), and the re-setup may not be necessary. However, we > can't tell the difference in finish_port_resume(), so unconditionally > re-setup the hub. It will add a slight delay to port resume as the > xHCI Evaluate Context command completes. Would it be better to do this in the HUB_RESET_RESUME case of hub_activate() instead? It could be merged with the HUB_INIT case (move the existing code from hub_configure). > Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx> > --- > > Alan, > > I'm not sure about the memory flags here. usb_reset_and_verify_device() > will eventually trickle down to xhci_discover_or_reset_device(), which > uses GFP_KERNEL to reallocate the xHCI device structures. Is this the > correct memory flag to use in this context? No; routines in the reset path need to use GFP_NOIO because the device being reset might be a mass-storage device holding the backing store for some dirty memory buffers. A GFP_KERNEL request might block, waiting for those dirty buffers to be written out, which obviously couldn't happen until after the device was reset. 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