linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3 00/14] libata: ZAC support
@ 2016-04-25 10:45 Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 01/14] libata: do not attempt to retrieve sense code twice Hannes Reinecke
                   ` (15 more replies)
  0 siblings, 16 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke

Hi all,

here's a patchset implementing ZAC support for libata.

This is the second part of a larger patchset for ZAC/ZBC support;
it requires the scsi trace fixes queued for in mkp/4.7/scsi-queue and
the patchset 'libata: SATL update' queued in tj/for-4.7-zac.
The full patchset can be found at:

git.kernel.org/hare/scsi-devel/h/zbc.v6

As usual, comments and reviews are welcome.

Changes to v2:
- Include reviews and fixes from Damien Le Moal
- Include reviews from Shaun Tancheff
- Remove NCQ encapsulation for READ LOG DMA EXT

Changes to v1:
- Include reviews from upstream
- Add NCQ encapsulation for ZAC MANAGEMENT commands
- Update libata-trace to decode ZAC MANAGEMENT commands
- Minor fixes accumulated during testing

Hannes Reinecke (14):
  libata: do not attempt to retrieve sense code twice
  libsas: enable FPDMA SEND/RECEIVE
  libata/libsas: Define ATA_CMD_NCQ_NON_DATA
  libata: Separate out ata_dev_config_ncq_send_recv()
  libata: Add command definitions for NCQ Encapsulation for READ LOG DMA
    EXT
  libata: Check log page directory before accessing pages
  libata-trace: decode subcommands
  libata-scsi: Generate sense code for disabled devices
  libata: fixup ZAC device disabling
  libata: implement ZBC IN translation
  libata: Implement ZBC OUT translation
  libata: NCQ encapsulation for ZAC MANAGEMENT OUT
  libata: support device-managed ZAC devices
  libata: support host-aware and host-managed ZAC devices

 drivers/ata/libata-core.c              | 195 +++++++++++++++++++---
 drivers/ata/libata-eh.c                |   6 +-
 drivers/ata/libata-scsi.c              | 295 +++++++++++++++++++++++++++++++--
 drivers/ata/libata-trace.c             |  72 ++++++++
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c |   3 +
 drivers/scsi/isci/request.c            |   5 +-
 drivers/scsi/libsas/sas_ata.c          |   7 +-
 drivers/scsi/mvsas/mv_sas.c            |   5 +-
 drivers/scsi/pm8001/pm8001_sas.c       |   5 +-
 include/linux/ata.h                    |  54 +++++-
 include/linux/libata.h                 |  34 +++-
 include/trace/events/libata.h          |  10 +-
 12 files changed, 649 insertions(+), 42 deletions(-)

-- 
1.8.5.6


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCHv3 01/14] libata: do not attempt to retrieve sense code twice
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
@ 2016-04-25 10:45 ` Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 02/14] libsas: enable FPDMA SEND/RECEIVE Hannes Reinecke
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke, Hannes Reinecke

Do not call ata_request_sense() if the sense code is already
present.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/ata/libata-eh.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 5b340ce..e816619 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1660,7 +1660,7 @@ static void ata_eh_request_sense(struct ata_queued_cmd *qc,
 		return;
 	}
 
-	if (!cmd)
+	if (!cmd || qc->flags & ATA_QCFLAG_SENSE_VALID)
 		return;
 
 	if (!ata_id_sense_reporting_enabled(dev->id)) {
@@ -1849,7 +1849,7 @@ 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) {
+	if ((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary) {
 		char sense_key, asc, ascq;
 
 		sense_key = (qc->result_tf.auxiliary >> 16) & 0xff;
-- 
1.8.5.6


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv3 02/14] libsas: enable FPDMA SEND/RECEIVE
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 01/14] libata: do not attempt to retrieve sense code twice Hannes Reinecke
@ 2016-04-25 10:45 ` Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 03/14] libata/libsas: Define ATA_CMD_NCQ_NON_DATA Hannes Reinecke
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke, Hannes Reinecke

Update libsas and dependent drivers to handle FPDMA
SEND/RECEIVE correctly.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 ++
 drivers/scsi/isci/request.c            | 4 +++-
 drivers/scsi/libsas/sas_ata.c          | 6 ++++--
 drivers/scsi/mvsas/mv_sas.c            | 4 +++-
 drivers/scsi/pm8001/pm8001_sas.c       | 4 +++-
 5 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index b733747..063c176 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -1573,6 +1573,8 @@ static u8 get_ata_protocol(u8 cmd, int direction)
 	switch (cmd) {
 	case ATA_CMD_FPDMA_WRITE:
 	case ATA_CMD_FPDMA_READ:
+	case ATA_CMD_FPDMA_RECV:
+	case ATA_CMD_FPDMA_SEND:
 	return SATA_PROTOCOL_FPDMA;
 
 	case ATA_CMD_ID_ATA:
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index cfd0084..29456e0 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -3169,7 +3169,9 @@ static enum sci_status isci_request_stp_request_construct(struct isci_request *i
 	status = sci_io_request_construct_basic_sata(ireq);
 
 	if (qc && (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
-		   qc->tf.command == ATA_CMD_FPDMA_READ)) {
+		   qc->tf.command == ATA_CMD_FPDMA_READ ||
+		   qc->tf.command == ATA_CMD_FPDMA_RECV ||
+		   qc->tf.command == ATA_CMD_FPDMA_SEND)) {
 		fis->sector_count = qc->tag << 3;
 		ireq->tc->type.stp.ncq_tag = qc->tag;
 	}
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index 9c706d8..fe1cd26 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -205,7 +205,9 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
 	task->task_done = sas_ata_task_done;
 
 	if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
-	    qc->tf.command == ATA_CMD_FPDMA_READ) {
+	    qc->tf.command == ATA_CMD_FPDMA_READ ||
+	    qc->tf.command == ATA_CMD_FPDMA_RECV ||
+	    qc->tf.command == ATA_CMD_FPDMA_SEND) {
 		/* Need to zero out the tag libata assigned us */
 		qc->tf.nsect = 0;
 	}
@@ -548,7 +550,7 @@ static struct ata_port_operations sas_sata_ops = {
 
 static struct ata_port_info sata_port_info = {
 	.flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA | ATA_FLAG_NCQ |
-		 ATA_FLAG_SAS_HOST,
+		 ATA_FLAG_SAS_HOST | ATA_FLAG_FPDMA_AUX,
 	.pio_mask = ATA_PIO4,
 	.mwdma_mask = ATA_MWDMA2,
 	.udma_mask = ATA_UDMA6,
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index 83cd3ea..db37149 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -429,7 +429,9 @@ static u32 mvs_get_ncq_tag(struct sas_task *task, u32 *tag)
 
 	if (qc) {
 		if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
-			qc->tf.command == ATA_CMD_FPDMA_READ) {
+		    qc->tf.command == ATA_CMD_FPDMA_READ ||
+		    qc->tf.command == ATA_CMD_FPDMA_RECV ||
+		    qc->tf.command == ATA_CMD_FPDMA_SEND) {
 			*tag = qc->tag;
 			return 1;
 		}
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 949198c..62abd98 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -280,7 +280,9 @@ u32 pm8001_get_ncq_tag(struct sas_task *task, u32 *tag)
 	struct ata_queued_cmd *qc = task->uldd_task;
 	if (qc) {
 		if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
-			qc->tf.command == ATA_CMD_FPDMA_READ) {
+		    qc->tf.command == ATA_CMD_FPDMA_READ ||
+		    qc->tf.command == ATA_CMD_FPDMA_RECV ||
+		    qc->tf.command == ATA_CMD_FPDMA_SEND) {
 			*tag = qc->tag;
 			return 1;
 		}
-- 
1.8.5.6


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv3 03/14] libata/libsas: Define ATA_CMD_NCQ_NON_DATA
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 01/14] libata: do not attempt to retrieve sense code twice Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 02/14] libsas: enable FPDMA SEND/RECEIVE Hannes Reinecke
@ 2016-04-25 10:45 ` Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 04/14] libata: Separate out ata_dev_config_ncq_send_recv() Hannes Reinecke
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke, Hannes Reinecke

Define the NCQ NON DATA command and update libsas to handle it
correctly.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 1 +
 drivers/scsi/isci/request.c            | 3 ++-
 drivers/scsi/libsas/sas_ata.c          | 3 ++-
 drivers/scsi/mvsas/mv_sas.c            | 3 ++-
 drivers/scsi/pm8001/pm8001_sas.c       | 3 ++-
 include/linux/ata.h                    | 1 +
 include/trace/events/libata.h          | 1 +
 7 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 063c176..e7b0a9f 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -1575,6 +1575,7 @@ static u8 get_ata_protocol(u8 cmd, int direction)
 	case ATA_CMD_FPDMA_READ:
 	case ATA_CMD_FPDMA_RECV:
 	case ATA_CMD_FPDMA_SEND:
+	case ATA_CMD_NCQ_NON_DATA:
 	return SATA_PROTOCOL_FPDMA;
 
 	case ATA_CMD_ID_ATA:
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index 29456e0..b709d2b 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -3171,7 +3171,8 @@ static enum sci_status isci_request_stp_request_construct(struct isci_request *i
 	if (qc && (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
 		   qc->tf.command == ATA_CMD_FPDMA_READ ||
 		   qc->tf.command == ATA_CMD_FPDMA_RECV ||
-		   qc->tf.command == ATA_CMD_FPDMA_SEND)) {
+		   qc->tf.command == ATA_CMD_FPDMA_SEND ||
+		   qc->tf.command == ATA_CMD_NCQ_NON_DATA)) {
 		fis->sector_count = qc->tag << 3;
 		ireq->tc->type.stp.ncq_tag = qc->tag;
 	}
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index fe1cd26..935c430 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -207,7 +207,8 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
 	if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
 	    qc->tf.command == ATA_CMD_FPDMA_READ ||
 	    qc->tf.command == ATA_CMD_FPDMA_RECV ||
-	    qc->tf.command == ATA_CMD_FPDMA_SEND) {
+	    qc->tf.command == ATA_CMD_FPDMA_SEND ||
+	    qc->tf.command == ATA_CMD_NCQ_NON_DATA) {
 		/* Need to zero out the tag libata assigned us */
 		qc->tf.nsect = 0;
 	}
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index db37149..5b9fcff 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -431,7 +431,8 @@ static u32 mvs_get_ncq_tag(struct sas_task *task, u32 *tag)
 		if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
 		    qc->tf.command == ATA_CMD_FPDMA_READ ||
 		    qc->tf.command == ATA_CMD_FPDMA_RECV ||
-		    qc->tf.command == ATA_CMD_FPDMA_SEND) {
+		    qc->tf.command == ATA_CMD_FPDMA_SEND ||
+		    qc->tf.command == ATA_CMD_NCQ_NON_DATA) {
 			*tag = qc->tag;
 			return 1;
 		}
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 62abd98..dc33dfa 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -282,7 +282,8 @@ u32 pm8001_get_ncq_tag(struct sas_task *task, u32 *tag)
 		if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
 		    qc->tf.command == ATA_CMD_FPDMA_READ ||
 		    qc->tf.command == ATA_CMD_FPDMA_RECV ||
