summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2016-04-04 11:43:59 +0200
committerTejun Heo <tj@kernel.org>2016-04-04 18:07:41 +0200
commit492bf62107347aca764070dbc9d412da6bda73d1 (patch)
tree6e91e0241f495f04789766492cd254b6f804afb7 /drivers/ata
parentlibata-scsi: use scsi_set_sense_information() (diff)
downloadlinux-492bf62107347aca764070dbc9d412da6bda73d1.tar.xz
linux-492bf62107347aca764070dbc9d412da6bda73d1.zip
libata-eh: Set 'information' field for autosense
If NCQ autosense or the sense data reporting feature is enabled the LBA of the offending command should be stored in the sense data 'information' field. tj: s/(u64)-1/U64_MAX/ Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-eh.c2
-rw-r--r--drivers/ata/libata-scsi.c17
-rw-r--r--drivers/ata/libata.h3
3 files changed, 22 insertions, 0 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 170e891e79af..e4e0e2e80c20 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1856,6 +1856,8 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
asc = (qc->result_tf.auxiliary >> 8) & 0xff;
ascq = qc->result_tf.auxiliary & 0xff;
ata_scsi_set_sense(qc->scsicmd, sense_key, asc, ascq);
+ ata_scsi_set_sense_information(dev, qc->scsicmd,
+ &qc->result_tf);
qc->flags |= ATA_QCFLAG_SENSE_VALID;
}
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 47b103d9baac..97e8f6b0494c 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -280,6 +280,23 @@ void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq);
}
+void ata_scsi_set_sense_information(struct ata_device *dev,
+ struct scsi_cmnd *cmd,
+ const struct ata_taskfile *tf)
+{
+ u64 information;
+
+ if (!cmd)
+ return;
+
+ information = ata_tf_read_block(tf, dev);
+ if (information == U64_MAX)
+ return;
+
+ scsi_set_sense_information(cmd->sense_buffer,
+ SCSI_SENSE_BUFFERSIZE, information);
+}
+
static ssize_t
ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 507c22f7a63b..dbc67604b3c5 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -139,6 +139,9 @@ extern int ata_scsi_add_hosts(struct ata_host *host,
extern void ata_scsi_scan_host(struct ata_port *ap, int sync);
extern int ata_scsi_offline_dev(struct ata_device *dev);
extern void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq);
+extern void ata_scsi_set_sense_information(struct ata_device *dev,
+ struct scsi_cmnd *cmd,
+ const struct ata_taskfile *tf);
extern void ata_scsi_media_change_notify(struct ata_device *dev);
extern void ata_scsi_hotplug(struct work_struct *work);
extern void ata_schedule_scsi_eh(struct Scsi_Host *shost);