From: Nathan Bryant <nbryant@optonline.net>
To: "'James Bottomley'" <James.Bottomley@steeleye.com>
Cc: Linux SCSI Reflector <linux-scsi@vger.kernel.org>,
Linux Kernel list <linux-kernel@vger.kernel.org>,
Pavel Machek <pavel@ucw.cz>,
jgarzik@pobox.com
Subject: [PATCH] SCSI midlayer power management
Date: Tue, 10 Aug 2004 19:58:21 -0400 [thread overview]
Message-ID: <4119611D.60401@optonline.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 1389 bytes --]
[resend] oops, sorry, forgot to send the patch!
Hi,
This proposed patch implements enough power-management support within
the SCSI midlayer to get ACPI S3 working on my system. Changes as follows:
* Add generic_scsi_{suspend,resume} methods to scsi.c
* Add suspend and resume callbacks to the scsi_driver structure, and
implement those callbacks in sd.c
* In sd.c, we call sd_shutdown on suspend, in order to synchronize the
write-back cache.
* In sd.c, we call sd_rescan from sd_resume in order to ensure that
drives have spun up and avoid passing not ready errors back to the block
layer.
* In generic_scsi_suspend, we call scsi_device_quiesce before calling
the scsi_driver suspend callback. We resume from quiesce state in
reverse order in generic_scsi_resume.
ACPI S1 and S4/swsusp are untested, but I think there should be no
regressions with S1. To do S1 properly, we probably need to tell the
drive to spin down, and I don't know what the SCSI command is for
that... For S4, the call to scsi_device_quiesce might pose a problem for
the subsequent state dump to disk. But I'm not sure swsusp ever worked
for SCSI.
This might help SATA drives, too, but I seem to remember that the SATA
layer doesn't properly emulate the SYNCHRONIZE_CACHE command.
Comments, anybody? Can this be applied upstream? I think it's a step in
the right direction.
Applies to scsi-misc-2.6
Nathan
[-- Attachment #2: scsi-powermanage.patch --]
[-- Type: text/x-patch, Size: 3765 bytes --]
===== drivers/scsi/scsi.c 1.145 vs edited =====
--- 1.145/drivers/scsi/scsi.c 2004-06-19 10:38:34 -04:00
+++ edited/drivers/scsi/scsi.c 2004-08-10 19:31:45 -04:00
@@ -60,6 +60,7 @@
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_dbg.h>
#include <scsi/scsi_device.h>
+#include <scsi/scsi_driver.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
@@ -1175,6 +1176,40 @@
#define register_scsi_cpu()
#define unregister_scsi_cpu()
#endif /* CONFIG_HOTPLUG_CPU */
+
+#ifdef CONFIG_PM
+int generic_scsi_suspend(struct device *dev, u32 state)
+{
+ int err;
+ struct scsi_device *sdev = to_scsi_device(dev);
+ struct scsi_driver *drv = to_scsi_driver(dev->driver);
+
+ err = scsi_device_quiesce(sdev);
+ if (err)
+ return err;
+
+ if (drv->suspend)
+ return drv->suspend(dev, state);
+
+ return 0;
+}
+
+int generic_scsi_resume(struct device *dev)
+{
+ int err;
+ struct scsi_device *sdev = to_scsi_device(dev);
+ struct scsi_driver *drv = to_scsi_driver(dev->driver);
+
+ if (drv->resume) {
+ err = drv->resume(dev);
+ if (err)
+ return err;
+ }
+
+ scsi_device_resume(sdev);
+ return 0;
+}
+#endif /*CONFIG_PM*/
MODULE_DESCRIPTION("SCSI core");
MODULE_LICENSE("GPL");
===== drivers/scsi/scsi_priv.h 1.33 vs edited =====
--- 1.33/drivers/scsi/scsi_priv.h 2004-06-16 11:45:44 -04:00
+++ edited/drivers/scsi/scsi_priv.h 2004-08-09 20:07:35 -04:00
@@ -92,6 +92,10 @@
static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
{ };
#endif
+#ifdef CONFIG_PM
+extern int generic_scsi_suspend(struct device *dev, u32 state);
+extern int generic_scsi_resume(struct device *dev);
+#endif
/* scsi_devinfo.c */
extern int scsi_get_device_flags(struct scsi_device *sdev,
===== drivers/scsi/scsi_sysfs.c 1.52 vs edited =====
--- 1.52/drivers/scsi/scsi_sysfs.c 2004-07-28 23:59:10 -04:00
+++ edited/drivers/scsi/scsi_sysfs.c 2004-08-10 17:43:04 -04:00
@@ -187,8 +187,12 @@
}
struct bus_type scsi_bus_type = {
- .name = "scsi",
- .match = scsi_bus_match,
+ .name = "scsi",
+ .match = scsi_bus_match,
+#ifdef CONFIG_PM
+ .suspend = generic_scsi_suspend,
+ .resume = generic_scsi_resume,
+#endif
};
int scsi_sysfs_register(void)
===== drivers/scsi/sd.c 1.154 vs edited =====
--- 1.154/drivers/scsi/sd.c 2004-06-19 10:38:40 -04:00
+++ edited/drivers/scsi/sd.c 2004-08-10 19:33:15 -04:00
@@ -110,6 +110,10 @@
static int sd_probe(struct device *);
static int sd_remove(struct device *);
+#ifdef CONFIG_PM
+static int sd_suspend(struct device *, u32);
+static int sd_resume(struct device *);
+#endif
static void sd_shutdown(struct device *dev);
static void sd_rescan(struct device *);
static int sd_init_command(struct scsi_cmnd *);
@@ -126,6 +130,10 @@
},
.rescan = sd_rescan,
.init_command = sd_init_command,
+#ifdef CONFIG_PM
+ .suspend = sd_suspend,
+ .resume = sd_resume,
+#endif
};
/* Device no to disk mapping:
@@ -1549,7 +1557,21 @@
scsi_release_request(sreq);
printk("\n");
-}
+}
+
+#ifdef CONFIG_PM
+static int sd_suspend(struct device *dev, u32 state)
+{
+ sd_shutdown(dev);
+ return 0;
+}
+
+static int sd_resume(struct device *dev)
+{
+ sd_rescan(dev);
+ return 0;
+}
+#endif /*CONFIG_PM*/
/**
* init_sd - entry point for this driver (both when built in or when
===== include/scsi/scsi_driver.h 1.2 vs edited =====
--- 1.2/include/scsi/scsi_driver.h 2003-11-12 09:15:46 -05:00
+++ edited/include/scsi/scsi_driver.h 2004-08-10 18:02:45 -04:00
@@ -13,6 +13,10 @@
int (*init_command)(struct scsi_cmnd *);
void (*rescan)(struct device *);
+#ifdef CONFIG_PM
+ int (*suspend)(struct device *dev, u32 state);
+ int (*resume)(struct device *dev);
+#endif
};
#define to_scsi_driver(drv) \
container_of((drv), struct scsi_driver, gendrv)
next reply other threads:[~2004-08-11 0:02 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-08-10 23:58 Nathan Bryant [this message]
2004-08-11 8:09 ` [PATCH] SCSI midlayer power management Pavel Machek
2004-08-11 13:13 ` Nathan Bryant
2004-08-11 13:37 ` James Bottomley
2004-08-11 15:21 ` Alan Cox
2004-08-11 16:28 ` James Bottomley
2004-08-11 16:43 ` Nathan Bryant
2004-08-11 23:36 ` Benjamin Herrenschmidt
2004-08-12 7:45 ` Pavel Machek
2004-08-12 10:38 ` Benjamin Herrenschmidt
2004-08-12 12:48 ` James Bottomley
2004-08-12 13:14 ` Pavel Machek
2004-08-12 16:29 ` James Bottomley
2004-08-12 19:11 ` Pavel Machek
2004-08-12 19:34 ` James Bottomley
2004-08-12 20:26 ` Pavel Machek
2004-08-12 20:31 ` James Bottomley
2004-08-12 20:37 ` Pavel Machek
2004-08-12 20:42 ` James Bottomley
2004-08-12 20:48 ` Pavel Machek
2004-08-12 20:52 ` Nathan Bryant
2004-08-12 20:40 ` Nathan Bryant
2004-08-12 23:05 ` Benjamin Herrenschmidt
2004-08-12 22:36 ` Nigel Cunningham
2004-08-12 22:43 ` Nigel Cunningham
2004-08-12 23:04 ` Benjamin Herrenschmidt
2004-08-12 13:41 ` Nathan Bryant
2004-08-12 16:45 ` Patrick Mansfield
2004-08-12 23:02 ` Benjamin Herrenschmidt
2004-08-11 20:19 ` Pavel Machek
2004-08-11 20:50 ` Nathan Bryant
2004-08-11 22:16 ` Nigel Cunningham
2004-08-11 22:48 ` Nathan Bryant
2004-08-12 7:43 ` Pavel Machek
2004-08-12 9:39 ` Nigel Cunningham
2004-08-12 13:43 ` Nathan Bryant
-- strict thread matches above, loose matches on Subject: below --
2004-08-16 13:29 James.Smart
2004-08-10 23:56 Nathan Bryant
2004-08-11 9:53 ` Alan Cox
2004-08-11 12:55 ` Nathan Bryant
2004-08-11 13:39 ` James Bottomley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4119611D.60401@optonline.net \
--to=nbryant@optonline.net \
--cc=James.Bottomley@steeleye.com \
--cc=jgarzik@pobox.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=pavel@ucw.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox