* [PATCH v5 1/6] ata: make ata port as parent device of scsi host
2011-12-05 1:20 [PATCH v5 0/6] ata port runtime power management support Lin Ming
@ 2011-12-05 1:20 ` Lin Ming
2011-12-07 20:04 ` Jeff Garzik
2011-12-05 1:20 ` [PATCH v5 2/6] [SCSI] add flag to skip the runtime PM calls on the host Lin Ming
` (4 subsequent siblings)
5 siblings, 1 reply; 15+ messages in thread
From: Lin Ming @ 2011-12-05 1:20 UTC (permalink / raw)
To: Jeff Garzik, James Bottomley, Alan Stern, Tejun Heo
Cc: linux-kernel, linux-ide, linux-scsi, linux-pm, Rafael J. Wysocki,
Huang Ying, Zhang Rui
Currently, the device tree of ata port and scsi host looks as below,
/sys/devices/pci0000:00/0000:00:1f.2 (ahci controller)
|-- ata1 (ata port)
|-- host0 (scsi host)
|-- target0:0:0 (scsi target)
|-- 0:0:0:0 (disk)
This patch makes ata port as parent device of scsi host, then it becomes
/sys/devices/pci0000:00/0000:00:1f.2 (ahci controller)
|-- ata1 (ata port)
|-- host0 (scsi host)
|-- target0:0:0 (scsi target)
|-- 0:0:0:0 (disk)
With this change, the ata port runtime PM is easier.
For example, the ata port runtime suspend will happen as,
disk suspend --> scsi target suspend --> scsi host suspend --> ata port
suspend.
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
---
drivers/ata/libata-scsi.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 2a5412e..7ae1e77 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3398,7 +3398,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
*/
shost->max_host_blocked = 1;
- rc = scsi_add_host(ap->scsi_host, ap->host->dev);
+ rc = scsi_add_host(ap->scsi_host, &ap->tdev);
if (rc)
goto err_add;
}
--
1.7.2.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v5 1/6] ata: make ata port as parent device of scsi host
2011-12-05 1:20 ` [PATCH v5 1/6] ata: make ata port as parent device of scsi host Lin Ming
@ 2011-12-07 20:04 ` Jeff Garzik
0 siblings, 0 replies; 15+ messages in thread
From: Jeff Garzik @ 2011-12-07 20:04 UTC (permalink / raw)
To: Lin Ming
Cc: James Bottomley, Alan Stern, Tejun Heo, linux-kernel, linux-ide,
linux-scsi, linux-pm, Rafael J. Wysocki, Huang Ying, Zhang Rui
On 12/04/2011 08:20 PM, Lin Ming wrote:
> Currently, the device tree of ata port and scsi host looks as below,
>
> /sys/devices/pci0000:00/0000:00:1f.2 (ahci controller)
> |-- ata1 (ata port)
> |-- host0 (scsi host)
> |-- target0:0:0 (scsi target)
> |-- 0:0:0:0 (disk)
>
> This patch makes ata port as parent device of scsi host, then it becomes
>
> /sys/devices/pci0000:00/0000:00:1f.2 (ahci controller)
> |-- ata1 (ata port)
> |-- host0 (scsi host)
> |-- target0:0:0 (scsi target)
> |-- 0:0:0:0 (disk)
>
> With this change, the ata port runtime PM is easier.
> For example, the ata port runtime suspend will happen as,
>
> disk suspend --> scsi target suspend --> scsi host suspend --> ata port
> suspend.
>
> Acked-by: Tejun Heo<tj@kernel.org>
> Signed-off-by: Lin Ming<ming.m.lin@intel.com>
> ---
> drivers/ata/libata-scsi.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
applied 1-6, thanks
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v5 2/6] [SCSI] add flag to skip the runtime PM calls on the host
2011-12-05 1:20 [PATCH v5 0/6] ata port runtime power management support Lin Ming
2011-12-05 1:20 ` [PATCH v5 1/6] ata: make ata port as parent device of scsi host Lin Ming
@ 2011-12-05 1:20 ` Lin Ming
2011-12-05 1:20 ` [PATCH v5 3/6] [SCSI] check runtime PM status in system PM Lin Ming
` (3 subsequent siblings)
5 siblings, 0 replies; 15+ messages in thread
From: Lin Ming @ 2011-12-05 1:20 UTC (permalink / raw)
To: Jeff Garzik, James Bottomley, Alan Stern, Tejun Heo
Cc: linux-kernel, linux-ide, linux-scsi, linux-pm, Rafael J. Wysocki,
Huang Ying, Zhang Rui
With previous change, now the ata port runtime suspend will happen as:
disk suspend --> scsi target suspend --> scsi host suspend --> ata port
suspend
ata port(parent device) suspend need to schedule scsi EH which will resume
scsi host(child device). Then the child device resume will in turn make
parent device resume first. This is kind of recursive.
This patch adds a new flag Scsi_Host::eh_noresume.
ata port will set this flag to skip the runtime PM calls on scsi host.
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
---
drivers/scsi/scsi_error.c | 5 +++--
include/scsi/scsi_host.h | 3 +++
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index dc6131e..5f84a14 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1812,7 +1812,7 @@ int scsi_error_handler(void *data)
* what we need to do to get it up and online again (if we can).
* If we fail, we end up taking the thing offline.
*/
- if (scsi_autopm_get_host(shost) != 0) {
+ if (!shost->eh_noresume && scsi_autopm_get_host(shost) != 0) {
SCSI_LOG_ERROR_RECOVERY(1,
printk(KERN_ERR "Error handler scsi_eh_%d "
"unable to autoresume\n",
@@ -1833,7 +1833,8 @@ int scsi_error_handler(void *data)
* which are still online.
*/
scsi_restart_operations(shost);
- scsi_autopm_put_host(shost);
+ if (!shost->eh_noresume)
+ scsi_autopm_put_host(shost);
set_current_state(TASK_INTERRUPTIBLE);
}
__set_current_state(TASK_RUNNING);
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 50266c9..5f7d5b3 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -669,6 +669,9 @@ struct Scsi_Host {
/* Asynchronous scan in progress */
unsigned async_scan:1;
+ /* Don't resume host in EH */
+ unsigned eh_noresume:1;
+
/*
* Optional work queue to be utilized by the transport
*/
--
1.7.2.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v5 3/6] [SCSI] check runtime PM status in system PM
2011-12-05 1:20 [PATCH v5 0/6] ata port runtime power management support Lin Ming
2011-12-05 1:20 ` [PATCH v5 1/6] ata: make ata port as parent device of scsi host Lin Ming
2011-12-05 1:20 ` [PATCH v5 2/6] [SCSI] add flag to skip the runtime PM calls on the host Lin Ming
@ 2011-12-05 1:20 ` Lin Ming
2011-12-05 1:20 ` [PATCH v5 4/6] [SCSI] sd: check runtime PM status in sd_shutdown Lin Ming
` (2 subsequent siblings)
5 siblings, 0 replies; 15+ messages in thread
From: Lin Ming @ 2011-12-05 1:20 UTC (permalink / raw)
To: Jeff Garzik, James Bottomley, Alan Stern, Tejun Heo
Cc: linux-kernel, linux-ide, linux-scsi, linux-pm, Rafael J. Wysocki,
Huang Ying, Zhang Rui
The only high-level SCSI driver that currently implements runtime PM is
sd, and sd treats runtime suspend exactly the same as the SUSPEND and
HIBERNATE stages of system sleep, but not the same as the FREEZE stage.
Therefore, when entering the SUSPEND or HIBERNATE stages of system
sleep, we can skip the callback to the driver if the device is already
in runtime suspend. When entering the FREEZE stage, however, we should
first issue a runtime resume. The overhead of doing this is
negligible, because a suspended drive would be spun up during the THAW
stage of hibernation anyway.
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
---
drivers/scsi/scsi_pm.c | 16 +++++++++++++++-
1 files changed, 15 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
index d329f8b..a633076 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -49,8 +49,22 @@ static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg)
{
int err = 0;
- if (scsi_is_sdev_device(dev))
+ if (scsi_is_sdev_device(dev)) {
+ /*
+ * sd is the only high-level SCSI driver to implement runtime
+ * PM, and sd treats runtime suspend, system suspend, and
+ * system hibernate identically (but not system freeze).
+ */
+ if (pm_runtime_suspended(dev)) {
+ if (msg.event == PM_EVENT_SUSPEND ||
+ msg.event == PM_EVENT_HIBERNATE)
+ return 0; /* already suspended */
+
+ /* wake up device so that FREEZE will succeed */
+ pm_runtime_resume(dev);
+ }
err = scsi_dev_type_suspend(dev, msg);
+ }
return err;
}
--
1.7.2.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v5 4/6] [SCSI] sd: check runtime PM status in sd_shutdown
2011-12-05 1:20 [PATCH v5 0/6] ata port runtime power management support Lin Ming
` (2 preceding siblings ...)
2011-12-05 1:20 ` [PATCH v5 3/6] [SCSI] check runtime PM status in system PM Lin Ming
@ 2011-12-05 1:20 ` Lin Ming
2011-12-05 1:20 ` [PATCH v5 5/6] ata: add ata port system PM callbacks Lin Ming
2011-12-05 1:20 ` [PATCH v5 6/6] ata: add ata port runtime " Lin Ming
5 siblings, 0 replies; 15+ messages in thread
From: Lin Ming @ 2011-12-05 1:20 UTC (permalink / raw)
To: Jeff Garzik, James Bottomley, Alan Stern, Tejun Heo
Cc: linux-kernel, linux-ide, linux-scsi, linux-pm, Rafael J. Wysocki,
Huang Ying, Zhang Rui
sd_shutdown is called during reboot/poweroff.
It may fail if parent device, for example, ata port, was runtime suspended.
Fix it by checking runtime PM status of sd.
Exit immediately if sd was runtime suspended already.
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
---
drivers/scsi/sd.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index fa3a591..7b3f807 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -50,6 +50,7 @@
#include <linux/string_helpers.h>
#include <linux/async.h>
#include <linux/slab.h>
+#include <linux/pm_runtime.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
@@ -2741,6 +2742,9 @@ static void sd_shutdown(struct device *dev)
if (!sdkp)
return; /* this can happen */
+ if (pm_runtime_suspended(dev))
+ goto exit;
+
if (sdkp->WCE) {
sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
sd_sync_cache(sdkp);
@@ -2751,6 +2755,7 @@ static void sd_shutdown(struct device *dev)
sd_start_stop_device(sdkp, 0);
}
+exit:
scsi_disk_put(sdkp);
}
--
1.7.2.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v5 5/6] ata: add ata port system PM callbacks
2011-12-05 1:20 [PATCH v5 0/6] ata port runtime power management support Lin Ming
` (3 preceding siblings ...)
2011-12-05 1:20 ` [PATCH v5 4/6] [SCSI] sd: check runtime PM status in sd_shutdown Lin Ming
@ 2011-12-05 1:20 ` Lin Ming
2011-12-07 8:38 ` Lin Ming
[not found] ` <CAF1ivSbRejpSEVfHAhOUxaqAedkCQVHWOgsJGFLM2yt2QaxtuQ@mail.gmail.com>
2011-12-05 1:20 ` [PATCH v5 6/6] ata: add ata port runtime " Lin Ming
5 siblings, 2 replies; 15+ messages in thread
From: Lin Ming @ 2011-12-05 1:20 UTC (permalink / raw)
To: Jeff Garzik, James Bottomley, Alan Stern, Tejun Heo
Cc: linux-kernel, linux-ide, linux-scsi, linux-pm, Rafael J. Wysocki,
Huang Ying, Zhang Rui
Change ata_host_request_pm to ata_port_request_pm which performs
port suspend/resume.
Add ata port type driver which implements port PM callbacks.
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
---
drivers/ata/libata-core.c | 144 ++++++++++++++++++++-------------------
drivers/ata/libata-transport.c | 1 +
drivers/ata/libata.h | 1 +
3 files changed, 76 insertions(+), 70 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index c04ad68..04c208e 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5234,112 +5234,116 @@ bool ata_link_offline(struct ata_link *link)
}
#ifdef CONFIG_PM
-static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
+static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
unsigned int action, unsigned int ehi_flags,
int wait)
{
+ struct ata_link *link;
unsigned long flags;
- int i, rc;
-
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
- struct ata_link *link;
+ int rc;
- /* Previous resume operation might still be in
- * progress. Wait for PM_PENDING to clear.
- */
- if (ap->pflags & ATA_PFLAG_PM_PENDING) {
- ata_port_wait_eh(ap);
- WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
- }
+ /* Previous resume operation might still be in
+ * progress. Wait for PM_PENDING to clear.
+ */
+ if (ap->pflags & ATA_PFLAG_PM_PENDING) {
+ ata_port_wait_eh(ap);
+ WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
+ }
- /* request PM ops to EH */
- spin_lock_irqsave(ap->lock, flags);
+ /* request PM ops to EH */
+ spin_lock_irqsave(ap->lock, flags);
- ap->pm_mesg = mesg;
- if (wait) {
- rc = 0;
- ap->pm_result = &rc;
- }
+ ap->pm_mesg = mesg;
+ if (wait) {
+ rc = 0;
+ ap->pm_result = &rc;
+ }
- ap->pflags |= ATA_PFLAG_PM_PENDING;
- ata_for_each_link(link, ap, HOST_FIRST) {
- link->eh_info.action |= action;
- link->eh_info.flags |= ehi_flags;
- }
+ ap->pflags |= ATA_PFLAG_PM_PENDING;
+ ata_for_each_link(link, ap, HOST_FIRST) {
+ link->eh_info.action |= action;
+ link->eh_info.flags |= ehi_flags;
+ }
- ata_port_schedule_eh(ap);
+ ata_port_schedule_eh(ap);
- spin_unlock_irqrestore(ap->lock, flags);
+ spin_unlock_irqrestore(ap->lock, flags);
- /* wait and check result */
- if (wait) {
- ata_port_wait_eh(ap);
- WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
- if (rc)
- return rc;
- }
+ /* wait and check result */
+ if (wait) {
+ ata_port_wait_eh(ap);
+ WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
}
- return 0;
+ return rc;
}
+#define to_ata_port(d) container_of(d, struct ata_port, tdev)
+
+static int ata_port_suspend_common(struct device *dev)
+{
+ struct ata_port *ap = to_ata_port(dev);
+ int rc;
+
+ rc = ata_port_request_pm(ap, PMSG_SUSPEND, 0, ATA_EHI_QUIET, 1);
+ return rc;
+}
+
+static int ata_port_suspend(struct device *dev)
+{
+ if (pm_runtime_suspended(dev))
+ return 0;
+
+ return ata_port_suspend_common(dev);
+}
+
+static int ata_port_resume(struct device *dev)
+{
+ struct ata_port *ap = to_ata_port(dev);
+ int rc;
+
+ rc = ata_port_request_pm(ap, PMSG_ON, ATA_EH_RESET,
+ ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 1);
+ return rc;
+}
+
+static const struct dev_pm_ops ata_port_pm_ops = {
+ .suspend = ata_port_suspend,
+ .resume = ata_port_resume,
+};
+
/**
* ata_host_suspend - suspend host
* @host: host to suspend
* @mesg: PM message
*
- * Suspend @host. Actual operation is performed by EH. This
- * function requests EH to perform PM operations and waits for EH
- * to finish.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
- *
- * RETURNS:
- * 0 on success, -errno on failure.
+ * Suspend @host. Actual operation is performed by port suspend.
*/
int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
{
- unsigned int ehi_flags = ATA_EHI_QUIET;
- int rc;
-
- /*
- * On some hardware, device fails to respond after spun down
- * for suspend. As the device won't be used before being
- * resumed, we don't need to touch the device. Ask EH to skip
- * the usual stuff and proceed directly to suspend.
- *
- * http://thread.gmane.org/gmane.linux.ide/46764
- */
- if (mesg.event == PM_EVENT_SUSPEND)
- ehi_flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_NO_RECOVERY;
-
- rc = ata_host_request_pm(host, mesg, 0, ehi_flags, 1);
- if (rc == 0)
- host->dev->power.power_state = mesg;
- return rc;
+ host->dev->power.power_state = mesg;
+ return 0;
}
/**
* ata_host_resume - resume host
* @host: host to resume
*
- * Resume @host. Actual operation is performed by EH. This
- * function requests EH to perform PM operations and returns.
- * Note that all resume operations are performed parallelly.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
+ * Resume @host. Actual operation is performed by port resume.
*/
void ata_host_resume(struct ata_host *host)
{
- ata_host_request_pm(host, PMSG_ON, ATA_EH_RESET,
- ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
host->dev->power.power_state = PMSG_ON;
}
#endif
+struct device_type ata_port_type = {
+ .name = "ata_port",
+#ifdef CONFIG_PM
+ .pm = &ata_port_pm_ops,
+#endif
+};
+
/**
* ata_dev_init - Initialize an ata_device structure
* @dev: Device structure to initialize
diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
index ce9dc62..3ceb3d9 100644
--- a/drivers/ata/libata-transport.c
+++ b/drivers/ata/libata-transport.c
@@ -279,6 +279,7 @@ int ata_tport_add(struct device *parent,
struct device *dev = &ap->tdev;
device_initialize(dev);
+ dev->type = &ata_port_type;
dev->parent = get_device(parent);
dev->release = ata_tport_release;
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 773de97..814486d 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -58,6 +58,7 @@ extern int atapi_passthru16;
extern int libata_fua;
extern int libata_noacpi;
extern int libata_allow_tpm;
+extern struct device_type ata_port_type;
extern struct ata_link *ata_dev_phys_link(struct ata_device *dev);
extern void ata_force_cbl(struct ata_port *ap);
extern u64 ata_tf_to_lba(const struct ata_taskfile *tf);
--
1.7.2.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v5 5/6] ata: add ata port system PM callbacks
2011-12-05 1:20 ` [PATCH v5 5/6] ata: add ata port system PM callbacks Lin Ming
@ 2011-12-07 8:38 ` Lin Ming
[not found] ` <CAF1ivSbRejpSEVfHAhOUxaqAedkCQVHWOgsJGFLM2yt2QaxtuQ@mail.gmail.com>
1 sibling, 0 replies; 15+ messages in thread
From: Lin Ming @ 2011-12-07 8:38 UTC (permalink / raw)
To: Jeff Garzik, James Bottomley, Alan Stern, Tejun Heo
Cc: linux-kernel, linux-ide, linux-scsi, linux-pm, Rafael J. Wysocki,
Huang Ying, Zhang Rui
On Mon, Dec 5, 2011 at 9:20 AM, Lin Ming <ming.m.lin@intel.com> wrote:
> Change ata_host_request_pm to ata_port_request_pm which performs
> port suspend/resume.
>
> Add ata port type driver which implements port PM callbacks.
Hi Tejun & Alan,
How about this patch?
Lin Ming
>
> Signed-off-by: Lin Ming <ming.m.lin@intel.com>
> ---
> drivers/ata/libata-core.c | 144 ++++++++++++++++++++-------------------
> drivers/ata/libata-transport.c | 1 +
> drivers/ata/libata.h | 1 +
> 3 files changed, 76 insertions(+), 70 deletions(-)
>
> diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
> index c04ad68..04c208e 100644
> --- a/drivers/ata/libata-core.c
> +++ b/drivers/ata/libata-core.c
> @@ -5234,112 +5234,116 @@ bool ata_link_offline(struct ata_link *link)
> }
>
> #ifdef CONFIG_PM
> -static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
> +static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
> unsigned int action, unsigned int ehi_flags,
> int wait)
> {
> + struct ata_link *link;
> unsigned long flags;
> - int i, rc;
> -
> - for (i = 0; i < host->n_ports; i++) {
> - struct ata_port *ap = host->ports[i];
> - struct ata_link *link;
> + int rc;
>
> - /* Previous resume operation might still be in
> - * progress. Wait for PM_PENDING to clear.
> - */
> - if (ap->pflags & ATA_PFLAG_PM_PENDING) {
> - ata_port_wait_eh(ap);
> - WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
> - }
> + /* Previous resume operation might still be in
> + * progress. Wait for PM_PENDING to clear.
> + */
> + if (ap->pflags & ATA_PFLAG_PM_PENDING) {
> + ata_port_wait_eh(ap);
> + WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
> + }
>
> - /* request PM ops to EH */
> - spin_lock_irqsave(ap->lock, flags);
> + /* request PM ops to EH */
> + spin_lock_irqsave(ap->lock, flags);
>
> - ap->pm_mesg = mesg;
> - if (wait) {
> - rc = 0;
> - ap->pm_result = &rc;
> - }
> + ap->pm_mesg = mesg;
> + if (wait) {
> + rc = 0;
> + ap->pm_result = &rc;
> + }
>
> - ap->pflags |= ATA_PFLAG_PM_PENDING;
> - ata_for_each_link(link, ap, HOST_FIRST) {
> - link->eh_info.action |= action;
> - link->eh_info.flags |= ehi_flags;
> - }
> + ap->pflags |= ATA_PFLAG_PM_PENDING;
> + ata_for_each_link(link, ap, HOST_FIRST) {
> + link->eh_info.action |= action;
> + link->eh_info.flags |= ehi_flags;
> + }
>
> - ata_port_schedule_eh(ap);
> + ata_port_schedule_eh(ap);
>
> - spin_unlock_irqrestore(ap->lock, flags);
> + spin_unlock_irqrestore(ap->lock, flags);
>
> - /* wait and check result */
> - if (wait) {
> - ata_port_wait_eh(ap);
> - WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
> - if (rc)
> - return rc;
> - }
> + /* wait and check result */
> + if (wait) {
> + ata_port_wait_eh(ap);
> + WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
> }
>
> - return 0;
> + return rc;
> }
>
> +#define to_ata_port(d) container_of(d, struct ata_port, tdev)
> +
> +static int ata_port_suspend_common(struct device *dev)
> +{
> + struct ata_port *ap = to_ata_port(dev);
> + int rc;
> +
> + rc = ata_port_request_pm(ap, PMSG_SUSPEND, 0, ATA_EHI_QUIET, 1);
> + return rc;
> +}
> +
> +static int ata_port_suspend(struct device *dev)
> +{
> + if (pm_runtime_suspended(dev))
> + return 0;
> +
> + return ata_port_suspend_common(dev);
> +}
> +
> +static int ata_port_resume(struct device *dev)
> +{
> + struct ata_port *ap = to_ata_port(dev);
> + int rc;
> +
> + rc = ata_port_request_pm(ap, PMSG_ON, ATA_EH_RESET,
> + ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 1);
> + return rc;
> +}
> +
> +static const struct dev_pm_ops ata_port_pm_ops = {
> + .suspend = ata_port_suspend,
> + .resume = ata_port_resume,
> +};
> +
> /**
> * ata_host_suspend - suspend host
> * @host: host to suspend
> * @mesg: PM message
> *
> - * Suspend @host. Actual operation is performed by EH. This
> - * function requests EH to perform PM operations and waits for EH
> - * to finish.
> - *
> - * LOCKING:
> - * Kernel thread context (may sleep).
> - *
> - * RETURNS:
> - * 0 on success, -errno on failure.
> + * Suspend @host. Actual operation is performed by port suspend.
> */
> int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
> {
> - unsigned int ehi_flags = ATA_EHI_QUIET;
> - int rc;
> -
> - /*
> - * On some hardware, device fails to respond after spun down
> - * for suspend. As the device won't be used before being
> - * resumed, we don't need to touch the device. Ask EH to skip
> - * the usual stuff and proceed directly to suspend.
> - *
> - * http://thread.gmane.org/gmane.linux.ide/46764
> - */
> - if (mesg.event == PM_EVENT_SUSPEND)
> - ehi_flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_NO_RECOVERY;
> -
> - rc = ata_host_request_pm(host, mesg, 0, ehi_flags, 1);
> - if (rc == 0)
> - host->dev->power.power_state = mesg;
> - return rc;
> + host->dev->power.power_state = mesg;
> + return 0;
> }
>
> /**
> * ata_host_resume - resume host
> * @host: host to resume
> *
> - * Resume @host. Actual operation is performed by EH. This
> - * function requests EH to perform PM operations and returns.
> - * Note that all resume operations are performed parallelly.
> - *
> - * LOCKING:
> - * Kernel thread context (may sleep).
> + * Resume @host. Actual operation is performed by port resume.
> */
> void ata_host_resume(struct ata_host *host)
> {
> - ata_host_request_pm(host, PMSG_ON, ATA_EH_RESET,
> - ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
> host->dev->power.power_state = PMSG_ON;
> }
> #endif
>
> +struct device_type ata_port_type = {
> + .name = "ata_port",
> +#ifdef CONFIG_PM
> + .pm = &ata_port_pm_ops,
> +#endif
> +};
> +
> /**
> * ata_dev_init - Initialize an ata_device structure
> * @dev: Device structure to initialize
> diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
> index ce9dc62..3ceb3d9 100644
> --- a/drivers/ata/libata-transport.c
> +++ b/drivers/ata/libata-transport.c
> @@ -279,6 +279,7 @@ int ata_tport_add(struct device *parent,
> struct device *dev = &ap->tdev;
>
> device_initialize(dev);
> + dev->type = &ata_port_type;
>
> dev->parent = get_device(parent);
> dev->release = ata_tport_release;
> diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
> index 773de97..814486d 100644
> --- a/drivers/ata/libata.h
> +++ b/drivers/ata/libata.h
> @@ -58,6 +58,7 @@ extern int atapi_passthru16;
> extern int libata_fua;
> extern int libata_noacpi;
> extern int libata_allow_tpm;
> +extern struct device_type ata_port_type;
> extern struct ata_link *ata_dev_phys_link(struct ata_device *dev);
> extern void ata_force_cbl(struct ata_port *ap);
> extern u64 ata_tf_to_lba(const struct ata_taskfile *tf);
> --
> 1.7.2.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 15+ messages in thread[parent not found: <CAF1ivSbRejpSEVfHAhOUxaqAedkCQVHWOgsJGFLM2yt2QaxtuQ@mail.gmail.com>]
* Re: [PATCH v5 5/6] ata: add ata port system PM callbacks
[not found] ` <CAF1ivSbRejpSEVfHAhOUxaqAedkCQVHWOgsJGFLM2yt2QaxtuQ@mail.gmail.com>
@ 2011-12-13 14:20 ` Lin Ming
2011-12-13 15:47 ` Alan Stern
0 siblings, 1 reply; 15+ messages in thread
From: Lin Ming @ 2011-12-13 14:20 UTC (permalink / raw)
To: Jeff Garzik, James Bottomley, Alan Stern, Tejun Heo
Cc: linux-kernel, linux-ide, linux-scsi, linux-pm, Rafael J. Wysocki,
Huang Ying, Zhang Rui
On Tue, 2011-12-13 at 21:56 +0800, Lin Ming wrote:
> +
> +static int ata_port_resume(struct device *dev)
> +{
> + struct ata_port *ap = to_ata_port(dev);
> + int rc;
> +
> + rc = ata_port_request_pm(ap, PMSG_ON, ATA_EH_RESET,
> + ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 1);
> + return rc;
> +}
I just realized that the ata port runtime PM status need to be updated
after system resume.
I tried below patch.
Unfortunately, it causes a problem that sd can't resume correctly.
During system resume, ata port is resumed first and then sd resumed.
When ata port resumed, device_resume(...) calls pm_runtime_put_sync(..),
which causes ata port to be runtime suspended immediately.
So sd resume fails because it requires ata port to be active to handle
start device command.
This seems a PM core's bug.
device_resume(...) should not runtime suspend the parent device, because
its children have not resumed yet.
Alan,
What do you think?
---
drivers/ata/libata-core.c | 18 ++++++++++++++++--
1 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 15a3d4d..8996758 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5298,7 +5298,7 @@ static int ata_port_suspend(struct device *dev)
return ata_port_suspend_common(dev);
}
-static int ata_port_resume(struct device *dev)
+static int ata_port_resume_common(struct device *dev)
{
struct ata_port *ap = to_ata_port(dev);
int rc;
@@ -5308,6 +5308,20 @@ static int ata_port_resume(struct device *dev)
return rc;
}
+static int ata_port_resume(struct device *dev)
+{
+ int rc;
+
+ rc = ata_port_resume_common(dev);
+ if (!rc) {
+ pm_runtime_disable(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ }
+
+ return rc;
+}
+
static int ata_port_runtime_idle(struct device *dev)
{
return pm_runtime_suspend(dev);
@@ -5318,7 +5332,7 @@ static const struct dev_pm_ops ata_port_pm_ops = {
.resume = ata_port_resume,
.runtime_suspend = ata_port_suspend_common,
- .runtime_resume = ata_port_resume,
+ .runtime_resume = ata_port_resume_common,
.runtime_idle = ata_port_runtime_idle,
};
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v5 5/6] ata: add ata port system PM callbacks
2011-12-13 14:20 ` Lin Ming
@ 2011-12-13 15:47 ` Alan Stern
2011-12-13 18:57 ` Lin Ming
0 siblings, 1 reply; 15+ messages in thread
From: Alan Stern @ 2011-12-13 15:47 UTC (permalink / raw)
To: Lin Ming
Cc: Jeff Garzik, James Bottomley, Tejun Heo, linux-kernel, linux-ide,
linux-scsi, linux-pm, Rafael J. Wysocki, Huang Ying, Zhang Rui
On Tue, 13 Dec 2011, Lin Ming wrote:
> I just realized that the ata port runtime PM status need to be updated
> after system resume.
>
> I tried below patch.
> Unfortunately, it causes a problem that sd can't resume correctly.
>
> During system resume, ata port is resumed first and then sd resumed.
>
> When ata port resumed, device_resume(...) calls pm_runtime_put_sync(..),
> which causes ata port to be runtime suspended immediately.
>
> So sd resume fails because it requires ata port to be active to handle
> start device command.
>
> This seems a PM core's bug.
>
> device_resume(...) should not runtime suspend the parent device, because
> its children have not resumed yet.
>
> Alan,
>
> What do you think?
This appears to be the first time this problem has come up. But it is
a real problem.
If a child device was runtime-suspended when a system suspend began,
then there will be nothing to prevent its parent from
runtime-suspending as soon as it is woken up during the system resume.
Then when the time comes to resume the child, the resume will fail
because the parent is already back at low power.
On the other hand, there are some devices which should remain at low
power across an entire suspend-resume cycle. The details depend on the
device and the platform.
This suggests that the PM core is not the right place to solve the
problem. One possible solution is for the subsystem or device driver
to call pm_runtime_get_sync(dev->parent) at the start of the
system-resume procedure and pm_runtime_put_sync(dev->parent) at the
end.
Alan Stern
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v5 5/6] ata: add ata port system PM callbacks
2011-12-13 15:47 ` Alan Stern
@ 2011-12-13 18:57 ` Lin Ming
2011-12-13 19:07 ` Alan Stern
0 siblings, 1 reply; 15+ messages in thread
From: Lin Ming @ 2011-12-13 18:57 UTC (permalink / raw)
To: Alan Stern
Cc: Jeff Garzik, James Bottomley, Tejun Heo,
linux-kernel@vger.kernel.org, linux-ide@vger.kernel.org,
linux-scsi@vger.kernel.org, linux-pm@vger.kernel.org,
Rafael J. Wysocki, Huang, Ying, Zhang, Rui
On Tue, 2011-12-13 at 23:47 +0800, Alan Stern wrote:
> On Tue, 13 Dec 2011, Lin Ming wrote:
>
> > I just realized that the ata port runtime PM status need to be updated
> > after system resume.
> >
> > I tried below patch.
> > Unfortunately, it causes a problem that sd can't resume correctly.
> >
> > During system resume, ata port is resumed first and then sd resumed.
> >
> > When ata port resumed, device_resume(...) calls pm_runtime_put_sync(..),
> > which causes ata port to be runtime suspended immediately.
> >
> > So sd resume fails because it requires ata port to be active to handle
> > start device command.
> >
> > This seems a PM core's bug.
> >
> > device_resume(...) should not runtime suspend the parent device, because
> > its children have not resumed yet.
> >
> > Alan,
> >
> > What do you think?
>
> This appears to be the first time this problem has come up. But it is
> a real problem.
>
> If a child device was runtime-suspended when a system suspend began,
> then there will be nothing to prevent its parent from
> runtime-suspending as soon as it is woken up during the system resume.
> Then when the time comes to resume the child, the resume will fail
> because the parent is already back at low power.
>
> On the other hand, there are some devices which should remain at low
> power across an entire suspend-resume cycle. The details depend on the
> device and the platform.
>
> This suggests that the PM core is not the right place to solve the
> problem. One possible solution is for the subsystem or device driver
> to call pm_runtime_get_sync(dev->parent) at the start of the
> system-resume procedure and pm_runtime_put_sync(dev->parent) at the
> end.
How about below?
(Not tested yet)
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
index a633076..5cf9a19 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -71,9 +71,17 @@ static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg)
static int scsi_bus_resume_common(struct device *dev)
{
int err = 0;
+ bool put = false;
- if (scsi_is_sdev_device(dev))
+ if (scsi_is_sdev_device(dev)) {
+ if (dev->parent && pm_runtime_suspended(dev->parent)) {
+ pm_runtime_get_sync(dev->parent);
+ put = true;
+ }
err = scsi_dev_type_resume(dev);
+ if (put)
+ pm_runtime_put_sync(dev->parent);
+ }
if (err == 0) {
pm_runtime_disable(dev);
>
> Alan Stern
>
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v5 5/6] ata: add ata port system PM callbacks
2011-12-13 18:57 ` Lin Ming
@ 2011-12-13 19:07 ` Alan Stern
0 siblings, 0 replies; 15+ messages in thread
From: Alan Stern @ 2011-12-13 19:07 UTC (permalink / raw)
To: Lin Ming
Cc: Jeff Garzik, James Bottomley, Tejun Heo,
linux-kernel@vger.kernel.org, linux-ide@vger.kernel.org,
linux-scsi@vger.kernel.org, linux-pm@vger.kernel.org,
Rafael J. Wysocki, Huang, Ying, Zhang, Rui
On Wed, 14 Dec 2011, Lin Ming wrote:
> > This suggests that the PM core is not the right place to solve the
> > problem. One possible solution is for the subsystem or device driver
> > to call pm_runtime_get_sync(dev->parent) at the start of the
> > system-resume procedure and pm_runtime_put_sync(dev->parent) at the
> > end.
>
> How about below?
> (Not tested yet)
>
> diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
> index a633076..5cf9a19 100644
> --- a/drivers/scsi/scsi_pm.c
> +++ b/drivers/scsi/scsi_pm.c
> @@ -71,9 +71,17 @@ static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg)
> static int scsi_bus_resume_common(struct device *dev)
> {
> int err = 0;
> + bool put = false;
>
> - if (scsi_is_sdev_device(dev))
> + if (scsi_is_sdev_device(dev)) {
> + if (dev->parent && pm_runtime_suspended(dev->parent)) {
> + pm_runtime_get_sync(dev->parent);
> + put = true;
> + }
You don't need to test anything. Always call pm_runtime_get_sync().
> err = scsi_dev_type_resume(dev);
> + if (put)
> + pm_runtime_put_sync(dev->parent);
Same here.
> + }
>
> if (err == 0) {
> pm_runtime_disable(dev);
Alan Stern
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v5 6/6] ata: add ata port runtime PM callbacks
2011-12-05 1:20 [PATCH v5 0/6] ata port runtime power management support Lin Ming
` (4 preceding siblings ...)
2011-12-05 1:20 ` [PATCH v5 5/6] ata: add ata port system PM callbacks Lin Ming
@ 2011-12-05 1:20 ` Lin Ming
2011-12-07 8:42 ` Lin Ming
5 siblings, 1 reply; 15+ messages in thread
From: Lin Ming @ 2011-12-05 1:20 UTC (permalink / raw)
To: Jeff Garzik, James Bottomley, Alan Stern, Tejun Heo
Cc: linux-kernel, linux-ide, linux-scsi, linux-pm, Rafael J. Wysocki,
Huang Ying, Zhang Rui
Add ata port runtime suspend/resume/idle callbacks.
Set ->eh_noresume to skip the runtime PM calls on scsi host
in the error handler to avoid dead lock.
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
---
drivers/ata/libata-core.c | 10 ++++++++++
drivers/ata/libata-scsi.c | 1 +
drivers/ata/libata-transport.c | 4 ++++
3 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 04c208e..15a3d4d 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -66,6 +66,7 @@
#include <asm/byteorder.h>
#include <linux/cdrom.h>
#include <linux/ratelimit.h>
+#include <linux/pm_runtime.h>
#include "libata.h"
#include "libata-transport.h"
@@ -5307,9 +5308,18 @@ static int ata_port_resume(struct device *dev)
return rc;
}
+static int ata_port_runtime_idle(struct device *dev)
+{
+ return pm_runtime_suspend(dev);
+}
+
static const struct dev_pm_ops ata_port_pm_ops = {
.suspend = ata_port_suspend,
.resume = ata_port_resume,
+
+ .runtime_suspend = ata_port_suspend_common,
+ .runtime_resume = ata_port_resume,
+ .runtime_idle = ata_port_runtime_idle,
};
/**
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 7ae1e77..508a60b 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3381,6 +3381,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
if (!shost)
goto err_alloc;
+ shost->eh_noresume = 1;
*(struct ata_port **)&shost->hostdata[0] = ap;
ap->scsi_host = shost;
diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
index 3ceb3d9..9a7f0ea 100644
--- a/drivers/ata/libata-transport.c
+++ b/drivers/ata/libata-transport.c
@@ -32,6 +32,7 @@
#include <linux/libata.h>
#include <linux/hdreg.h>
#include <linux/uaccess.h>
+#include <linux/pm_runtime.h>
#include "libata.h"
#include "libata-transport.h"
@@ -290,6 +291,9 @@ int ata_tport_add(struct device *parent,
goto tport_err;
}
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
transport_add_device(dev);
transport_configure_device(dev);
--
1.7.2.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v5 6/6] ata: add ata port runtime PM callbacks
2011-12-05 1:20 ` [PATCH v5 6/6] ata: add ata port runtime " Lin Ming
@ 2011-12-07 8:42 ` Lin Ming
2011-12-07 18:29 ` Tejun Heo
0 siblings, 1 reply; 15+ messages in thread
From: Lin Ming @ 2011-12-07 8:42 UTC (permalink / raw)
To: Jeff Garzik, James Bottomley, Alan Stern, Tejun Heo
Cc: linux-kernel, linux-ide, linux-scsi, linux-pm, Rafael J. Wysocki,
Huang Ying, Zhang Rui
On Mon, Dec 5, 2011 at 9:20 AM, Lin Ming <ming.m.lin@intel.com> wrote:
> Add ata port runtime suspend/resume/idle callbacks.
> Set ->eh_noresume to skip the runtime PM calls on scsi host
> in the error handler to avoid dead lock.
Hi Tejun & Alan,
How about this patch?
Lin Ming
>
> Signed-off-by: Lin Ming <ming.m.lin@intel.com>
> ---
> drivers/ata/libata-core.c | 10 ++++++++++
> drivers/ata/libata-scsi.c | 1 +
> drivers/ata/libata-transport.c | 4 ++++
> 3 files changed, 15 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
> index 04c208e..15a3d4d 100644
> --- a/drivers/ata/libata-core.c
> +++ b/drivers/ata/libata-core.c
> @@ -66,6 +66,7 @@
> #include <asm/byteorder.h>
> #include <linux/cdrom.h>
> #include <linux/ratelimit.h>
> +#include <linux/pm_runtime.h>
>
> #include "libata.h"
> #include "libata-transport.h"
> @@ -5307,9 +5308,18 @@ static int ata_port_resume(struct device *dev)
> return rc;
> }
>
> +static int ata_port_runtime_idle(struct device *dev)
> +{
> + return pm_runtime_suspend(dev);
> +}
> +
> static const struct dev_pm_ops ata_port_pm_ops = {
> .suspend = ata_port_suspend,
> .resume = ata_port_resume,
> +
> + .runtime_suspend = ata_port_suspend_common,
> + .runtime_resume = ata_port_resume,
> + .runtime_idle = ata_port_runtime_idle,
> };
>
> /**
> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> index 7ae1e77..508a60b 100644
> --- a/drivers/ata/libata-scsi.c
> +++ b/drivers/ata/libata-scsi.c
> @@ -3381,6 +3381,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
> if (!shost)
> goto err_alloc;
>
> + shost->eh_noresume = 1;
> *(struct ata_port **)&shost->hostdata[0] = ap;
> ap->scsi_host = shost;
>
> diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
> index 3ceb3d9..9a7f0ea 100644
> --- a/drivers/ata/libata-transport.c
> +++ b/drivers/ata/libata-transport.c
> @@ -32,6 +32,7 @@
> #include <linux/libata.h>
> #include <linux/hdreg.h>
> #include <linux/uaccess.h>
> +#include <linux/pm_runtime.h>
>
> #include "libata.h"
> #include "libata-transport.h"
> @@ -290,6 +291,9 @@ int ata_tport_add(struct device *parent,
> goto tport_err;
> }
>
> + pm_runtime_set_active(dev);
> + pm_runtime_enable(dev);
> +
> transport_add_device(dev);
> transport_configure_device(dev);
>
> --
> 1.7.2.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ide" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH v5 6/6] ata: add ata port runtime PM callbacks
2011-12-07 8:42 ` Lin Ming
@ 2011-12-07 18:29 ` Tejun Heo
0 siblings, 0 replies; 15+ messages in thread
From: Tejun Heo @ 2011-12-07 18:29 UTC (permalink / raw)
To: Lin Ming
Cc: Jeff Garzik, James Bottomley, Alan Stern, linux-kernel, linux-ide,
linux-scsi, linux-pm, Rafael J. Wysocki, Huang Ying, Zhang Rui
On Wed, Dec 07, 2011 at 04:42:09PM +0800, Lin Ming wrote:
> On Mon, Dec 5, 2011 at 9:20 AM, Lin Ming <ming.m.lin@intel.com> wrote:
> > Add ata port runtime suspend/resume/idle callbacks.
> > Set ->eh_noresume to skip the runtime PM calls on scsi host
> > in the error handler to avoid dead lock.
>
> Hi Tejun & Alan,
>
> How about this patch?
Looks good to me.
Acked-by: Tejun Heo <tj@kernel.org>
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 15+ messages in thread