[Devel] [PATCH RHEL7 COMMIT] ms/libata: Implement NCQ autosense
Konstantin Khorenko
khorenko at virtuozzo.com
Tue Oct 1 17:49:57 MSK 2019
The commit is pushed to "branch-rh7-3.10.0-957.27.2.vz7.107.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-957.27.2.vz7.107.11
------>
commit c9ca61b3aacf972ffe982e7d811c058a1a38312d
Author: Hannes Reinecke <hare at suse.de>
Date: Tue Oct 1 17:49:53 2019 +0300
ms/libata: Implement NCQ autosense
Some newer devices support NCQ autosense (cf ACS-4), so we should
be using it to retrieve the sense code and speed up recovery.
Signed-off-by: Hannes Reinecke <hare at suse.de>
Signed-off-by: Tejun Heo <tj at kernel.org>
https://pmc.acronis.com/browse/VSTOR-26930
(cherry picked from commit 5b01e4b9efa0b78672cbbea830c9fbcc7f239e29)
Signed-off-by: Ildar Ismagilov <ildar.ismagilov at virtuozzo.com>
=====================
Patchset description:
Add support of SMR ATA disk
This patchset adds support of SMR ATA disk through SCSI generic interface
aka /dev/sgX.
The SCSI generic interface is used by libzbc library for communicate
with SMR disk. These patches allow us to use SMR disk through
"ata" backend of libzbc ("scsi" and "block" backends aren't supported).
These patches were tested with following command:
libzbc/test/zbc_test.sh /dev/sgX
JIRA: https://pmc.acronis.com/browse/VSTOR-26930
Damien Le Moal (1):
libata: Fix ATA request sense
Hannes Reinecke (5):
libata: Implement ATA_DEV_ZAC
libata-scsi: Update SATL for ZAC drives
libata: Implement NCQ autosense
libata: Implement support for sense data reporting
libata: fixup ZAC device disabling
---
drivers/ata/libata-eh.c | 12 ++++++++++++
drivers/ata/libata-scsi.c | 7 ++++++-
drivers/ata/libata.h | 1 +
include/linux/ata.h | 2 ++
4 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index e52e2758075a..c055ec0c28d5 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1605,6 +1605,8 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
tf->hob_lbah = buf[10];
tf->nsect = buf[12];
tf->hob_nsect = buf[13];
+ if (ata_id_has_ncq_autosense(dev->id))
+ tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16];
return 0;
}
@@ -1802,6 +1804,16 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
memcpy(&qc->result_tf, &tf, sizeof(tf));
qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ;
+ if (qc->result_tf.auxiliary) {
+ char sense_key, asc, ascq;
+
+ 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(qc->scsicmd, sense_key, asc, ascq);
+ qc->flags |= ATA_QCFLAG_SENSE_VALID;
+ }
+
ehc->i.err_mask &= ~AC_ERR_DEV;
}
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 8d907c11c3c9..23311363e1f8 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -269,8 +269,11 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR,
ata_scsi_park_show, ata_scsi_park_store);
EXPORT_SYMBOL_GPL(dev_attr_unload_heads);
-static void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
+void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
{
+ if (!cmd)
+ return;
+
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq);
@@ -1785,6 +1788,8 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
((cdb[2] & 0x20) || need_sense))
ata_gen_passthru_sense(qc);
+ else if (qc->flags & ATA_QCFLAG_SENSE_VALID)
+ cmd->result = SAM_STAT_CHECK_CONDITION;
else if (need_sense)
ata_gen_ata_sense(qc);
else
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index a569b205635c..162f98eb3799 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -137,6 +137,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 void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq);
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);
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 832257f6e6d9..ffde13097ed1 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -527,6 +527,8 @@ struct ata_bmdma_prd {
#define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20)
#define ata_id_has_da(id) ((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4))
#define ata_id_has_devslp(id) ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8))
+#define ata_id_has_ncq_autosense(id) \
+ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7))
static inline bool ata_id_has_hipm(const u16 *id)
{
More information about the Devel
mailing list