The following patch series fixes hibernate/wake-on-lan for my System (Asus M2N-SLI Deluxe, Dual MCP55 Gigabit Ethernet). See also http://bugzilla.kernel.org/show_bug.cgi?id=8381 "(net forcedeth) doesn't wol on suspend". Note that so far this is only tested on my system with hibernate using the 'shutdown' method. The local setup combines the two onboard nforce gigabit interfaces eth0 and eth1 into a bridge br0, so it doesn't matter which port I plug the cable into. The bridging means eth0 and eth1 normally operate in promiscous mode. The initial situation (unpatched driver) was as follows: After a normal boot, turning on wol and sending the system into hibernate, waking it up with etherwake works as expected. However, after waking up (be it via wol or via manual poweron) from hibernate network connectivity is down. This is because 1) the mac address is now swapped and 2) promiscous mode is not restored. The first patch addresses 2) After this patch wake-on-lan stops working, since in 'shutdown' mode the suspend callback of the device does not get called again before poweroff and promiscous mode is apparently incompatible with wol. So the second patch introduces a shutdown handler, which prepares the device for wake-on-lan before the system is powered off. Now waking the system up works again, but the 'swapped mac' problem is still there. The reason for this is that in my case the MCP55 is not flagged as 'DEV_HAS_CORRECT_MACADDR' and 'NVREG_TRANSMITPOLL_MAC_ADDR_REV' is not set by the bios, so in nv_probe during the initial loading of the driver the MAC address is read in reversed order and NVREG_TRANSMITPOLL_MAC_ADDR_REV is set. However during hibernate the device configuration space is lost (reset do BIOS defaults) and so we get the reversed MAC again, but resume unconditionally sets NVREG_TRANSMITPOLL_MAC_ADDR_REV, which means we now have effectively swapped the MAC. The third patch fixes this by saving and restoring the configuration space between ...
From: Tobias Diedrich <ranma+kernel@tdiedrich.de> nv_open() resets multicast settings, call nv_set_multicast(dev) to restore them. (Maybe this should rather be moved into nv_open()) Signed-off-by: Tobias Diedrich <ranma+kernel@tdiedrich.de> Index: linux-2.6.26-rc2.forcedwol/drivers/net/forcedeth.c =================================================================== --- linux-2.6.26-rc2.forcedwol.orig/drivers/net/forcedeth.c 2008-05-18 13:52:59.000000000 +0200 +++ linux-2.6.26-rc2.forcedwol/drivers/net/forcedeth.c 2008-05-18 13:53:02.000000000 +0200 @@ -5823,6 +5823,7 @@ writel(txreg, base + NvRegTransmitPoll); rc = nv_open(dev); + nv_set_multicast(dev); out: return rc; } --
applied Ayaz, have you reviewed the other patches in this series? --
From: Tobias Diedrich <ranma+kernel@tdiedrich.de>
When hibernating in 'shutdown' mode, after saving the image the suspend hook
is not called again.
However, if the device is in promiscous mode, wake-on-lan will not work.
This adds a shutdown hook to setup wake-on-lan before the final shutdown.
Signed-off-by: Tobias Diedrich <ranma+kernel@tdiedrich.de>
Index: linux-2.6.26-rc2.forcedwol/drivers/net/forcedeth.c
===================================================================
--- linux-2.6.26-rc2.forcedwol.orig/drivers/net/forcedeth.c 2008-05-18 13:53:02.000000000 +0200
+++ linux-2.6.26-rc2.forcedwol/drivers/net/forcedeth.c 2008-05-18 13:53:06.000000000 +0200
@@ -5827,8 +5827,23 @@
out:
return rc;
}
+
+static void nv_shutdown(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct fe_priv *np = netdev_priv(dev);
+
+ if (netif_running(dev))
+ nv_close(dev);
+
+ pci_enable_wake(pdev, PCI_D3hot, np->wolenabled);
+ pci_enable_wake(pdev, PCI_D3cold, np->wolenabled);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+}
#else
#define nv_suspend NULL
+#define nv_shutdown NULL
#define nv_resume NULL
#endif /* CONFIG_PM */
@@ -5999,6 +6014,7 @@
.remove = __devexit_p(nv_remove),
.suspend = nv_suspend,
.resume = nv_resume,
+ .shutdown = nv_shutdown,
};
static int __init init_nic(void)
--
From: Tobias Diedrich <ranma+kernel@tdiedrich.de>
The memory mapped device configuration space is lost during hibernate.
Save and restore it (fixes 'swapped mac' problem).
Signed-off-by: TTobias Diedrich <ranma+kernel@tdiedrich.de>
Index: linux-2.6.26-rc2.forcedwol/drivers/net/forcedeth.c
===================================================================
--- linux-2.6.26-rc2.forcedwol.orig/drivers/net/forcedeth.c 2008-05-18 13:53:06.000000000 +0200
+++ linux-2.6.26-rc2.forcedwol/drivers/net/forcedeth.c 2008-05-18 13:53:10.000000000 +0200
@@ -426,6 +426,7 @@
#define NV_PCI_REGSZ_VER1 0x270
#define NV_PCI_REGSZ_VER2 0x2d4
#define NV_PCI_REGSZ_VER3 0x604
+#define NV_PCI_REGSZ_MAX 0x604
/* various timeout delays: all in usec */
#define NV_TXRX_RESET_DELAY 4
@@ -784,6 +785,9 @@
/* flow control */
u32 pause_flags;
+
+ /* power saved state */
+ u32 saved_config_space[NV_PCI_REGSZ_MAX/4];
};
/*
@@ -5785,6 +5789,8 @@
{
struct net_device *dev = pci_get_drvdata(pdev);
struct fe_priv *np = netdev_priv(dev);
+ u8 __iomem *base = get_hwbase(dev);
+ int i;
if (!netif_running(dev))
goto out;
@@ -5794,6 +5800,10 @@
// Gross.
nv_close(dev);
+ /* save non-pci configuration space */
+ for (i = 0;i <= np->register_size/sizeof(u32); i++)
+ np->saved_config_space[i] = readl(base + i*sizeof(u32));
+
pci_save_state(pdev);
pci_enable_wake(pdev, pci_choose_state(pdev, state), np->wolenabled);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
@@ -5804,9 +5814,9 @@
static int nv_resume(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
- int rc = 0;
- u32 txreg;
+ int i, rc = 0;
if (!netif_running(dev))
goto out;
@@ -5817,10 +5827,9 @@
pci_restore_state(pdev);
pci_enable_wake(pdev, PCI_D0, 0);
- /* restore mac address reverse flag */
- txreg = readl(base + ...From: Tobias Diedrich <ranma+kernel@tdiedrich.de>
Match the suspend/resume code ordering in e100/e1000e more closely.
For example the configuration space should be saved on suspend even for
devices that are not up.
Signed-off-by: Tobias Diedrich <ranma+kernel@tdiedrich.de>
Index: linux-2.6.26-rc2.forcedwol/drivers/net/forcedeth.c
===================================================================
--- linux-2.6.26-rc2.forcedwol.orig/drivers/net/forcedeth.c 2008-05-18 13:53:10.000000000 +0200
+++ linux-2.6.26-rc2.forcedwol/drivers/net/forcedeth.c 2008-05-18 13:54:04.000000000 +0200
@@ -5792,22 +5792,20 @@
u8 __iomem *base = get_hwbase(dev);
int i;
- if (!netif_running(dev))
- goto out;
-
+ if (netif_running(dev)) {
+ // Gross.
+ nv_close(dev);
+ }
netif_device_detach(dev);
- // Gross.
- nv_close(dev);
-
/* save non-pci configuration space */
for (i = 0;i <= np->register_size/sizeof(u32); i++)
np->saved_config_space[i] = readl(base + i*sizeof(u32));
pci_save_state(pdev);
pci_enable_wake(pdev, pci_choose_state(pdev, state), np->wolenabled);
+ pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
-out:
return 0;
}
@@ -5818,22 +5816,20 @@
u8 __iomem *base = get_hwbase(dev);
int i, rc = 0;
- if (!netif_running(dev))
- goto out;
-
- netif_device_attach(dev);
-
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
+ /* ack any pending wake events, disable PME */
pci_enable_wake(pdev, PCI_D0, 0);
/* restore non-pci configuration space */
for (i = 0;i <= np->register_size/sizeof(u32); i++)
writel(np->saved_config_space[i], base+i*sizeof(u32));
- rc = nv_open(dev);
- nv_set_multicast(dev);
-out:
+ netif_device_attach(dev);
+ if (netif_running(dev)) {
+ rc = nv_open(dev);
+ nv_set_multicast(dev);
+ }
return rc;
}
--
Ok, I've run tests now:
First Windoze:
Windoze, Standby (equiv. to Linux 'mem' state): WOL borked, resumes fine
Windoze, Hibernate: WOL borked, resumes fine
Linux, unpatched:
Hibernate, shutdown method: Works with known caveats
Hibernate, platform method: WOL borked, resumes fine
Linux, patched:
Hibernate, shutdown method: Works
Hibernate, platform method: WOL borked, resumes fine
Suspend ('standby' state):
WOL borked, USB borked after resume, kernel freeze
Suspend ('mem' state, text console):
WOL borked, VGA stays dark, otherwise working
Suspend ('mem' state, radeonfb):
WOL borked, VGA stays dark, userspace dead after resume (but pingable)
Summary: I suspect my BIOS sucks
Version: ASUS M2N-SLI DELUXE ACPI BIOS Revision 0903
Release Date: 02/13/2007
1 point for Linux, 0 points for Windows, Linux wins ;)
Serial Console Log (of some of the tries, I should've written down what
I tried in which order...):
[ 0.000000] Linux version 2.6.26-rc2 (ranma@melchior) (gcc version 4.2.3 (Debian 4.2.3-5)) #6 PREEMPT Sun May 18 11:35:22 CEST 2008
[ 0.000000] Command line: root=/dev/sda5 resume=/dev/sda6 vga=6 apic=verbose console=ttyS0,115200 console=tty0 pci=nomsi ro
[ 0.000000] BIOS-provided physical RAM map:
[ 0.000000] BIOS-e820: 0000000000000000 - 000000000009f800 (usable)
[ 0.000000] BIOS-e820: 000000000009f800 - 00000000000a0000 (reserved)
[ 0.000000] BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
[ 0.000000] BIOS-e820: 0000000000100000 - 000000007fee0000 (usable)
[ 0.000000] BIOS-e820: 000000007fee0000 - 000000007fee3000 (ACPI NVS)
[ 0.000000] BIOS-e820: 000000007fee3000 - 000000007fef0000 (ACPI data)
[ 0.000000] BIOS-e820: 000000007fef0000 - 000000007ff00000 (reserved)
[ 0.000000] BIOS-e820: 00000000f0000000 - 00000000f4000000 (reserved)
[ 0.000000] BIOS-e820: 00000000fec00000 - 0000000100000000 (reserved)
[ 0.000000] max_pfn_mapped = 1048576
[ 0.000000] x86 PAT enabled: cpu 0, ...That may be worth some investigation. However, since that doesn't work on You can try s2ram to bring the VGA to life, I think Thanks, Rafael --
I have to correct myself on this: I ran the above test an a japanese version of Windows (where I have some difficulty reading all the technical texts) I've retested this on an english version of Windows and found that I accidentally enabled one checkbox, which said: "Only allow management stations to bring the computer out of standby" If I disable that one, I can wakeup the machine without problems. So my BIOS is not as borked as I thought and it should be possible to wake up the machine even with platform. Further debugging will have to wait until at least next weekend though (maybe longer)... -- Tobias PGP: http://9ac7e0bc.uguu.de このメールは十割再利用されたビットで作られています。 --
Or maybe it doesn't have to wait, I was just too curious:
Summary first: I got platform mode to work!
After grepping and reading through kernel/power/disk.c and
(rather obfuscated) drivers/acpi/.* code, and reading up on
ACPI _GPE (General Purpose Event?), and having a look at my DSDT I
noticed two things:
1) The network controllers are assigned to their own _GPE bits(pins?):
|[...]
| Scope (\_GPE)
| {
|[...]
| Method (_L0B, 0, NotSerialized)
| {
| Notify (\_SB.PCI0.MMAC, 0x02)
| }
|
| Method (_L0A, 0, NotSerialized)
| {
| Notify (\_SB.PCI0.MAC1, 0x02)
| }
|[...]
2) drivers/acpi/sleep/proc.c registers a 'wakeup' file:
| proc_create("wakeup", S_IFREG | S_IRUGO | S_IWUSR,
| acpi_root_dir, &acpi_system_wakeup_device_fops);
And I then remembered that someone said in
http://bugzilla.kernel.org/show_bug.cgi?id=8381
it works for him if he writes $MAGICVALUE into a proc file.
And yes, if I write 'MMAC' and 'MAC1' into /proc/acpi/wakeup, then
wake-on-lan works even in platform mode.
So...
AFAICS this bit of setup magic should not be required, because:
1) /proc/acpi/wakeup knows which pci device is associated to each GPE bit
|ranma@melchior:~$ cat /proc/acpi/wakeup
|Device S-state Status Sysfs node
|HUB0 S5 disabled pci:0000:00:06.0
|XVR0 S5 disabled
|XVR1 S5 disabled pci:0000:00:0e.0
|XVR2 S5 disabled
|XVR3 S5 disabled
|XVR4 S5 disabled
|XVR5 S5 disabled pci:0000:00:0a.0
|UAR1 S5 disabled pnp:00:09
|PS2K S4 disabled pnp:00:0b
|USB0 S4 disabled pci:0000:00:02.0
|USB2 S4 disabled pci:0000:00:02.1
|AZAD S5 disabled pci:0000:00:06.1
|MMAC S5 enabled pci:0000:00:08.0
|MAC1 S5 enabled pci:0000:00:09.0
(values after manually enabling MMAC and MAC1)
2) kernel/power/disk.c calls hibernation_ops->enter(), which is
acpi_suspend_enter, which calls acpi_enable_wakeup_device, which
sets up GPE wakup ...Any reason this patch hasn't made it into the kernel so far? http://lists.laptop.org/pipermail/devel/2007-April/004691.html (Ok, I tried getting it to apply to a current kernel, but it a splodes (reboots instead of powering off, last message on the serial console is "ACPI handle has no context!", see below)) The platform_enable_wakeup() hook is still there, but unused. AFAICS this patch should solve the "'ethtool -s eth0 wol g' doesn't suffice, I also have to write magic values into /proc/acpi/wakeup" issue. [14315431.627226] PM: Hibernation mode set to 'platform' [14315431.639031] PM: Marking nosave pages: 000000000009f000 - 0000000000100000 [14315431.646879] PM: Basic memory bitmaps created [14315431.651822] PM: Syncing filesystems ... done. [14315431.660495] Freezing user space processes ... (elapsed 0.00 seconds) done. [14315431.669364] Freezing remaining freezable tasks ... (elapsed 0.00 seconds) [14315431.677609] PM: Shrinking memory... done (0 pages freed) [14315431.924310] PM: Freed 0 kbytes in 0.24 seconds (0.00 MB/s) [14315431.932191] sd 0:0:0:0: [sda] Synchronizing SCSI cache [14315431.938679] ACPI handle has no context! [14315432.534157] serial 00:09: activated [14315432.539218] sd 0:0:0:0: [sda] Starting disk [14315432.749996] PM: writing image. [14315432.775321] PM: Free swap pages: 977947 [14315432.779662] PM: Saving image data pages (72491 pages) ... done [14315436.437643] PM: Wrote 289964 kbytes in 3.65 seconds (79.44 MB/s) [14315436.444385] PM: S| [14315436.840487] ohci_hcd 0000:00:02.0: Unlink after no-IRQ? Controller is probably using the wrong IRQ. [14315436.854132] sd 0:0:0:0: [sda] Synchronizing SCSI cache [14315436.859325] sd 0:0:0:0: [sda] Stopping disk [14315437.284158] ACPI handle has no context! ^@[ 0.000000] Linux version 2.6.26-rc2 (ranma@melchior) (gcc version 4.2.3 (Debian 4.2.3-5)) #8 PREEMPT Tue May 27 00:03:20 CEST 2008 [ 0.000000] Command line: root=/dev/sda5 resume=/dev/sda6 vga=6 apic=verbose console=ttyS0,115200 console=tty0 ...
Yeah; under ACPI, PCI does not act like it does everywhere else. Nor does wakeup in general. After sending patches to fix that for a couple years now, I'm well past being tired of doing that. I suggest it's overdue for the ACPI team to get this part of their act together. That is: either start merging those patches, possibly with updates to handle broken hardware better; or rewrite them; ... or just say explicitly the message I've been receiving: "Linux ACPI will never support wakeup the way the rest of Linux can and does". (And the "why" should be something reasonable.) --
I'm afraid you expect too much from the acpi team. If you can't merge patches yourself, perhaps someone interested (Tobias? me?) can push them for you? Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html --
I'm likewise "afraid" that may be too much to expect. If that's true, it's going to be even harder making the cross-platform Linux PM framework do what it needs to do. Having various devices (not just laptop lids or power buttons, or RTC alarms) wake systems from low power states is pretty fundamental to the "P" part of ACPI. I kind of think the ACPI team needs to just become more responsive. They helped Windows do this stuff; why has Linux only seen delays and obstacles in this area? --
Ok, after another long debugging session I finally found out the reason for the immediate reboot (after finding the place that suspends the serial console (drivers/pnp) and disabling that suspend path): The system is woken up by USB activity! (Optical mouse, anyone?) Lo and behold: drivers/usb/core/hcd-pci.c tries it's best to activate 'wake on usb', which I didn't know since it apparently also never worked. However, after applying the 'use platform_enable_wakeup'-patch, not only forcedeth wake starts working, also usb wake. If I prevent usb wake: |echo disabled > /sys/devices/pci0000\:00/0000\:00\:02.0/power/wakeup' |echo disabled > /sys/devices/pci0000\:00/0000\:00\:02.1/power/wakeup' And then hibernate in platform mode, the immediate reboot is gone and waking up using magic packets works fine even without setting up /proc/acpi/wakeup first. Maybe I should try hooking mouse and keyboard onto different usb host controllers, so I can disable wakeup for the mouse host controller and enable wakeup for the keyboard host controller, then it should be possible to wake the system by pressing a key. :) -- Tobias PGP: http://9ac7e0bc.uguu.de このメールは十割再利用されたビットで作られています。 --
You don't need to do that. Wakeup can be set specifically for each individual USB device, provided CONFIG_USB_SUSPEND is enabled. Can you provide debugging information (i.e., CONFIG_USB_DEBUG) with the details on this bogus wakeup? Alan Stern --
Sure. Here is the complete log of one boot and two s2disk_platform cycles captured using the serial console (in the first s2disk I forgot to remove the 'turn off /sys/bus/usb/device/usb?/power/wakeup' part). Interestingly even with power/wakeup disabled for usb1 and usb2, which I assume to be the usb root ports, I could wake up the system by pressing a key on my keyboard (which didn't work before turning on CONFIG_USB_SUSPEND). On the second suspend the system rebooted immediately as expected (I power/wakeup for usb1 and usb2 back on and disabled the part in the script). I think this might be some general usb hw flakiness, since it seems to detect (and has so for a long time) a non-existing device: lsusb output: Bus 002 Device 003: ID 045e:00db Microsoft Corp. Natural Ergonomic Keyboard 4000 V1.0 Bus 002 Device 002: ID 045e:0040 Microsoft Corp. Wheel Mouse Optical Bus 002 Device 001: ID 1d6b:0001 Bus 001 Device 001: ID 1d6b:0002 bogus device?: [14316046.469949] usb 2-4: new full speed USB device using ohci_hcd and address 12 [14316046.679951] usb 2-4: device descriptor read/64, error -62 [14316046.986619] usb 2-4: device descriptor read/64, error -62 [14316047.263284] usb 2-4: new full speed USB device using ohci_hcd and address 13 [14316047.476614] usb 2-4: device descriptor read/64, error -62 [14316047.786618] usb 2-4: device descriptor read/64, error -62 [14316048.063282] usb 2-4: new full speed USB device using ohci_hcd and address 14 [14316048.499945] usb 2-4: device not accepting address 14, error -62 [14316048.669950] usb 2-4: new full speed USB device using ohci_hcd and address 15 [14316049.106612] usb 2-4: device not accepting address 15, error -62 [14316049.112960] hub 2-0:1.0: unable to enumerate USB device on port 4 complete log: [ 0.000000] Linux version 2.6.26-rc4 (ranma@melchior) (gcc version 4.2.3 (Debian 4.2.3-5)) #28 PREEMPT Sun Jun 1 09:06:24 CEST 2008 [ 0.000000] Command line: root=/dev/sda5 resume=/dev/sda6 vga=6 apic=verbose ...
It's possible. Maybe there's a builtin broken USB device, or maybe the D+ pin on port 4 is wired to a positive voltage source. The log didn't reveal anything. Perhaps you can learn more by looking at the "registers" file for that OHCI controller in debugfs. Also, you should run "lspci -vv" as root to see what wakeup signals the USB controllers are issuing. Alan Stern --
One of the ports on the back of the board seems to be broken (Maybe esd?), the other three work fine, but nothing happens when I plug a 00:00.0 RAM memory: nVidia Corporation MCP55 Memory Controller (rev a1) Subsystem: ASUSTeK Computer Inc. Unknown device 8239 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Capabilities: [44] HyperTransport: Slave or Primary Interface Command: BaseUnitID=0 UnitCnt=15 MastHost- DefDir- DUL- Link Control 0: CFlE+ CST- CFE- <LkFail- Init+ EOC- TXO- <CRCErr=0 IsocEn- LSEn+ ExtCTL- 64b- Link Config 0: MLWI=16bit DwFcIn- MLWO=16bit DwFcOut- LWI=16bit DwFcInEn- LWO=16bit DwFcOutEn- Link Control 1: CFlE- CST- CFE- <LkFail+ Init- EOC+ TXO+ <CRCErr=0 IsocEn- LSEn- ExtCTL- 64b- Link Config 1: MLWI=8bit DwFcIn- MLWO=8bit DwFcOut- LWI=8bit DwFcInEn- LWO=8bit DwFcOutEn- Revision ID: 1.03 Link Frequency 0: 1.0GHz Link Error 0: <Prot- <Ovfl- <EOC- CTLTm- Link Frequency Capability 0: 200MHz+ 300MHz+ 400MHz+ 500MHz+ 600MHz+ 800MHz+ 1.0GHz+ 1.2GHz- 1.4GHz- 1.6GHz- Vend- Feature Capability: IsocFC+ LDTSTOP+ CRCTM- ECTLT- 64bA- UIDRD- Link Frequency 1: 200MHz Link Error 1: <Prot- <Ovfl- <EOC- CTLTm- Link Frequency Capability 1: 200MHz- 300MHz- 400MHz- 500MHz- 600MHz- 800MHz- 1.0GHz- 1.2GHz- 1.4GHz- 1.6GHz- Vend- Error Handling: PFlE+ OFlE+ PFE- OFE- EOCFE- RFE- CRCFE- SERRFE- CF- RE- PNFE- ONFE- EOCNFE- RNFE- CRCNFE- SERRNFE- Prefetchable memory behind bridge Upper: 00-00 Bus Number: 00 Capabilities: [e0] #00 [fee0] 00:01.0 ISA bridge: nVidia Corporation MCP55 LPC Bridge (rev a2) Subsystem: ASUSTeK Computer Inc. Unknown device 8239 Control: I/O+ Mem+ BusMaster+ SpecCycle+ MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap- 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 00:01.1 ...
The OHCI controller settings look normal. It doesn't appear to be The EHCI controller settings, however, are strange. The relevant part This means the controller is in the D0 state (as expected) and PME-Enable is currently turned off ("PME" stands for "Power Management Event"). But the PME+ at the end means that as soon as PME does get enabled -- like when the controller is suspended at the start of a system sleep -- it _will_ send a PME signal. So for some reason your EHCI controller thinks a wakeup event is pending. This means you should examine the contents of the "registers" file in the debugfs directory for the EHCI controller, not OHCI. Alan Stern --
melchior:/mnt/ehci/0000:00:02.1# cat registers bus pci, device 0000:00:02.1 (driver 10 Dec 2004) EHCI Host Controller EHCI 1.00, hcd state 1 ownership 00000001 SMI sts/enable 0xc0080000 structural params 0x00101a8a capability params 0x0000a086 status 0008 FLR command 010009 (park)=0 ithresh=1 period=256 RUN intrenable 37 IAA FATAL PCD ERR INT uframe 3f3a port 1 status 003400 POWER OWNER sig=k port 2 status 001000 POWER sig=se0 port 3 status 003400 POWER OWNER sig=k port 4 status 003400 POWER OWNER sig=k port 5 status 001000 POWER sig=se0 port 6 status 001000 POWER sig=se0 port 7 status 001000 POWER sig=se0 port 8 status 001000 POWER sig=se0 port 9 status 001000 POWER sig=se0 port 10 status 001000 POWER sig=se0 irq normal 0 err 0 reclaim 0 (lost 0) complete 0 unlink 0 HTH, -- Tobias PGP: http://9ac7e0bc.uguu.de このメールは十割再利用されたビットで作られています。 --
Got to admit, I'm stumped. There's nothing in the state description to indicate why the controller should want to signal a wakeup event. As an experiment, you could try disabling wakeup on the EHCI controller alone, leaving it enabled on the OHCI controller. Since the keyboard -- and in fact all your USB devices -- is attached to the OHCI controller, it should do what you want. Alan Stern --
From: Tobias Diedrich <ranma+kernel@tdiedrich.de> We currently don't signal the kernel we that this device can wake the system. Call device_init_wakeup() to correct this. Without this device_can_wakeup and device_may_wakeup will return incorrect values. Together with the minimized acpi wakeup patch (6/4 ;)), which will follow in the next mail, this really makes wake-on-lan work for me as expected (i.e. "ethtool -s eth0 wol g" is sufficient, no additional magic needed). Signed-off-by: Tobias Diedrich <ranma+kernel@tdiedrich.de> Index: linux-2.6.26-rc4.forcedwol/drivers/net/forcedeth.c =================================================================== --- linux-2.6.26-rc4.forcedwol.orig/drivers/net/forcedeth.c 2008-06-01 00:29:58.000000000 +0200 +++ linux-2.6.26-rc4.forcedwol/drivers/net/forcedeth.c 2008-06-01 00:30:48.000000000 +0200 @@ -5539,6 +5539,11 @@ /* set mac address */ nv_copy_mac_to_hw(dev); + /* Workaround current PCI init glitch: wakeup bits aren't + * being set from PCI PM capability. + */ + device_init_wakeup(&pci_dev->dev, 1); + /* disable WOL */ writel(0, base + NvRegWakeUpFlags); np->wolenabled = 0; --
From: Tobias Diedrich <ranma+kernel@tdiedrich.de> This patch is the minimal amount of code needed to support wake-on-lan in platform mode properly (i.e. "ethtool -s eth0 wol g" is sufficient, no additional magic needed) for me. This is derived from David Brownells patch (http://lists.laptop.org/pipermail/devel/2007-April/004691.html). However I decided to move the hook into pci-acpi.c since the other two pci hooks also live there and pci and acpi are the only users of the platform_enable_wakeup-hook. As a 'side-effect' this also makes wake on usb activity work for me and I had to disable usb wakeup (which is enabled by default) using the power/wakeup sysfs functionality ("echo disabled > ${sysfs_path_to_device}/power/wakeup"). (BTW I first thought the 'immediate reboot because of usb wake' effect is caused by the optical mouse generating a wake event, but it rather seems to be a problem with a flaky secondary usb host controller, which sees a connected device where nothing is attached) Signed-off-by: Tobias Diedrich <ranma+kernel@tdiedrich.de> Index: linux-2.6.26-rc4.forcedwol/drivers/pci/pci-acpi.c =================================================================== --- linux-2.6.26-rc4.forcedwol.orig/drivers/pci/pci-acpi.c 2008-06-01 00:40:23.000000000 +0200 +++ linux-2.6.26-rc4.forcedwol/drivers/pci/pci-acpi.c 2008-06-01 00:46:55.000000000 +0200 @@ -315,6 +315,25 @@ } return PCI_POWER_ERROR; } + +static int acpi_platform_enable_wakeup(struct device *dev, int is_on) +{ + struct acpi_device *adev; + int status; + + if (!device_can_wakeup(dev)) + return -EINVAL; + + if (is_on && !device_may_wakeup(dev)) + return -EINVAL; + + status = acpi_bus_get_device(DEVICE_ACPI_HANDLE(dev), &adev); + if (status < 0) + return status; + + adev->wakeup.state.enabled = !!is_on; + return 0; +} #endif static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) @@ -399,6 +418,7 @@ return 0; #ifdef CONFIG_ACPI_SLEEP ...
