summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-03-27 19:14:24 +0900
committerJeff Garzik <jgarzik@redhat.com>2008-04-17 15:44:20 -0400
commit03faab7827e4e45823fd27c47b84c133e20a0cd0 (patch)
tree046b04c7e650f5318beb330d70e855a889750154
parenta5987e0a1b569146ed9cfa0a8c275a21b344fcaa (diff)
downloadlinux-03faab7827e4e45823fd27c47b84c133e20a0cd0.tar.gz
linux-03faab7827e4e45823fd27c47b84c133e20a0cd0.tar.bz2
linux-03faab7827e4e45823fd27c47b84c133e20a0cd0.zip
libata: implement ATA_QCFLAG_RETRY
Currently whether a command should be retried after failure is determined inside ata_eh_finish(). Add ATA_QCFLAG_RETRY and move the logic into ata_eh_autopsy(). This makes things clearer and helps extending retry determination logic. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/ata/libata-eh.c18
-rw-r--r--include/linux/libata.h1
2 files changed, 9 insertions, 10 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index ec32082356cb..cc8548e1572a 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1785,6 +1785,11 @@ static void ata_eh_link_autopsy(struct ata_link *link)
if (qc->flags & ATA_QCFLAG_SENSE_VALID)
qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
+ /* determine whether the command is worth retrying */
+ if (!(qc->err_mask & AC_ERR_INVALID) &&
+ ((qc->flags & ATA_QCFLAG_IO) || qc->err_mask != AC_ERR_DEV))
+ qc->flags |= ATA_QCFLAG_RETRY;
+
/* accumulate error info */
ehc->i.dev = qc->dev;
all_err_mask |= qc->err_mask;
@@ -2783,18 +2788,11 @@ void ata_eh_finish(struct ata_port *ap)
/* FIXME: Once EH migration is complete,
* generate sense data in this function,
* considering both err_mask and tf.
- *
- * There's no point in retrying invalid
- * (detected by libata) and non-IO device
- * errors (rejected by device). Finish them
- * immediately.
*/
- if ((qc->err_mask & AC_ERR_INVALID) ||
- (!(qc->flags & ATA_QCFLAG_IO) &&
- qc->err_mask == AC_ERR_DEV))
- ata_eh_qc_complete(qc);
- else
+ if (qc->flags & ATA_QCFLAG_RETRY)
ata_eh_qc_retry(qc);
+ else
+ ata_eh_qc_complete(qc);
} else {
if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
ata_eh_qc_complete(qc);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 61a7f8d06971..b25ea6ab1be9 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -224,6 +224,7 @@ enum {
ATA_QCFLAG_RESULT_TF = (1 << 4), /* result TF requested */
ATA_QCFLAG_CLEAR_EXCL = (1 << 5), /* clear excl_link on completion */
ATA_QCFLAG_QUIET = (1 << 6), /* don't report device error */
+ ATA_QCFLAG_RETRY = (1 << 7), /* retry after failure */
ATA_QCFLAG_FAILED = (1 << 16), /* cmd failed and is owned by EH */
ATA_QCFLAG_SENSE_VALID = (1 << 17), /* sense data valid */