Re: [PATCH 1/3] USB: fix race between root-hub suspend and remote wakeup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Apr 03, 2012 at 03:24:18PM -0400, Alan Stern wrote:
> This patch (as1533) fixes a race between root-hub suspend and remote
> wakeup.  If a wakeup event occurs while a root hub is suspending, it
> might not cause the suspend to fail.  Although the host controller
> drivers check for pending wakeup events at the start of their
> bus_suspend routines, they generally do not check for wakeup events
> while the routines are running.
> 
> In addition, if a wakeup event occurs any time after khubd is frozen
> and before the root hub is fully suspended, it might not cause a
> system sleep transition to fail.  For example, the host controller
> drivers do not fail root-hub suspends when a connect-change event is
> pending.
> 
> To fix both these issues, this patch causes hcd_bus_suspend() to query
> the controller driver's hub_status_data method after a root hub is
> suspended, if the root hub is enabled for wakeup.  Any pending status
> changes will count as wakeup events, causing the root hub to be
> resumed and the overall suspend to fail with -EBUSY.
> 
> A significant point is that not all events are reflected immediately
> in the status bits.  Both EHCI and UHCI controllers notify the CPU
> when remote wakeup begins on a port, but the port's suspend-change
> status bit doesn't get set until after the port has completed the
> transition out of the suspend state, some 25 milliseconds later.
> Consequently, the patch will interpret any nonzero return value from
> hub_status_data as indicating a pending event, even if none of the
> status bits are set in the data buffer.  Follow-up patches make the
> necessary changes to ehci-hcd and uhci-hcd.
> 
> Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
> CC: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
> CC: Chen Peter-B29397 <B29397@xxxxxxxxxxxxx>
> CC: <stable@xxxxxxxxxxxxxxx>
> 
> ---
> 
>  drivers/usb/core/hcd.c |   12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> Index: usb-3.3/drivers/usb/core/hcd.c
> ===================================================================
> --- usb-3.3.orig/drivers/usb/core/hcd.c
> +++ usb-3.3/drivers/usb/core/hcd.c
> @@ -1978,6 +1978,18 @@ int hcd_bus_suspend(struct usb_device *r
>  	if (status == 0) {
>  		usb_set_device_state(rhdev, USB_STATE_SUSPENDED);
>  		hcd->state = HC_STATE_SUSPENDED;
> +
> +		/* Did we race with a root-hub wakeup event? */
> +		if (rhdev->do_remote_wakeup) {
> +			char	buffer[6];
> +
> +			status = hcd->driver->hub_status_data(hcd, buffer);
I have run this patch at FSL board, and found the kernel is hang at reading
portsc of above code, the reason is controller is off after bus suspend. I
have checked the ehci-tegra.c, it also powers off its controller at bus
suspend, maybe there are other controllers also do that.

> +			if (status != 0) {
> +				dev_dbg(&rhdev->dev, "suspend raced with wakeup event\n");
> +				hcd_bus_resume(rhdev, PMSG_AUTO_RESUME);
> +				status = -EBUSY;
> +			}
> +		}
>  	} else {
>  		spin_lock_irq(&hcd_root_hub_lock);
>  		if (!HCD_DEAD(hcd)) {
> 
> 

-- 

Best Regards,
Peter Chen

--
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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux