qc->err_mask &= ~AC_ERR_OTHER;
/* SENSE_VALID trumps dev/unknown error and revalidation */
- if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
+ if (qc->flags & ATA_QCFLAG_SENSE_VALID)
qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
- ehc->i.action &= ~ATA_EH_REVALIDATE;
- }
/* accumulate error info */
ehc->i.dev = qc->dev;
if (ap->pflags & ATA_PFLAG_FROZEN ||
all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT))
ehc->i.action |= ATA_EH_SOFTRESET;
- else if (all_err_mask)
+ else if ((is_io && all_err_mask) ||
+ (!is_io && (all_err_mask & ~AC_ERR_DEV)))
ehc->i.action |= ATA_EH_REVALIDATE;
/* if we have offending qcs and the associated failed device */
/* 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)
+ if ((qc->err_mask & AC_ERR_INVALID) ||
+ (!(qc->flags & ATA_QCFLAG_IO) &&
+ qc->err_mask == AC_ERR_DEV))
ata_eh_qc_complete(qc);
else
ata_eh_qc_retry(qc);
unsigned int err_mask, action;
const char *desc;
} sil24_cerr_db[] = {
- [0] = { AC_ERR_DEV, ATA_EH_REVALIDATE,
+ [0] = { AC_ERR_DEV, 0,
"device error" },
- [PORT_CERR_DEV] = { AC_ERR_DEV, ATA_EH_REVALIDATE,
+ [PORT_CERR_DEV] = { AC_ERR_DEV, 0,
"device error via D2H FIS" },
- [PORT_CERR_SDB] = { AC_ERR_DEV, ATA_EH_REVALIDATE,
+ [PORT_CERR_SDB] = { AC_ERR_DEV, 0,
"device error via SDB FIS" },
[PORT_CERR_DATA] = { AC_ERR_ATA_BUS, ATA_EH_SOFTRESET,
"error in data FIS" },