summaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-eh.c
diff options
context:
space:
mode:
authorHannes Reinecke2016-04-04 11:44:01 +0200
committerTejun Heo2016-04-04 18:07:41 +0200
commit3852e37382664a06cd006bb389a8223e32cedf45 (patch)
treebcdb3a96ee06503433225cde2d3d8dd84d60213a /drivers/ata/libata-eh.c
parentlibata-scsi: use ata_scsi_set_sense() (diff)
downloadkernel-qcow2-linux-3852e37382664a06cd006bb389a8223e32cedf45.tar.gz
kernel-qcow2-linux-3852e37382664a06cd006bb389a8223e32cedf45.tar.xz
kernel-qcow2-linux-3852e37382664a06cd006bb389a8223e32cedf45.zip
libata: evaluate SCSI sense code
Whenever a sense code is set it would need to be evaluated to update the error mask. tj: Cosmetic formatting updates. Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r--drivers/ata/libata-eh.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index e4e0e2e80c20..e37258b78e01 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1920,20 +1920,31 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
tmp = atapi_eh_request_sense(qc->dev,
qc->scsicmd->sense_buffer,
qc->result_tf.feature >> 4);
- if (!tmp) {
- /* ATA_QCFLAG_SENSE_VALID is used to
- * tell atapi_qc_complete() that sense
- * data is already valid.
- *
- * TODO: interpret sense data and set
- * appropriate err_mask.
- */
+ if (!tmp)
qc->flags |= ATA_QCFLAG_SENSE_VALID;
- } else
+ else
qc->err_mask |= tmp;
}
}
+ if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
+ int ret = scsi_check_sense(qc->scsicmd);
+ /*
+ * SUCCESS here means that the sense code could
+ * evaluated and should be passed to the upper layers
+ * for correct evaluation.
+ * FAILED means the sense code could not interpreted
+ * and the device would need to be reset.
+ * NEEDS_RETRY and ADD_TO_MLQUEUE means that the
+ * command would need to be retried.
+ */
+ if (ret == NEEDS_RETRY || ret == ADD_TO_MLQUEUE) {
+ qc->flags |= ATA_QCFLAG_RETRY;
+ qc->err_mask |= AC_ERR_OTHER;
+ } else if (ret != SUCCESS) {
+ qc->err_mask |= AC_ERR_HSM;
+ }
+ }
if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS))
action |= ATA_EH_RESET;