-		    qc->tf.command == ATA_CMD_FPDMA_SEND) {
+		    qc->tf.command == ATA_CMD_FPDMA_SEND ||
+		    qc->tf.command == ATA_CMD_NCQ_NON_DATA) {
 			*tag = qc->tag;
 			return 1;
 		}
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 00aebc4..b84210a 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -243,6 +243,7 @@ enum {
 	ATA_CMD_WRITE_QUEUED_FUA_EXT = 0x3E,
 	ATA_CMD_FPDMA_READ	= 0x60,
 	ATA_CMD_FPDMA_WRITE	= 0x61,
+	ATA_CMD_NCQ_NON_DATA	= 0x63,
 	ATA_CMD_FPDMA_SEND	= 0x64,
 	ATA_CMD_FPDMA_RECV	= 0x65,
 	ATA_CMD_PIO_READ	= 0x20,
diff --git a/include/trace/events/libata.h b/include/trace/events/libata.h
index 8b0fbd9..0168603 100644
--- a/include/trace/events/libata.h
+++ b/include/trace/events/libata.h
@@ -39,6 +39,7 @@
 		 ata_opcode_name(ATA_CMD_WRITE_QUEUED_FUA_EXT), \
 		 ata_opcode_name(ATA_CMD_FPDMA_READ),		\
 		 ata_opcode_name(ATA_CMD_FPDMA_WRITE),		\
+		 ata_opcode_name(ATA_CMD_NCQ_NON_DATA),		\
 		 ata_opcode_name(ATA_CMD_FPDMA_SEND),		\
 		 ata_opcode_name(ATA_CMD_FPDMA_RECV),		\
 		 ata_opcode_name(ATA_CMD_PIO_READ),		\
-- 
1.8.5.6


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv3 04/14] libata: Separate out ata_dev_config_ncq_send_recv()
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
                   ` (2 preceding siblings ...)
  2016-04-25 10:45 ` [PATCHv3 03/14] libata/libsas: Define ATA_CMD_NCQ_NON_DATA Hannes Reinecke
@ 2016-04-25 10:45 ` Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 05/14] libata: Add command definitions for NCQ Encapsulation for READ LOG DMA EXT Hannes Reinecke
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke, Hannes Reinecke

Move NCQ SEND/RECEIVE checks into a separate function.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/ata/libata-core.c | 47 +++++++++++++++++++++++++++--------------------
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 7bdb2c4..fa74b57 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2079,6 +2079,31 @@ static inline u8 ata_dev_knobble(struct ata_device *dev)
 	return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
 }
 
+static void ata_dev_config_ncq_send_recv(struct ata_device *dev)
+{
+	struct ata_port *ap = dev->link->ap;
+	unsigned int err_mask;
+
+	err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV,
+				     0, ap->sector_buf, 1);
+	if (err_mask) {
+		ata_dev_dbg(dev,
+			    "failed to get NCQ Send/Recv Log Emask 0x%x\n",
+			    err_mask);
+	} else {
+		u8 *cmds = dev->ncq_send_recv_cmds;
+
+		dev->flags |= ATA_DFLAG_NCQ_SEND_RECV;
+		memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_SEND_RECV_SIZE);
+
+		if (dev->horkage & ATA_HORKAGE_NO_NCQ_TRIM) {
+			ata_dev_dbg(dev, "disabling queued TRIM support\n");
+			cmds[ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET] &=
+				~ATA_LOG_NCQ_SEND_RECV_DSM_TRIM;
+		}
+	}
+}
+
 static int ata_dev_config_ncq(struct ata_device *dev,
 			       char *desc, size_t desc_sz)
 {
@@ -2124,26 +2149,8 @@ static int ata_dev_config_ncq(struct ata_device *dev,
 			ddepth, aa_desc);
 
 	if ((ap->flags & ATA_FLAG_FPDMA_AUX) &&
-	    ata_id_has_ncq_send_and_recv(dev->id)) {
-		err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV,
-					     0, ap->sector_buf, 1);
-		if (err_mask) {
-			ata_dev_dbg(dev,
-				    "failed to get NCQ Send/Recv Log Emask 0x%x\n",
-				    err_mask);
-		} else {
-			u8 *cmds = dev->ncq_send_recv_cmds;
-
-			dev->flags |= ATA_DFLAG_NCQ_SEND_RECV;
-			memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_SEND_RECV_SIZE);
-
-			if (dev->horkage & ATA_HORKAGE_NO_NCQ_TRIM) {
-				ata_dev_dbg(dev, "disabling queued TRIM support\n");
-				cmds[ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET] &=
-					~ATA_LOG_NCQ_SEND_RECV_DSM_TRIM;
-			}
-		}
-	}
+	    ata_id_has_ncq_send_and_recv(dev->id))
+		ata_dev_config_ncq_send_recv(dev);
 
 	return 0;
 }
-- 
1.8.5.6


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv3 05/14] libata: Add command definitions for NCQ Encapsulation for READ LOG DMA EXT
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
                   ` (3 preceding siblings ...)
  2016-04-25 10:45 ` [PATCHv3 04/14] libata: Separate out ata_dev_config_ncq_send_recv() Hannes Reinecke
@ 2016-04-25 10:45 ` Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 06/14] libata: Check log page directory before accessing pages Hannes Reinecke
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke, Hannes Reinecke

ACS-4 defines an NCQ encapsulation for READ LOG DMA EXT.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 include/linux/ata.h    | 5 +++++
 include/linux/libata.h | 7 +++++++
 2 files changed, 12 insertions(+)

diff --git a/include/linux/ata.h b/include/linux/ata.h
index b84210a..94ccde5 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -306,6 +306,9 @@ enum {
 	/* marked obsolete in the ATA/ATAPI-7 spec */
 	ATA_CMD_RESTORE		= 0x10,
 
+	/* Subcmds for ATA_CMD_FPDMA_RECV */
+	ATA_SUBCMD_FPDMA_RECV_RD_LOG_DMA_EXT = 0x01,
+
 	/* Subcmds for ATA_CMD_FPDMA_SEND */
 	ATA_SUBCMD_FPDMA_SEND_DSM            = 0x00,
 	ATA_SUBCMD_FPDMA_SEND_WR_LOG_DMA_EXT = 0x02,
@@ -329,7 +332,9 @@ enum {
 	ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET	= 0x04,
 	ATA_LOG_NCQ_SEND_RECV_DSM_TRIM		= (1 << 0),
 	ATA_LOG_NCQ_SEND_RECV_RD_LOG_OFFSET	= 0x08,
+	ATA_LOG_NCQ_SEND_RECV_RD_LOG_SUPPORTED  = (1 << 0),
 	ATA_LOG_NCQ_SEND_RECV_WR_LOG_OFFSET	= 0x0C,
+	ATA_LOG_NCQ_SEND_RECV_WR_LOG_SUPPORTED  = (1 << 0),
 	ATA_LOG_NCQ_SEND_RECV_SIZE		= 0x10,
 
 	/* READ/WRITE LONG (obsolete) */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index a418bca..09ddb5a 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1642,6 +1642,13 @@ static inline bool ata_fpdma_dsm_supported(struct ata_device *dev)
 		 ATA_LOG_NCQ_SEND_RECV_DSM_TRIM);
 }
 
+static inline bool ata_fpdma_read_log_supported(struct ata_device *dev)
+{
+	return (dev->flags & ATA_DFLAG_NCQ_SEND_RECV) &&
+		(dev->ncq_send_recv_cmds[ATA_LOG_NCQ_SEND_RECV_RD_LOG_OFFSET] &
+		 ATA_LOG_NCQ_SEND_RECV_RD_LOG_SUPPORTED);
+}
+
 static inline void ata_qc_set_polling(struct ata_queued_cmd *qc)
 {
 	qc->tf.ctl |= ATA_NIEN;
-- 
1.8.5.6


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv3 06/14] libata: Check log page directory before accessing pages
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
                   ` (4 preceding siblings ...)
  2016-04-25 10:45 ` [PATCHv3 05/14] libata: Add command definitions for NCQ Encapsulation for READ LOG DMA EXT Hannes Reinecke
@ 2016-04-25 10:45 ` Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 07/14] libata-trace: decode subcommands Hannes Reinecke
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke, Hannes Reinecke

When reading the NCQ Send/Recv log it might actually not
supported, thereby causing irritating messages
'READ LOG DMA EXT failed'.
Instead we should be reading the log directory first to
figure out if the log is actually supported before trying
to access it.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/ata/libata-core.c | 17 +++++++++++++++++
 include/linux/ata.h       |  1 +
 2 files changed, 18 insertions(+)

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index fa74b57..b2bd7c4 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -66,6 +66,7 @@
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 #include <asm/byteorder.h>
+#include <asm/unaligned.h>
 #include <linux/cdrom.h>
 #include <linux/ratelimit.h>
 #include <linux/pm_runtime.h>
@@ -2083,7 +2084,23 @@ static void ata_dev_config_ncq_send_recv(struct ata_device *dev)
 {
 	struct ata_port *ap = dev->link->ap;
 	unsigned int err_mask;
+	int log_index = ATA_LOG_NCQ_SEND_RECV * 2;
+	u16 log_pages;
 
+	err_mask = ata_read_log_page(dev, ATA_LOG_DIRECTORY,
+				     0, ap->sector_buf, 1);
+	if (err_mask) {
+		ata_dev_dbg(dev,
+			    "failed to get Log Directory Emask 0x%x\n",
+			    err_mask);
+		return;
+	}
+	log_pages = get_unaligned_le16(&ap->sector_buf[log_index]);
+	if (!log_pages) {
+		ata_dev_warn(dev,
+			     "NCQ Send/Recv Log not supported\n");
+		return;
+	}
 	err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV,
 				     0, ap->sector_buf, 1);
 	if (err_mask) {
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 94ccde5..b5be5e8 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -314,6 +314,7 @@ enum {
 	ATA_SUBCMD_FPDMA_SEND_WR_LOG_DMA_EXT = 0x02,
 
 	/* READ_LOG_EXT pages */
+	ATA_LOG_DIRECTORY	= 0x0,
 	ATA_LOG_SATA_NCQ	= 0x10,
 	ATA_LOG_NCQ_SEND_RECV	  = 0x13,
 	ATA_LOG_SATA_ID_DEV_DATA  = 0x30,
-- 
1.8.5.6


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv3 07/14] libata-trace: decode subcommands
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
                   ` (5 preceding siblings ...)
  2016-04-25 10:45 ` [PATCHv3 06/14] libata: Check log page directory before accessing pages Hannes Reinecke
@ 2016-04-25 10:45 ` Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 08/14] libata-scsi: Generate sense code for disabled devices Hannes Reinecke
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke, Hannes Reinecke

Some commands like FPDMA RECEIVE or NCQ NON DATA can encapsulate
other commands to NCQ transport. So decode the subcmds, too.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/ata/libata-trace.c    | 43 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/ata.h           | 17 +++++++++++++++++
 include/trace/events/libata.h |  7 ++++++-
 3 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/drivers/ata/libata-trace.c b/drivers/ata/libata-trace.c
index fd30b8c..99ec1e8 100644
--- a/drivers/ata/libata-trace.c
+++ b/drivers/ata/libata-trace.c
@@ -149,3 +149,46 @@ libata_trace_parse_qc_flags(struct trace_seq *p, unsigned int qc_flags)
 
 	return ret;
 }
