Skip to contentSkip to conversation

libata: ZAC SATL implementation

PATCH In review Hannes Reinecke 2 participants 5 messages Mar 31, 2015

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover libata: ZAC SATL implementation

Hi Tejun,

this patchset implements support for the new ZAC commands 'ZBC IN' and 'ZBC OUT', aka 'REPORT ZONES' and 'RESET WRITE POINTER'. And some additional support bits for host-aware ZAC drives.

Hannes Reinecke (3):
libata: implement ZBC IN translation
libata: Implement ZBC OUT translation
libata: support host-aware ZAC devices

 drivers/ata/libata-core.c     |  17 +++
 drivers/ata/libata-eh.c       |   2 +
 drivers/ata/libata-scsi.c     | 252 +++++++++++++++++++++++++++++++++++++++++-
 include/linux/ata.h           |  16 +++
 include/linux/libata.h        |   1 +
 include/scsi/scsi.h           |   9 ++
 include/trace/events/libata.h |   2 +
 7 files changed, 293 insertions(+), 6 deletions(-)
Signature · 1 line
1.8.5.2
#1 lore raw

PATCH 1/3 libata: implement ZBC IN translation

ZAC drives implement 'zac management in' command template, which maps onto the ZBC IN command.

---
 drivers/ata/libata-eh.c       |   1 +
 drivers/ata/libata-scsi.c     | 144 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/ata.h           |   4 ++
 include/scsi/scsi.h           |   3 +
 include/trace/events/libata.h |   1 +
 5 files changed, 153 insertions(+)
drivers/ata/libata-eh.c +1 -0
index 07f41be..adf306e 100644
@@ -2479,6 +2479,7 @@ const char *ata_get_cmd_descript(u8 command)
 		{ ATA_CMD_CFA_WRITE_MULT_NE,	"CFA WRITE MULTIPLE WITHOUT ERASE" },
 		{ ATA_CMD_REQ_SENSE_DATA,	"REQUEST SENSE DATA EXT" },
 		{ ATA_CMD_SANITIZE_DEVICE,	"SANITIZE DEVICE" },
+		{ ATA_CMD_ZAC_MGMT_IN,		"ZAC MANAGEMENT IN" },
 		{ ATA_CMD_READ_LONG,		"READ LONG (with retries)" },
 		{ ATA_CMD_READ_LONG_ONCE,	"READ LONG (without retries)" },
 		{ ATA_CMD_WRITE_LONG,		"WRITE LONG (with retries)" },
drivers/ata/libata-scsi.c +144 -0

156 lines not on this page · raw message

