diff options
author | Tejun Heo <htejun@gmail.com> | 2008-03-27 19:14:24 +0900 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-17 15:44:20 -0400 |
commit | 03faab7827e4e45823fd27c47b84c133e20a0cd0 (patch) | |
tree | 046b04c7e650f5318beb330d70e855a889750154 | |
parent | a5987e0a1b569146ed9cfa0a8c275a21b344fcaa (diff) | |
download | linux-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.c | 18 | ||||
-rw-r--r-- | include/linux/libata.h | 1 |
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 */ |