diff options
author | Tejun Heo <htejun@gmail.com> | 2006-07-03 03:07:26 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-07-05 22:16:28 -0400 |
commit | 02670bf379267f55a43aa57f6895689697e90eb3 (patch) | |
tree | 830b74690371e39cf8e94de678768993be743437 /include/linux | |
parent | c0b6c0377c32fe3f6a2cf1e018db6da8a3b78379 (diff) |
[PATCH] libata: implement PM EH actions
Implement two PM per-dev EH actions - ATA_EH_SUSPEND and
ATA_EH_RESUME. Each action puts the target device into suspended mode
and resumes from it respectively.
Once a device is put to suspended mode, no EH operations other than
RESUME is allowed on the device. The device will stay suspended till
it gets resumed and thus reset and revalidated. To implement this, a
new device state helper - ata_dev_ready() - is implemented and used in
EH action implementations to make them operate only on attached &
running devices.
If all possible devices on a port are suspended, reset is skipped too.
This prevents spurious events including hotplug events from disrupting
suspended devices.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/libata.h | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/include/linux/libata.h b/include/linux/libata.h index 2aa1398bbd52..363c7501843a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -131,6 +131,7 @@ enum { | |||
131 | ATA_DFLAG_CFG_MASK = (1 << 8) - 1, | 131 | ATA_DFLAG_CFG_MASK = (1 << 8) - 1, |
132 | 132 | ||
133 | ATA_DFLAG_PIO = (1 << 8), /* device currently in PIO mode */ | 133 | ATA_DFLAG_PIO = (1 << 8), /* device currently in PIO mode */ |
134 | ATA_DFLAG_SUSPENDED = (1 << 9), /* device suspended */ | ||
134 | ATA_DFLAG_INIT_MASK = (1 << 16) - 1, | 135 | ATA_DFLAG_INIT_MASK = (1 << 16) - 1, |
135 | 136 | ||
136 | ATA_DFLAG_DETACH = (1 << 16), | 137 | ATA_DFLAG_DETACH = (1 << 16), |
@@ -253,9 +254,13 @@ enum { | |||
253 | ATA_EH_REVALIDATE = (1 << 0), | 254 | ATA_EH_REVALIDATE = (1 << 0), |
254 | ATA_EH_SOFTRESET = (1 << 1), | 255 | ATA_EH_SOFTRESET = (1 << 1), |
255 | ATA_EH_HARDRESET = (1 << 2), | 256 | ATA_EH_HARDRESET = (1 << 2), |
257 | ATA_EH_SUSPEND = (1 << 3), | ||
258 | ATA_EH_RESUME = (1 << 4), | ||
259 | ATA_EH_PM_FREEZE = (1 << 5), | ||
256 | 260 | ||
257 | ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, | 261 | ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, |
258 | ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE, | 262 | ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_SUSPEND | |
263 | ATA_EH_RESUME | ATA_EH_PM_FREEZE, | ||
259 | 264 | ||
260 | /* ata_eh_info->flags */ | 265 | /* ata_eh_info->flags */ |
261 | ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ | 266 | ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ |
@@ -944,6 +949,11 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev) | |||
944 | return ata_class_absent(dev->class); | 949 | return ata_class_absent(dev->class); |
945 | } | 950 | } |
946 | 951 | ||
952 | static inline unsigned int ata_dev_ready(const struct ata_device *dev) | ||
953 | { | ||
954 | return ata_dev_enabled(dev) && !(dev->flags & ATA_DFLAG_SUSPENDED); | ||
955 | } | ||
956 | |||
947 | /* | 957 | /* |
948 | * port helpers | 958 | * port helpers |
949 | */ | 959 | */ |