Re: [linux-usb-devel] 2.6.18-rc6-mm1

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

 



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

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux