diff options
author | Gwendal Grignou <gwendal@google.com> | 2010-05-25 15:31:38 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2010-10-21 20:21:03 -0400 |
commit | d9027470b88631d0956ac37cdadfdeb9cdcf2c99 (patch) | |
tree | b15273e88431ba734a24965dfc81132ac13bc8bd /drivers/ata/libata-eh.c | |
parent | f6f94e2ab1b33f0082ac22d71f66385a60d8157f (diff) |
[libata] Add ATA transport class
This is a scheleton for libata transport class.
All information is read only, exporting information from libata:
- ata_port class: one per ATA port
- ata_link class: one per ATA port or 15 for SATA Port Multiplier
- ata_device class: up to 2 for PATA link, usually one for SATA.
Signed-off-by: Gwendal Grignou <gwendal@google.com>
Reviewed-by: Grant Grundler <grundler@google.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
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 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 | ||
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, |