Re: Strange behavior of high-speed hub during hibernation test
Alan Stern <stern-nwvwT67g6+6dFdvTe/[email protected]>
| Newsgroups | gmane.linux.usb.general,gmane.linux.usb.devel |
|---|---|
| Message-ID | <[email protected]> |
On Wed, 12 Dec 2007, David Brownell wrote: > On Tuesday 11 December 2007, Alan Stern wrote: > > Dave: > > > > I just tried doing some hibernation testing, and my external high-speed > > hub is behaving very strangely. The test is simple. First plug in the > > hub, then plug a flash drive into the hub to keep it from > > autosuspending. Then: > > > > echo test >/sys/power/disk > > echo disk >/sys/power/state > > > > The first line causes the hibernation to stop after the PM_EVENT_FREEZE > > message has been sent; after that everything is woken back up. There > > are no bus-power-level changes since the EHCI controller remains in D0 > > throughout. > > > > This sequence causes the hub to disconnect and reconnect itself! When > > khubd starts running again, it sees the port-connect-change event. > This doesn't ring any bells with me. It seems buglike. :) Well, I can't tell exactly what the cause is. But this patch fixes it. Look okay to you? Alan Stern This patch (as1029) adds a short delay to the bus-suspend routine in ehci-hcd. Without it some devices disconnect when they should suspend. The patch also moves a del_timer_sync() call outside the scope of a spinlock, where it could cause a deadlock, and adds a new del_timer_sync() call for the new IAA watchdog timer (it was omitted by mistake). Signed-off-by: Alan Stern <stern-nwvwT67g6+6dFdvTe/[email protected]> --- Index: usb-2.6/drivers/usb/host/ehci-hub.c =================================================================== --- usb-2.6.orig/drivers/usb/host/ehci-hub.c +++ usb-2.6/drivers/usb/host/ehci-hub.c @@ -170,8 +170,11 @@ static int ehci_bus_suspend (struct usb_ } } + /* Apparently some devices need a 1-uframe delay here */ + if (ehci->bus_suspended) + udelay(125); + /* turn off now-idle HC */ - del_timer_sync (&ehci->watchdog); ehci_halt (ehci); hcd->state = HC_STATE_SUSPENDED; @@ -184,6 +187,9 @@ static int ehci_bus_suspend (struct usb_ ehci->next_statechange = jiffies + msecs_to_jiffies(10); spin_unlock_irq (&ehci->lock); + + del_timer_sync(&ehci->watchdog); + del_timer_sync(&ehci->iaa_watchdog); return 0; } - To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html