+
+const char *
+libata_trace_parse_subcmd(struct trace_seq *p, unsigned char cmd,
+			  unsigned char feature, unsigned char hob_nsect)
+{
+	const char *ret = trace_seq_buffer_ptr(p);
+
+	switch (cmd) {
+	case ATA_CMD_FPDMA_RECV:
+		switch (hob_nsect & 0x5f) {
+		case ATA_SUBCMD_FPDMA_RECV_RD_LOG_DMA_EXT:
+			trace_seq_printf(p, " READ_LOG_DMA_EXT");
+			break;
+		}
+		break;
+	case ATA_CMD_FPDMA_SEND:
+		switch (hob_nsect & 0x5f) {
+		case ATA_SUBCMD_FPDMA_SEND_WR_LOG_DMA_EXT:
+			trace_seq_printf(p, " WRITE_LOG_DMA_EXT");
+			break;
+		case ATA_SUBCMD_FPDMA_SEND_DSM:
+			trace_seq_printf(p, " DATASET_MANAGEMENT");
+			break;
+		}
+		break;
+	case ATA_CMD_NCQ_NON_DATA:
+		switch (feature) {
+		case ATA_SUBCMD_NCQ_NON_DATA_ABORT_QUEUE:
+			trace_seq_printf(p, " ABORT_QUEUE");
+			break;
+		case ATA_SUBCMD_NCQ_NON_DATA_SET_FEATURES:
+			trace_seq_printf(p, " SET_FEATURES");
+			break;
+		case ATA_SUBCMD_NCQ_NON_DATA_ZERO_EXT:
+			trace_seq_printf(p, " ZERO_EXT");
+			break;
+		}
+		break;
+	}
+	trace_seq_putc(p, 0);
+
+	return ret;
+}
diff --git a/include/linux/ata.h b/include/linux/ata.h
index b5be5e8..032bb22 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -313,6 +313,11 @@ enum {
 	ATA_SUBCMD_FPDMA_SEND_DSM            = 0x00,
 	ATA_SUBCMD_FPDMA_SEND_WR_LOG_DMA_EXT = 0x02,
 
+	/* Subcmds for ATA_CMD_NCQ_NON_DATA */
+	ATA_SUBCMD_NCQ_NON_DATA_ABORT_QUEUE  = 0x00,
+	ATA_SUBCMD_NCQ_NON_DATA_SET_FEATURES = 0x05,
+	ATA_SUBCMD_NCQ_NON_DATA_ZERO_EXT     = 0x06,
+
 	/* READ_LOG_EXT pages */
 	ATA_LOG_DIRECTORY	= 0x0,
 	ATA_LOG_SATA_NCQ	= 0x10,
@@ -338,6 +343,18 @@ enum {
 	ATA_LOG_NCQ_SEND_RECV_WR_LOG_SUPPORTED  = (1 << 0),
 	ATA_LOG_NCQ_SEND_RECV_SIZE		= 0x10,
 
+	/* NCQ Non-Data log */
+	ATA_LOG_NCQ_NON_DATA_SUBCMDS_OFFSET	= 0x00,
+	ATA_LOG_NCQ_NON_DATA_ABORT_OFFSET	= 0x00,
+	ATA_LOG_NCQ_NON_DATA_ABORT_NCQ		= (1 << 0),
+	ATA_LOG_NCQ_NON_DATA_ABORT_ALL		= (1 << 1),
+	ATA_LOG_NCQ_NON_DATA_ABORT_STREAMING	= (1 << 2),
+	ATA_LOG_NCQ_NON_DATA_ABORT_NON_STREAMING = (1 << 3),
+	ATA_LOG_NCQ_NON_DATA_ABORT_SELECTED	= (1 << 4),
+	ATA_LOG_NCQ_NON_DATA_ZAC_MGMT_OFFSET	= 0x1C,
+	ATA_LOG_NCQ_NON_DATA_ZAC_MGMT_OUT	= (1 << 0),
+	ATA_LOG_NCQ_NON_DATA_SIZE		= 0x40,
+
 	/* READ/WRITE LONG (obsolete) */
 	ATA_CMD_READ_LONG	= 0x22,
 	ATA_CMD_READ_LONG_ONCE	= 0x23,
diff --git a/include/trace/events/libata.h b/include/trace/events/libata.h
index 0168603..8e77572 100644
--- a/include/trace/events/libata.h
+++ b/include/trace/events/libata.h
@@ -140,6 +140,10 @@ const char *libata_trace_parse_eh_err_mask(struct trace_seq *, unsigned int);
 const char *libata_trace_parse_qc_flags(struct trace_seq *, unsigned int);
 #define __parse_qc_flags(f) libata_trace_parse_qc_flags(p, f)
 
+const char *libata_trace_parse_subcmd(struct trace_seq *, unsigned char,
+				      unsigned char, unsigned char);
+#define __parse_subcmd(c,f,h) libata_trace_parse_subcmd(p, c, f, h)
+
 TRACE_EVENT(ata_qc_issue,
 
 	TP_PROTO(struct ata_queued_cmd *qc),
@@ -186,11 +190,12 @@ TRACE_EVENT(ata_qc_issue,
 		__entry->hob_nsect	= qc->tf.hob_nsect;
 	),
 
-	TP_printk("ata_port=%u ata_dev=%u tag=%d proto=%s cmd=%s " \
+	TP_printk("ata_port=%u ata_dev=%u tag=%d proto=%s cmd=%s%s " \
 		  " tf=(%02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x)",
 		  __entry->ata_port, __entry->ata_dev, __entry->tag,
 		  show_protocol_name(__entry->proto),
 		  show_opcode_name(__entry->cmd),
+		  __parse_subcmd(__entry->cmd, __entry->feature, __entry->hob_nsect),
 		  __entry->cmd, __entry->feature, __entry->nsect,
 		  __entry->lbal, __entry->lbam, __entry->lbah,
 		  __entry->hob_feature, __entry->hob_nsect,
-- 
1.8.5.6


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv3 08/14] libata-scsi: Generate sense code for disabled devices
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
                   ` (6 preceding siblings ...)
  2016-04-25 10:45 ` [PATCHv3 07/14] libata-trace: decode subcommands Hannes Reinecke
@ 2016-04-25 10:45 ` Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 09/14] libata: fixup ZAC device disabling Hannes Reinecke
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke, Hannes Reinecke

If a device is disabled after error recovery it doesn't make
any sense to generate an ATA sense, but we should rather
return a generic sense code indicating the device is gone.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/ata/libata-scsi.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 8b61d63..6d78b4b 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1126,6 +1126,12 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
 
 	cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
 
+	if (ata_dev_disabled(dev)) {
+		/* Device disabled after error recovery */
+		/* LOGICAL UNIT NOT READY, HARD RESET REQUIRED */
+		ata_scsi_set_sense(dev, cmd, NOT_READY, 0x04, 0x21);
+		return;
+	}
 	/* Use ata_to_sense_error() to map status register bits
 	 * onto sense key, asc & ascq.
 	 */
-- 
1.8.5.6


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv3 09/14] libata: fixup ZAC device disabling
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
                   ` (7 preceding siblings ...)
  2016-04-25 10:45 ` [PATCHv3 08/14] libata-scsi: Generate sense code for disabled devices Hannes Reinecke
@ 2016-04-25 10:45 ` Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 10/14] libata: implement ZBC IN translation Hannes Reinecke
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke, Hannes Reinecke

libata device disabling is ... curious. So add the correct
definitions that we can disable ZAC devices properly.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 include/linux/libata.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/linux/libata.h b/include/linux/libata.h
index 09ddb5a..92297cd 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -192,7 +192,8 @@ enum {
 	ATA_DEV_SEMB		= 7,	/* SEMB */
 	ATA_DEV_SEMB_UNSUP	= 8,	/* SEMB (unsupported) */
 	ATA_DEV_ZAC		= 9,	/* ZAC device */
-	ATA_DEV_NONE		= 10,	/* no device */
+	ATA_DEV_ZAC_UNSUP	= 10,	/* ZAC device (unsupported) */
+	ATA_DEV_NONE		= 11,	/* no device */
 
 	/* struct ata_link flags */
 	ATA_LFLAG_NO_HRST	= (1 << 1), /* avoid hardreset */
@@ -1524,7 +1525,8 @@ static inline unsigned int ata_class_enabled(unsigned int class)
 static inline unsigned int ata_class_disabled(unsigned int class)
 {
 	return class == ATA_DEV_ATA_UNSUP || class == ATA_DEV_ATAPI_UNSUP ||
-		class == ATA_DEV_PMP_UNSUP || class == ATA_DEV_SEMB_UNSUP;
+		class == ATA_DEV_PMP_UNSUP || class == ATA_DEV_SEMB_UNSUP ||
+		class == ATA_DEV_ZAC_UNSUP;
 }
 
 static inline unsigned int ata_class_absent(unsigned int class)
-- 
1.8.5.6


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv3 10/14] libata: implement ZBC IN translation
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
                   ` (8 preceding siblings ...)
  2016-04-25 10:45 ` [PATCHv3 09/14] libata: fixup ZAC device disabling Hannes Reinecke
@ 2016-04-25 10:45 ` Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 11/14] libata: Implement ZBC OUT translation Hannes Reinecke
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke

ZAC drives implement a 'ZAC Management In' command template,
which maps onto the ZBC IN command.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/ata/libata-eh.c       |   1 +
 drivers/ata/libata-scsi.c     | 157 ++++++++++++++++++++++++++++++++++++++++++
 drivers/ata/libata-trace.c    |  10 +++
 include/linux/ata.h           |  10 ++-
 include/linux/libata.h        |   7 ++
 include/trace/events/libata.h |   1 +
 6 files changed, 185 insertions(+), 1 deletion(-)

diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index e816619..ee6c572 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2482,6 +2482,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)" },
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 6d78b4b..06d5a62 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3318,6 +3318,160 @@ invalid_opcode:
 }
 
 /**
+ *	ata_scsi_report_zones_complete - convert ATA output
+ *	@qc: command structure returning the data
+ *
+ *	Convert T-13 little-endian field representation into
+ *	T-10 big-endian field representation.
+ *	What a mess.
+ */
+static void ata_scsi_report_zones_complete(struct ata_queued_cmd *qc)
+{
+	struct scsi_cmnd *scmd = qc->scsicmd;
+	struct sg_mapping_iter miter;
+	unsigned long flags;
+	unsigned int bytes = 0;
+
+	sg_miter_start(&miter, scsi_sglist(scmd), scsi_sg_count(scmd),
+		       SG_MITER_TO_SG | SG_MITER_ATOMIC);
+
+	local_irq_save(flags);
+	while (sg_miter_next(&miter)) {
+		unsigned int offset = 0;
+
+		if (bytes == 0) {
+			char *hdr;
+			u32 list_length;
+			u64 max_lba, opt_lba;
+			u16 same;
+
+			/* Swizzle header */
+			hdr = miter.addr;
+			list_length = get_unaligned_le32(&hdr[0]);
+			same = get_unaligned_le16(&hdr[4]);
+			max_lba = get_unaligned_le64(&hdr[8]);
+			opt_lba = get_unaligned_le64(&hdr[16]);
+			put_unaligned_be32(list_length, &hdr[0]);
+			hdr[4] = same & 0xf;
+			put_unaligned_be64(max_lba, &hdr[8]);
+			put_unaligned_be64(opt_lba, &hdr[16]);
+			offset += 64;
+			bytes += 64;
+		}
+		while (offset < miter.length) {
+			char *rec;
+			u8 cond, type, non_seq, reset;
+			u64 size, start, wp;
+
+			/* Swizzle zone descriptor */
+			rec = miter.addr + offset;
+			type = rec[0] & 0xf;
+			cond = (rec[1] >> 4) & 0xf;
+			non_seq = (rec[1] & 2);
+			reset = (rec[1] & 1);
+			size = get_unaligned_le64(&rec[8]);
+			start = get_unaligned_le64(&rec[16]);
+			wp = get_unaligned_le64(&rec[24]);
+			rec[0] = type;
+			rec[1] = (cond << 4) | non_seq | reset;
+			put_unaligned_be64(size, &rec[8]);
+			put_unaligned_be64(start, &rec[16]);
+			put_unaligned_be64(wp, &rec[24]);
+			WARN_ON(offset + 64 > miter.length);
+			offset += 64;
+			bytes += 64;
+		}
+	}
+	sg_miter_stop(&miter);
+	local_irq_restore(flags);
+
+	ata_scsi_qc_complete(qc);
+}
+
+static unsigned int ata_scsi_zbc_in_xlat(struct ata_queued_cmd *qc)
+{
+	struct ata_taskfile *tf = &qc->tf;
+	struct scsi_cmnd *scmd = qc->scsicmd;
+	const u8 *cdb = scmd->cmnd;
+	u16 sect, fp = (u16)-1;
+	u8 sa, options, bp = 0xff;
+	u64 block;
+	u32 n_block;
+
+	if (unlikely(scmd->cmd_len < 16)) {
+		ata_dev_warn(qc->dev, "invalid cdb length %d\n",
+			     scmd->cmd_len);
+		fp = 15;
+		goto invalid_fld;
+	}
+	scsi_16_lba_len(cdb, &block, &n_block);
+	if (n_block != scsi_bufflen(scmd)) {
+		ata_dev_warn(qc->dev, "non-matching transfer count (%d/%d)\n",
+			     n_block, scsi_bufflen(scmd));
+		goto invalid_param_len;
+	}
+	sa = cdb[1] & 0x1f;
+	if (sa != ZI_REPORT_ZONES) {
+		ata_dev_warn(qc->dev, "invalid service action %d\n", sa);
+		fp = 1;
+		goto invalid_fld;
+	}
+	/*
+	 * ZAC allows only for transfers in 512 byte blocks,
+	 * and uses a 16 bit value for the transfer count.
+	 */
+	if ((n_block / 512) > 0xffff || n_block < 512 || (n_block % 512)) {
+		ata_dev_warn(qc->dev, "invalid transfer count %d\n", n_block);
+		goto invalid_param_len;
+	}
+	sect = n_block / 512;
+	options = cdb[14];
+
+	if (ata_ncq_enabled(qc->dev) &&
+	    ata_fpdma_zac_mgmt_in_supported(qc->dev)) {
+		tf->protocol = ATA_PROT_NCQ;
+		tf->command = ATA_CMD_FPDMA_RECV;
+		tf->hob_nsect = ATA_SUBCMD_FPDMA_RECV_ZAC_MGMT_IN & 0x1f;
+		tf->nsect = qc->tag << 3;
+		tf->feature = sect & 0xff;
+		tf->hob_feature = (sect >> 8) & 0xff;
+		tf->auxiliary = ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES;
+	} else {
+		tf->command = ATA_CMD_ZAC_MGMT_IN;
+		tf->feature = ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES;
+		tf->protocol = ATA_PROT_DMA;
+		tf->hob_feature = options;
+		tf->hob_nsect = (sect >> 8) & 0xff;
+		tf->nsect = sect & 0xff;
+	}
+	tf->device = ATA_LBA;
+	tf->lbah = (block >> 16) & 0xff;
+	tf->lbam = (block >> 8) & 0xff;
+	tf->lbal = block & 0xff;
+	tf->hob_lbah = (block >> 40) & 0xff;
+	tf->hob_lbam = (block >> 32) & 0xff;
+	tf->hob_lbal = (block >> 24) & 0xff;
+
+	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48;
+	qc->flags |= ATA_QCFLAG_RESULT_TF;
+
+	ata_qc_set_pc_nbytes(qc);
+
+	qc->complete_fn = ata_scsi_report_zones_complete;
+
+	return 0;
+
+invalid_fld:
+	ata_scsi_set_invalid_field(qc->dev, scmd, fp, bp);
+	return 1;
+
+invalid_param_len:
+	/* "Parameter list length error" */
+	ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0);
+	return 1;
+}
+
+/**
  *	ata_mselect_caching - Simulate MODE SELECT for caching info page
  *	@qc: Storage for translated ATA taskfile
  *	@buf: input buffer
@@ -3632,6 +3786,9 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
 		return ata_scsi_mode_select_xlat;
 		break;
 
+	case ZBC_IN:
+		return ata_scsi_zbc_in_xlat;
+
 	case START_STOP:
 		return ata_scsi_start_stop_xlat;
 	}
diff --git a/drivers/ata/libata-trace.c b/drivers/ata/libata-trace.c
index 99ec1e8..9caeabd 100644
--- a/drivers/ata/libata-trace.c
+++ b/drivers/ata/libata-trace.c
@@ -162,6 +162,9 @@ libata_trace_parse_subcmd(struct trace_seq *p, unsigned char cmd,
 		case ATA_SUBCMD_FPDMA_RECV_RD_LOG_DMA_EXT:
 			trace_seq_printf(p, " READ_LOG_DMA_EXT");
 			break;
+		case ATA_SUBCMD_FPDMA_RECV_ZAC_MGMT_IN:
+			trace_seq_printf(p, " ZAC_MGMT_IN");
+			break;
 		}
 		break;
 	case ATA_CMD_FPDMA_SEND:
@@ -187,6 +190,13 @@ libata_trace_parse_subcmd(struct trace_seq *p, unsigned char cmd,
 			break;
 		}
 		break;
+	case ATA_CMD_ZAC_MGMT_IN:
+		switch (feature) {
+		case ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES:
+			trace_seq_printf(p, " REPORT_ZONES");
+			break;
+		}
+		break;
 	}
 	trace_seq_putc(p, 0);
 
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 032bb22..255aa0f 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -302,12 +302,14 @@ 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,
 
 	/* Subcmds for ATA_CMD_FPDMA_RECV */
 	ATA_SUBCMD_FPDMA_RECV_RD_LOG_DMA_EXT = 0x01,
+	ATA_SUBCMD_FPDMA_RECV_ZAC_MGMT_IN    = 0x02,
 
 	/* Subcmds for ATA_CMD_FPDMA_SEND */
 	ATA_SUBCMD_FPDMA_SEND_DSM            = 0x00,
@@ -318,6 +320,9 @@ enum {
 	ATA_SUBCMD_NCQ_NON_DATA_SET_FEATURES = 0x05,
 	ATA_SUBCMD_NCQ_NON_DATA_ZERO_EXT     = 0x06,
 
+	/* Subcmds for ATA_CMD_ZAC_MGMT_IN */
+	ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES = 0x00,
+
 	/* READ_LOG_EXT pages */
 	ATA_LOG_DIRECTORY	= 0x0,
 	ATA_LOG_SATA_NCQ	= 0x10,
@@ -341,7 +346,10 @@ enum {
 	ATA_LOG_NCQ_SEND_RECV_RD_LOG_SUPPORTED  = (1 << 0),
 	ATA_LOG_NCQ_SEND_RECV_WR_LOG_OFFSET	= 0x0C,
 	ATA_LOG_NCQ_SEND_RECV_WR_LOG_SUPPORTED  = (1 << 0),
-	ATA_LOG_NCQ_SEND_RECV_SIZE		= 0x10,
+	ATA_LOG_NCQ_SEND_RECV_ZAC_MGMT_OFFSET	= 0x10,
+	ATA_LOG_NCQ_SEND_RECV_ZAC_MGMT_OUT_SUPPORTED = (1 << 0),
+	ATA_LOG_NCQ_SEND_RECV_ZAC_MGMT_IN_SUPPORTED = (1 << 1),
+	ATA_LOG_NCQ_SEND_RECV_SIZE		= 0x14,
 
 	/* NCQ Non-Data log */
 	ATA_LOG_NCQ_NON_DATA_SUBCMDS_OFFSET	= 0x00,
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 92297cd..c0806b6 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1651,6 +1651,13 @@ static inline bool ata_fpdma_read_log_supported(struct ata_device *dev)
 		 ATA_LOG_NCQ_SEND_RECV_RD_LOG_SUPPORTED);
 }
 
+static inline bool ata_fpdma_zac_mgmt_in_supported(struct ata_device *dev)
+{
+	return (dev->flags & ATA_DFLAG_NCQ_SEND_RECV) &&
+		(dev->ncq_send_recv_cmds[ATA_LOG_NCQ_SEND_RECV_ZAC_MGMT_OFFSET] &
+		ATA_LOG_NCQ_SEND_RECV_ZAC_MGMT_IN_SUPPORTED);
+}
+
 static inline void ata_qc_set_polling(struct ata_queued_cmd *qc)
 {
 	qc->tf.ctl |= ATA_NIEN;
diff --git a/include/trace/events/libata.h b/include/trace/events/libata.h
index 8e77572..77370a6 100644
--- a/include/trace/events/libata.h
+++ b/include/trace/events/libata.h
@@ -98,6 +98,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),	\
-- 
1.8.5.6


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv3 11/14] libata: Implement ZBC OUT translation
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
                   ` (9 preceding siblings ...)
  2016-04-25 10:45 ` [PATCHv3 10/14] libata: implement ZBC IN translation Hannes Reinecke
@ 2016-04-25 10:45 ` Hannes Reinecke
  2016-04-25 10:45 ` [PATCHv3 12/14] libata: NCQ encapsulation for ZAC MANAGEMENT OUT Hannes Reinecke
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke

ZAC drives implement a 'ZAC Management Out' command template,
which maps onto the ZBC OUT command.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/ata/libata-eh.c       |  1 +
 drivers/ata/libata-scsi.c     | 67 +++++++++++++++++++++++++++++++++++++++++++
 drivers/ata/libata-trace.c    | 16 +++++++++++
 include/linux/ata.h           |  7 +++++
 include/trace/events/libata.h |  1 +
 5 files changed, 92 insertions(+)

diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index ee6c572..61dc7a9 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2483,6 +2483,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)" },
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 06d5a62..6afd084 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3471,6 +3471,70 @@ invalid_param_len:
 	return 1;
 }
 
+static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc)
+{
+	struct ata_taskfile *tf = &qc->tf;
+	struct scsi_cmnd *scmd = qc->scsicmd;
+	struct ata_device *dev = qc->dev;
+	const u8 *cdb = scmd->cmnd;
+	u8 reset_all, sa;
+	u64 block;
+	u32 n_block;
+	u16 fp = (u16)-1;
+
+	if (unlikely(scmd->cmd_len < 16)) {
+		fp = 15;
+		goto invalid_fld;
+	}
+
+	sa = cdb[1] & 0x1f;
+	if ((sa != ZO_CLOSE_ZONE) && (sa != ZO_FINISH_ZONE) &&
+	    (sa != ZO_OPEN_ZONE) && (sa != ZO_RESET_WRITE_POINTER)) {
+		fp = 1;
+		goto invalid_fld;
+	}
+
+	scsi_16_lba_len(cdb, &block, &n_block);
+	if (n_block) {
+		/*
+		 * ZAC MANAGEMENT OUT doesn't define any length
+		 */
+		goto invalid_param_len;
+	}
+	if (block > dev->n_sectors)
+		goto out_of_range;
+
+	reset_all = cdb[14] & 0x1;
+
+	tf->protocol = ATA_PROT_NODATA;
+	tf->command = ATA_CMD_ZAC_MGMT_OUT;
+	tf->feature = sa;
+	tf->hob_feature = reset_all & 0x1;
+
+	tf->lbah = (block >> 16) & 0xff;
+	tf->lbam = (block >> 8) & 0xff;
+	tf->lbal = block & 0xff;
+	tf->hob_lbah = (block >> 40) & 0xff;
+	tf->hob_lbam = (block >> 32) & 0xff;
+	tf->hob_lbal = (block >> 24) & 0xff;
+	tf->device = ATA_LBA;
+	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48;
+
+	return 0;
+
+ invalid_fld:
+	ata_scsi_set_invalid_field(qc->dev, scmd, fp, 0xff);
+	return 1;
+ out_of_range:
+	/* "Logical Block Address out of range" */
+	ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x21, 0x00);
+	return 1;
+invalid_param_len:
+	/* "Parameter list length error" */
+	ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0);
+	return 1;
+}
+
 /**
  *	ata_mselect_caching - Simulate MODE SELECT for caching info page
  *	@qc: Storage for translated ATA taskfile
@@ -3789,6 +3853,9 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
 	case ZBC_IN:
 		return ata_scsi_zbc_in_xlat;
 
+	case ZBC_OUT:
+		return ata_scsi_zbc_out_xlat;
+
 	case START_STOP:
 		return ata_scsi_start_stop_xlat;
 	}
diff --git a/drivers/ata/libata-trace.c b/drivers/ata/libata-trace.c
index 9caeabd..1111ba7 100644
--- a/drivers/ata/libata-trace.c
+++ b/drivers/ata/libata-trace.c
@@ -197,6 +197,22 @@ libata_trace_parse_subcmd(struct trace_seq *p, unsigned char cmd,
 			break;
 		}
 		break;
+	case ATA_CMD_ZAC_MGMT_OUT:
+		switch (feature) {
+		case ATA_SUBCMD_ZAC_MGMT_OUT_CLOSE_ZONE:
+			trace_seq_printf(p, " CLOSE_ZONE");
+			break;
+		case ATA_SUBCMD_ZAC_MGMT_OUT_FINISH_ZONE:
+			trace_seq_printf(p, " FINISH_ZONE");
+			break;
+		case ATA_SUBCMD_ZAC_MGMT_OUT_OPEN_ZONE:
+			trace_seq_printf(p, " OPEN_ZONE");
+			break;
+		case ATA_SUBCMD_ZAC_MGMT_OUT_RESET_WRITE_POINTER:
+			trace_seq_printf(p, " RESET_WRITE_POINTER");
+			break;
+		}
+		break;
 	}
 	trace_seq_putc(p, 0);
 
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 255aa0f..9d7c470 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -303,6 +303,7 @@ enum {
 	ATA_CMD_REQ_SENSE_DATA  = 0x0B,
 	ATA_CMD_SANITIZE_DEVICE = 0xB4,
 	ATA_CMD_ZAC_MGMT_IN	= 0x4A,
+	ATA_CMD_ZAC_MGMT_OUT	= 0x9F,
 
 	/* marked obsolete in the ATA/ATAPI-7 spec */
 	ATA_CMD_RESTORE		= 0x10,
@@ -323,6 +324,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_DIRECTORY	= 0x0,
 	ATA_LOG_SATA_NCQ	= 0x10,
diff --git a/include/trace/events/libata.h b/include/trace/events/libata.h
index 77370a6..75fff86 100644
--- a/include/trace/events/libata.h
+++ b/include/trace/events/libata.h
@@ -99,6 +99,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),	\
-- 
1.8.5.6


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv3 12/14] libata: NCQ encapsulation for ZAC MANAGEMENT OUT
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
                   ` (10 preceding siblings ...)
  2016-04-25 10:45 ` [PATCHv3 11/14] libata: Implement ZBC OUT translation Hannes Reinecke
@ 2016-04-25 10:45 ` Hannes Reinecke
  2016-05-13  8:32   ` Damien Le Moal
  2016-04-25 10:45 ` [PATCHv3 13/14] libata: support device-managed ZAC devices Hannes Reinecke
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke, Hannes Reinecke

Add NCQ encapsulation for ZAC MANAGEMENT OUT and evaluate
NCQ Non-Data log pages to figure out if NCQ encapsulation
is supported.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/ata/libata-core.c  | 43 ++++++++++++++++++++++++++++++++++++++++---
 drivers/ata/libata-scsi.c  | 18 +++++++++++++-----
 drivers/ata/libata-trace.c |  3 +++
 include/linux/ata.h        |  7 +++++++
 include/linux/libata.h     |  7 +++++++
 5 files changed, 70 insertions(+), 8 deletions(-)

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b2bd7c4..1528c7c 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2121,6 +2121,40 @@ static void ata_dev_config_ncq_send_recv(struct ata_device *dev)
 	}
 }
 
+static void ata_dev_config_ncq_non_data(struct ata_device *dev)
+{
+	struct ata_port *ap = dev->link->ap;
+	unsigned int err_mask;
+	int log_index = ATA_LOG_NCQ_NON_DATA * 2;
+	u16 log_pages;
+
+	err_mask = ata_read_log_page(dev, ATA_LOG_DIRECTORY,
+				     0, ap->sector_buf, 1);
+	if (err_mask) {
+		ata_dev_dbg(dev,
+			    "failed to get Log Directory Emask 0x%x\n",
+			    err_mask);
+		return;
+	}
+	log_pages = get_unaligned_le16(&ap->sector_buf[log_index]);
+	if (!log_pages) {
+		ata_dev_warn(dev,
+			     "NCQ Send/Recv Log not supported\n");
+		return;
+	}
+	err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_NON_DATA,
+				     0, ap->sector_buf, 1);
+	if (err_mask) {
+		ata_dev_dbg(dev,
+			    "failed to get NCQ Non-Data Log Emask 0x%x\n",
+			    err_mask);
+	} else {
+		u8 *cmds = dev->ncq_non_data_cmds;
+
+		memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_NON_DATA_SIZE);
+	}
+}
+
 static int ata_dev_config_ncq(struct ata_device *dev,
 			       char *desc, size_t desc_sz)
 {
@@ -2165,9 +2199,12 @@ static int ata_dev_config_ncq(struct ata_device *dev,
 		snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth,
 			ddepth, aa_desc);
 
-	if ((ap->flags & ATA_FLAG_FPDMA_AUX) &&
-	    ata_id_has_ncq_send_and_recv(dev->id))
-		ata_dev_config_ncq_send_recv(dev);
+	if ((ap->flags & ATA_FLAG_FPDMA_AUX)) {
+		if (ata_id_has_ncq_send_and_recv(dev->id))
+			ata_dev_config_ncq_send_recv(dev);
+		if (ata_id_has_ncq_non_data(dev->id))
+			ata_dev_config_ncq_non_data(dev);
+	}
 
 	return 0;
 }
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 6afd084..43403aa 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3506,11 +3506,19 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc)
 
 	reset_all = cdb[14] & 0x1;
 
