On Tue, 12 Sep 2006, Rafael J. Wysocki wrote:

> Now I have another symtom: during the _second_ suspend the suspending of
> USB controllers fails with messages like this:
> 
> usb_hcd_pci_suspend(): ehci_pci_suspend+0x0/0xab [ehci_hcd]() returns -22
> pci_device_suspend(): usb_hcd_pci_suspend+0x0/0x16d [usbcore]() returns -22
> suspend_device(): pci_device_suspend+0x0/0x4b() returns -22
> Could not suspend device 0000:00:13.2: error -22
> 
> Could you please tell me which patches might have caused this, in your 
> opinion?

It's a little difficult to pin down the blame.  In one form or another
this problem probably existed all along, although it may not have been 
very obvious.

For those interested in the explanation:

The EHCI USB controller is represented in sysfs by two device structures.  
The higher one represents the controller's PCI interface (let's call it
the "PCI-controller") and the lower one represents the USB interface
(let's call it the "root hub").  Inside the resume() routine for the
PCI-controller, if the driver finds that power was lost during the suspend
-- as it would be for suspend-to-disk -- the driver reinitializes the root
hub but without telling usbcore it has done so.  If the root hub had
already been suspended at the time of the suspend-to-disk, then
resume-from-disk would skip calling its resume() method.  So as far as 
usbcore knows the root hub should still be suspended, but in fact it is 
awake.

Consequently during the second suspend-to-disk, usbcore does not pass the
suspend() call on to the root hub's driver.  Then the suspend() method for
the PCI-controller fails, because it sees that the child root hub is still
unsuspended.

I was just going to send in a patch to fix the problem.  I haven't had
much of a chance to try it out yet.  The patch is included below, so you
can test it right away and let me know if it works for you before I submit 
it.

Alan Stern


Index: usb-2.6/drivers/usb/core/hub.c
===================================================================
--- usb-2.6.orig/drivers/usb/core/hub.c
+++ usb-2.6/drivers/usb/core/hub.c
@@ -1066,6 +1066,12 @@ void usb_root_hub_lost_power(struct usb_
        unsigned long flags;
 
        dev_warn(&rhdev->dev, "root hub lost power or was reset\n");
+
+       /* Make sure no potential wakeup events get lost,
+        * by forcing the root hub to be resumed.
+        */
+       rhdev->dev.power.prev_state.event = PM_EVENT_ON;
+
        spin_lock_irqsave(&device_state_lock, flags);
        hub = hdev_to_hub(rhdev);
        for (port1 = 1; port1 <= rhdev->maxchild; ++port1) {


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to