@@ -1431,8 +1431,10 @@ static void ata_eh_request_sense(struct ata_queued_cmd *qc)
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
/* Ignore err_mask; ATA_ERR might be set */
if (tf.status & ATA_SENSE) {
- ata_scsi_set_sense(dev, cmd, tf.lbah, tf.lbam, tf.lbal);
- qc->flags |= ATA_QCFLAG_SENSE_VALID;
+ if (ata_scsi_sense_is_valid(tf.lbah, tf.lbam, tf.lbal)) {
+ ata_scsi_set_sense(dev, cmd, tf.lbah, tf.lbam, tf.lbal);
+ qc->flags |= ATA_QCFLAG_SENSE_VALID;
+ }
} else {
ata_dev_warn(dev, "request sense failed stat %02x emask %x\n",
tf.status, err_mask);
@@ -1468,10 +1468,13 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
sense_key = (qc->result_tf.auxiliary >> 16) & 0xff;
asc = (qc->result_tf.auxiliary >> 8) & 0xff;
ascq = qc->result_tf.auxiliary & 0xff;
- ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc, ascq);
- ata_scsi_set_sense_information(dev, qc->scsicmd,
- &qc->result_tf);
- qc->flags |= ATA_QCFLAG_SENSE_VALID;
+ if (ata_scsi_sense_is_valid(sense_key, asc, ascq)) {
+ ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc,
+ ascq);
+ ata_scsi_set_sense_information(dev, qc->scsicmd,
+ &qc->result_tf);
+ qc->flags |= ATA_QCFLAG_SENSE_VALID;
+ }
}
ehc->i.err_mask &= ~AC_ERR_DEV;
@@ -188,6 +188,22 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR,
ata_scsi_park_show, ata_scsi_park_store);
EXPORT_SYMBOL_GPL(dev_attr_unload_heads);
+bool ata_scsi_sense_is_valid(u8 sk, u8 asc, u8 ascq)
+{
+ /*
+ * If sk == NO_SENSE, and asc + ascq == NO ADDITIONAL SENSE INFORMATION,
+ * then there is no sense data to add.
+ */
+ if (sk == 0 && asc == 0 && ascq == 0)
+ return false;
+
+ /* If sk > COMPLETED, sense data is bogus. */
+ if (sk > COMPLETED)
+ return false;
+
+ return true;
+}
+
void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd,
u8 sk, u8 asc, u8 ascq)
{
@@ -114,6 +114,7 @@ extern int ata_scsi_add_hosts(struct ata_host *host,
struct scsi_host_template *sht);
extern void ata_scsi_scan_host(struct ata_port *ap, int sync);
extern int ata_scsi_offline_dev(struct ata_device *dev);
+extern bool ata_scsi_sense_is_valid(u8 sk, u8 asc, u8 ascq);
extern void ata_scsi_set_sense(struct ata_device *dev,
struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq);
extern void ata_scsi_set_sense_information(struct ata_device *dev,