-	tf->protocol = ATA_PROT_NODATA;
-	tf->command = ATA_CMD_ZAC_MGMT_OUT;
-	tf->feature = sa;
-	tf->hob_feature = reset_all & 0x1;
-
+	if (ata_ncq_enabled(qc->dev) &&
+	    ata_fpdma_zac_mgmt_out_supported(qc->dev)) {
+		tf->protocol = ATA_PROT_NCQ;
+		tf->command = ATA_CMD_NCQ_NON_DATA;
+		tf->hob_nsect = ATA_SUBCMD_NCQ_NON_DATA_ZAC_MGMT_OUT;
+		tf->nsect = qc->tag << 3;
+		tf->auxiliary = sa | (reset_all & 0x1) << 8;
+	} else {
+		tf->protocol = ATA_PROT_NODATA;
+		tf->command = ATA_CMD_ZAC_MGMT_OUT;
+		tf->feature = sa;
+		tf->hob_feature = reset_all & 0x1;
+	}
 	tf->lbah = (block >> 16) & 0xff;
 	tf->lbam = (block >> 8) & 0xff;
 	tf->lbal = block & 0xff;
diff --git a/drivers/ata/libata-trace.c b/drivers/ata/libata-trace.c
index 1111ba7..f8c550d 100644
--- a/drivers/ata/libata-trace.c
+++ b/drivers/ata/libata-trace.c
@@ -188,6 +188,9 @@ libata_trace_parse_subcmd(struct trace_seq *p, unsigned char cmd,
 		case ATA_SUBCMD_NCQ_NON_DATA_ZERO_EXT:
 			trace_seq_printf(p, " ZERO_EXT");
 			break;
+		case ATA_SUBCMD_NCQ_NON_DATA_ZAC_MGMT_OUT:
+			trace_seq_printf(p, " ZAC_MGMT_OUT");
+			break;
 		}
 		break;
 	case ATA_CMD_ZAC_MGMT_IN:
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 9d7c470..e627032 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -320,6 +320,7 @@ enum {
 	ATA_SUBCMD_NCQ_NON_DATA_ABORT_QUEUE  = 0x00,
 	ATA_SUBCMD_NCQ_NON_DATA_SET_FEATURES = 0x05,
 	ATA_SUBCMD_NCQ_NON_DATA_ZERO_EXT     = 0x06,
+	ATA_SUBCMD_NCQ_NON_DATA_ZAC_MGMT_OUT = 0x07,
 
 	/* Subcmds for ATA_CMD_ZAC_MGMT_IN */
 	ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES = 0x00,
@@ -333,6 +334,7 @@ enum {
 	/* READ_LOG_EXT pages */
 	ATA_LOG_DIRECTORY	= 0x0,
 	ATA_LOG_SATA_NCQ	= 0x10,
+	ATA_LOG_NCQ_NON_DATA	  = 0x12,
 	ATA_LOG_NCQ_SEND_RECV	  = 0x13,
 	ATA_LOG_SATA_ID_DEV_DATA  = 0x30,
 	ATA_LOG_SATA_SETTINGS	  = 0x08,
@@ -877,6 +879,11 @@ static inline bool ata_id_has_ncq_send_and_recv(const u16 *id)
 	return id[ATA_ID_SATA_CAPABILITY_2] & BIT(6);
 }
 
+static inline bool ata_id_has_ncq_non_data(const u16 *id)
+{
+	return id[ATA_ID_SATA_CAPABILITY_2] & BIT(5);
+}
+
 static inline bool ata_id_has_trim(const u16 *id)
 {
 	if (ata_id_major_version(id) >= 7 &&
diff --git a/include/linux/libata.h b/include/linux/libata.h
index c0806b6..0019d4b 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -729,6 +729,7 @@ struct ata_device {
 
 	/* NCQ send and receive log subcommand support */
 	u8			ncq_send_recv_cmds[ATA_LOG_NCQ_SEND_RECV_SIZE];
+	u8			ncq_non_data_cmds[ATA_LOG_NCQ_NON_DATA_SIZE];
 
 	/* error history */
 	int			spdn_cnt;
@@ -1658,6 +1659,12 @@ static inline bool ata_fpdma_zac_mgmt_in_supported(struct ata_device *dev)
 		ATA_LOG_NCQ_SEND_RECV_ZAC_MGMT_IN_SUPPORTED);
 }
 
+static inline bool ata_fpdma_zac_mgmt_out_supported(struct ata_device *dev)
+{
+	return (dev->ncq_non_data_cmds[ATA_LOG_NCQ_NON_DATA_ZAC_MGMT_OFFSET] &
+		ATA_LOG_NCQ_NON_DATA_ZAC_MGMT_OUT);
+}
+
 static inline void ata_qc_set_polling(struct ata_queued_cmd *qc)
 {
 	qc->tf.ctl |= ATA_NIEN;
-- 
1.8.5.6


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv3 13/14] libata: support device-managed ZAC devices
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
                   ` (11 preceding siblings ...)
  2016-04-25 10:45 ` [PATCHv3 12/14] libata: NCQ encapsulation for ZAC MANAGEMENT OUT Hannes Reinecke
@ 2016-04-25 10:45 ` Hannes Reinecke
  2016-04-25 12:17   ` Sergei Shtylyov
  2016-04-25 10:45 ` [PATCHv3 14/14] libata: support host-aware and host-managed " Hannes Reinecke
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke

Device-managed ZAC devices just set the zoned capabilities field
in INQUIRY byte 69 (cf ACS-4). This corresponds to the 'zoned'
field in the block device characteristics VPD page.
As this is only defined in SPC-5/SBC-4 we also need to update
the supported SCSI version descriptor.

Reviewed-by: Shaun Tancheff <shaun.tancheff@seagate.com>
Tested-by: Shaun Tancheff <shaun.tancheff@seagate.com>
Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/ata/libata-scsi.c | 19 ++++++++++---------
 include/linux/ata.h       |  5 +++++
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 43403aa..96abd42 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2082,14 +2082,14 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
 		0x00,
 		0xA0,	/* SAM-5 (no version claimed) */
 
-		0x04,
-		0xC0,	/* SBC-3 (no version claimed) */
+		0x06,
+		0x00,	/* SBC-4 (no version claimed) */
 
-		0x04,
-		0x60,	/* SPC-4 (no version claimed) */
+		0x05,
+		0xC0,	/* SPC-5 (no version claimed) */
 
 		0x60,
-		0x20,   /* ZBC (no version claimed) */
+		0x24,   /* ZBC r05 */
 	};
 
 	u8 hdr[] = {
@@ -2109,10 +2109,8 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
 	    (args->dev->link->ap->pflags & ATA_PFLAG_EXTERNAL))
 		hdr[1] |= (1 << 7);
 
-	if (args->dev->class == ATA_DEV_ZAC) {
+	if (args->dev->class == ATA_DEV_ZAC)
 		hdr[0] = TYPE_ZBC;
-		hdr[2] = 0x6; /* ZBC is defined in SPC-4 */
-	}
 
 	memcpy(rbuf, hdr, sizeof(hdr));
 	memcpy(&rbuf[8], "ATA     ", 8);
@@ -2126,7 +2124,7 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
 	if (rbuf[32] == 0 || rbuf[32] == ' ')
 		memcpy(&rbuf[32], "n/a ", 4);
 
-	if (args->dev->class == ATA_DEV_ZAC)
+	if (ata_id_zoned_cap(args->id) || args->dev->class == ATA_DEV_ZAC)
 		memcpy(rbuf + 58, versions_zbc, sizeof(versions_zbc));
 	else
 		memcpy(rbuf + 58, versions, sizeof(versions));
@@ -2322,12 +2320,15 @@ static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf)
 {
 	int form_factor = ata_id_form_factor(args->id);
 	int media_rotation_rate = ata_id_rotation_rate(args->id);
+	u8 zoned = ata_id_zoned_cap(args->id);
 
 	rbuf[1] = 0xb1;
 	rbuf[3] = 0x3c;
 	rbuf[4] = media_rotation_rate >> 8;
 	rbuf[5] = media_rotation_rate;
 	rbuf[7] = form_factor;
+	if (zoned)
+		rbuf[8] = (zoned << 4);
 
 	return 0;
 }
diff --git a/include/linux/ata.h b/include/linux/ata.h
index e627032..ac1cb93 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -935,6 +935,11 @@ static inline bool ata_id_is_ssd(const u16 *id)
 	return id[ATA_ID_ROT_SPEED] == 0x01;
 }
 
+static inline u8 ata_id_zoned_cap(const u16 *id)
+{
+	return (id[ATA_ID_ADDITIONAL_SUPP] & 0x3);
+}
+
 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. */
-- 
1.8.5.6


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv3 14/14] libata: support host-aware and host-managed ZAC devices
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
                   ` (12 preceding siblings ...)
  2016-04-25 10:45 ` [PATCHv3 13/14] libata: support device-managed ZAC devices Hannes Reinecke
@ 2016-04-25 10:45 ` Hannes Reinecke
  2016-04-25 20:16 ` [PATCHv3 00/14] libata: ZAC support Tejun Heo
  2016-04-26  0:42 ` Damien Le Moal
  15 siblings, 0 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-25 10:45 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi, Hannes Reinecke

Byte 69 bits 0:1 in the IDENTIFY DEVICE data indicate a
host-aware ZAC device.
Host-managed ZAC devices have their own individual signature,
and to not set the bits in the IDENTIFY DEVICE data.
And whenever we detect a ZAC-compatible device we should
be displaying the zoned block characteristics VPD page.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/ata/libata-core.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/ata/libata-scsi.c | 38 ++++++++++++++++++-
 include/linux/ata.h       |  1 +
 include/linux/libata.h    |  7 ++++
 4 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 1528c7c..97f3170 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2227,6 +2227,99 @@ static void ata_dev_config_sense_reporting(struct ata_device *dev)
 	}
 }
 
