Alan Stern ha scritto:

On Sat, 24 Sep 2005, Patrizio Bassi wrote:

[ONLY UHCI LOADED, TRYING TO SUSPEND AGAIN]


Stopping tasks: =============|
Freeing memory... done (0 pages freed)
uhci_hcd 0000:00:0a.1: suspend_rh
usb usb3: usb suspend
uhci_hcd 0000:00:0a.0: suspend_rh
usb usb2: usb suspend
uhci_hcd 0000:00:04.2: suspend_rh
usb usb1: usb suspend
ACPI: PCI interrupt for device 0000:00:0d.0 disabled
uhci_hcd 0000:00:0a.1: uhci_suspend
ACPI: PCI interrupt for device 0000:00:0a.1 disabled
uhci_hcd 0000:00:0a.1: --> PCI D3
Could not suspend device 0000:00:0a.1: error -22

I think this is caused by a failure to enable remote wakeup. To check this diagnostic, as root run this command:

        lspci -vv -s a.1

The patch below should fix this problem.  Let me know how well it works.

The reason this affected both the UHCI and EHCI ports on the PCI card, but not the port on the motherboard, is because the Intel controller on the motherboard does not support PCI Power Management whereas the card does.

Alan Stern



--- a/drivers/usb/core/hcd-pci.c        Tue Sep 13 13:06:21 2005
+++ b/drivers/usb/core/hcd-pci.c        Sat Sep 24 10:30:56 2005
@@ -232,6 +232,10 @@
                hcd->state = HC_STATE_SUSPENDED;
                /* FALLTHROUGH */

+       /* entry for controllers that have died and been reset */
+       case HC_STATE_HALT:
+               /* FALLTHROUGH */
+
        /* entry with CONFIG_USB_SUSPEND, or hcds that autosuspend: the
         * controller and/or root hub will already have been suspended,
         * but it won't be ready for a PCI resume call.
@@ -259,11 +263,20 @@
                 */
                retval = pci_set_power_state (dev, PCI_D3hot);
                if (retval == 0) {
+                       int     rc;
+                       int     wakeup = hcd->remote_wakeup;
+
                        dev_dbg (hcd->self.controller, "--> PCI D3\n");
-                       retval = pci_enable_wake (dev, PCI_D3hot, 
hcd->remote_wakeup);
-                       if (retval)
-                               break;
-                       retval = pci_enable_wake (dev, PCI_D3cold, 
hcd->remote_wakeup);
+                       rc = pci_enable_wake (dev, PCI_D3hot, wakeup);
+                       if (rc && wakeup)
+                               dev_warn(&dev->dev, "Unable to activate "
+                                               "remote wakeup from %d: %d\n",
+                                               PCI_D3hot, rc);
+                       rc = pci_enable_wake (dev, PCI_D3cold, wakeup);
+                       if (rc && wakeup)
+                               dev_warn(&dev->dev, "Unable to activate "
+                                               "remote wakeup from %d: %d\n",
+                                               PCI_D3cold, rc);
                } else if (retval < 0) {
                        dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n",
                                        retval);
@@ -298,7 +311,8 @@
        int                     retval;

        hcd = pci_get_drvdata(dev);
-       if (hcd->state != HC_STATE_SUSPENDED) {
+       if (hcd->state != HC_STATE_SUSPENDED &&
+                       hcd->state != HC_STATE_HALT) {
dev_dbg (hcd->self.controller, "can't resume, not suspended!\n");
                return 0;
@@ -312,6 +326,7 @@
#ifdef  DEBUG
                int     pci_pm;
                u16     pmcr;
+               int     rc;

                pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM);
                pci_read_config_word(dev, pci_pm + PCI_PM_CTRL, &pmcr);
@@ -337,19 +352,17 @@
                                dev->current_state);
                }
#endif
-               retval = pci_enable_wake (dev, dev->current_state, 0);
-               if (retval) {
-                       dev_err(hcd->self.controller,
-                               "can't enable_wake to %d, %d!\n",
-                               dev->current_state, retval);
-                       return retval;
-               }
-               retval = pci_enable_wake (dev, PCI_D3cold, 0);
-               if (retval) {
-                       dev_err(hcd->self.controller,
-                               "can't enable_wake to %d, %d!\n",
-                               PCI_D3cold, retval);
-                       return retval;
+               rc = pci_enable_wake (dev, dev->current_state, 0);
+               if (rc)
+                       dev_warn(hcd->self.controller,
+                               "can't disable wake from %d, %d!\n",
+                               dev->current_state, rc);
+               if (dev->current_state != PCI_D3cold) {
+                       rc = pci_enable_wake (dev, PCI_D3cold, 0);
+                       if (rc)
+                               dev_warn(hcd->self.controller,
+                                       "can't disable wake from %d, %d!\n",
+                                       PCI_D3cold, rc);
                }
        } else {
                /* Same basic cases: clean (powered/not), dirty */
@@ -372,7 +385,8 @@

        dev->dev.power.power_state = PMSG_ON;

-       hcd->state = HC_STATE_RESUMING;
+       if (hcd->state == HC_STATE_SUSPENDED)
+               hcd->state = HC_STATE_RESUMING;
        hcd->saw_irq = 0;
        retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ,
                                hcd->irq_descr, hcd);


ok....it's a trivial "error"

just declare rc before the #ifdef DEBUG

i've disabled debug actually. now i'm gonna test.


-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
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