aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-eh.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r--drivers/ata/libata-eh.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index e48302eae55f..95838b382231 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -57,6 +57,7 @@ enum {
57 /* error flags */ 57 /* error flags */
58 ATA_EFLAG_IS_IO = (1 << 0), 58 ATA_EFLAG_IS_IO = (1 << 0),
59 ATA_EFLAG_DUBIOUS_XFER = (1 << 1), 59 ATA_EFLAG_DUBIOUS_XFER = (1 << 1),
60 ATA_EFLAG_OLD_ER = (1 << 31),
60 61
61 /* error categories */ 62 /* error categories */
62 ATA_ECAT_NONE = 0, 63 ATA_ECAT_NONE = 0,
@@ -396,14 +397,9 @@ static struct ata_ering_entry *ata_ering_top(struct ata_ering *ering)
396 return NULL; 397 return NULL;
397} 398}
398 399
399static void ata_ering_clear(struct ata_ering *ering) 400int ata_ering_map(struct ata_ering *ering,
400{ 401 int (*map_fn)(struct ata_ering_entry *, void *),
401 memset(ering, 0, sizeof(*ering)); 402 void *arg)
402}
403
404static int ata_ering_map(struct ata_ering *ering,
405 int (*map_fn)(struct ata_ering_entry *, void *),
406 void *arg)
407{ 403{
408 int idx, rc = 0; 404 int idx, rc = 0;
409 struct ata_ering_entry *ent; 405 struct ata_ering_entry *ent;
@@ -422,6 +418,17 @@ static int ata_ering_map(struct ata_ering *ering,
422 return rc; 418 return rc;
423} 419}
424 420
421int ata_ering_clear_cb(struct ata_ering_entry *ent, void *void_arg)
422{
423 ent->eflags |= ATA_EFLAG_OLD_ER;
424 return 0;
425}
426
427static void ata_ering_clear(struct ata_ering *ering)
428{
429 ata_ering_map(ering, ata_ering_clear_cb, NULL);
430}
431
425static unsigned int ata_eh_dev_action(struct ata_device *dev) 432static unsigned int ata_eh_dev_action(struct ata_device *dev)
426{ 433{
427 struct ata_eh_context *ehc = &dev->link->eh_context; 434 struct ata_eh_context *ehc = &dev->link->eh_context;
@@ -572,19 +579,19 @@ void ata_scsi_error(struct Scsi_Host *host)
572 int nr_timedout = 0; 579 int nr_timedout = 0;
573 580
574 spin_lock_irqsave(ap->lock, flags); 581 spin_lock_irqsave(ap->lock, flags);
575 582
576 /* This must occur under the ap->lock as we don't want 583 /* This must occur under the ap->lock as we don't want
577 a polled recovery to race the real interrupt handler 584 a polled recovery to race the real interrupt handler
578 585
579 The lost_interrupt handler checks for any completed but 586 The lost_interrupt handler checks for any completed but
580 non-notified command and completes much like an IRQ handler. 587 non-notified command and completes much like an IRQ handler.
581 588
582 We then fall into the error recovery code which will treat 589 We then fall into the error recovery code which will treat
583 this as if normal completion won the race */ 590 this as if normal completion won the race */
584 591
585 if (ap->ops->lost_interrupt) 592 if (ap->ops->lost_interrupt)
586 ap->ops->lost_interrupt(ap); 593 ap->ops->lost_interrupt(ap);
587 594
588 list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) { 595 list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) {
589 struct ata_queued_cmd *qc; 596 struct ata_queued_cmd *qc;
590 597
@@ -628,7 +635,7 @@ void ata_scsi_error(struct Scsi_Host *host)
628 ap->eh_tries = ATA_EH_MAX_TRIES; 635 ap->eh_tries = ATA_EH_MAX_TRIES;
629 } else 636 } else
630 spin_unlock_wait(ap->lock); 637 spin_unlock_wait(ap->lock);
631 638
632 /* If we timed raced normal completion and there is nothing to 639 /* If we timed raced normal completion and there is nothing to
633 recover nr_timedout == 0 why exactly are we doing error recovery ? */ 640 recover nr_timedout == 0 why exactly are we doing error recovery ? */
634 641
@@ -1755,7 +1762,7 @@ static int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg)
1755 struct speed_down_verdict_arg *arg = void_arg; 1762 struct speed_down_verdict_arg *arg = void_arg;
1756 int cat; 1763 int cat;
1757 1764
1758 if (ent->timestamp < arg->since) 1765 if ((ent->eflags & ATA_EFLAG_OLD_ER) || (ent->timestamp < arg->since))
1759 return -1; 1766 return -1;
1760 1767
1761 cat = ata_eh_categorize_error(ent->eflags, ent->err_mask, 1768 cat = ata_eh_categorize_error(ent->eflags, ent->err_mask,