Skip to contentSkip to conversation

Use global system_state to avoid system-state confusion

PATCH Pavel Machek 4 participants 5 messages Aug 19, 2004 – Aug 20, 2004

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

Hi!

I started using system_state (already defined in kernel.h) to allow drivers to do something different in response to swsusp. This at least kills ide-disk.c hack.

Please apply,
Pavel

drivers/ide/ide-disk.c +1 -2
@@ -1406,7 +1406,7 @@
 {
 	switch (rq->pm->pm_step) {
 	case idedisk_pm_flush_cache:	/* Suspend step 1 (flush cache) complete */
-		if (rq->pm->pm_state == 4)
+		if (system_state == SYSTEM_SWSUSP_SNAPSHOT)
 			rq->pm->pm_step = ide_pm_state_completed;
 		else
 			rq->pm->pm_step = idedisk_pm_standby;
@@ -1678,7 +1678,6 @@
 		return;
 	}
 
-	printk("Shutdown: %s\n", drive->name);
 	dev->bus->suspend(dev, PM_SUSPEND_STANDBY);
 }
 
include/linux/kernel.h +3 -0
@@ -136,6 +136,9 @@
 extern enum system_states {
 	SYSTEM_BOOTING,
 	SYSTEM_RUNNING,
+	SYSTEM_SWSUSP_SNAPSHOT,
+	SYSTEM_DISK_SUSPEND,
+	SYSTEM_RAM_SUSPEND,
 	SYSTEM_HALT,
 	SYSTEM_POWER_OFF,
 	SYSTEM_RESTART,
include/linux/pm.h +5 -5
@@ -193,11 +193,11 @@
 extern void (*pm_idle)(void);
 extern void (*pm_power_off)(void);
 
-enum {
-	PM_SUSPEND_ON,
-	PM_SUSPEND_STANDBY,
-	PM_SUSPEND_MEM,
-	PM_SUSPEND_DISK,
+enum system_state {
+	PM_SUSPEND_ON = 0,
+	PM_SUSPEND_STANDBY = 1,
+	PM_SUSPEND_MEM = 2,
+	PM_SUSPEND_DISK = 3,
 	PM_SUSPEND_MAX,
 };
 
kernel/power/disk.c +6 -0
@@ -15,6 +15,7 @@
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/fs.h>
+#include <linux/device.h>
 #include "power.h"
 
 
@@ -49,15 +50,18 @@
 	local_irq_save(flags);
 	switch(mode) {
 	case PM_DISK_PLATFORM:
+		system_state = SYSTEM_DISK_SUSPEND;
 		device_power_down(PM_SUSPEND_DISK);
 		error = pm_ops->enter(PM_SUSPEND_DISK);
 		break;
 	case PM_DISK_SHUTDOWN:
+		system_state = SYSTEM_POWER_OFF;
 		printk("Powering off system\n");
 		device_shutdown();
 		machine_power_off();
 		break;
 	case PM_DISK_REBOOT:
+		system_state = SYSTEM_RESTART;
 		device_shutdown();
 		machine_restart(NULL);
 		break;
@@ -114,6 +118,7 @@
 {
 	int error;
 
+	system_state = SYSTEM_SWSUSP_SNAPSHOT;
 	pm_prepare_console();
 
 	sys_sync();
@@ -226,6 +231,7 @@
 
 	pr_debug("PM: Preparing system for restore.\n");
 
+	system_state = SYSTEM_SWSUSP_SNAPSHOT;
 	if ((error = prepare()))
 		goto Free;
 
kernel/power/main.c +2 -0
@@ -151,6 +151,7 @@
 		goto Unlock;
 	}
 
+	system_state = SYSTEM_RAM_SUSPEND;
 	pr_debug("PM: Preparing system for suspend\n");
 	if ((error = suspend_prepare(state)))
 		goto Unlock;
@@ -162,6 +163,7 @@
 	suspend_finish(state);
  Unlock:
 	up(&pm_sem);
+	system_state = SYSTEM_RUNNING;
 	return error;
 }
 
Signature · 2 lines
People were complaining that M$ turns users into beta-testers...
...jr ghea gurz vagb qrirybcref, naq gurl frrz gb yvxr vg gung jnl!
#1 lore raw

Hi.

drivers/ide/ide-disk.c line 1409

Quoted 1 line · Pavel Machek
drivers/ide/ide-disk.c +1 -0
+		if (system_state == SYSTEM_SWSUSP_SNAPSHOT)

Would you consider getting rid of the 'SWSUSP'? It's so ugly! SYSTEM_SNAPSHOT would be clear and concise.

Regards,

Nigel

Signature · 6 lines
Nigel Cunningham
Christian Reformed Church of Tuggeranong
PO Box 1004, Tuggeranong, ACT 2901

Many today claim to be tolerant. But true tolerance can cope with others
being intolerant.
#2 lore raw

Hi!

Quoted 4 lines

drivers/ide/ide-disk.c line 1409

Quoted 1 line
drivers/ide/ide-disk.c +1 -0
+		if (system_state == SYSTEM_SWSUSP_SNAPSHOT)

Would you consider getting rid of the 'SWSUSP'? It's so ugly! SYSTEM_SNAPSHOT would be clear and concise.

Ok.
Pavel

Signature · 2 lines
People were complaining that M$ turns users into beta-testers...
...jr ghea gurz vagb qrirybcref, naq gurl frrz gb yvxr vg gung jnl!
#3 lore raw
In reply to Pavel Machek

drivers/ide/ide-disk.c line 1682

Quoted 11 lines · Pavel Machek

Hi!

I started using system_state (already defined in kernel.h) to allow drivers to do something different in response to swsusp. This at least kills ide-disk.c hack.

Please apply,

drivers/ide/ide-disk.c +0 -1
-	printk("Shutdown: %s\n", drive->name);
 	dev->bus->suspend(dev, PM_SUSPEND_STANDBY);
 }

Please leave the printk - its very handy for debugging IDE exit paths, and those are not entirely bug free yet.

#4 lore raw

Hi!

Quoted 4 lines
Quoted 4 lines

I started using system_state (already defined in kernel.h) to allow drivers to do something different in response to swsusp. This at least kills ide-disk.c hack.

Quoted 8 lines

Review

Quoted 5 lines

Please apply,

(quoted diff) +0 -1
-	printk("Shutdown: %s\n", drive->name);
 	dev->bus->suspend(dev, PM_SUSPEND_STANDBY);
 }