+static void ata_dev_config_zac(struct ata_device *dev)
+{
+	struct ata_port *ap = dev->link->ap;
+	unsigned int err_mask;
+	u8 *identify_buf = ap->sector_buf;
+	int log_index = ATA_LOG_SATA_ID_DEV_DATA * 2, i, found = 0;
+	u16 log_pages;
+
+	dev->zac_zones_optimal_open = U32_MAX;
+	dev->zac_zones_optimal_nonseq = U32_MAX;
+	dev->zac_zones_max_open = U32_MAX;
+
+	/*
+	 * Always set the 'ZAC' flag for Host-managed devices.
+	 */
+	if (dev->class == ATA_DEV_ZAC)
+		dev->flags |= ATA_DFLAG_ZAC;
+	else if (ata_id_zoned_cap(dev->id) == 0x01)
+		/*
+		 * Check for host-aware devices.
+		 */
+		dev->flags |= ATA_DFLAG_ZAC;
+
+	if (!(dev->flags & ATA_DFLAG_ZAC))
+		return;
+
+	/*
+	 * Read Log Directory to figure out if IDENTIFY DEVICE log
+	 * is supported.
+	 */
+	err_mask = ata_read_log_page(dev, ATA_LOG_DIRECTORY,
+				     0, ap->sector_buf, 1);
+	if (err_mask) {
+		ata_dev_info(dev,
+			     "failed to get Log Directory Emask 0x%x\n",
+			     err_mask);
+		return;
+	}
+	log_pages = get_unaligned_le16(&ap->sector_buf[log_index]);
+	if (log_pages == 0) {
+		ata_dev_warn(dev,
+			     "ATA Identify Device Log not supported\n");
+		return;
+	}
+	/*
+	 * Read IDENTIFY DEVICE data log, page 0, to figure out
+	 * if page 9 is supported.
+	 */
+	err_mask = ata_read_log_page(dev, ATA_LOG_SATA_ID_DEV_DATA, 0,
+				     identify_buf, 1);
+	if (err_mask) {
+		ata_dev_info(dev,
+			     "failed to get Device Identify Log Emask 0x%x\n",
+			     err_mask);
+		return;
+	}
+	log_pages = identify_buf[8];
+	for (i = 0; i < log_pages; i++) {
+		if (identify_buf[9 + i] == ATA_LOG_ZONED_INFORMATION) {
+			found++;
+			break;
+		}
+	}
+	if (!found) {
+		ata_dev_warn(dev,
+			     "ATA Zoned Information Log not supported\n");
+		return;
+	}
+
+	/*
+	 * Read IDENTIFY DEVICE data log, page 9 (Zoned-device information)
+	 */
+	err_mask = ata_read_log_page(dev, ATA_LOG_SATA_ID_DEV_DATA,
+				     ATA_LOG_ZONED_INFORMATION,
+				     identify_buf, 1);
+	if (!err_mask) {
+		u64 zoned_cap, opt_open, opt_nonseq, max_open;
+
+		zoned_cap = get_unaligned_le64(&identify_buf[8]);
+		if ((zoned_cap >> 63))
+			dev->zac_zoned_cap = (zoned_cap & 1);
+		opt_open = get_unaligned_le64(&identify_buf[24]);
+		if ((opt_open >> 63))
+			dev->zac_zones_optimal_open = (u32)opt_open;
+		opt_nonseq = get_unaligned_le64(&identify_buf[32]);
+		if ((opt_nonseq >> 63))
+			dev->zac_zones_optimal_nonseq = (u32)opt_nonseq;
+		max_open = get_unaligned_le64(&identify_buf[40]);
+		if ((max_open >> 63))
+			dev->zac_zones_max_open = (u32)max_open;
+	}
+}
+
 /**
  *	ata_dev_configure - Configure the specified ATA/ATAPI device
  *	@dev: Target device to configure
@@ -2450,6 +2543,7 @@ int ata_dev_configure(struct ata_device *dev)
 				}
 		}
 		ata_dev_config_sense_reporting(dev);
+		ata_dev_config_zac(dev);
 		dev->cdb_len = 16;
 	}
 
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 96abd42..b86af14 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2144,6 +2144,7 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
  */
 static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf)
 {
+	int num_pages;
 	const u8 pages[] = {
 		0x00,	/* page 0x00, this page */
 		0x80,	/* page 0x80, unit serial no page */
@@ -2152,10 +2153,14 @@ static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf)
 		0xb0,	/* page 0xb0, block limits page */
 		0xb1,	/* page 0xb1, block device characteristics page */
 		0xb2,	/* page 0xb2, thin provisioning page */
+		0xb6,	/* page 0xb6, zoned block device characteristics */
 	};
 
