diff options
author | Tejun Heo <tj@kernel.org> | 2009-01-29 06:31:32 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2009-02-02 23:03:17 -0500 |
commit | 99cf610aa4840d822cdc67d194b23b55010ca9bd (patch) | |
tree | 68bc3d6c1f13849731bb7b4b11414b4b0e5fbffb /drivers | |
parent | 9913ff8abf1c70a8d52560dc931e1901d025ad27 (diff) |
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 'drivers')
-rw-r--r-- | drivers/ata/libata-core.c | 4 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 7 |
2 files changed, 9 insertions, 2 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index d006e5c4768c..564c03c4ebb3 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -5404,8 +5404,8 @@ void ata_dev_init(struct ata_device *dev) | |||
5404 | dev->horkage = 0; | 5404 | dev->horkage = 0; |
5405 | spin_unlock_irqrestore(ap->lock, flags); | 5405 | spin_unlock_irqrestore(ap->lock, flags); |
5406 | 5406 | ||
5407 | memset((void *)dev + ATA_DEVICE_CLEAR_OFFSET, 0, | 5407 | memset((void *)dev + ATA_DEVICE_CLEAR_BEGIN, 0, |
5408 | sizeof(*dev) - ATA_DEVICE_CLEAR_OFFSET); | 5408 | ATA_DEVICE_CLEAR_END - ATA_DEVICE_CLEAR_BEGIN); |
5409 | dev->pio_mask = UINT_MAX; | 5409 | dev->pio_mask = UINT_MAX; |
5410 | dev->mwdma_mask = UINT_MAX; | 5410 | dev->mwdma_mask = UINT_MAX; |
5411 | dev->udma_mask = UINT_MAX; | 5411 | dev->udma_mask = UINT_MAX; |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index aafe82bf5e2e..90092c1aae53 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -1194,6 +1194,11 @@ void ata_dev_disable(struct ata_device *dev) | |||
1194 | ata_acpi_on_disable(dev); | 1194 | ata_acpi_on_disable(dev); |
1195 | ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET); | 1195 | ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET); |
1196 | dev->class++; | 1196 | dev->class++; |
1197 | |||
1198 | /* From now till the next successful probe, ering is used to | ||
1199 | * track probe failures. Clear accumulated device error info. | ||
1200 | */ | ||
1201 | ata_ering_clear(&dev->ering); | ||
1197 | } | 1202 | } |
1198 | 1203 | ||
1199 | /** | 1204 | /** |
@@ -2765,6 +2770,8 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, | |||
2765 | readid_flags, dev->id); | 2770 | readid_flags, dev->id); |
2766 | switch (rc) { | 2771 | switch (rc) { |
2767 | case 0: | 2772 | case 0: |
2773 | /* clear error info accumulated during probe */ | ||
2774 | ata_ering_clear(&dev->ering); | ||
2768 | new_mask |= 1 << dev->devno; | 2775 | new_mask |= 1 << dev->devno; |
2769 | break; | 2776 | break; |
2770 | case -ENOENT: | 2777 | case -ENOENT: |