Commit 3852e373 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Tejun Heo

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: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent b525e773
...@@ -1920,20 +1920,31 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, ...@@ -1920,20 +1920,31 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
tmp = atapi_eh_request_sense(qc->dev, tmp = atapi_eh_request_sense(qc->dev,
qc->scsicmd->sense_buffer, qc->scsicmd->sense_buffer,
qc->result_tf.feature >> 4); qc->result_tf.feature >> 4);
if (!tmp) { 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.
*/
qc->flags |= ATA_QCFLAG_SENSE_VALID; qc->flags |= ATA_QCFLAG_SENSE_VALID;
} else else
qc->err_mask |= tmp; 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)) if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS))
action |= ATA_EH_RESET; action |= ATA_EH_RESET;
......
...@@ -452,7 +452,7 @@ static void scsi_report_sense(struct scsi_device *sdev, ...@@ -452,7 +452,7 @@ static void scsi_report_sense(struct scsi_device *sdev,
* When a deferred error is detected the current command has * When a deferred error is detected the current command has
* not been executed and needs retrying. * not been executed and needs retrying.
*/ */
static int scsi_check_sense(struct scsi_cmnd *scmd) int scsi_check_sense(struct scsi_cmnd *scmd)
{ {
struct scsi_device *sdev = scmd->device; struct scsi_device *sdev = scmd->device;
struct scsi_sense_hdr sshdr; struct scsi_sense_hdr sshdr;
...@@ -602,6 +602,7 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) ...@@ -602,6 +602,7 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
return SUCCESS; return SUCCESS;
} }
} }
EXPORT_SYMBOL_GPL(scsi_check_sense);
static void scsi_handle_queue_ramp_up(struct scsi_device *sdev) static void scsi_handle_queue_ramp_up(struct scsi_device *sdev)
{ {
......
...@@ -16,6 +16,7 @@ extern void scsi_report_device_reset(struct Scsi_Host *, int, int); ...@@ -16,6 +16,7 @@ extern void scsi_report_device_reset(struct Scsi_Host *, int, int);
extern int scsi_block_when_processing_errors(struct scsi_device *); extern int scsi_block_when_processing_errors(struct scsi_device *);
extern bool scsi_command_normalize_sense(const struct scsi_cmnd *cmd, extern bool scsi_command_normalize_sense(const struct scsi_cmnd *cmd,
struct scsi_sense_hdr *sshdr); struct scsi_sense_hdr *sshdr);
extern int scsi_check_sense(struct scsi_cmnd *);
static inline bool scsi_sense_is_deferred(const struct scsi_sense_hdr *sshdr) static inline bool scsi_sense_is_deferred(const struct scsi_sense_hdr *sshdr)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment