From 7e15e9be37eb834aaaca69030064ac97eaf5df2f Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Tue, 15 Jan 2013 17:21:04 +0800 Subject: libata: do not suspend port if normal ODD is attached For ODDs, the upper layer will poll for media change every few seconds, which will make it enter and leave suspend state very often. And as each suspend will also cause a hard/soft reset, the gain of runtime suspend is very little while the ODD may malfunction after constantly being reset. So the idle callback here will not proceed to suspend if a non-ZPODD capable ODD is attached to the port. Signed-off-by: Aaron Lu Acked-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index c7ecd8492f1e..b7eed827daae 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5413,8 +5413,27 @@ static int ata_port_resume(struct device *dev) return rc; } +/* + * For ODDs, the upper layer will poll for media change every few seconds, + * which will make it enter and leave suspend state every few seconds. And + * as each suspend will cause a hard/soft reset, the gain of runtime suspend + * is very little and the ODD may malfunction after constantly being reset. + * So the idle callback here will not proceed to suspend if a non-ZPODD capable + * ODD is attached to the port. + */ static int ata_port_runtime_idle(struct device *dev) { + struct ata_port *ap = to_ata_port(dev); + struct ata_link *link; + struct ata_device *adev; + + ata_for_each_link(link, ap, HOST_FIRST) { + ata_for_each_dev(adev, link, ENABLED) + if (adev->class == ATA_DEV_ATAPI && + !zpodd_dev_enabled(adev)) + return -EBUSY; + } + return pm_runtime_suspend(dev); } -- cgit v1.2.3