Bug#677472: [3.1->3.2 regression] Immediate wake on suspend, associated with OHCI on MCP51
- To: Frank Schäfer <fschaefer.oss@googlemail.com>
- Cc: Alan Stern <stern@rowland.harvard.edu>, Lan Tianyu <lantianyu1986@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Octavio Alvarez <alvarezp@alvarezp.com>, 677472@bugs.debian.org, Ben Hutchings <ben@decadent.org.uk>, linux-usb@vger.kernel.org, Frank Schäfer <schaefer.frank@gmx.net>
- Subject: Bug#677472: [3.1->3.2 regression] Immediate wake on suspend, associated with OHCI on MCP51
- From: Lan Tianyu <tianyu.lan@intel.com>
- Date: Thu, 13 Dec 2012 16:45:05 +0800
- Message-id: <[🔎] 50C99591.1000801@intel.com>
- Reply-to: Lan Tianyu <tianyu.lan@intel.com>, 677472@bugs.debian.org
- In-reply-to: <[🔎] 50C8E8E0.8050301@googlemail.com>
- References: <[🔎] Pine.LNX.4.44L0.1212111135420.1372-100000@iolanthe.rowland.org> <[🔎] 50C7ACD2.6010808@googlemail.com> <[🔎] 50C83F06.4090309@intel.com> <[🔎] 50C8E8E0.8050301@googlemail.com>
On 2012年12月13日 04:28, Frank Schäfer wrote:
> Am 12.12.2012 09:23, schrieb Lan Tianyu:
>> On 2012年12月12日 05:59, Frank Schäfer wrote:
>>> Am 11.12.2012 17:48, schrieb Alan Stern:
>>>
>>> [snip]
>>>> We really need to know which component is bad: the host controller or
>>>> the device.
>>> It happens with all USB 1.1 devices I have (several mice and a HP
>>> Deskjet 960c printer).
>>> The same devices do not cause other machines to wake up, so I assume
>>> it's the host controller.
>> Good information. Attaching device makes hc work abnormally during
>> entering into s3 since without device it can work, right?
>
> Right.
> The system successfully enters S3 (machine switches off = fan stops,
> light off etc.) but it resumes immediately.
> No errors in the log, it looks like this:
>
> <snip>
> ...
> [24685.640361] PM: Syncing filesystems ... done.
> [24686.022132] PM: Preparing system for mem sleep
> [24686.110208] Freezing user space processes ... (elapsed 0.01 seconds)
> done.
> [24686.123851] Freezing remaining freezable tasks ... (elapsed 0.01
> seconds) done.
> [24686.134818] PM: Entering mem sleep
> [24686.134840] Suspending console(s) (use no_console_suspend to debug)
> [24686.135751] sd 1:0:0:0: [sda] Synchronizing SCSI cache
> [24686.136509] sd 1:0:0:0: [sda] Stopping disk
> [24686.150741] i8042 kbd 00:0b: wake-up capability enabled by ACPI
> [24686.150833] i8042 aux 00:0a: wake-up capability disabled by ACPI
> [24686.150926] parport_pc 00:09: disabled
> [24686.151029] serial 00:08: disabled
> [24686.151056] serial 00:08: wake-up capability disabled by ACPI
> [24686.151219] ACPI handle has no context!
> [24686.151299] [drm] nouveau 0000:00:0d.0: Disabling display...
> [24686.151302] [drm] nouveau 0000:00:0d.0: Disabling fbcon...
> [24686.151311] [drm] nouveau 0000:00:0d.0: Unpinning framebuffer(s)...
> [24686.151341] [drm] nouveau 0000:00:0d.0: Evicting buffers...
> [24686.255063] usb 1-5: reset high-speed USB device number 3 using ehci_hcd
> [24686.346351] [drm] nouveau 0000:00:0d.0: Idling channels...
> [24686.346668] [drm] nouveau 0000:00:0d.0: Suspending GPU objects...
> [24686.447591] [drm] nouveau 0000:00:0d.0: And we're gone!
> [24687.547695] PM: suspend of devices complete after 1412.642 msecs
> [24687.547853] PM: late suspend of devices complete after 0.153 msecs
> [24687.548029] forcedeth 0000:00:07.0: wake-up capability enabled by ACPI
> [24687.559652] ehci_hcd 0000:00:02.1: wake-up capability enabled by ACPI
> [24687.570602] ohci_hcd 0000:00:02.0: wake-up capability enabled by ACPI
> [24687.581671] PM: noirq suspend of devices complete after 33.815 msecs
> [24687.581735] ACPI: Preparing to enter system sleep state S3
> [24687.582536] PM: Saving platform NVS memory
> [24687.582591] Disabling non-boot CPUs ...
> [24687.583984] smpboot: CPU 1 is now offline
> [24687.584703] Extended CMOS year: 2000
> [24687.584703] ACPI: Low-level resume complete
> [24687.584703] PM: Restoring platform NVS memory
> [24687.584703] Extended CMOS year: 2000
> [24687.586196] Enabling non-boot CPUs ...
> [24687.589496] smpboot: Booting Node 0 Processor 1 APIC 0x1
> [24687.583795] Initializing CPU#1
> [24687.583795] process: Switch to broadcast mode on CPU1
> [24687.601153] CPU1 is up
> [24687.601538] ACPI: Waking up from system sleep state S3
> [24687.613683] ohci_hcd 0000:00:02.0: wake-up capability disabled by ACPI
> [24687.624693] ehci_hcd 0000:00:02.1: wake-up capability disabled by ACPI
> [24687.624746] pci 0000:00:00.0: Found enabled HT MSI Mapping
> [24687.635726] pci 0000:00:00.0: Found enabled HT MSI Mapping
> [24687.657735] pci 0000:00:00.0: Found enabled HT MSI Mapping
> [24687.668730] pci 0000:00:00.0: Found enabled HT MSI Mapping
> [24687.679730] pci 0000:00:00.0: Found enabled HT MSI Mapping
> [24687.679803] pci 0000:00:00.0: Found enabled HT MSI Mapping
> [24687.679878] pci 0000:00:00.0: Found enabled HT MSI Mapping
> [24687.679956] pci 0000:00:00.0: Found enabled HT MSI Mapping
> [24687.773804] PM: noirq resume of devices complete after 171.507 msecs
> [24687.773907] PM: early resume of devices complete after 0.056 msecs
> [24687.773980] ohci_hcd 0000:00:02.0: setting latency timer to 64
> [24687.774001] ehci_hcd 0000:00:02.1: setting latency timer to 64
> [24687.774023] pci 0000:00:04.0: setting latency timer to 64
> ...
> <snip>
>
>
> When I disconnect all USB 1.1 devices, suspend works fine.
>
>> I am curious about whether disabling usb device's wakeup rather than usb
>> hc's would make suspend work. Can you do a test?
>>
>> Go to /sys/bus/usb/devices/ and enter the usb 1,1 device
>> directory(normally it will be something like"1-1.1".)
>> run "echo disabled > power/wakeup".
>
> Are you sure the file is called 'wakeup' for the devices ? I have no
> such file in the power directory...
Oh. That means the device doesn't support wakeup function.
Non-wakeupable devices also will cause the issue. Now Confirm this is
hcd problem.
I write a quirk patch. Can you test?
I just find one MCP51 and two MCP79 OHCI id. Can you provide more buggy
hcd id via "lspci -nnvvv"?
Thanks.
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index f034716..9335f1b 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2509,7 +2509,8 @@ int usb_add_hcd(struct usb_hcd *hcd,
* they only forward requests from the root hub. Therefore
* controllers should always be enabled for remote wakeup.
*/
- device_wakeup_enable(hcd->self.controller);
+ if (!usb_hcd_wakeup_quirks(hcd->self.controller))
+ device_wakeup_enable(hcd->self.controller);
return retval;
error_create_attr_group:
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index fdefd9c..ba847d3 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -12,6 +12,7 @@
*/
#include <linux/usb.h>
+#include <linux/pci.h>
#include <linux/usb/quirks.h>
#include "usb.h"
@@ -226,3 +227,33 @@ void usb_detect_interface_quirks(struct usb_device
*udev)
quirks);
udev->quirks |= quirks;
}
+
+struct pci_hcd {
+ u32 vendor;
+ u32 device;
+};
+
+static struct pci_hcd hcd_wakeup_qrk[] = {
+ {PCI_VENDOR_ID_NVIDIA, 0x026d}, /* MCP51 OHCI */
+ {PCI_VENDOR_ID_NVIDIA, 0x0aa5}, /* MCP79 OHCI */
+ {PCI_VENDOR_ID_NVIDIA, 0x0aa7}, /* MCP79 OHCI */
+ { }
+};
+
+int usb_hcd_wakeup_quirks(struct device *dev)
+{
+ struct pci_dev *pdev;
+ int i;
+
+ if (dev->bus != (struct bus_type *)&pci_bus_type)
+ return 0;
+
+ pdev = to_pci_dev(dev);
+ for (i = 0; hcd_wakeup_qrk[i].vendor || hcd_wakeup_qrk[i].device; i++)
+ if ((hcd_wakeup_qrk[i].vendor == pdev->vendor) &&
+ (hcd_wakeup_qrk[i].device == pdev->device)) {
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 1c528c1..eb2da6a 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -164,6 +164,8 @@ extern void usbfs_conn_disc_event(void);
extern int usb_devio_init(void);
extern void usb_devio_cleanup(void);
+extern int usb_hcd_wakeup_quirks(struct device *dev);
+
/* internal notify stuff */
extern void usb_notify_add_device(struct usb_device *udev);
extern void usb_notify_remove_device(struct usb_device *udev);
>
> Regards,
> Frank
>
--
Best regards
Tianyu Lan
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index f034716..9335f1b 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2509,7 +2509,8 @@ int usb_add_hcd(struct usb_hcd *hcd,
* they only forward requests from the root hub. Therefore
* controllers should always be enabled for remote wakeup.
*/
- device_wakeup_enable(hcd->self.controller);
+ if (!usb_hcd_wakeup_quirks(hcd->self.controller))
+ device_wakeup_enable(hcd->self.controller);
return retval;
error_create_attr_group:
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index fdefd9c..ba847d3 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -12,6 +12,7 @@
*/
#include <linux/usb.h>
+#include <linux/pci.h>
#include <linux/usb/quirks.h>
#include "usb.h"
@@ -226,3 +227,33 @@ void usb_detect_interface_quirks(struct usb_device *udev)
quirks);
udev->quirks |= quirks;
}
+
+struct pci_hcd {
+ u32 vendor;
+ u32 device;
+};
+
+static struct pci_hcd hcd_wakeup_qrk[] = {
+ {PCI_VENDOR_ID_NVIDIA, 0x026d}, /* MCP51 OHCI */
+ {PCI_VENDOR_ID_NVIDIA, 0x0aa5}, /* MCP79 OHCI */
+ {PCI_VENDOR_ID_NVIDIA, 0x0aa7}, /* MCP79 OHCI */
+ { }
+};
+
+int usb_hcd_wakeup_quirks(struct device *dev)
+{
+ struct pci_dev *pdev;
+ int i;
+
+ if (dev->bus != (struct bus_type *)&pci_bus_type)
+ return 0;
+
+ pdev = to_pci_dev(dev);
+ for (i = 0; hcd_wakeup_qrk[i].vendor || hcd_wakeup_qrk[i].device; i++)
+ if ((hcd_wakeup_qrk[i].vendor == pdev->vendor) &&
+ (hcd_wakeup_qrk[i].device == pdev->device)) {
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 1c528c1..eb2da6a 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -164,6 +164,8 @@ extern void usbfs_conn_disc_event(void);
extern int usb_devio_init(void);
extern void usb_devio_cleanup(void);
+extern int usb_hcd_wakeup_quirks(struct device *dev);
+
/* internal notify stuff */
extern void usb_notify_add_device(struct usb_device *udev);
extern void usb_notify_remove_device(struct usb_device *udev);
Reply to: