diff options
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r-- | drivers/ata/libata-eh.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 8077bdf5d30d..32da9a93ce44 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -610,9 +610,6 @@ void ata_scsi_error(struct Scsi_Host *host) | |||
610 | if (ata_ncq_enabled(dev)) | 610 | if (ata_ncq_enabled(dev)) |
611 | ehc->saved_ncq_enabled |= 1 << devno; | 611 | ehc->saved_ncq_enabled |= 1 << devno; |
612 | } | 612 | } |
613 | |||
614 | /* set last reset timestamp to some time in the past */ | ||
615 | ehc->last_reset = jiffies - 60 * HZ; | ||
616 | } | 613 | } |
617 | 614 | ||
618 | ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS; | 615 | ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS; |
@@ -2281,17 +2278,21 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2281 | if (link->flags & ATA_LFLAG_NO_SRST) | 2278 | if (link->flags & ATA_LFLAG_NO_SRST) |
2282 | softreset = NULL; | 2279 | softreset = NULL; |
2283 | 2280 | ||
2284 | now = jiffies; | 2281 | /* make sure each reset attemp is at least COOL_DOWN apart */ |
2285 | deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN); | 2282 | if (ehc->i.flags & ATA_EHI_DID_RESET) { |
2286 | if (time_before(now, deadline)) | 2283 | now = jiffies; |
2287 | schedule_timeout_uninterruptible(deadline - now); | 2284 | WARN_ON(time_after(ehc->last_reset, now)); |
2285 | deadline = ata_deadline(ehc->last_reset, | ||
2286 | ATA_EH_RESET_COOL_DOWN); | ||
2287 | if (time_before(now, deadline)) | ||
2288 | schedule_timeout_uninterruptible(deadline - now); | ||
2289 | } | ||
2288 | 2290 | ||
2289 | spin_lock_irqsave(ap->lock, flags); | 2291 | spin_lock_irqsave(ap->lock, flags); |
2290 | ap->pflags |= ATA_PFLAG_RESETTING; | 2292 | ap->pflags |= ATA_PFLAG_RESETTING; |
2291 | spin_unlock_irqrestore(ap->lock, flags); | 2293 | spin_unlock_irqrestore(ap->lock, flags); |
2292 | 2294 | ||
2293 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); | 2295 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); |
2294 | ehc->last_reset = jiffies; | ||
2295 | 2296 | ||
2296 | ata_link_for_each_dev(dev, link) { | 2297 | ata_link_for_each_dev(dev, link) { |
2297 | /* If we issue an SRST then an ATA drive (not ATAPI) | 2298 | /* If we issue an SRST then an ATA drive (not ATAPI) |
@@ -2379,7 +2380,6 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2379 | /* | 2380 | /* |
2380 | * Perform reset | 2381 | * Perform reset |
2381 | */ | 2382 | */ |
2382 | ehc->last_reset = jiffies; | ||
2383 | if (ata_is_host_link(link)) | 2383 | if (ata_is_host_link(link)) |
2384 | ata_eh_freeze_port(ap); | 2384 | ata_eh_freeze_port(ap); |
2385 | 2385 | ||
@@ -2391,6 +2391,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2391 | reset == softreset ? "soft" : "hard"); | 2391 | reset == softreset ? "soft" : "hard"); |
2392 | 2392 | ||
2393 | /* mark that this EH session started with reset */ | 2393 | /* mark that this EH session started with reset */ |
2394 | ehc->last_reset = jiffies; | ||
2394 | if (reset == hardreset) | 2395 | if (reset == hardreset) |
2395 | ehc->i.flags |= ATA_EHI_DID_HARDRESET; | 2396 | ehc->i.flags |= ATA_EHI_DID_HARDRESET; |
2396 | else | 2397 | else |
@@ -2535,7 +2536,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2535 | ata_eh_done(link, NULL, ATA_EH_RESET); | 2536 | ata_eh_done(link, NULL, ATA_EH_RESET); |
2536 | if (slave) | 2537 | if (slave) |
2537 | ata_eh_done(slave, NULL, ATA_EH_RESET); | 2538 | ata_eh_done(slave, NULL, ATA_EH_RESET); |
2538 | ehc->last_reset = jiffies; | 2539 | ehc->last_reset = jiffies; /* update to completion time */ |
2539 | ehc->i.action |= ATA_EH_REVALIDATE; | 2540 | ehc->i.action |= ATA_EH_REVALIDATE; |
2540 | 2541 | ||
2541 | rc = 0; | 2542 | rc = 0; |