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-10 23:59 UTC|newest]
Thread overview: 42+ 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-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 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.