aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-10-30 21:17:04 -0400
committerJeff Garzik <jeff@garzik.org>2007-11-03 08:46:54 -0400
commit08cf69d005acda706bc014c61301993758ce9c5f (patch)
treea7254a45b25ea52bc77a3340650a9b45386f1650
parent416dc9ed206bba09807300ee5f155a81cebbd4a1 (diff)
libata: more robust reset failure handling
Reset failure is a critical error. It results in disabling the link requiring user intervention to re-enable it. Make reset failure handling more robust such that libata EH doesn't give up too early. * Temporary glitches during hardreset may lead to classification failure when there's no softreset available. Retry instead of giving up. * Initial softreset or follow up softreset may fail classification. Move classification error handling block out of followup softreset block such that both cases are handled and retry instead of giving up. Also, on the last try, give ATA class a blind shot. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/ata/libata-eh.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index dae2174f3877..7a2e54e92164 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2184,25 +2184,32 @@ int ata_eh_reset(struct ata_link *link, int classify,
2184 "follow-up softreset required " 2184 "follow-up softreset required "
2185 "but no softreset avaliable\n"); 2185 "but no softreset avaliable\n");
2186 rc = -EINVAL; 2186 rc = -EINVAL;
2187 goto out; 2187 goto fail;
2188 } 2188 }
2189 2189
2190 ata_eh_about_to_do(link, NULL, ATA_EH_RESET_MASK); 2190 ata_eh_about_to_do(link, NULL, ATA_EH_RESET_MASK);
2191 rc = ata_do_reset(link, reset, classes, deadline); 2191 rc = ata_do_reset(link, reset, classes, deadline);
2192
2193 if (rc == 0 && classify && classes[0] == ATA_DEV_UNKNOWN &&
2194 !(lflags & ATA_LFLAG_ASSUME_CLASS)) {
2195 ata_link_printk(link, KERN_ERR,
2196 "classification failed\n");
2197 rc = -EINVAL;
2198 goto out;
2199 }
2200 } 2192 }
2201 2193
2202 /* -EAGAIN can happen if we skipped followup SRST */ 2194 /* -EAGAIN can happen if we skipped followup SRST */
2203 if (rc && rc != -EAGAIN) 2195 if (rc && rc != -EAGAIN)
2204 goto fail; 2196 goto fail;
2205 2197
2198 /* was classification successful? */
2199 if (classify && classes[0] == ATA_DEV_UNKNOWN &&
2200 !(lflags & ATA_LFLAG_ASSUME_CLASS)) {
2201 if (try < max_tries) {
2202 ata_link_printk(link, KERN_WARNING,
2203 "classification failed\n");
2204 rc = -EINVAL;
2205 goto fail;
2206 }
2207
2208 ata_link_printk(link, KERN_WARNING,
2209 "classfication failed, assuming ATA\n");
2210 lflags |= ATA_LFLAG_ASSUME_ATA;
2211 }
2212
2206 ata_link_for_each_dev(dev, link) { 2213 ata_link_for_each_dev(dev, link) {
2207 /* After the reset, the device state is PIO 0 and the 2214 /* After the reset, the device state is PIO 0 and the
2208 * controller state is undefined. Reset also wakes up 2215 * controller state is undefined. Reset also wakes up