aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/libata-eh.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-05-15 20:58:19 +0900
committerTejun Heo <htejun@gmail.com>2006-05-15 20:58:19 +0900
commit0c247c559cd70f85ba9f0764ce13ae00e20fcad8 (patch)
tree9b0d00b300ad9178438b9c7feba95ed62f540c1a /drivers/scsi/libata-eh.c
parent9be1e979f2e1e57a091a658fa88dac266f9fd6fe (diff)
[PATCH] libata-eh: implement dev->ering
This patch implements ata_ering and uses it to define dev->ering. ata_ering is a ring buffer which records libata errors - whether a command was for normar IO request, err_mask and timestamp. Errors are recorded per-device in dev->ering. This will be used by EH to determine recovery actions. Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/scsi/libata-eh.c')
-rw-r--r--drivers/scsi/libata-eh.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c
index 0803231f657..71ad18b7cff 100644
--- a/drivers/scsi/libata-eh.c
+++ b/drivers/scsi/libata-eh.c
@@ -46,6 +46,51 @@
static void __ata_port_freeze(struct ata_port *ap);
+static void ata_ering_record(struct ata_ering *ering, int is_io,
+ unsigned int err_mask)
+{
+ struct ata_ering_entry *ent;
+
+ WARN_ON(!err_mask);
+
+ ering->cursor++;
+ ering->cursor %= ATA_ERING_SIZE;
+
+ ent = &ering->ring[ering->cursor];
+ ent->is_io = is_io;
+ ent->err_mask = err_mask;
+ ent->timestamp = get_jiffies_64();
+}
+
+static struct ata_ering_entry * ata_ering_top(struct ata_ering *ering)
+{
+ struct ata_ering_entry *ent = &ering->ring[ering->cursor];
+ if (!ent->err_mask)
+ return NULL;
+ return ent;
+}
+
+static int ata_ering_map(struct ata_ering *ering,
+ int (*map_fn)(struct ata_ering_entry *, void *),
+ void *arg)
+{
+ int idx, rc = 0;
+ struct ata_ering_entry *ent;
+
+ idx = ering->cursor;
+ do {
+ ent = &ering->ring[idx];
+ if (!ent->err_mask)
+ break;
+ rc = map_fn(ent, arg);
+ if (rc)
+ break;
+ idx = (idx - 1 + ATA_ERING_SIZE) % ATA_ERING_SIZE;
+ } while (idx != ering->cursor);
+
+ return rc;
+}
+
/**
* ata_scsi_timed_out - SCSI layer time out callback
* @cmd: timed out SCSI command