On Tue, Apr 03, 2012 at 03:24:04PM -0400, Alan Stern wrote: > Greg: > > The following series of patches fixes an outstanding race between > suspending a root hub and getting a wakeup event on any of the root > hub's ports. > > Currently we don't handle these races very well. The host controller > drivers check for some wakeup events before starting a suspend but not > for all (e.g., they check for port resume in progress but not port > connect change). Also, the drivers don't check for wakeup events that > occur while the root hub is being suspended, or events that occurred > before the suspend began but have not yet been handled. > > The first patch fixes the general problem by making > usb_hcd_bus_suspend() query each HCD's hub_status_data method after > suspending its root hub, if that root hub is enabled for wakeup. A > nonzero return value, indicating that a status change is pending, will > cause the root hub to be resumed and the suspend attempt to fail with > -EBUSY. > > The second and third patches make some necessary adjustments to > ehci-hcd and uhci-hcd. Right now the hub_status_data methods return a > nonzero value only when some of the status bits are set. However, in > the case of a remote wakeup request received from downstream, the > port's suspend-change status bit doesn't get set until _after_ the port > resume is complete, which is at least 25 ms after the CPU is notified > about the wakeup request. The patches make the hub_status_data methods > return nonzero while the port resume is in progress, even if none of > the status bits are set. > > Although I'm not familiar with the details of xhci-hcd's root-hub > management, I assume that it will need adjustments quite similar to > those for ehci-hcd. Sarah, please take note. For the most part, you > or Andiry ought to be able to copy the changes I made -- they are > pretty simple. xHCI does a similar thing of only returning a non-zero status when we're in the middle of resume. I think it does that for both USB 2.0 and USB 3.0 ports. There are also a couple other port status change events that we hide from the USB core, because there is no equivalent port status bit in external hubs. Will the USB core now handle a non-zero return status from hub_status_data() when none of the hub change bits are set? If so, that simplifies the xHCI hub architecture quite a bit. I think that means we should set the polling bit and return a non-zero value whenever a change bit is set. That will take care of some of the issues we've been seeing with xHCI ports seeming "dead" because the xHCI driver didn't clear a port change bit when it should have. 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