Please leave the printk - its very handy for debugging IDE exit paths, and those are not entirely bug free yet.

Okay, here's newer patch. It does:

* use system_state so that disk is not spun down during swsusp
* kill unused constants from old pm.h sections, and make those sections deprecated
* introduce enums into kernel/power so that we have more descriptive types than u32
* pass 3 to device_suspend in suspend-to-RAM case. This should solve EHCI problems.

Please apply,

Pavel

drivers/base/power/power.h +1 -2
@@ -1,5 +1,4 @@
-
-
+/* FIXME: This needs explanation... */
 enum {
 	DEVICE_PM_ON,
 	DEVICE_PM1,
drivers/ide/ide-disk.c +1 -1
@@ -1406,7 +1406,7 @@
 {
 	switch (rq->pm->pm_step) {
 	case idedisk_pm_flush_cache:	/* Suspend step 1 (flush cache) complete */
-		if (rq->pm->pm_state == 4)
+		if (system_state == SYSTEM_SNAPSHOT)
 			rq->pm->pm_step = ide_pm_state_completed;
 		else
 			rq->pm->pm_step = idedisk_pm_standby;
include/linux/kernel.h +3 -0
@@ -136,6 +136,9 @@
 extern enum system_states {
 	SYSTEM_BOOTING,
 	SYSTEM_RUNNING,
+	SYSTEM_SNAPSHOT,
+	SYSTEM_DISK_SUSPEND,
+	SYSTEM_RAM_SUSPEND,
 	SYSTEM_HALT,
 	SYSTEM_POWER_OFF,
 	SYSTEM_RESTART,
include/linux/pm.h +21 -34

99 lines not on this page · raw message

kernel/power/disk.c +11 -3
@@ -15,10 +15,11 @@
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/fs.h>
+#include <linux/device.h>
 #include "power.h"
 
 
-extern u32 pm_disk_mode;
+extern enum suspend_disk_method pm_disk_mode;
 extern struct pm_ops * pm_ops;
 
 extern int swsusp_suspend(void);
@@ -41,7 +42,7 @@
  *	there ain't no turning back.
  */
 
-static int power_down(u32 mode)
+static int power_down(enum suspend_disk_method mode)
 {
 	unsigned long flags;
 	int error = 0;
@@ -49,18 +50,23 @@
 	local_irq_save(flags);
 	switch(mode) {
 	case PM_DISK_PLATFORM:
+		system_state = SYSTEM_DISK_SUSPEND;
 		device_power_down(PM_SUSPEND_DISK);
 		error = pm_ops->enter(PM_SUSPEND_DISK);
 		break;
 	case PM_DISK_SHUTDOWN:
+		system_state = SYSTEM_POWER_OFF;
 		printk("Powering off system\n");
 		device_shutdown();
 		machine_power_off();
 		break;
 	case PM_DISK_REBOOT:
+		system_state = SYSTEM_RESTART;
 		device_shutdown();
 		machine_restart(NULL);
 		break;
+	default:
+		BUG();
 	}
 	machine_halt();
 	/* Valid image is on the disk, if we continue we risk serious data corruption
@@ -114,6 +120,7 @@
 {
 	int error;
 
+	system_state = SYSTEM_SNAPSHOT;
 	pm_prepare_console();
 
 	sys_sync();
@@ -226,6 +233,7 @@
 
 	pr_debug("PM: Preparing system for restore.\n");
 
+	system_state = SYSTEM_SNAPSHOT;
 	if ((error = prepare()))
 		goto Free;
 
@@ -292,7 +300,7 @@
 	int i;
 	int len;
 	char *p;
-	u32 mode = 0;
+	enum suspend_disk_method mode = 0;
 
 	p = memchr(buf, '\n', n);
 	len = p ? p - buf : n;
kernel/power/main.c +16 -9
@@ -22,7 +22,7 @@
 DECLARE_MUTEX(pm_sem);
 
 struct pm_ops * pm_ops = NULL;
-u32 pm_disk_mode = PM_DISK_SHUTDOWN;
+enum suspend_disk_method pm_disk_mode = PM_DISK_SHUTDOWN;
 
 /**
  *	pm_set_ops - Set the global power method table. 
@@ -46,7 +46,7 @@
  *	the platform can enter the requested state.
  */
 
-static int suspend_prepare(u32 state)
+static int suspend_prepare(enum suspend_state state)
 {
 	int error = 0;
 
@@ -65,7 +65,11 @@
 			goto Thaw;
 	}
 
-	if ((error = device_suspend(state)))
+	/* FIXME: this is suspend confusion biting us. If we pass
+	   state, we'll pass 2 in suspend-to-RAM case; EHCI will
+	   actually break suspend, because it interprets 2 as PCI_D2
+	   state. Oops. */
+	if ((error = device_suspend(3)))
 		goto Finish;
 	return 0;
  Finish:
@@ -78,13 +82,14 @@
 }
 
 
-static int suspend_enter(u32 state)
+static int suspend_enter(enum suspend_state state)
 {
 	int error = 0;
 	unsigned long flags;
 
 	local_irq_save(flags);
-	if ((error = device_power_down(state)))
+	/* FIXME: see suspend_prepare */
+	if ((error = device_power_down(3)))
 		goto Done;
 	error = pm_ops->enter(state);
 	device_power_up();
@@ -102,7 +107,7 @@
  *	console that we've allocated.
  */
 
-static void suspend_finish(u32 state)
+static void suspend_finish(enum suspend_state state)
 {
 	device_resume();
 	if (pm_ops && pm_ops->finish)
@@ -133,7 +138,7 @@
  *	we've woken up).
  */
 
-static int enter_state(u32 state)
+static int enter_state(enum suspend_state state)
 {
 	int error;
 
@@ -151,6 +156,7 @@
 		goto Unlock;
 	}
 
+	system_state = SYSTEM_RAM_SUSPEND;
 	pr_debug("PM: Preparing system for suspend\n");
 	if ((error = suspend_prepare(state)))
 		goto Unlock;
@@ -162,6 +168,7 @@
 	suspend_finish(state);
  Unlock:
 	up(&pm_sem);
+	system_state = SYSTEM_RUNNING;
 	return error;
 }
 
@@ -183,7 +190,7 @@
  *	structure, and enter (above).
  */
 
-int pm_suspend(u32 state)
+int pm_suspend(enum suspend_state state)
 {
 	if (state > PM_SUSPEND_ON && state < PM_SUSPEND_MAX)
 		return enter_state(state);
@@ -221,7 +228,7 @@
 
 static ssize_t state_store(struct subsystem * subsys, const char * buf, size_t n)
 {
-	u32 state = PM_SUSPEND_STANDBY;
+	enum suspend_state state = PM_SUSPEND_STANDBY;
 	char ** s;
 	char *p;
 	int error;
kernel/power/swsusp.c +1 -1
@@ -1119,7 +1119,7 @@
 		 */
 		error = bio_write_page(0,&swsusp_header);
 	} else { 
-		pr_debug(KERN_ERR "swsusp: Invalid partition type.\n");
+		pr_debug(KERN_ERR "swsusp: Suspend partition has wrong signature?\n");
 		return -EINVAL;
 	}
 	if (!error)
Signature · 2 lines
People were complaining that M$ turns users into beta-testers...
...jr ghea gurz vagb qrirybcref, naq gurl frrz gb yvxr vg gung jnl!