-	rbuf[3] = sizeof(pages);	/* number of supported VPD pages */
-	memcpy(rbuf + 4, pages, sizeof(pages));
+	num_pages = sizeof(pages);
+	if (!(args->dev->flags & ATA_DFLAG_ZAC))
+		num_pages--;
+	rbuf[3] = num_pages;	/* number of supported VPD pages */
+	memcpy(rbuf + 4, pages, num_pages);
 	return 0;
 }
 
@@ -2343,6 +2348,26 @@ static unsigned int ata_scsiop_inq_b2(struct ata_scsi_args *args, u8 *rbuf)
 	return 0;
 }
 
+static unsigned int ata_scsiop_inq_b6(struct ata_scsi_args *args, u8 *rbuf)
+{
+	/*
+	 * zbc-r05 SCSI Zoned Block device characteristics VPD page
+	 */
+	rbuf[1] = 0xb6;
+	rbuf[3] = 0x3C;
+
+	/*
+	 * URSWRZ bit is only meaningful for host-managed ZAC drives
+	 */
+	if (args->dev->zac_zoned_cap & 1)
+		rbuf[4] |= 1;
+	put_unaligned_be32(args->dev->zac_zones_optimal_open, &rbuf[8]);
+	put_unaligned_be32(args->dev->zac_zones_optimal_nonseq, &rbuf[12]);
+	put_unaligned_be32(args->dev->zac_zones_max_open, &rbuf[16]);
+
+	return 0;
+}
+
 /**
  *	ata_scsiop_noop - Command handler that simply returns success.
  *	@args: device IDENTIFY data / SCSI command of interest.
@@ -2661,6 +2686,9 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
 				rbuf[14] |= 0x40; /* LBPRZ */
 			}
 		}
