2019-05-19 20:08:55 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
2010-06-17 22:36:49 +08:00
|
|
|
/*
|
|
|
|
* scsi_pm.c Copyright (C) 2010 Alan Stern
|
|
|
|
*
|
|
|
|
* SCSI dynamic Power Management
|
|
|
|
* Initial version: Alan Stern <stern@rowland.harvard.edu>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/pm_runtime.h>
|
2011-05-27 21:37:25 +08:00
|
|
|
#include <linux/export.h>
|
[SCSI] scsi_pm: Fix bug in the SCSI power management handler
This patch (as1520) fixes a bug in the SCSI layer's power management
implementation.
LUN scanning can be carried out asynchronously in do_scan_async(), and
sd uses an asynchronous thread for the time-consuming parts of disk
probing in sd_probe_async(). Currently nothing coordinates these
async threads with system sleep transitions; they can and do attempt
to continue scanning/probing SCSI devices even after the host adapter
has been suspended. As one might expect, the outcome is not ideal.
This is what the "prepare" stage of system suspend was created for.
After the prepare callback has been called for a host, target, or
device, drivers are not allowed to register any children underneath
them. Currently the SCSI prepare callback is not implemented; this
patch rectifies that omission.
For SCSI hosts, the prepare routine calls scsi_complete_async_scans()
to wait until async scanning is finished. It might be slightly more
efficient to wait only until the host in question has been scanned,
but there's currently no way to do that. Besides, during a sleep
transition we will ultimately have to wait until all the host scanning
has finished anyway.
For SCSI devices, the prepare routine calls async_synchronize_full()
to wait until sd probing is finished. The routine does nothing for
SCSI targets, because asynchronous target scanning is done only as
part of host scanning.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: <stable@kernel.org>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
2012-02-18 05:25:08 +08:00
|
|
|
#include <linux/async.h>
|
2018-09-27 05:01:03 +08:00
|
|
|
#include <linux/blk-pm.h>
|
2010-06-17 22:36:49 +08:00
|
|
|
|
|
|
|
#include <scsi/scsi.h>
|
|
|
|
#include <scsi/scsi_device.h>
|
|
|
|
#include <scsi/scsi_driver.h>
|
|
|
|
#include <scsi/scsi_host.h>
|
|
|
|
|
|
|
|
#include "scsi_priv.h"
|
|
|
|
|
2013-10-28 15:27:49 +08:00
|
|
|
#ifdef CONFIG_PM_SLEEP
|
|
|
|
|
2014-04-11 06:30:35 +08:00
|
|
|
static int do_scsi_suspend(struct device *dev, const struct dev_pm_ops *pm)
|
2010-06-17 22:36:49 +08:00
|
|
|
{
|
2014-04-11 06:30:35 +08:00
|
|
|
return pm && pm->suspend ? pm->suspend(dev) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int do_scsi_freeze(struct device *dev, const struct dev_pm_ops *pm)
|
|
|
|
{
|
|
|
|
return pm && pm->freeze ? pm->freeze(dev) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int do_scsi_poweroff(struct device *dev, const struct dev_pm_ops *pm)
|
|
|
|
{
|
|
|
|
return pm && pm->poweroff ? pm->poweroff(dev) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int do_scsi_resume(struct device *dev, const struct dev_pm_ops *pm)
|
|
|
|
{
|
|
|
|
return pm && pm->resume ? pm->resume(dev) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int do_scsi_thaw(struct device *dev, const struct dev_pm_ops *pm)
|
|
|
|
{
|
|
|
|
return pm && pm->thaw ? pm->thaw(dev) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int do_scsi_restore(struct device *dev, const struct dev_pm_ops *pm)
|
|
|
|
{
|
|
|
|
return pm && pm->restore ? pm->restore(dev) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int scsi_dev_type_suspend(struct device *dev,
|
|
|
|
int (*cb)(struct device *, const struct dev_pm_ops *))
|
|
|
|
{
|
|
|
|
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
|
2010-06-17 22:36:49 +08:00
|
|
|
int err;
|
|
|
|
|
2014-04-11 06:30:35 +08:00
|
|
|
/* flush pending in-flight resume operations, suspend is synchronous */
|
|
|
|
async_synchronize_full_domain(&scsi_sd_pm_domain);
|
|
|
|
|
2010-06-17 22:36:49 +08:00
|
|
|
err = scsi_device_quiesce(to_scsi_device(dev));
|
|
|
|
if (err == 0) {
|
2014-04-11 06:30:35 +08:00
|
|
|
err = cb(dev, pm);
|
|
|
|
if (err)
|
|
|
|
scsi_device_resume(to_scsi_device(dev));
|
2010-06-17 22:36:49 +08:00
|
|
|
}
|
|
|
|
dev_dbg(dev, "scsi suspend: %d\n", err);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2014-04-11 06:30:35 +08:00
|
|
|
static int scsi_dev_type_resume(struct device *dev,
|
|
|
|
int (*cb)(struct device *, const struct dev_pm_ops *))
|
2010-06-17 22:36:49 +08:00
|
|
|
{
|
2014-04-11 06:30:35 +08:00
|
|
|
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
|
2010-06-17 22:36:49 +08:00
|
|
|
int err = 0;
|
|
|
|
|
2014-04-11 06:30:35 +08:00
|
|
|
err = cb(dev, pm);
|
2010-06-17 22:36:49 +08:00
|
|
|
scsi_device_resume(to_scsi_device(dev));
|
|
|
|
dev_dbg(dev, "scsi resume: %d\n", err);
|
2014-04-11 06:30:35 +08:00
|
|
|
|
|
|
|
if (err == 0) {
|
scsi: pm: Balance pm_only counter of request queue during system resume
During system resume, scsi_resume_device() decreases a request queue's
pm_only counter if the scsi device was quiesced before. But after that, if
the scsi device's RPM status is RPM_SUSPENDED, the pm_only counter is still
held (non-zero). Current SCSI resume hook only sets the RPM status of the
scsi_device and its request queue to RPM_ACTIVE, but leaves the pm_only
counter unchanged. This may make the request queue's pm_only counter remain
non-zero after resume hook returns, hence those who are waiting on the
mq_freeze_wq would never be woken up. Fix this by calling
blk_post_runtime_resume() if a sdev's RPM status was RPM_SUSPENDED.
(struct request_queue)0xFFFFFF815B69E938
pm_only = (counter = 2),
rpm_status = 0,
dev = 0xFFFFFF815B0511A0,
((struct device)0xFFFFFF815B0511A0)).power
is_suspended = FALSE,
runtime_status = RPM_ACTIVE,
(struct scsi_device)0xffffff815b051000
request_queue = 0xFFFFFF815B69E938,
sdev_state = SDEV_RUNNING,
quiesced_by = 0x0,
B::v.f_/task_0xFFFFFF810C246940
-000|__switch_to(prev = 0xFFFFFF810C246940, next = 0xFFFFFF80A49357C0)
-001|context_switch(inline)
-001|__schedule(?)
-002|schedule()
-003|blk_queue_enter(q = 0xFFFFFF815B69E938, flags = 0)
-004|generic_make_request(?)
-005|submit_bio(bio = 0xFFFFFF80A8195B80)
Link: https://lore.kernel.org/r/1588740936-28846-1-git-send-email-cang@codeaurora.org
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Can Guo <cang@codeaurora.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2020-05-06 12:55:35 +08:00
|
|
|
bool was_runtime_suspended;
|
|
|
|
|
|
|
|
was_runtime_suspended = pm_runtime_suspended(dev);
|
|
|
|
|
2014-04-11 06:30:35 +08:00
|
|
|
pm_runtime_disable(dev);
|
2019-01-03 22:08:05 +08:00
|
|
|
err = pm_runtime_set_active(dev);
|
2014-04-11 06:30:35 +08:00
|
|
|
pm_runtime_enable(dev);
|
2019-01-03 22:08:05 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Forcibly set runtime PM status of request queue to "active"
|
|
|
|
* to make sure we can again get requests from the queue
|
|
|
|
* (see also blk_pm_peek_request()).
|
|
|
|
*
|
|
|
|
* The resume hook will correct runtime PM status of the disk.
|
|
|
|
*/
|
|
|
|
if (!err && scsi_is_sdev_device(dev)) {
|
|
|
|
struct scsi_device *sdev = to_scsi_device(dev);
|
scsi: pm: Balance pm_only counter of request queue during system resume
During system resume, scsi_resume_device() decreases a request queue's
pm_only counter if the scsi device was quiesced before. But after that, if
the scsi device's RPM status is RPM_SUSPENDED, the pm_only counter is still
held (non-zero). Current SCSI resume hook only sets the RPM status of the
scsi_device and its request queue to RPM_ACTIVE, but leaves the pm_only
counter unchanged. This may make the request queue's pm_only counter remain
non-zero after resume hook returns, hence those who are waiting on the
mq_freeze_wq would never be woken up. Fix this by calling
blk_post_runtime_resume() if a sdev's RPM status was RPM_SUSPENDED.
(struct request_queue)0xFFFFFF815B69E938
pm_only = (counter = 2),
rpm_status = 0,
dev = 0xFFFFFF815B0511A0,
((struct device)0xFFFFFF815B0511A0)).power
is_suspended = FALSE,
runtime_status = RPM_ACTIVE,
(struct scsi_device)0xffffff815b051000
request_queue = 0xFFFFFF815B69E938,
sdev_state = SDEV_RUNNING,
quiesced_by = 0x0,
B::v.f_/task_0xFFFFFF810C246940
-000|__switch_to(prev = 0xFFFFFF810C246940, next = 0xFFFFFF80A49357C0)
-001|context_switch(inline)
-001|__schedule(?)
-002|schedule()
-003|blk_queue_enter(q = 0xFFFFFF815B69E938, flags = 0)
-004|generic_make_request(?)
-005|submit_bio(bio = 0xFFFFFF80A8195B80)
Link: https://lore.kernel.org/r/1588740936-28846-1-git-send-email-cang@codeaurora.org
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Can Guo <cang@codeaurora.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2020-05-06 12:55:35 +08:00
|
|
|
if (was_runtime_suspended)
|
|
|
|
blk_post_runtime_resume(sdev->request_queue, 0);
|
|
|
|
else
|
|
|
|
blk_set_runtime_active(sdev->request_queue);
|
2019-01-03 22:08:05 +08:00
|
|
|
}
|
2014-04-11 06:30:35 +08:00
|
|
|
}
|
|
|
|
|
2010-06-17 22:36:49 +08:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2012-11-09 15:27:54 +08:00
|
|
|
static int
|
2014-04-11 06:30:35 +08:00
|
|
|
scsi_bus_suspend_common(struct device *dev,
|
|
|
|
int (*cb)(struct device *, const struct dev_pm_ops *))
|
2010-06-17 22:36:49 +08:00
|
|
|
{
|
|
|
|
int err = 0;
|
|
|
|
|
2011-12-05 09:20:25 +08:00
|
|
|
if (scsi_is_sdev_device(dev)) {
|
|
|
|
/*
|
2012-11-09 15:27:54 +08:00
|
|
|
* All the high-level SCSI drivers that implement runtime
|
|
|
|
* PM treat runtime suspend, system suspend, and system
|
2013-09-16 19:28:15 +08:00
|
|
|
* hibernate nearly identically. In all cases the requirements
|
|
|
|
* for runtime suspension are stricter.
|
2011-12-05 09:20:25 +08:00
|
|
|
*/
|
2012-11-09 15:27:54 +08:00
|
|
|
if (pm_runtime_suspended(dev))
|
|
|
|
return 0;
|
2011-12-05 09:20:25 +08:00
|
|
|
|
2012-11-09 15:27:54 +08:00
|
|
|
err = scsi_dev_type_suspend(dev, cb);
|
2011-12-05 09:20:25 +08:00
|
|
|
}
|
2012-11-09 15:27:54 +08:00
|
|
|
|
2010-06-17 22:36:49 +08:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2014-04-11 06:30:35 +08:00
|
|
|
static void async_sdev_resume(void *dev, async_cookie_t cookie)
|
2010-06-17 22:36:49 +08:00
|
|
|
{
|
2014-04-11 06:30:35 +08:00
|
|
|
scsi_dev_type_resume(dev, do_scsi_resume);
|
|
|
|
}
|
2010-06-17 22:36:49 +08:00
|
|
|
|
2014-04-11 06:30:35 +08:00
|
|
|
static void async_sdev_thaw(void *dev, async_cookie_t cookie)
|
|
|
|
{
|
|
|
|
scsi_dev_type_resume(dev, do_scsi_thaw);
|
|
|
|
}
|
2012-11-09 15:27:52 +08:00
|
|
|
|
2014-04-11 06:30:35 +08:00
|
|
|
static void async_sdev_restore(void *dev, async_cookie_t cookie)
|
|
|
|
{
|
|
|
|
scsi_dev_type_resume(dev, do_scsi_restore);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int scsi_bus_resume_common(struct device *dev,
|
|
|
|
int (*cb)(struct device *, const struct dev_pm_ops *))
|
|
|
|
{
|
|
|
|
async_func_t fn;
|
|
|
|
|
|
|
|
if (!scsi_is_sdev_device(dev))
|
|
|
|
fn = NULL;
|
|
|
|
else if (cb == do_scsi_resume)
|
|
|
|
fn = async_sdev_resume;
|
|
|
|
else if (cb == do_scsi_thaw)
|
|
|
|
fn = async_sdev_thaw;
|
|
|
|
else if (cb == do_scsi_restore)
|
|
|
|
fn = async_sdev_restore;
|
|
|
|
else
|
|
|
|
fn = NULL;
|
|
|
|
|
|
|
|
if (fn) {
|
|
|
|
async_schedule_domain(fn, dev, &scsi_sd_pm_domain);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If a user has disabled async probing a likely reason
|
|
|
|
* is due to a storage enclosure that does not inject
|
|
|
|
* staggered spin-ups. For safety, make resume
|
|
|
|
* synchronous as well in that case.
|
|
|
|
*/
|
|
|
|
if (strncmp(scsi_scan_type, "async", 5) != 0)
|
|
|
|
async_synchronize_full_domain(&scsi_sd_pm_domain);
|
|
|
|
} else {
|
[SCSI] implement runtime Power Management
This patch (as1398b) adds runtime PM support to the SCSI layer. Only
the machanism is provided; use of it is up to the various high-level
drivers, and the patch doesn't change any of them. Except for sg --
the patch expicitly prevents a device from being runtime-suspended
while its sg device file is open.
The implementation is simplistic. In general, hosts and targets are
automatically suspended when all their children are asleep, but for
them the runtime-suspend code doesn't actually do anything. (A host's
runtime PM status is propagated up the device tree, though, so a
runtime-PM-aware lower-level driver could power down the host adapter
hardware at the appropriate times.) There are comments indicating
where a transport class might be notified or some other hooks added.
LUNs are runtime-suspended by calling the drivers' existing suspend
handlers (and likewise for runtime-resume). Somewhat arbitrarily, the
implementation delays for 100 ms before suspending an eligible LUN.
This is because there typically are occasions during bootup when the
same device file is opened and closed several times in quick
succession.
The way this all works is that the SCSI core increments a device's
PM-usage count when it is registered. If a high-level driver does
nothing then the device will not be eligible for runtime-suspend
because of the elevated usage count. If a high-level driver wants to
use runtime PM then it can call scsi_autopm_put_device() in its probe
routine to decrement the usage count and scsi_autopm_get_device() in
its remove routine to restore the original count.
Hosts, targets, and LUNs are not suspended while they are being probed
or removed, or while the error handler is running. In fact, a fairly
large part of the patch consists of code to make sure that things
aren't suspended at such times.
[jejb: fix up compile issues in PM config variations]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-06-17 22:41:42 +08:00
|
|
|
pm_runtime_disable(dev);
|
|
|
|
pm_runtime_set_active(dev);
|
|
|
|
pm_runtime_enable(dev);
|
|
|
|
}
|
2014-04-11 06:30:35 +08:00
|
|
|
return 0;
|
2010-06-17 22:36:49 +08:00
|
|
|
}
|
|
|
|
|
[SCSI] scsi_pm: Fix bug in the SCSI power management handler
This patch (as1520) fixes a bug in the SCSI layer's power management
implementation.
LUN scanning can be carried out asynchronously in do_scan_async(), and
sd uses an asynchronous thread for the time-consuming parts of disk
probing in sd_probe_async(). Currently nothing coordinates these
async threads with system sleep transitions; they can and do attempt
to continue scanning/probing SCSI devices even after the host adapter
has been suspended. As one might expect, the outcome is not ideal.
This is what the "prepare" stage of system suspend was created for.
After the prepare callback has been called for a host, target, or
device, drivers are not allowed to register any children underneath
them. Currently the SCSI prepare callback is not implemented; this
patch rectifies that omission.
For SCSI hosts, the prepare routine calls scsi_complete_async_scans()
to wait until async scanning is finished. It might be slightly more
efficient to wait only until the host in question has been scanned,
but there's currently no way to do that. Besides, during a sleep
transition we will ultimately have to wait until all the host scanning
has finished anyway.
For SCSI devices, the prepare routine calls async_synchronize_full()
to wait until sd probing is finished. The routine does nothing for
SCSI targets, because asynchronous target scanning is done only as
part of host scanning.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: <stable@kernel.org>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
2012-02-18 05:25:08 +08:00
|
|
|
static int scsi_bus_prepare(struct device *dev)
|
|
|
|
{
|
2019-05-01 05:39:18 +08:00
|
|
|
if (scsi_is_host_device(dev)) {
|
[SCSI] scsi_pm: Fix bug in the SCSI power management handler
This patch (as1520) fixes a bug in the SCSI layer's power management
implementation.
LUN scanning can be carried out asynchronously in do_scan_async(), and
sd uses an asynchronous thread for the time-consuming parts of disk
probing in sd_probe_async(). Currently nothing coordinates these
async threads with system sleep transitions; they can and do attempt
to continue scanning/probing SCSI devices even after the host adapter
has been suspended. As one might expect, the outcome is not ideal.
This is what the "prepare" stage of system suspend was created for.
After the prepare callback has been called for a host, target, or
device, drivers are not allowed to register any children underneath
them. Currently the SCSI prepare callback is not implemented; this
patch rectifies that omission.
For SCSI hosts, the prepare routine calls scsi_complete_async_scans()
to wait until async scanning is finished. It might be slightly more
efficient to wait only until the host in question has been scanned,
but there's currently no way to do that. Besides, during a sleep
transition we will ultimately have to wait until all the host scanning
has finished anyway.
For SCSI devices, the prepare routine calls async_synchronize_full()
to wait until sd probing is finished. The routine does nothing for
SCSI targets, because asynchronous target scanning is done only as
part of host scanning.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: <stable@kernel.org>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
2012-02-18 05:25:08 +08:00
|
|
|
/* Wait until async scanning is finished */
|
|
|
|
scsi_complete_async_scans();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-06-17 22:36:49 +08:00
|
|
|
static int scsi_bus_suspend(struct device *dev)
|
|
|
|
{
|
2014-04-11 06:30:35 +08:00
|
|
|
return scsi_bus_suspend_common(dev, do_scsi_suspend);
|
2012-11-09 15:27:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int scsi_bus_resume(struct device *dev)
|
|
|
|
{
|
2014-04-11 06:30:35 +08:00
|
|
|
return scsi_bus_resume_common(dev, do_scsi_resume);
|
2010-06-17 22:36:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int scsi_bus_freeze(struct device *dev)
|
|
|
|
{
|
2014-04-11 06:30:35 +08:00
|
|
|
return scsi_bus_suspend_common(dev, do_scsi_freeze);
|
2012-11-09 15:27:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int scsi_bus_thaw(struct device *dev)
|
|
|
|
{
|
2014-04-11 06:30:35 +08:00
|
|
|
return scsi_bus_resume_common(dev, do_scsi_thaw);
|
2010-06-17 22:36:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int scsi_bus_poweroff(struct device *dev)
|
|
|
|
{
|
2014-04-11 06:30:35 +08:00
|
|
|
return scsi_bus_suspend_common(dev, do_scsi_poweroff);
|
2012-11-09 15:27:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int scsi_bus_restore(struct device *dev)
|
|
|
|
{
|
2014-04-11 06:30:35 +08:00
|
|
|
return scsi_bus_resume_common(dev, do_scsi_restore);
|
2010-06-17 22:36:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#else /* CONFIG_PM_SLEEP */
|
|
|
|
|
[SCSI] scsi_pm: Fix bug in the SCSI power management handler
This patch (as1520) fixes a bug in the SCSI layer's power management
implementation.
LUN scanning can be carried out asynchronously in do_scan_async(), and
sd uses an asynchronous thread for the time-consuming parts of disk
probing in sd_probe_async(). Currently nothing coordinates these
async threads with system sleep transitions; they can and do attempt
to continue scanning/probing SCSI devices even after the host adapter
has been suspended. As one might expect, the outcome is not ideal.
This is what the "prepare" stage of system suspend was created for.
After the prepare callback has been called for a host, target, or
device, drivers are not allowed to register any children underneath
them. Currently the SCSI prepare callback is not implemented; this
patch rectifies that omission.
For SCSI hosts, the prepare routine calls scsi_complete_async_scans()
to wait until async scanning is finished. It might be slightly more
efficient to wait only until the host in question has been scanned,
but there's currently no way to do that. Besides, during a sleep
transition we will ultimately have to wait until all the host scanning
has finished anyway.
For SCSI devices, the prepare routine calls async_synchronize_full()
to wait until sd probing is finished. The routine does nothing for
SCSI targets, because asynchronous target scanning is done only as
part of host scanning.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: <stable@kernel.org>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
2012-02-18 05:25:08 +08:00
|
|
|
#define scsi_bus_prepare NULL
|
2010-06-17 22:36:49 +08:00
|
|
|
#define scsi_bus_suspend NULL
|
2012-11-09 15:27:54 +08:00
|
|
|
#define scsi_bus_resume NULL
|
2010-06-17 22:36:49 +08:00
|
|
|
#define scsi_bus_freeze NULL
|
2012-11-09 15:27:54 +08:00
|
|
|
#define scsi_bus_thaw NULL
|
2010-06-17 22:36:49 +08:00
|
|
|
#define scsi_bus_poweroff NULL
|
2012-11-09 15:27:54 +08:00
|
|
|
#define scsi_bus_restore NULL
|
2010-06-17 22:36:49 +08:00
|
|
|
|
|
|
|
#endif /* CONFIG_PM_SLEEP */
|
|
|
|
|
2013-10-28 15:27:49 +08:00
|
|
|
static int sdev_runtime_suspend(struct device *dev)
|
2013-03-23 11:42:28 +08:00
|
|
|
{
|
2013-10-28 15:27:49 +08:00
|
|
|
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
|
|
|
|
struct scsi_device *sdev = to_scsi_device(dev);
|
2015-08-17 23:02:42 +08:00
|
|
|
int err = 0;
|
2013-03-23 11:42:28 +08:00
|
|
|
|
2015-12-01 14:45:23 +08:00
|
|
|
err = blk_pre_runtime_suspend(sdev->request_queue);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
if (pm && pm->runtime_suspend)
|
2013-10-28 15:27:49 +08:00
|
|
|
err = pm->runtime_suspend(dev);
|
2015-12-01 14:45:23 +08:00
|
|
|
blk_post_runtime_suspend(sdev->request_queue, err);
|
|
|
|
|
2013-03-23 11:42:28 +08:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
[SCSI] implement runtime Power Management
This patch (as1398b) adds runtime PM support to the SCSI layer. Only
the machanism is provided; use of it is up to the various high-level
drivers, and the patch doesn't change any of them. Except for sg --
the patch expicitly prevents a device from being runtime-suspended
while its sg device file is open.
The implementation is simplistic. In general, hosts and targets are
automatically suspended when all their children are asleep, but for
them the runtime-suspend code doesn't actually do anything. (A host's
runtime PM status is propagated up the device tree, though, so a
runtime-PM-aware lower-level driver could power down the host adapter
hardware at the appropriate times.) There are comments indicating
where a transport class might be notified or some other hooks added.
LUNs are runtime-suspended by calling the drivers' existing suspend
handlers (and likewise for runtime-resume). Somewhat arbitrarily, the
implementation delays for 100 ms before suspending an eligible LUN.
This is because there typically are occasions during bootup when the
same device file is opened and closed several times in quick
succession.
The way this all works is that the SCSI core increments a device's
PM-usage count when it is registered. If a high-level driver does
nothing then the device will not be eligible for runtime-suspend
because of the elevated usage count. If a high-level driver wants to
use runtime PM then it can call scsi_autopm_put_device() in its probe
routine to decrement the usage count and scsi_autopm_get_device() in
its remove routine to restore the original count.
Hosts, targets, and LUNs are not suspended while they are being probed
or removed, or while the error handler is running. In fact, a fairly
large part of the patch consists of code to make sure that things
aren't suspended at such times.
[jejb: fix up compile issues in PM config variations]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-06-17 22:41:42 +08:00
|
|
|
static int scsi_runtime_suspend(struct device *dev)
|
|
|
|
{
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
dev_dbg(dev, "scsi_runtime_suspend\n");
|
2013-03-23 11:42:28 +08:00
|
|
|
if (scsi_is_sdev_device(dev))
|
|
|
|
err = sdev_runtime_suspend(dev);
|
[SCSI] implement runtime Power Management
This patch (as1398b) adds runtime PM support to the SCSI layer. Only
the machanism is provided; use of it is up to the various high-level
drivers, and the patch doesn't change any of them. Except for sg --
the patch expicitly prevents a device from being runtime-suspended
while its sg device file is open.
The implementation is simplistic. In general, hosts and targets are
automatically suspended when all their children are asleep, but for
them the runtime-suspend code doesn't actually do anything. (A host's
runtime PM status is propagated up the device tree, though, so a
runtime-PM-aware lower-level driver could power down the host adapter
hardware at the appropriate times.) There are comments indicating
where a transport class might be notified or some other hooks added.
LUNs are runtime-suspended by calling the drivers' existing suspend
handlers (and likewise for runtime-resume). Somewhat arbitrarily, the
implementation delays for 100 ms before suspending an eligible LUN.
This is because there typically are occasions during bootup when the
same device file is opened and closed several times in quick
succession.
The way this all works is that the SCSI core increments a device's
PM-usage count when it is registered. If a high-level driver does
nothing then the device will not be eligible for runtime-suspend
because of the elevated usage count. If a high-level driver wants to
use runtime PM then it can call scsi_autopm_put_device() in its probe
routine to decrement the usage count and scsi_autopm_get_device() in
its remove routine to restore the original count.
Hosts, targets, and LUNs are not suspended while they are being probed
or removed, or while the error handler is running. In fact, a fairly
large part of the patch consists of code to make sure that things
aren't suspended at such times.
[jejb: fix up compile issues in PM config variations]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-06-17 22:41:42 +08:00
|
|
|
|
|
|
|
/* Insert hooks here for targets, hosts, and transport classes */
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2013-10-28 15:27:49 +08:00
|
|
|
static int sdev_runtime_resume(struct device *dev)
|
[SCSI] implement runtime Power Management
This patch (as1398b) adds runtime PM support to the SCSI layer. Only
the machanism is provided; use of it is up to the various high-level
drivers, and the patch doesn't change any of them. Except for sg --
the patch expicitly prevents a device from being runtime-suspended
while its sg device file is open.
The implementation is simplistic. In general, hosts and targets are
automatically suspended when all their children are asleep, but for
them the runtime-suspend code doesn't actually do anything. (A host's
runtime PM status is propagated up the device tree, though, so a
runtime-PM-aware lower-level driver could power down the host adapter
hardware at the appropriate times.) There are comments indicating
where a transport class might be notified or some other hooks added.
LUNs are runtime-suspended by calling the drivers' existing suspend
handlers (and likewise for runtime-resume). Somewhat arbitrarily, the
implementation delays for 100 ms before suspending an eligible LUN.
This is because there typically are occasions during bootup when the
same device file is opened and closed several times in quick
succession.
The way this all works is that the SCSI core increments a device's
PM-usage count when it is registered. If a high-level driver does
nothing then the device will not be eligible for runtime-suspend
because of the elevated usage count. If a high-level driver wants to
use runtime PM then it can call scsi_autopm_put_device() in its probe
routine to decrement the usage count and scsi_autopm_get_device() in
its remove routine to restore the original count.
Hosts, targets, and LUNs are not suspended while they are being probed
or removed, or while the error handler is running. In fact, a fairly
large part of the patch consists of code to make sure that things
aren't suspended at such times.
[jejb: fix up compile issues in PM config variations]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-06-17 22:41:42 +08:00
|
|
|
{
|
2013-10-28 15:27:49 +08:00
|
|
|
struct scsi_device *sdev = to_scsi_device(dev);
|
|
|
|
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
|
[SCSI] implement runtime Power Management
This patch (as1398b) adds runtime PM support to the SCSI layer. Only
the machanism is provided; use of it is up to the various high-level
drivers, and the patch doesn't change any of them. Except for sg --
the patch expicitly prevents a device from being runtime-suspended
while its sg device file is open.
The implementation is simplistic. In general, hosts and targets are
automatically suspended when all their children are asleep, but for
them the runtime-suspend code doesn't actually do anything. (A host's
runtime PM status is propagated up the device tree, though, so a
runtime-PM-aware lower-level driver could power down the host adapter
hardware at the appropriate times.) There are comments indicating
where a transport class might be notified or some other hooks added.
LUNs are runtime-suspended by calling the drivers' existing suspend
handlers (and likewise for runtime-resume). Somewhat arbitrarily, the
implementation delays for 100 ms before suspending an eligible LUN.
This is because there typically are occasions during bootup when the
same device file is opened and closed several times in quick
succession.
The way this all works is that the SCSI core increments a device's
PM-usage count when it is registered. If a high-level driver does
nothing then the device will not be eligible for runtime-suspend
because of the elevated usage count. If a high-level driver wants to
use runtime PM then it can call scsi_autopm_put_device() in its probe
routine to decrement the usage count and scsi_autopm_get_device() in
its remove routine to restore the original count.
Hosts, targets, and LUNs are not suspended while they are being probed
or removed, or while the error handler is running. In fact, a fairly
large part of the patch consists of code to make sure that things
aren't suspended at such times.
[jejb: fix up compile issues in PM config variations]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-06-17 22:41:42 +08:00
|
|
|
int err = 0;
|
2013-03-23 11:42:28 +08:00
|
|
|
|
2015-12-01 14:45:23 +08:00
|
|
|
blk_pre_runtime_resume(sdev->request_queue);
|
|
|
|
if (pm && pm->runtime_resume)
|
2013-10-28 15:27:49 +08:00
|
|
|
err = pm->runtime_resume(dev);
|
2015-12-01 14:45:23 +08:00
|
|
|
blk_post_runtime_resume(sdev->request_queue, err);
|
|
|
|
|
2013-03-23 11:42:28 +08:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int scsi_runtime_resume(struct device *dev)
|
|
|
|
{
|
|
|
|
int err = 0;
|
[SCSI] implement runtime Power Management
This patch (as1398b) adds runtime PM support to the SCSI layer. Only
the machanism is provided; use of it is up to the various high-level
drivers, and the patch doesn't change any of them. Except for sg --
the patch expicitly prevents a device from being runtime-suspended
while its sg device file is open.
The implementation is simplistic. In general, hosts and targets are
automatically suspended when all their children are asleep, but for
them the runtime-suspend code doesn't actually do anything. (A host's
runtime PM status is propagated up the device tree, though, so a
runtime-PM-aware lower-level driver could power down the host adapter
hardware at the appropriate times.) There are comments indicating
where a transport class might be notified or some other hooks added.
LUNs are runtime-suspended by calling the drivers' existing suspend
handlers (and likewise for runtime-resume). Somewhat arbitrarily, the
implementation delays for 100 ms before suspending an eligible LUN.
This is because there typically are occasions during bootup when the
same device file is opened and closed several times in quick
succession.
The way this all works is that the SCSI core increments a device's
PM-usage count when it is registered. If a high-level driver does
nothing then the device will not be eligible for runtime-suspend
because of the elevated usage count. If a high-level driver wants to
use runtime PM then it can call scsi_autopm_put_device() in its probe
routine to decrement the usage count and scsi_autopm_get_device() in
its remove routine to restore the original count.
Hosts, targets, and LUNs are not suspended while they are being probed
or removed, or while the error handler is running. In fact, a fairly
large part of the patch consists of code to make sure that things
aren't suspended at such times.
[jejb: fix up compile issues in PM config variations]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-06-17 22:41:42 +08:00
|
|
|
|
|
|
|
dev_dbg(dev, "scsi_runtime_resume\n");
|
|
|
|
if (scsi_is_sdev_device(dev))
|
2013-03-23 11:42:28 +08:00
|
|
|
err = sdev_runtime_resume(dev);
|
[SCSI] implement runtime Power Management
This patch (as1398b) adds runtime PM support to the SCSI layer. Only
the machanism is provided; use of it is up to the various high-level
drivers, and the patch doesn't change any of them. Except for sg --
the patch expicitly prevents a device from being runtime-suspended
while its sg device file is open.
The implementation is simplistic. In general, hosts and targets are
automatically suspended when all their children are asleep, but for
them the runtime-suspend code doesn't actually do anything. (A host's
runtime PM status is propagated up the device tree, though, so a
runtime-PM-aware lower-level driver could power down the host adapter
hardware at the appropriate times.) There are comments indicating
where a transport class might be notified or some other hooks added.
LUNs are runtime-suspended by calling the drivers' existing suspend
handlers (and likewise for runtime-resume). Somewhat arbitrarily, the
implementation delays for 100 ms before suspending an eligible LUN.
This is because there typically are occasions during bootup when the
same device file is opened and closed several times in quick
succession.
The way this all works is that the SCSI core increments a device's
PM-usage count when it is registered. If a high-level driver does
nothing then the device will not be eligible for runtime-suspend
because of the elevated usage count. If a high-level driver wants to
use runtime PM then it can call scsi_autopm_put_device() in its probe
routine to decrement the usage count and scsi_autopm_get_device() in
its remove routine to restore the original count.
Hosts, targets, and LUNs are not suspended while they are being probed
or removed, or while the error handler is running. In fact, a fairly
large part of the patch consists of code to make sure that things
aren't suspended at such times.
[jejb: fix up compile issues in PM config variations]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-06-17 22:41:42 +08:00
|
|
|
|
|
|
|
/* Insert hooks here for targets, hosts, and transport classes */
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int scsi_runtime_idle(struct device *dev)
|
|
|
|
{
|
|
|
|
dev_dbg(dev, "scsi_runtime_idle\n");
|
|
|
|
|
|
|
|
/* Insert hooks here for targets, hosts, and transport classes */
|
|
|
|
|
2013-03-23 11:42:28 +08:00
|
|
|
if (scsi_is_sdev_device(dev)) {
|
2013-10-28 15:27:49 +08:00
|
|
|
pm_runtime_mark_last_busy(dev);
|
|
|
|
pm_runtime_autosuspend(dev);
|
|
|
|
return -EBUSY;
|
2013-03-23 11:42:28 +08:00
|
|
|
}
|
2013-10-28 15:27:49 +08:00
|
|
|
|
PM / Runtime: Rework the "runtime idle" helper routine
The "runtime idle" helper routine, rpm_idle(), currently ignores
return values from .runtime_idle() callbacks executed by it.
However, it turns out that many subsystems use
pm_generic_runtime_idle() which checks the return value of the
driver's callback and executes pm_runtime_suspend() for the device
unless that value is not 0. If that logic is moved to rpm_idle()
instead, pm_generic_runtime_idle() can be dropped and its users
will not need any .runtime_idle() callbacks any more.
Moreover, the PCI, SCSI, and SATA subsystems' .runtime_idle()
routines, pci_pm_runtime_idle(), scsi_runtime_idle(), and
ata_port_runtime_idle(), respectively, as well as a few drivers'
ones may be simplified if rpm_idle() calls rpm_suspend() after 0 has
been returned by the .runtime_idle() callback executed by it.
To reduce overall code bloat, make the changes described above.
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Tested-by: Kevin Hilman <khilman@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Kevin Hilman <khilman@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
2013-06-04 03:49:52 +08:00
|
|
|
return 0;
|
[SCSI] implement runtime Power Management
This patch (as1398b) adds runtime PM support to the SCSI layer. Only
the machanism is provided; use of it is up to the various high-level
drivers, and the patch doesn't change any of them. Except for sg --
the patch expicitly prevents a device from being runtime-suspended
while its sg device file is open.
The implementation is simplistic. In general, hosts and targets are
automatically suspended when all their children are asleep, but for
them the runtime-suspend code doesn't actually do anything. (A host's
runtime PM status is propagated up the device tree, though, so a
runtime-PM-aware lower-level driver could power down the host adapter
hardware at the appropriate times.) There are comments indicating
where a transport class might be notified or some other hooks added.
LUNs are runtime-suspended by calling the drivers' existing suspend
handlers (and likewise for runtime-resume). Somewhat arbitrarily, the
implementation delays for 100 ms before suspending an eligible LUN.
This is because there typically are occasions during bootup when the
same device file is opened and closed several times in quick
succession.
The way this all works is that the SCSI core increments a device's
PM-usage count when it is registered. If a high-level driver does
nothing then the device will not be eligible for runtime-suspend
because of the elevated usage count. If a high-level driver wants to
use runtime PM then it can call scsi_autopm_put_device() in its probe
routine to decrement the usage count and scsi_autopm_get_device() in
its remove routine to restore the original count.
Hosts, targets, and LUNs are not suspended while they are being probed
or removed, or while the error handler is running. In fact, a fairly
large part of the patch consists of code to make sure that things
aren't suspended at such times.
[jejb: fix up compile issues in PM config variations]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-06-17 22:41:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int scsi_autopm_get_device(struct scsi_device *sdev)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = pm_runtime_get_sync(&sdev->sdev_gendev);
|
2011-07-02 04:29:15 +08:00
|
|
|
if (err < 0 && err !=-EACCES)
|
[SCSI] implement runtime Power Management
This patch (as1398b) adds runtime PM support to the SCSI layer. Only
the machanism is provided; use of it is up to the various high-level
drivers, and the patch doesn't change any of them. Except for sg --
the patch expicitly prevents a device from being runtime-suspended
while its sg device file is open.
The implementation is simplistic. In general, hosts and targets are
automatically suspended when all their children are asleep, but for
them the runtime-suspend code doesn't actually do anything. (A host's
runtime PM status is propagated up the device tree, though, so a
runtime-PM-aware lower-level driver could power down the host adapter
hardware at the appropriate times.) There are comments indicating
where a transport class might be notified or some other hooks added.
LUNs are runtime-suspended by calling the drivers' existing suspend
handlers (and likewise for runtime-resume). Somewhat arbitrarily, the
implementation delays for 100 ms before suspending an eligible LUN.
This is because there typically are occasions during bootup when the
same device file is opened and closed several times in quick
succession.
The way this all works is that the SCSI core increments a device's
PM-usage count when it is registered. If a high-level driver does
nothing then the device will not be eligible for runtime-suspend
because of the elevated usage count. If a high-level driver wants to
use runtime PM then it can call scsi_autopm_put_device() in its probe
routine to decrement the usage count and scsi_autopm_get_device() in
its remove routine to restore the original count.
Hosts, targets, and LUNs are not suspended while they are being probed
or removed, or while the error handler is running. In fact, a fairly
large part of the patch consists of code to make sure that things
aren't suspended at such times.
[jejb: fix up compile issues in PM config variations]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-06-17 22:41:42 +08:00
|
|
|
pm_runtime_put_sync(&sdev->sdev_gendev);
|
2011-07-02 04:29:15 +08:00
|
|
|
else
|
[SCSI] implement runtime Power Management
This patch (as1398b) adds runtime PM support to the SCSI layer. Only
the machanism is provided; use of it is up to the various high-level
drivers, and the patch doesn't change any of them. Except for sg --
the patch expicitly prevents a device from being runtime-suspended
while its sg device file is open.
The implementation is simplistic. In general, hosts and targets are
automatically suspended when all their children are asleep, but for
them the runtime-suspend code doesn't actually do anything. (A host's
runtime PM status is propagated up the device tree, though, so a
runtime-PM-aware lower-level driver could power down the host adapter
hardware at the appropriate times.) There are comments indicating
where a transport class might be notified or some other hooks added.
LUNs are runtime-suspended by calling the drivers' existing suspend
handlers (and likewise for runtime-resume). Somewhat arbitrarily, the
implementation delays for 100 ms before suspending an eligible LUN.
This is because there typically are occasions during bootup when the
same device file is opened and closed several times in quick
succession.
The way this all works is that the SCSI core increments a device's
PM-usage count when it is registered. If a high-level driver does
nothing then the device will not be eligible for runtime-suspend
because of the elevated usage count. If a high-level driver wants to
use runtime PM then it can call scsi_autopm_put_device() in its probe
routine to decrement the usage count and scsi_autopm_get_device() in
its remove routine to restore the original count.
Hosts, targets, and LUNs are not suspended while they are being probed
or removed, or while the error handler is running. In fact, a fairly
large part of the patch consists of code to make sure that things
aren't suspended at such times.
[jejb: fix up compile issues in PM config variations]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-06-17 22:41:42 +08:00
|
|
|
err = 0;
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(scsi_autopm_get_device);
|
|
|
|
|
|
|
|
void scsi_autopm_put_device(struct scsi_device *sdev)
|
|
|
|
{
|
|
|
|
pm_runtime_put_sync(&sdev->sdev_gendev);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(scsi_autopm_put_device);
|
|
|
|
|
|
|
|
void scsi_autopm_get_target(struct scsi_target *starget)
|
|
|
|
{
|
|
|
|
pm_runtime_get_sync(&starget->dev);
|
|
|
|
}
|
|
|
|
|
|
|
|
void scsi_autopm_put_target(struct scsi_target *starget)
|
|
|
|
{
|
|
|
|
pm_runtime_put_sync(&starget->dev);
|
|
|
|
}
|
|
|
|
|
|
|
|
int scsi_autopm_get_host(struct Scsi_Host *shost)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = pm_runtime_get_sync(&shost->shost_gendev);
|
2011-07-02 04:29:15 +08:00
|
|
|
if (err < 0 && err !=-EACCES)
|
[SCSI] implement runtime Power Management
This patch (as1398b) adds runtime PM support to the SCSI layer. Only
the machanism is provided; use of it is up to the various high-level
drivers, and the patch doesn't change any of them. Except for sg --
the patch expicitly prevents a device from being runtime-suspended
while its sg device file is open.
The implementation is simplistic. In general, hosts and targets are
automatically suspended when all their children are asleep, but for
them the runtime-suspend code doesn't actually do anything. (A host's
runtime PM status is propagated up the device tree, though, so a
runtime-PM-aware lower-level driver could power down the host adapter
hardware at the appropriate times.) There are comments indicating
where a transport class might be notified or some other hooks added.
LUNs are runtime-suspended by calling the drivers' existing suspend
handlers (and likewise for runtime-resume). Somewhat arbitrarily, the
implementation delays for 100 ms before suspending an eligible LUN.
This is because there typically are occasions during bootup when the
same device file is opened and closed several times in quick
succession.
The way this all works is that the SCSI core increments a device's
PM-usage count when it is registered. If a high-level driver does
nothing then the device will not be eligible for runtime-suspend
because of the elevated usage count. If a high-level driver wants to
use runtime PM then it can call scsi_autopm_put_device() in its probe
routine to decrement the usage count and scsi_autopm_get_device() in
its remove routine to restore the original count.
Hosts, targets, and LUNs are not suspended while they are being probed
or removed, or while the error handler is running. In fact, a fairly
large part of the patch consists of code to make sure that things
aren't suspended at such times.
[jejb: fix up compile issues in PM config variations]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-06-17 22:41:42 +08:00
|
|
|
pm_runtime_put_sync(&shost->shost_gendev);
|
2011-07-02 04:29:15 +08:00
|
|
|
else
|
[SCSI] implement runtime Power Management
This patch (as1398b) adds runtime PM support to the SCSI layer. Only
the machanism is provided; use of it is up to the various high-level
drivers, and the patch doesn't change any of them. Except for sg --
the patch expicitly prevents a device from being runtime-suspended
while its sg device file is open.
The implementation is simplistic. In general, hosts and targets are
automatically suspended when all their children are asleep, but for
them the runtime-suspend code doesn't actually do anything. (A host's
runtime PM status is propagated up the device tree, though, so a
runtime-PM-aware lower-level driver could power down the host adapter
hardware at the appropriate times.) There are comments indicating
where a transport class might be notified or some other hooks added.
LUNs are runtime-suspended by calling the drivers' existing suspend
handlers (and likewise for runtime-resume). Somewhat arbitrarily, the
implementation delays for 100 ms before suspending an eligible LUN.
This is because there typically are occasions during bootup when the
same device file is opened and closed several times in quick
succession.
The way this all works is that the SCSI core increments a device's
PM-usage count when it is registered. If a high-level driver does
nothing then the device will not be eligible for runtime-suspend
because of the elevated usage count. If a high-level driver wants to
use runtime PM then it can call scsi_autopm_put_device() in its probe
routine to decrement the usage count and scsi_autopm_get_device() in
its remove routine to restore the original count.
Hosts, targets, and LUNs are not suspended while they are being probed
or removed, or while the error handler is running. In fact, a fairly
large part of the patch consists of code to make sure that things
aren't suspended at such times.
[jejb: fix up compile issues in PM config variations]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-06-17 22:41:42 +08:00
|
|
|
err = 0;
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
void scsi_autopm_put_host(struct Scsi_Host *shost)
|
|
|
|
{
|
|
|
|
pm_runtime_put_sync(&shost->shost_gendev);
|
|
|
|
}
|
|
|
|
|
2010-06-17 22:36:49 +08:00
|
|
|
const struct dev_pm_ops scsi_bus_pm_ops = {
|
[SCSI] scsi_pm: Fix bug in the SCSI power management handler
This patch (as1520) fixes a bug in the SCSI layer's power management
implementation.
LUN scanning can be carried out asynchronously in do_scan_async(), and
sd uses an asynchronous thread for the time-consuming parts of disk
probing in sd_probe_async(). Currently nothing coordinates these
async threads with system sleep transitions; they can and do attempt
to continue scanning/probing SCSI devices even after the host adapter
has been suspended. As one might expect, the outcome is not ideal.
This is what the "prepare" stage of system suspend was created for.
After the prepare callback has been called for a host, target, or
device, drivers are not allowed to register any children underneath
them. Currently the SCSI prepare callback is not implemented; this
patch rectifies that omission.
For SCSI hosts, the prepare routine calls scsi_complete_async_scans()
to wait until async scanning is finished. It might be slightly more
efficient to wait only until the host in question has been scanned,
but there's currently no way to do that. Besides, during a sleep
transition we will ultimately have to wait until all the host scanning
has finished anyway.
For SCSI devices, the prepare routine calls async_synchronize_full()
to wait until sd probing is finished. The routine does nothing for
SCSI targets, because asynchronous target scanning is done only as
part of host scanning.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: <stable@kernel.org>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
2012-02-18 05:25:08 +08:00
|
|
|
.prepare = scsi_bus_prepare,
|
2010-06-17 22:36:49 +08:00
|
|
|
.suspend = scsi_bus_suspend,
|
2012-11-09 15:27:54 +08:00
|
|
|
.resume = scsi_bus_resume,
|
2010-06-17 22:36:49 +08:00
|
|
|
.freeze = scsi_bus_freeze,
|
2012-11-09 15:27:54 +08:00
|
|
|
.thaw = scsi_bus_thaw,
|
2010-06-17 22:36:49 +08:00
|
|
|
.poweroff = scsi_bus_poweroff,
|
2012-11-09 15:27:54 +08:00
|
|
|
.restore = scsi_bus_restore,
|
[SCSI] implement runtime Power Management
This patch (as1398b) adds runtime PM support to the SCSI layer. Only
the machanism is provided; use of it is up to the various high-level
drivers, and the patch doesn't change any of them. Except for sg --
the patch expicitly prevents a device from being runtime-suspended
while its sg device file is open.
The implementation is simplistic. In general, hosts and targets are
automatically suspended when all their children are asleep, but for
them the runtime-suspend code doesn't actually do anything. (A host's
runtime PM status is propagated up the device tree, though, so a
runtime-PM-aware lower-level driver could power down the host adapter
hardware at the appropriate times.) There are comments indicating
where a transport class might be notified or some other hooks added.
LUNs are runtime-suspended by calling the drivers' existing suspend
handlers (and likewise for runtime-resume). Somewhat arbitrarily, the
implementation delays for 100 ms before suspending an eligible LUN.
This is because there typically are occasions during bootup when the
same device file is opened and closed several times in quick
succession.
The way this all works is that the SCSI core increments a device's
PM-usage count when it is registered. If a high-level driver does
nothing then the device will not be eligible for runtime-suspend
because of the elevated usage count. If a high-level driver wants to
use runtime PM then it can call scsi_autopm_put_device() in its probe
routine to decrement the usage count and scsi_autopm_get_device() in
its remove routine to restore the original count.
Hosts, targets, and LUNs are not suspended while they are being probed
or removed, or while the error handler is running. In fact, a fairly
large part of the patch consists of code to make sure that things
aren't suspended at such times.
[jejb: fix up compile issues in PM config variations]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
2010-06-17 22:41:42 +08:00
|
|
|
.runtime_suspend = scsi_runtime_suspend,
|
|
|
|
.runtime_resume = scsi_runtime_resume,
|
|
|
|
.runtime_idle = scsi_runtime_idle,
|
2010-06-17 22:36:49 +08:00
|
|
|
};
|