include/linux/ata.h +4 -0
index b666b77..63427b1 100644
@@ -300,6 +300,7 @@ enum {
 	ATA_CMD_CFA_WRITE_MULT_NE = 0xCD,
 	ATA_CMD_REQ_SENSE_DATA  = 0x0B,
 	ATA_CMD_SANITIZE_DEVICE = 0xB4,
+	ATA_CMD_ZAC_MGMT_IN	= 0x4A,
 
 	/* marked obsolete in the ATA/ATAPI-7 spec */
 	ATA_CMD_RESTORE		= 0x10,
@@ -308,6 +309,9 @@ enum {
 	ATA_SUBCMD_FPDMA_SEND_DSM            = 0x00,
 	ATA_SUBCMD_FPDMA_SEND_WR_LOG_DMA_EXT = 0x02,
 
+	/* Subcmds for ATA_CMD_ZAC_MGMT_IN */
+	ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES = 0x00,
+
 	/* READ_LOG_EXT pages */
 	ATA_LOG_SATA_NCQ	= 0x10,
 	ATA_LOG_NCQ_SEND_RECV	  = 0x13,
include/scsi/scsi.h +3 -0
index d0a66aa..607c25a 100644
@@ -153,6 +153,7 @@ enum scsi_timeouts {
 #define VERIFY_16	      0x8f
 #define SYNCHRONIZE_CACHE_16  0x91
 #define WRITE_SAME_16	      0x93
+#define ZBC_IN		      0x95
 #define SERVICE_ACTION_BIDIRECTIONAL 0x9d
 #define SERVICE_ACTION_IN_16  0x9e
 #define SERVICE_ACTION_OUT_16 0x9f
@@ -181,6 +182,8 @@ enum scsi_timeouts {
 #define MO_SET_PRIORITY       0x0e
 #define MO_SET_TIMESTAMP      0x0f
 #define MO_MANAGEMENT_PROTOCOL_OUT 0x10
+/* values for ZBC_IN */
+#define ZI_REPORT_ZONES	      0x00
 /* values for variable length command */
 #define XDREAD_32	      0x03
 #define XDWRITE_32	      0x04
include/trace/events/libata.h +1 -0
index 8b0fbd9..02ec4e5 100644
@@ -97,6 +97,7 @@
 		 ata_opcode_name(ATA_CMD_CFA_WRITE_MULT_NE),	\
 		 ata_opcode_name(ATA_CMD_REQ_SENSE_DATA),	\
 		 ata_opcode_name(ATA_CMD_SANITIZE_DEVICE),	\
+		 ata_opcode_name(ATA_CMD_ZAC_MGMT_IN),		\
 		 ata_opcode_name(ATA_CMD_RESTORE),		\
 		 ata_opcode_name(ATA_CMD_READ_LONG),		\
 		 ata_opcode_name(ATA_CMD_READ_LONG_ONCE),	\
Signature · 1 line
1.8.5.2
#2 lore raw

PATCH 2/3 libata: Implement ZBC OUT translation

In reply to Hannes Reinecke

ZAC drives implement 'zac management out' command template, which maps onto the ZBC OUT command.

---
 drivers/ata/libata-eh.c       |  1 +
 drivers/ata/libata-scsi.c     | 65 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/ata.h           |  7 +++++
 include/scsi/scsi.h           |  6 ++++
 include/trace/events/libata.h |  1 +
 5 files changed, 80 insertions(+)
drivers/ata/libata-eh.c +1 -0
index adf306e..f12b6e3 100644
@@ -2480,6 +2480,7 @@ const char *ata_get_cmd_descript(u8 command)
 		{ ATA_CMD_REQ_SENSE_DATA,	"REQUEST SENSE DATA EXT" },
 		{ ATA_CMD_SANITIZE_DEVICE,	"SANITIZE DEVICE" },
 		{ ATA_CMD_ZAC_MGMT_IN,		"ZAC MANAGEMENT IN" },
+		{ ATA_CMD_ZAC_MGMT_OUT,		"ZAC MANAGEMENT OUT" },
 		{ ATA_CMD_READ_LONG,		"READ LONG (with retries)" },
 		{ ATA_CMD_READ_LONG_ONCE,	"READ LONG (without retries)" },
 		{ ATA_CMD_WRITE_LONG,		"WRITE LONG (with retries)" },
drivers/ata/libata-scsi.c +65 -0

77 lines not on this page · raw message

include/linux/ata.h +7 -0
index 63427b1..6b2d2b5 100644
@@ -301,6 +301,7 @@ enum {
 	ATA_CMD_REQ_SENSE_DATA  = 0x0B,
 	ATA_CMD_SANITIZE_DEVICE = 0xB4,
 	ATA_CMD_ZAC_MGMT_IN	= 0x4A,
+	ATA_CMD_ZAC_MGMT_OUT	= 0x94,
 
 	/* marked obsolete in the ATA/ATAPI-7 spec */
 	ATA_CMD_RESTORE		= 0x10,
@@ -312,6 +313,12 @@ enum {
 	/* Subcmds for ATA_CMD_ZAC_MGMT_IN */
 	ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES = 0x00,
 
+	/* Subcmds for ATA_CMD_ZAC_MGMT_OUT */
+	ATA_SUBCMD_ZAC_MGMT_OUT_CLOSE_ZONE = 0x01,
+	ATA_SUBCMD_ZAC_MGMT_OUT_FINISH_ZONE = 0x02,
+	ATA_SUBCMD_ZAC_MGMT_OUT_OPEN_ZONE = 0x03,
+	ATA_SUBCMD_ZAC_MGMT_OUT_RESET_WRITE_POINTER = 0x04,
+
 	/* READ_LOG_EXT pages */
 	ATA_LOG_SATA_NCQ	= 0x10,
 	ATA_LOG_NCQ_SEND_RECV	  = 0x13,
include/scsi/scsi.h +6 -0
index 607c25a..ed1c108 100644
@@ -153,6 +153,7 @@ enum scsi_timeouts {
 #define VERIFY_16	      0x8f
 #define SYNCHRONIZE_CACHE_16  0x91
 #define WRITE_SAME_16	      0x93
+#define ZBC_OUT		      0x94
 #define ZBC_IN		      0x95
 #define SERVICE_ACTION_BIDIRECTIONAL 0x9d
 #define SERVICE_ACTION_IN_16  0x9e
@@ -184,6 +185,11 @@ enum scsi_timeouts {
 #define MO_MANAGEMENT_PROTOCOL_OUT 0x10
 /* values for ZBC_IN */
 #define ZI_REPORT_ZONES	      0x00
+/* values for ZBC_OUT */
+#define ZO_CLOSE_ZONE	      0x01
+#define ZO_OPEN_ZONE	      0x02
+#define ZO_FINISH_ZONE	      0x03
+#define ZO_RESET_WRITE_POINTER 0x04
 /* values for variable length command */
 #define XDREAD_32	      0x03
 #define XDWRITE_32	      0x04
include/trace/events/libata.h +1 -0
index 02ec4e5..24dcd43 100644
@@ -98,6 +98,7 @@
 		 ata_opcode_name(ATA_CMD_REQ_SENSE_DATA),	\
 		 ata_opcode_name(ATA_CMD_SANITIZE_DEVICE),	\
 		 ata_opcode_name(ATA_CMD_ZAC_MGMT_IN),		\
+		 ata_opcode_name(ATA_CMD_ZAC_MGMT_OUT),		\
 		 ata_opcode_name(ATA_CMD_RESTORE),		\
 		 ata_opcode_name(ATA_CMD_READ_LONG),		\
 		 ata_opcode_name(ATA_CMD_READ_LONG_ONCE),	\
Signature · 1 line
1.8.5.2
#3 lore raw

PATCH 3/3 libata: support host-aware ZAC devices

In reply to Hannes Reinecke

Byte 69 bits 0:1 in the IDENTIFY DEVICE data are proposed to indicate a host-aware ZAC device.
And whenever we detect a ZAC-compatible device we should be displaying the zoned block characteristics VPD page.

---
 drivers/ata/libata-core.c | 17 +++++++++++++++++
 drivers/ata/libata-scsi.c | 43 +++++++++++++++++++++++++++++++++++++------
 include/linux/ata.h       |  5 +++++
 include/linux/libata.h    |  1 +
 4 files changed, 60 insertions(+), 6 deletions(-)
drivers/ata/libata-core.c +17 -0
index 1882fd2..a3cad3c 100644
@@ -2165,6 +2165,22 @@ static void ata_dev_config_sense_reporting(struct ata_device *dev)
 	}
 }
 
+static void ata_dev_config_zac(struct ata_device *dev)
+{
+	/*
+	 * Always set the 'ZAC' flag for Host-managed devices.
+	 */
+	if (dev->class == ATA_DEV_ZAC) {
+		dev->flags |= ATA_DFLAG_ZAC;
+		return;
+	}
+	/*
+	 * Check for host-aware devices.
+	 */
+	if (ata_id_is_zac_host_aware(dev->id))
+		dev->flags |= ATA_DFLAG_ZAC;
+}
+
 /**
  *	ata_dev_configure - Configure the specified ATA/ATAPI device
  *	@dev: Target device to configure
@@ -2388,6 +2404,7 @@ int ata_dev_configure(struct ata_device *dev)
 				}
 		}
 		ata_dev_config_sense_reporting(dev);
+		ata_dev_config_zac(dev);
 		dev->cdb_len = 16;
 	}
 
drivers/ata/libata-scsi.c +37 -6

94 lines not on this page · raw message

include/linux/ata.h +5 -0
index 6b2d2b5..f8cab27 100644
@@ -889,6 +889,11 @@ static inline bool ata_id_is_ssd(const u16 *id)
 	return id[ATA_ID_ROT_SPEED] == 0x01;
 }
 
+static inline bool ata_id_is_zac_host_aware(const u16 *id)
+{
+	return (id[ATA_ID_ADDITIONAL_SUPP] & 0x3) == 0x1;
+}
+
 static inline bool ata_id_pio_need_iordy(const u16 *id, const u8 pio)
 {
 	/* CF spec. r4.1 Table 22 says no IORDY on PIO5 and PIO6. */
include/linux/libata.h +1 -0
index 6b08cc1..ffef372 100644
@@ -181,6 +181,7 @@ enum {
 	ATA_DFLAG_DA		= (1 << 26), /* device supports Device Attention */
 	ATA_DFLAG_DEVSLP	= (1 << 27), /* device supports Device Sleep */
 	ATA_DFLAG_ACPI_DISABLED = (1 << 28), /* ACPI for the device is disabled */
+	ATA_DFLAG_ZAC		= (1 << 29), /* ZAC device */
 
 	ATA_DEV_UNKNOWN		= 0,	/* unknown device */
 	ATA_DEV_ATA		= 1,	/* ATA device */
Signature · 1 line
1.8.5.2
#4 lore raw

Re: [PATCH 3/3] libata: support host-aware ZAC devices

Quoted 4 lines · On Tue, 31 Mar 2015 10:52:43 +0200 Hannes Reinecke <[email protected]> wrote:

Byte 69 bits 0:1 in the IDENTIFY DEVICE data are proposed to indicate a host-aware ZAC device.
And whenever we detect a ZAC-compatible device we should be displaying the zoned block characteristics VPD page.

I don't think this belongs upstream as is - because this is a "proposed"
- it might change and then we have Linux boxes in the field randomly misinterpreting bits if instead other bits are used or the definition changes.

Until it's officially in the spec there ought IMHO to be a boot option to enable the test.

Alan