+		if (ata_id_zoned_cap(args->id) ||
+		    args->dev->class == ATA_DEV_ZAC)
+			rbuf[12] = (1 << 4); /* RC_BASIS */
 	}
 	return 0;
 }
@@ -4046,6 +4074,12 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
 		case 0xb2:
 			ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2);
 			break;
+		case 0xb6:
+			if (dev->flags & ATA_DFLAG_ZAC) {
+				ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b6);
+				break;
+			}
+			/* Fallthrough */
 		default:
 			ata_scsi_invalid_field(dev, cmd, 2);
 			break;
diff --git a/include/linux/ata.h b/include/linux/ata.h
index ac1cb93..83e2a99 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -338,6 +338,7 @@ enum {
 	ATA_LOG_NCQ_SEND_RECV	  = 0x13,
 	ATA_LOG_SATA_ID_DEV_DATA  = 0x30,
 	ATA_LOG_SATA_SETTINGS	  = 0x08,
+	ATA_LOG_ZONED_INFORMATION = 0x09,
 	ATA_LOG_DEVSLP_OFFSET	  = 0x30,
 	ATA_LOG_DEVSLP_SIZE	  = 0x08,
 	ATA_LOG_DEVSLP_MDAT	  = 0x00,
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 0019d4b..d15c19e 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -181,6 +181,7 @@ enum {
 	ATA_DFLAG_DEVSLP	= (1 << 27), /* device supports Device Sleep */
 	ATA_DFLAG_ACPI_DISABLED = (1 << 28), /* ACPI for the device is disabled */
 	ATA_DFLAG_D_SENSE	= (1 << 29), /* Descriptor sense requested */
+	ATA_DFLAG_ZAC		= (1 << 30), /* ZAC device */
 
 	ATA_DEV_UNKNOWN		= 0,	/* unknown device */
 	ATA_DEV_ATA		= 1,	/* ATA device */
@@ -731,6 +732,12 @@ struct ata_device {
 	u8			ncq_send_recv_cmds[ATA_LOG_NCQ_SEND_RECV_SIZE];
 	u8			ncq_non_data_cmds[ATA_LOG_NCQ_NON_DATA_SIZE];
 
+	/* ZAC zone configuration */
+	u32			zac_zoned_cap;
+	u32			zac_zones_optimal_open;
+	u32			zac_zones_optimal_nonseq;
+	u32			zac_zones_max_open;
+
 	/* error history */
 	int			spdn_cnt;
 	/* ering is CLEAR_END, read comment above CLEAR_END */
-- 
1.8.5.6


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCHv3 13/14] libata: support device-managed ZAC devices
  2016-04-25 10:45 ` [PATCHv3 13/14] libata: support device-managed ZAC devices Hannes Reinecke
@ 2016-04-25 12:17   ` Sergei Shtylyov
  0 siblings, 0 replies; 23+ messages in thread
From: Sergei Shtylyov @ 2016-04-25 12:17 UTC (permalink / raw)
  To: Hannes Reinecke, Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi

Hello.

On 4/25/2016 1:45 PM, Hannes Reinecke wrote:

> Device-managed ZAC devices just set the zoned capabilities field
> in INQUIRY byte 69 (cf ACS-4). This corresponds to the 'zoned'
> field in the block device characteristics VPD page.
> As this is only defined in SPC-5/SBC-4 we also need to update
> the supported SCSI version descriptor.
>
> Reviewed-by: Shaun Tancheff <shaun.tancheff@seagate.com>
> Tested-by: Shaun Tancheff <shaun.tancheff@seagate.com>
> Signed-off-by: Hannes Reinecke <hare@suse.de>
> ---
>  drivers/ata/libata-scsi.c | 19 ++++++++++---------
>  include/linux/ata.h       |  5 +++++
>  2 files changed, 15 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> index 43403aa..96abd42 100644
> --- a/drivers/ata/libata-scsi.c
> +++ b/drivers/ata/libata-scsi.c
[...]
> @@ -2322,12 +2320,15 @@ static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf)
>  {
>  	int form_factor = ata_id_form_factor(args->id);
>  	int media_rotation_rate = ata_id_rotation_rate(args->id);
> +	u8 zoned = ata_id_zoned_cap(args->id);
>
>  	rbuf[1] = 0xb1;
>  	rbuf[3] = 0x3c;
>  	rbuf[4] = media_rotation_rate >> 8;
>  	rbuf[5] = media_rotation_rate;
>  	rbuf[7] = form_factor;
> +	if (zoned)
> +		rbuf[8] = (zoned << 4);

    Parens not needed here...

[...]
> diff --git a/include/linux/ata.h b/include/linux/ata.h
> index e627032..ac1cb93 100644
> --- a/include/linux/ata.h
> +++ b/include/linux/ata.h
> @@ -935,6 +935,11 @@ static inline bool ata_id_is_ssd(const u16 *id)
>  	return id[ATA_ID_ROT_SPEED] == 0x01;
>  }
>
> +static inline u8 ata_id_zoned_cap(const u16 *id)
> +{
> +	return (id[ATA_ID_ADDITIONAL_SUPP] & 0x3);

    And here as well...

[...]

MBR, Sergei


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCHv3 00/14] libata: ZAC support
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
                   ` (13 preceding siblings ...)
  2016-04-25 10:45 ` [PATCHv3 14/14] libata: support host-aware and host-managed " Hannes Reinecke
@ 2016-04-25 20:16 ` Tejun Heo
  2016-05-06 11:05   ` Hannes Reinecke
  2016-04-26  0:42 ` Damien Le Moal
  15 siblings, 1 reply; 23+ messages in thread
From: Tejun Heo @ 2016-04-25 20:16 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi

Hello,

On Mon, Apr 25, 2016 at 12:45:42PM +0200, Hannes Reinecke wrote:
> here's a patchset implementing ZAC support for libata.
> 
> This is the second part of a larger patchset for ZAC/ZBC support;
> it requires the scsi trace fixes queued for in mkp/4.7/scsi-queue and
> the patchset 'libata: SATL update' queued in tj/for-4.7-zac.

The patches look good from libata side.  If others are okay with it, I
can pull mkp/4.7/scsi-queue into tj/for-4.7-zac and apply this series
on top of it.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCHv3 00/14] libata: ZAC support
  2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
                   ` (14 preceding siblings ...)
  2016-04-25 20:16 ` [PATCHv3 00/14] libata: ZAC support Tejun Heo
@ 2016-04-26  0:42 ` Damien Le Moal
  2016-04-26  5:47   ` Hannes Reinecke
  15 siblings, 1 reply; 23+ messages in thread
From: Damien Le Moal @ 2016-04-26  0:42 UTC (permalink / raw)
  To: Hannes Reinecke, Tejun Heo
  Cc: linux-ide@vger.kernel.org, Shaun Tancheff, Martin K. Petersen,
	linux-scsi@vger.kernel.org


Hannes,

>Hi all,
>
>here's a patchset implementing ZAC support for libata.
>
>This is the second part of a larger patchset for ZAC/ZBC support;
>it requires the scsi trace fixes queued for in mkp/4.7/scsi-queue and
>the patchset 'libata: SATL update' queued in tj/for-4.7-zac.
>The full patchset can be found at:
>
>git.kernel.org/hare/scsi-devel/h/zbc.v6

I do not see a zbc.v6 branch in your scsi-devel tree...


Cheers.

------------------------
Damien Le Moal, Ph.D.
Sr. Manager, System Software Group, HGST Research,
HGST, a Western Digital company
Damien.LeMoal@hgst.com
(+81) 0466-98-3593 (ext. 513593)
1 kirihara-cho, Fujisawa, 
Kanagawa, 252-0888 Japan
www.hgst.com

Western Digital Corporation (and its subsidiaries) E-mail Confidentiality Notice & Disclaimer:

This e-mail and any files transmitted with it may contain confidential or legally privileged information of WDC and/or its affiliates, and are intended solely for the use of the individual or entity to which they are addressed. If you are not the intended recipient, any disclosure, copying, distribution or any action taken or omitted to be taken in reliance on it, is prohibited. If you have received this e-mail in error, please notify the sender immediately and delete the e-mail in its entirety from your system.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCHv3 00/14] libata: ZAC support
  2016-04-26  0:42 ` Damien Le Moal
@ 2016-04-26  5:47   ` Hannes Reinecke
  0 siblings, 0 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-04-26  5:47 UTC (permalink / raw)
  To: Damien Le Moal, Tejun Heo
  Cc: linux-ide@vger.kernel.org, Shaun Tancheff, Martin K. Petersen,
	linux-scsi@vger.kernel.org

On 04/26/2016 02:42 AM, Damien Le Moal wrote:
> 
> Hannes,
> 
>> Hi all,
>>
>> here's a patchset implementing ZAC support for libata.
>>
>> This is the second part of a larger patchset for ZAC/ZBC support;
>> it requires the scsi trace fixes queued for in mkp/4.7/scsi-queue and
>> the patchset 'libata: SATL update' queued in tj/for-4.7-zac.
>> The full patchset can be found at:
>>
>> git.kernel.org/hare/scsi-devel/h/zbc.v6
> 
> I do not see a zbc.v6 branch in your scsi-devel tree...
> 
You do now :-)

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCHv3 00/14] libata: ZAC support
  2016-04-25 20:16 ` [PATCHv3 00/14] libata: ZAC support Tejun Heo
@ 2016-05-06 11:05   ` Hannes Reinecke
  2016-05-09 16:38     ` Tejun Heo
  0 siblings, 1 reply; 23+ messages in thread
From: Hannes Reinecke @ 2016-05-06 11:05 UTC (permalink / raw)
  To: Tejun Heo
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi

On 04/25/2016 10:16 PM, Tejun Heo wrote:
> Hello,
> 
> On Mon, Apr 25, 2016 at 12:45:42PM +0200, Hannes Reinecke wrote:
>> here's a patchset implementing ZAC support for libata.
>>
>> This is the second part of a larger patchset for ZAC/ZBC support;
>> it requires the scsi trace fixes queued for in mkp/4.7/scsi-queue and
>> the patchset 'libata: SATL update' queued in tj/for-4.7-zac.
> 
> The patches look good from libata side.  If others are okay with it, I
> can pull mkp/4.7/scsi-queue into tj/for-4.7-zac and apply this series
> on top of it.
> 
Ping?

I can easily split off the libsas bits into a different patchset if
this turns out to be an issue.
But it would be really good if this could make it 4.7, it will help
further integration a _lot_.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCHv3 00/14] libata: ZAC support
  2016-05-06 11:05   ` Hannes Reinecke
@ 2016-05-09 16:38     ` Tejun Heo
  0 siblings, 0 replies; 23+ messages in thread
