All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch/rft 2.6.17-rc2] swsusp resume must not device_suspend()
@ 2006-04-24 21:29 David Brownell
  2006-04-24 21:47 ` [linux-pm] " Rafael J. Wysocki
                   ` (3 more replies)
  0 siblings, 4 replies; 80+ messages in thread
From: David Brownell @ 2006-04-24 21:29 UTC (permalink / raw)
  To: linux-pm, linux-usb-devel; +Cc: Andrew Morton

[-- Attachment #1: Type: text/plain, Size: 1127 bytes --]

I've noticed a bunch of problem reports that go like this:

 - boot system with some USB devices attached
 - echo disk > /sys/power/state
 - ... later resume ...
 - now those USB devices don't work right
 - unplug them/replug them, all is OK

I recently observed this myself and tracked down one problem.  The solution
involves what kexec() does in much the same situation:  before starting a
new kernel, most hardware needs to be reset.  Today, swsusp will suspend it
instead, which is the root cause of the problem.

This seems like something that might need to sit in the MM tree for
a while, as it's a longstanding bug and the fix could shake loose driver
goofs.  Luckily there's a partial workaround already in wide use:  link
drivers as modules if they use true suspend states (like all USB HCDs),
don't link them statically into the kernel image.

That workaround is partial because when BIOS takes over a controller, the
resume() method has to handle that nasty case too!  Last I checked, all
the USB HCDs do handle that case; and few drivers other than those HCDs
would ever need to worry about such issues.

- Dave



[-- Attachment #2: swsusp.patch --]
[-- Type: text/x-diff, Size: 1712 bytes --]

Currently the swsusp resume path puts devices into a bogus suspend state
before switching to the new kernel.  It's neither the suspend state that
the driver left the device in, nor a "device lost power" reset state.

Instead, it's a semi-functional state from the kernel which loaded the
snapshot.  There's no way that a driver can properly resume from that.
Some drivers issue resets in their resume methods, but that's wrong for
every driver which uses more power states than just "on" and "reset".

This patch shuts down (resets) the devices, just like kexec() does, so
that non-modular drivers will know they must fully re-initialize even
when they wouldn't ordinarily do so during resume().


--- linux.orig/kernel/power/swsusp.c	2006-04-23 08:41:22.000000000 -0700
+++ linux/kernel/power/swsusp.c	2006-04-24 13:20:17.000000000 -0700
@@ -49,6 +49,7 @@
 #include <linux/bootmem.h>
 #include <linux/syscalls.h>
 #include <linux/highmem.h>
+#include <linux/reboot.h>
 
 #include "power.h"
 
@@ -249,10 +250,16 @@
 int swsusp_resume(void)
 {
 	int error;
-	local_irq_disable();
-	if (device_power_down(PMSG_FREEZE))
-		printk(KERN_ERR "Some devices failed to power down, very bad\n");
+
+	/* We need to shutdown/reset devices so that drivers which use
+	 * non-powerdown suspend() states will see sane states in their
+	 * resume() methods.  At this point "reset" is the only option,
+	 * since we clobbered any valid suspend state a long time ago.
+	 */
+	kernel_restart_prepare(NULL);
+
 	/* We'll ignore saved state, but this gets preempt count (etc) right */
+	local_irq_disable();
 	save_processor_state();
 	error = swsusp_arch_resume();
 	/* Code below is only ever reached in case of failure. Otherwise

^ permalink raw reply	[flat|nested] 80+ messages in thread

end of thread, other threads:[~2006-06-07 22:58 UTC | newest]

Thread overview: 80+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-04-24 21:29 [patch/rft 2.6.17-rc2] swsusp resume must not device_suspend() David Brownell
2006-04-24 21:47 ` [linux-pm] " Rafael J. Wysocki
2006-04-24 22:47   ` David Brownell
2006-04-25 10:34     ` Nigel Cunningham
2006-04-25 14:41       ` Alan Stern
2006-04-25 17:37         ` [linux-pm] " David Brownell
2006-04-25 20:45           ` Alan Stern
2006-04-26  0:30             ` David Brownell
2006-04-27  8:20               ` Pavel Machek
2006-04-27  8:16             ` Pavel Machek
2006-04-27  8:08         ` Pavel Machek
2006-04-27 14:34           ` [linux-pm] " Alan Stern
2006-04-27 16:55             ` Patrick Mochel
2006-04-27 17:41               ` Alan Stern
2006-04-27 19:21               ` David Brownell
2006-04-27 20:35                 ` Nigel Cunningham
2006-04-27 20:58                   ` Pavel Machek
2006-04-25 16:56       ` David Brownell
2006-04-24 22:31 ` [linux-pm] " Nigel Cunningham
2006-04-25  8:32   ` Rafael J. Wysocki
2006-04-25 16:11     ` David Brownell
2006-04-25 18:56       ` Rafael J. Wysocki
2006-04-25 20:28         ` Nigel Cunningham
2006-04-25 20:53           ` [linux-pm] " Rafael J. Wysocki
2006-04-25 21:03             ` Nigel Cunningham
2006-04-25 22:06               ` Rafael J. Wysocki
2006-04-25 22:18                 ` Nigel Cunningham
2006-04-25 22:34                   ` Rafael J. Wysocki
2006-04-25 23:55                   ` David Brownell
2006-04-26  1:16                     ` Nigel Cunningham
2006-04-26  3:32                       ` [linux-pm] " David Brownell
2006-04-26  3:44                         ` Nigel Cunningham
2006-04-26 14:24           ` Alan Stern
2006-04-26 19:47             ` [linux-pm] " Nigel Cunningham
2006-04-25 21:04         ` David Brownell
2006-04-25 21:41           ` Pavel Machek
2006-04-25 23:13             ` [linux-pm] " David Brownell
2006-04-26  9:07               ` Pavel Machek
2006-04-25 21:55           ` Rafael J. Wysocki
2006-04-25 22:56             ` David Brownell
2006-04-26 11:26               ` Rafael J. Wysocki
2006-04-26 14:38                 ` [linux-pm] " Alan Stern
2006-04-26 15:26                   ` Rafael J. Wysocki
2006-04-26 15:38                     ` Alan Stern
2006-04-26 16:09                       ` Rafael J. Wysocki
2006-04-26 19:06                         ` Alan Stern
2006-04-26 20:37                           ` Rafael J. Wysocki
2006-04-26 21:31                 ` David Brownell
2006-04-26 22:24                   ` Rafael J. Wysocki
2006-04-27 19:44                     ` David Brownell
2006-04-25 15:56   ` David Brownell
2006-04-27 10:54     ` Pavel Machek
2006-04-25 13:50 ` [linux-usb-devel] " Alan Stern
2006-04-25 15:49   ` David Brownell
2006-04-27  1:22 ` Patrick Mochel
2006-04-27 19:41   ` [linux-pm] " David Brownell
2006-05-02 16:12     ` Patrick Mochel
2006-05-26  3:06       ` David Brownell
2006-05-26 19:50         ` Rafael J. Wysocki
2006-05-26 23:16         ` Pavel Machek
2006-05-27  0:19           ` [linux-usb-devel] " David Brownell
2006-05-27 16:38             ` Pavel Machek
2006-06-05 15:31               ` David Brownell
2006-06-05 16:36               ` [patch/rft 2.6.17-rc5-git 0/6] PM_EVENT_PRETHAW David Brownell
2006-06-05 16:36               ` [patch/rft 2.6.17-rc5-git 1/6] fix broken/dubious driver suspend() methods David Brownell
     [not found]                 ` <20060530191140.GA4017@ucw.cz>
2006-06-07  0:53                   ` David Brownell
2006-06-05 16:37               ` [patch/rft 2.6.17-rc5-git 2/6] add PM_EVENT_PRETHAW David Brownell
2006-05-30 19:17                 ` Pavel Machek
2006-06-07  1:02                   ` David Brownell
2006-06-05 16:38               ` [patch/rft 2.6.17-rc5-git 3/6] PM_EVENT_PRETHAW, handle in IDE and PCI David Brownell
2006-05-30 19:21                 ` Pavel Machek
2006-06-07  0:51                   ` David Brownell
2006-06-05 16:38               ` [patch/rft 2.6.17-rc5-git 4/6] PM_EVENT_PRETHAW for various graphics cards David Brownell
2006-05-30 19:30                 ` Pavel Machek
2006-06-07  1:24                   ` David Brownell
2006-06-07 18:57                     ` PM docs and API? bsmith
2006-06-07 22:58                       ` David Brownell
2006-06-05 16:38               ` [patch/rft 2.6.17-rc5-git 5/6] PM_EVENT_PRETHAW, handle for USB David Brownell
2006-06-05 16:38               ` [patch/rft 2.6.17-rc5-git 6/6] PM_EVENT_PRETHAW, issue from PM core David Brownell
2006-05-30 19:28                 ` Pavel Machek

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.