summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-01-29 12:31:32 +0100
committerJeff Garzik <jgarzik@redhat.com>2009-02-03 05:03:17 +0100
commit99cf610aa4840d822cdc67d194b23b55010ca9bd (patch)
tree68bc3d6c1f13849731bb7b4b11414b4b0e5fbffb /include
parentlibata: check onlineness before using SPD in sata_down_spd_limit() (diff)
downloadlinux-99cf610aa4840d822cdc67d194b23b55010ca9bd.tar.xz
linux-99cf610aa4840d822cdc67d194b23b55010ca9bd.zip
libata: clear dev->ering in smarter way
dev->ering used to be cleared together with the rest of ata_device in ata_dev_init() which is called whenever a probing event occurs. dev->ering is about to be used to track probing failures so it needs to remain persistent over multiple porbing events. This patch achieves this by doing the following. * Instead of CLEAR_OFFSET, define CLEAR_BEGIN and CLEAR_END and only clear between BEGIN and END. ering is moved after END. The split of persistent area is to allow hotter items remain at the head. * ering is explicitly cleared on ata_dev_disable() and when device attach succeeds. So, ering is persistent throug a device's life time (unless explicitly cleared of course) and also through periods inbetween disablement of an attached device and successful detection of the next one. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/libata.h18
1 files changed, 10 insertions, 8 deletions
diff --git a/include/linux/libata.h b/include/linux/libata.h
index bca3ba25f52a..9dcefee5843c 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -580,7 +580,7 @@ struct ata_device {
acpi_handle acpi_handle;
union acpi_object *gtf_cache;
#endif
- /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
+ /* n_sector is CLEAR_BEGIN, read comment above CLEAR_BEGIN */
u64 n_sectors; /* size of device, if ATA */
unsigned int class; /* ATA_DEV_xxx */
unsigned long unpark_deadline;
@@ -605,20 +605,22 @@ struct ata_device {
u16 heads; /* Number of heads */
u16 sectors; /* Number of sectors per track */
- /* error history */
- int spdn_cnt;
- struct ata_ering ering;
-
union {
u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
u32 gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */
};
+
+ /* error history */
+ int spdn_cnt;
+ /* ering is CLEAR_END, read comment above CLEAR_END */
+ struct ata_ering ering;
};
-/* Offset into struct ata_device. Fields above it are maintained
- * acress device init. Fields below are zeroed.
+/* Fields between ATA_DEVICE_CLEAR_BEGIN and ATA_DEVICE_CLEAR_END are
+ * cleared to zero on ata_dev_init().
*/
-#define ATA_DEVICE_CLEAR_OFFSET offsetof(struct ata_device, n_sectors)
+#define ATA_DEVICE_CLEAR_BEGIN offsetof(struct ata_device, n_sectors)
+#define ATA_DEVICE_CLEAR_END offsetof(struct ata_device, ering)
struct ata_eh_info {
struct ata_device *dev; /* offending device */