diff options
Diffstat (limited to 'drivers/ata/libata-eh.c')
| -rw-r--r-- | drivers/ata/libata-eh.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index e48302eae55..95838b38223 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 | ||
| 399 | static void ata_ering_clear(struct ata_ering *ering) | 400 | int 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 | |||
| 404 | static 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 | ||
| 421 | int 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 | |||
| 427 | static void ata_ering_clear(struct ata_ering *ering) | ||
| 428 | { | ||
| 429 | ata_ering_map(ering, ata_ering_clear_cb, NULL); | ||
| 430 | } | ||
| 431 | |||
| 425 | static unsigned int ata_eh_dev_action(struct ata_device *dev) | 432 | static 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, |
