On Thu, Dec 23, 2010 at 05:53:38PM -0500, Alan Stern wrote: > 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? Sure, it should be harmless. An Evaluate Context command will be issued, but none of the fields will be changed, and the hardware should return success for the command. Or if the hub driver is unbound, and the interface changes from mult-tt to single-tt (or vice versa), the hardware should accept the change. It will just introduce a slight delay. > > 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). I'm not as familiar with the hub code, but that did look like a plausible place to put it. I just didn't know if all hubs received a reset resume, or some would only get a resume. > > 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. Ok, I'll have to send a patch to fix the xhci device allocation to use the proper memory flag. Sarah Sharp -- 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