From: Tejun Heo @ 2016-05-09 16:38 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: linux-ide, Shaun Tancheff, Damien Le Moal, Martin K. Petersen,
	linux-scsi

On Fri, May 06, 2016 at 01:05:36PM +0200, Hannes Reinecke wrote:
> On 04/25/2016 10:16 PM, Tejun Heo wrote:
> > Hello,
> > 
> > On Mon, Apr 25, 2016 at 12:45:42PM +0200, Hannes Reinecke wrote:
> >> here's a patchset implementing ZAC support for libata.
> >>
> >> This is the second part of a larger patchset for ZAC/ZBC support;
> >> it requires the scsi trace fixes queued for in mkp/4.7/scsi-queue and
> >> the patchset 'libata: SATL update' queued in tj/for-4.7-zac.
> > 
> > The patches look good from libata side.  If others are okay with it, I
> > can pull mkp/4.7/scsi-queue into tj/for-4.7-zac and apply this series
> > on top of it.
> > 
> Ping?
> 
> I can easily split off the libsas bits into a different patchset if
> this turns out to be an issue.
> But it would be really good if this could make it 4.7, it will help
> further integration a _lot_.

Pulled in mkp/4.7/scsi-queue into libata/for-4.7-zac and applied the
patches on top.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCHv3 12/14] libata: NCQ encapsulation for ZAC MANAGEMENT OUT
  2016-04-25 10:45 ` [PATCHv3 12/14] libata: NCQ encapsulation for ZAC MANAGEMENT OUT Hannes Reinecke
@ 2016-05-13  8:32   ` Damien Le Moal
  2016-05-13  8:53     ` Hannes Reinecke
  0 siblings, 1 reply; 23+ messages in thread
From: Damien Le Moal @ 2016-05-13  8:32 UTC (permalink / raw)
  To: Hannes Reinecke, Tejun Heo
  Cc: linux-ide@vger.kernel.org, Martin K. Petersen, Hannes Reinecke


Hannes,

>Add NCQ encapsulation for ZAC MANAGEMENT OUT and evaluate
>NCQ Non-Data log pages to figure out if NCQ encapsulation
>is supported.
...
>diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
>index 6afd084..43403aa 100644
>--- a/drivers/ata/libata-scsi.c
>+++ b/drivers/ata/libata-scsi.c
>@@ -3506,11 +3506,19 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc)
> 
> 	reset_all = cdb[14] & 0x1;
> 
>-	tf->protocol = ATA_PROT_NODATA;
>-	tf->command = ATA_CMD_ZAC_MGMT_OUT;
>-	tf->feature = sa;
>-	tf->hob_feature = reset_all & 0x1;
>-
>+	if (ata_ncq_enabled(qc->dev) &&
>+	    ata_fpdma_zac_mgmt_out_supported(qc->dev)) {
>+		tf->protocol = ATA_PROT_NCQ;
>+		tf->command = ATA_CMD_NCQ_NON_DATA;
>+		tf->hob_nsect = ATA_SUBCMD_NCQ_NON_DATA_ZAC_MGMT_OUT;
>+		tf->nsect = qc->tag << 3;
>+		tf->auxiliary = sa | (reset_all & 0x1) << 8;
>+	} else {
>+		tf->protocol = ATA_PROT_NODATA;
>+		tf->command = ATA_CMD_ZAC_MGMT_OUT;
>+		tf->feature = sa;
>+		tf->hob_feature = reset_all & 0x1;
>+	}

Calls to ata_is_data(prot) for ATA_PROT_NCQ task files will always
return "true", even if the command is ATA_CMD_NCQ_NON_DATA (because
the DMA prot flag is always set by ata_prot_flags for NCQ protocol).
This result in all the ATA_CMD_ZAC_MGMT_OUT commands to fail in
ata_qc_issue because of the check: 

        if (WARN_ON_ONCE(ata_is_data(prot) &&
                         (!qc->sg || !qc->n_elem || !qc->nbytes)))
                goto sys_err;


I am not sure the best way to fix this... Hacking ata_qc_issue using the protocol
AND command code to define a bool "is_data" prevents the error but ata_is_data is
also used in different drivers so a more solid fix seem necessary.

Adding a new ATA_PROT_NCQ_NODATA for ATA_CMD_NCQ_NON_DATA would be better, but this
does not really correspond to anything in the standards. And with this, the error
moves to the command sg dma setup complaining that the DMA direction is not known.
Any ideas ?


Also, the "& 0x1" in "tf->auxiliary = sa | (reset_all & 0x1) << 8;" is not necessary
since reset_all is initialized already as "reset_all = cdb[14] & 0x1;"

Best regards.

------------------------
Damien Le Moal, Ph.D.
Sr. Manager, System Software Group, HGST Research,
HGST, a Western Digital company
Damien.LeMoal@hgst.com
(+81) 0466-98-3593 (ext. 513593)
1 kirihara-cho, Fujisawa, 
Kanagawa, 252-0888 Japan
www.hgst.com
Western Digital Corporation (and its subsidiaries) E-mail Confidentiality Notice & Disclaimer:

This e-mail and any files transmitted with it may contain confidential or legally privileged information of WDC and/or its affiliates, and are intended solely for the use of the individual or entity to which they are addressed. If you are not the intended recipient, any disclosure, copying, distribution or any action taken or omitted to be taken in reliance on it, is prohibited. If you have received this e-mail in error, please notify the sender immediately and delete the e-mail in its entirety from your system.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCHv3 12/14] libata: NCQ encapsulation for ZAC MANAGEMENT OUT
  2016-05-13  8:32   ` Damien Le Moal
@ 2016-05-13  8:53     ` Hannes Reinecke
  0 siblings, 0 replies; 23+ messages in thread
From: Hannes Reinecke @ 2016-05-13  8:53 UTC (permalink / raw)
  To: Damien Le Moal, Hannes Reinecke, Tejun Heo
  Cc: linux-ide@vger.kernel.org, Martin K. Petersen

On 05/13/2016 10:32 AM, Damien Le Moal wrote:
>
> Hannes,
>
>> Add NCQ encapsulation for ZAC MANAGEMENT OUT and evaluate
>> NCQ Non-Data log pages to figure out if NCQ encapsulation
>> is supported.
> ...
>> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
>> index 6afd084..43403aa 100644
>> --- a/drivers/ata/libata-scsi.c
>> +++ b/drivers/ata/libata-scsi.c
>> @@ -3506,11 +3506,19 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc)
>>
>> 	reset_all = cdb[14] & 0x1;
>>
>> -	tf->protocol = ATA_PROT_NODATA;
>> -	tf->command = ATA_CMD_ZAC_MGMT_OUT;
>> -	tf->feature = sa;
>> -	tf->hob_feature = reset_all & 0x1;
>> -
>> +	if (ata_ncq_enabled(qc->dev) &&
>> +	    ata_fpdma_zac_mgmt_out_supported(qc->dev)) {
>> +		tf->protocol = ATA_PROT_NCQ;
>> +		tf->command = ATA_CMD_NCQ_NON_DATA;
>> +		tf->hob_nsect = ATA_SUBCMD_NCQ_NON_DATA_ZAC_MGMT_OUT;
>> +		tf->nsect = qc->tag << 3;
>> +		tf->auxiliary = sa | (reset_all & 0x1) << 8;
>> +	} else {
>> +		tf->protocol = ATA_PROT_NODATA;
>> +		tf->command = ATA_CMD_ZAC_MGMT_OUT;
>> +		tf->feature = sa;
>> +		tf->hob_feature = reset_all & 0x1;
>> +	}
>
> Calls to ata_is_data(prot) for ATA_PROT_NCQ task files will always
> return "true", even if the command is ATA_CMD_NCQ_NON_DATA (because
> the DMA prot flag is always set by ata_prot_flags for NCQ protocol).
> This result in all the ATA_CMD_ZAC_MGMT_OUT commands to fail in
> ata_qc_issue because of the check:
>
>          if (WARN_ON_ONCE(ata_is_data(prot) &&
>                           (!qc->sg || !qc->n_elem || !qc->nbytes)))
>                  goto sys_err;
>
>
> I am not sure the best way to fix this... Hacking ata_qc_issue using the protocol
> AND command code to define a bool "is_data" prevents the error but ata_is_data is
> also used in different drivers so a more solid fix seem necessary.
>
> Adding a new ATA_PROT_NCQ_NODATA for ATA_CMD_NCQ_NON_DATA would be better, but this
> does not really correspond to anything in the standards. And with this, the error
> moves to the command sg dma setup complaining that the DMA direction is not known.
> Any ideas ?
>
Hmm. Isn't there simply an 'ATA_TFLAG_WRITE' missing in tf->flags later on?

>
> Also, the "& 0x1" in "tf->auxiliary = sa | (reset_all & 0x1) << 8;" is not necessary
> since reset_all is initialized already as "reset_all = cdb[14] & 0x1;"
>
Yeah. We can fix it up.

Cheers,

Hannes


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2016-05-13  8:53 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-25 10:45 [PATCHv3 00/14] libata: ZAC support Hannes Reinecke
2016-04-25 10:45 ` [PATCHv3 01/14] libata: do not attempt to retrieve sense code twice Hannes Reinecke
2016-04-25 10:45 ` [PATCHv3 02/14] libsas: enable FPDMA SEND/RECEIVE Hannes Reinecke
2016-04-25 10:45 ` [PATCHv3 03/14] libata/libsas: Define ATA_CMD_NCQ_NON_DATA Hannes Reinecke
2016-04-25 10:45 ` [PATCHv3 04/14] libata: Separate out ata_dev_config_ncq_send_recv() Hannes Reinecke
2016-04-25 10:45 ` [PATCHv3 05/14] libata: Add command definitions for NCQ Encapsulation for READ LOG DMA EXT Hannes Reinecke
2016-04-25 10:45 ` [PATCHv3 06/14] libata: Check log page directory before accessing pages Hannes Reinecke
2016-04-25 10:45 ` [PATCHv3 07/14] libata-trace: decode subcommands Hannes Reinecke
2016-04-25 10:45 ` [PATCHv3 08/14] libata-scsi: Generate sense code for disabled devices Hannes Reinecke
2016-04-25 10:45 ` [PATCHv3 09/14] libata: fixup ZAC device disabling Hannes Reinecke
2016-04-25 10:45 ` [PATCHv3 10/14] libata: implement ZBC IN translation Hannes Reinecke
2016-04-25 10:45 ` [PATCHv3 11/14] libata: Implement ZBC OUT translation Hannes Reinecke
2016-04-25 10:45 ` [PATCHv3 12/14] libata: NCQ encapsulation for ZAC MANAGEMENT OUT Hannes Reinecke
2016-05-13  8:32   ` Damien Le Moal
2016-05-13  8:53     ` Hannes Reinecke
2016-04-25 10:45 ` [PATCHv3 13/14] libata: support device-managed ZAC devices Hannes Reinecke
2016-04-25 12:17   ` Sergei Shtylyov
2016-04-25 10:45 ` [PATCHv3 14/14] libata: support host-aware and host-managed " Hannes Reinecke
2016-04-25 20:16 ` [PATCHv3 00/14] libata: ZAC support Tejun Heo
2016-05-06 11:05   ` Hannes Reinecke
2016-05-09 16:38     ` Tejun Heo
2016-04-26  0:42 ` Damien Le Moal
2016-04-26  5:47   ` Hannes Reinecke

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).