linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/5] CDL Feature control improvements
@ 2025-04-18  7:55 Damien Le Moal
  2025-04-18  7:55 ` [PATCH v2 1/5] ata: libata-scsi: Fix ata_mselect_control_ata_feature() return type Damien Le Moal
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Damien Le Moal @ 2025-04-18  7:55 UTC (permalink / raw)
  To: linux-ide, Niklas Cassel, linux-scsi, Martin K . Petersen

Control of the enable/disable state of an ATA device Command Duration
Limits (CDL) features has issues:
1) Incorrect checks of the feature support for translating a MODE SELECT
   command
2) Incorrect feature state report translation in libata-scsi
3) The state reported when enabling the feature was being ignored, which
   caused needless SET FEATURES commands to be issued to the device,
   thus causing an unwanted reset of the CDL statistics log page (which
   is implied by any CDL activation action).

Patches 2 to 5 patches address these issues. In addition to these, patch
1 corrects an incorrect function return type.

Martin,

I can take the scsi patch if you are OK with it. Or the reverse, you can
take all patches through the scsi tree if you prefer. Please let me
know.

Changes from v1:
 - Added Patch 1 and 2
 - Added review tags to patches 3, 4 and 5

Damien Le Moal (5):
  ata: libata-scsi: Fix ata_mselect_control_ata_feature() return type
  ata: libata-scsi: Fail MODE SELECT for unsupported mode pages
  ata: libata-scsi: Fix ata_msense_control_ata_feature()
  ata: libata-scsi: Improve CDL control
  scsi: Improve CDL control

 drivers/ata/libata-scsi.c | 36 ++++++++++++++++++++++++++++--------
 drivers/scsi/scsi.c       | 36 ++++++++++++++++++++++++------------
 2 files changed, 52 insertions(+), 20 deletions(-)

-- 
2.49.0


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

* [PATCH v2 1/5] ata: libata-scsi: Fix ata_mselect_control_ata_feature() return type
  2025-04-18  7:55 [PATCH v2 0/5] CDL Feature control improvements Damien Le Moal
@ 2025-04-18  7:55 ` Damien Le Moal
  2025-04-18  8:14   ` Niklas Cassel
  2025-04-18  7:55 ` [PATCH v2 2/5] ata: libata-scsi: Fail MODE SELECT for unsupported mode pages Damien Le Moal
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Damien Le Moal @ 2025-04-18  7:55 UTC (permalink / raw)
  To: linux-ide, Niklas Cassel, linux-scsi, Martin K . Petersen

The function ata_mselect_control_ata_feature() has a return type defined
as unsigned int but this function may return negative error codes, which
are correctly propagated up the call chain as integers.

Fix ata_mselect_control_ata_feature() to have the correct int return
type.

While at it, also fix a typo in this function description comment.

Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
---
 drivers/ata/libata-scsi.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 2796c0da8257..24e662c837e3 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3886,12 +3886,11 @@ static int ata_mselect_control_spg0(struct ata_queued_cmd *qc,
 }
 
 /*
- * Translate MODE SELECT control mode page, sub-pages f2h (ATA feature mode
+ * Translate MODE SELECT control mode page, sub-page f2h (ATA feature mode
  * page) into a SET FEATURES command.
  */
-static unsigned int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc,
-						    const u8 *buf, int len,
-						    u16 *fp)
+static int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc,
+					   const u8 *buf, int len, u16 *fp)
 {
 	struct ata_device *dev = qc->dev;
 	struct ata_taskfile *tf = &qc->tf;
-- 
2.49.0


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

* [PATCH v2 2/5] ata: libata-scsi: Fail MODE SELECT for unsupported mode pages
  2025-04-18  7:55 [PATCH v2 0/5] CDL Feature control improvements Damien Le Moal
  2025-04-18  7:55 ` [PATCH v2 1/5] ata: libata-scsi: Fix ata_mselect_control_ata_feature() return type Damien Le Moal
@ 2025-04-18  7:55 ` Damien Le Moal
  2025-04-18  8:40   ` Niklas Cassel
  2025-04-18  7:55 ` [PATCH v2 3/5] ata: libata-scsi: Fix ata_msense_control_ata_feature() Damien Le Moal
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Damien Le Moal @ 2025-04-18  7:55 UTC (permalink / raw)
  To: linux-ide, Niklas Cassel, linux-scsi, Martin K . Petersen

For devices that do not support CDL, the subpage F2h of the control mode
page 0Ah should not be supported. However, the function
ata_mselect_control_ata_feature() does not fail for a device that does
not have the ATA_DFLAG_CDL device flag set, which can lead to an invalid
SET FEATURES command (which will be failed by the device) to be issued.

Modify ata_mselect_control_ata_feature() to return -EOPNOTSUPP if it is
executed for a device without CDL support. This error code is checked by
ata_scsi_mode_select_xlat() (through ata_mselect_control()) to fail the
MODE SELECT command immediately with an ILLEGAL REQUEST / INVALID FIELD
IN CDB asc/ascq as mandated by the SPC specifications for unsupported
mode pages.

Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
---
 drivers/ata/libata-scsi.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 24e662c837e3..15661b05cb48 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3896,6 +3896,15 @@ static int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc,
 	struct ata_taskfile *tf = &qc->tf;
 	u8 cdl_action;
 
+	/*
+	 * The sub-page f2h should only be supported for devices that support
+	 * the T2A and T2B command duration limits mode pages (note here the
+	 * "should" which is what SAT-6 defines). So fail this command if the
+	 * device does not support CDL.
+	 */
+	if (!(dev->flags & ATA_DFLAG_CDL))
+		return -EOPNOTSUPP;
+
 	/*
 	 * The first four bytes of ATA Feature Control mode page are a header,
 	 * so offsets in mpage are off by 4 compared to buf.  Same for len.
@@ -4101,6 +4110,8 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
 	case CONTROL_MPAGE:
 		ret = ata_mselect_control(qc, spg, p, pg_len, &fp);
 		if (ret < 0) {
+			if (ret == -EOPNOTSUPP)
+				goto invalid_fld;
 			fp += hdr_len + bd_len;
 			goto invalid_param;
 		}
-- 
2.49.0


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

* [PATCH v2 3/5] ata: libata-scsi: Fix ata_msense_control_ata_feature()
  2025-04-18  7:55 [PATCH v2 0/5] CDL Feature control improvements Damien Le Moal
  2025-04-18  7:55 ` [PATCH v2 1/5] ata: libata-scsi: Fix ata_mselect_control_ata_feature() return type Damien Le Moal
  2025-04-18  7:55 ` [PATCH v2 2/5] ata: libata-scsi: Fail MODE SELECT for unsupported mode pages Damien Le Moal
@ 2025-04-18  7:55 ` Damien Le Moal
  2025-04-18  7:55 ` [PATCH v2 4/5] ata: libata-scsi: Improve CDL control Damien Le Moal
  2025-04-18  7:55 ` [PATCH v2 5/5] scsi: " Damien Le Moal
  4 siblings, 0 replies; 11+ messages in thread
From: Damien Le Moal @ 2025-04-18  7:55 UTC (permalink / raw)
  To: linux-ide, Niklas Cassel, linux-scsi, Martin K . Petersen

For the ATA features subpage of the control mode page, the T10 SAT-6
specifications state that:

For a MODE SENSE command, the SATL shall return the CDL_CTRL field value
that was last set by an application client.

However, the function ata_msense_control_ata_feature() always sets the
CDL_CTRL field to the 0x02 value to indicate support for the CDL T2A and
T2B pages. This is thus incorrect and the value 0x02 must be reported
only after the user enables the CDL feature, which is indicated with the
ATA_DFLAG_CDL_ENABLED device flag. When this flag is not set, the
CDL_CTRL field of the ATA feature subpage of the control mode page must
report a value of 0x00.

Fix ata_msense_control_ata_feature() to report the correct values for
the CDL_CTRL field, according to the enable/disable state of the device
CDL feature.

Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Niklas Cassel <cassel@kernel.org>
Reviewed-by: Igor Pylypiv <ipylypiv@google.com>
---
 drivers/ata/libata-scsi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 15661b05cb48..f54e8a3dc46d 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2453,8 +2453,8 @@ static unsigned int ata_msense_control_ata_feature(struct ata_device *dev,
 	 */
 	put_unaligned_be16(ATA_FEATURE_SUB_MPAGE_LEN - 4, &buf[2]);
 
-	if (dev->flags & ATA_DFLAG_CDL)
-		buf[4] = 0x02; /* Support T2A and T2B pages */
+	if (dev->flags & ATA_DFLAG_CDL_ENABLED)
+		buf[4] = 0x02; /* T2A and T2B pages enabled */
 	else
 		buf[4] = 0;
 
-- 
2.49.0


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

* [PATCH v2 4/5] ata: libata-scsi: Improve CDL control
  2025-04-18  7:55 [PATCH v2 0/5] CDL Feature control improvements Damien Le Moal
                   ` (2 preceding siblings ...)
  2025-04-18  7:55 ` [PATCH v2 3/5] ata: libata-scsi: Fix ata_msense_control_ata_feature() Damien Le Moal
@ 2025-04-18  7:55 ` Damien Le Moal
  2025-04-18  7:55 ` [PATCH v2 5/5] scsi: " Damien Le Moal
  4 siblings, 0 replies; 11+ messages in thread
From: Damien Le Moal @ 2025-04-18  7:55 UTC (permalink / raw)
  To: linux-ide, Niklas Cassel, linux-scsi, Martin K . Petersen

With ATA devices supporting the CDL feature, using CDL requires that the
feature be enabled with a SET FEATURES command. This command is issued
as the translated command for the MODE SELECT command issued by
scsi_cdl_enable() when the user enables CDL through the device
cdl_enable sysfs attribute.

Currently, ata_mselect_control_ata_feature() always translates a MODE
SELECT command for the ATA features subpage of the control mode page to
a SET FEATURES command to enable or disable CDL based on the cdl_ctrl
field. However, there is no need to issue the SET FEATURES command if:
1) The MODE SELECT command requests disabling CDL and CDL is already
   disabled.
2) The MODE SELECT command requests enabling CDL and CDL is already
   enabled.

Fix ata_mselect_control_ata_feature() to issue the SET FEATURES command
only when necessary. Since enabling CDL also implies a reset of the CDL
statistics log page, avoiding useless CDL enable operations also avoids
clearing the CDL statistics log.

Also add debug messages to clearly signal when CDL is being enabled or
disabled using a SET FEATURES command.

Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Niklas Cassel <cassel@kernel.org>
Reviewed-by: Igor Pylypiv <ipylypiv@google.com>
---
 drivers/ata/libata-scsi.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index f54e8a3dc46d..589dc0df63e9 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3917,17 +3917,27 @@ static int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc,
 	/* Check cdl_ctrl */
 	switch (buf[0] & 0x03) {
 	case 0:
-		/* Disable CDL */
+		/* Disable CDL if it is enabled */
+		if (!(dev->flags & ATA_DFLAG_CDL_ENABLED))
+			return 0;
+		ata_dev_dbg(dev, "Disabling CDL\n");
 		cdl_action = 0;
 		dev->flags &= ~ATA_DFLAG_CDL_ENABLED;
 		break;
 	case 0x02:
-		/* Enable CDL T2A/T2B: NCQ priority must be disabled */
+		/*
+		 * Enable CDL if not already enabled. Since this is mutually
+		 * exclusive with NCQ priority, allow this only if NCQ priority
+		 * is disabled.
+		 */
+		if (dev->flags & ATA_DFLAG_CDL_ENABLED)
+			return 0;
 		if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED) {
 			ata_dev_err(dev,
 				"NCQ priority must be disabled to enable CDL\n");
 			return -EINVAL;
 		}
+		ata_dev_dbg(dev, "Enabling CDL\n");
 		cdl_action = 1;
 		dev->flags |= ATA_DFLAG_CDL_ENABLED;
 		break;
-- 
2.49.0


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

* [PATCH v2 5/5] scsi: Improve CDL control
  2025-04-18  7:55 [PATCH v2 0/5] CDL Feature control improvements Damien Le Moal
                   ` (3 preceding siblings ...)
  2025-04-18  7:55 ` [PATCH v2 4/5] ata: libata-scsi: Improve CDL control Damien Le Moal
@ 2025-04-18  7:55 ` Damien Le Moal
  4 siblings, 0 replies; 11+ messages in thread
From: Damien Le Moal @ 2025-04-18  7:55 UTC (permalink / raw)
  To: linux-ide, Niklas Cassel, linux-scsi, Martin K . Petersen

With ATA devices supporting the CDL feature, using CDL requires that the
feature be enabled with a SET FEATURES command. This command is issued
as the translated command for the MODE SELECT command issued by
scsi_cdl_enable() when the user enables CDL through the device
cdl_enable sysfs attribute.

However, the implementation of scsi_cdl_enable() always issues a MODE
SELECT command for ATA devices when the enable argument is true, even if
CDL is already enabled on the device. While this does not cause any
issue with using CDL descriptors with read/write commands (the CDL
feature will be enabled on the drive), issuing the MODE SELECT command
even when the device CDL feature is already enabled will cause a reset
of the ATA device CDL statistics log page (as defined in ACS, any CDL
enable action must reset the device statistics).

Avoid this needless actions (and the implied statistics log page reset)
by modifying scsi_cdl_enable() to issue the MODE SELECT command to
enable CDL if and only if CDL is not reported as already enabled on the
device.

And while at it, simplify the initialization of the is_ata boolean
variable and move the declaration of the scsi mode data and sense header
variables to within the scope of ATA device handling.

Fixes: 1b22cfb14142 ("scsi: core: Allow enabling and disabling command duration limits")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Niklas Cassel <cassel@kernel.org>
Reviewed-by: Igor Pylypiv <ipylypiv@google.com>
---
 drivers/scsi/scsi.c | 36 ++++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 53daf923ad8e..518a252eb6aa 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -707,26 +707,23 @@ void scsi_cdl_check(struct scsi_device *sdev)
  */
 int scsi_cdl_enable(struct scsi_device *sdev, bool enable)
 {
-	struct scsi_mode_data data;
-	struct scsi_sense_hdr sshdr;
-	struct scsi_vpd *vpd;
-	bool is_ata = false;
 	char buf[64];
+	bool is_ata;
 	int ret;
 
 	if (!sdev->cdl_supported)
 		return -EOPNOTSUPP;
 
 	rcu_read_lock();
-	vpd = rcu_dereference(sdev->vpd_pg89);
-	if (vpd)
-		is_ata = true;
+	is_ata = rcu_dereference(sdev->vpd_pg89);
 	rcu_read_unlock();
 
 	/*
 	 * For ATA devices, CDL needs to be enabled with a SET FEATURES command.
 	 */
 	if (is_ata) {
+		struct scsi_mode_data data;
+		struct scsi_sense_hdr sshdr;
 		char *buf_data;
 		int len;
 
@@ -735,16 +732,30 @@ int scsi_cdl_enable(struct scsi_device *sdev, bool enable)
 		if (ret)
 			return -EINVAL;
 
-		/* Enable CDL using the ATA feature page */
+		/* Enable or disable CDL using the ATA feature page */
 		len = min_t(size_t, sizeof(buf),
 			    data.length - data.header_length -
 			    data.block_descriptor_length);
 		buf_data = buf + data.header_length +
 			data.block_descriptor_length;
-		if (enable)
-			buf_data[4] = 0x02;
-		else
-			buf_data[4] = 0;
+
+		/*
+		 * If we want to enable CDL and CDL is already enabled on the
+		 * device, do nothing. This avoids needlessly resetting the CDL
+		 * statistics on the device as that is implied by the CDL enable
+		 * action. Similar to this, there is no need to do anything if
+		 * we want to disable CDL and CDL is already disabled.
+		 */
+		if (enable) {
+			if ((buf_data[4] & 0x03) == 0x02)
+				goto out;
+			buf_data[4] &= ~0x03;
+			buf_data[4] |= 0x02;
+		} else {
+			if ((buf_data[4] & 0x03) == 0x00)
+				goto out;
+			buf_data[4] &= ~0x03;
+		}
 
 		ret = scsi_mode_select(sdev, 1, 0, buf_data, len, 5 * HZ, 3,
 				       &data, &sshdr);
@@ -756,6 +767,7 @@ int scsi_cdl_enable(struct scsi_device *sdev, bool enable)
 		}
 	}
 
+out:
 	sdev->cdl_enable = enable;
 
 	return 0;
-- 
2.49.0


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

* Re: [PATCH v2 1/5] ata: libata-scsi: Fix ata_mselect_control_ata_feature() return type
  2025-04-18  7:55 ` [PATCH v2 1/5] ata: libata-scsi: Fix ata_mselect_control_ata_feature() return type Damien Le Moal
@ 2025-04-18  8:14   ` Niklas Cassel
  0 siblings, 0 replies; 11+ messages in thread
From: Niklas Cassel @ 2025-04-18  8:14 UTC (permalink / raw)
  To: Damien Le Moal; +Cc: linux-ide, linux-scsi, Martin K . Petersen

On Fri, Apr 18, 2025 at 04:55:13PM +0900, Damien Le Moal wrote:
> The function ata_mselect_control_ata_feature() has a return type defined
> as unsigned int but this function may return negative error codes, which
> are correctly propagated up the call chain as integers.
> 
> Fix ata_mselect_control_ata_feature() to have the correct int return
> type.
> 
> While at it, also fix a typo in this function description comment.
> 
> Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation")
> Cc: stable@vger.kernel.org
> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
> ---

Reviewed-by: Niklas Cassel <cassel@kernel.org>

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

* Re: [PATCH v2 2/5] ata: libata-scsi: Fail MODE SELECT for unsupported mode pages
  2025-04-18  7:55 ` [PATCH v2 2/5] ata: libata-scsi: Fail MODE SELECT for unsupported mode pages Damien Le Moal
@ 2025-04-18  8:40   ` Niklas Cassel
  2025-04-18  9:30     ` Damien Le Moal
  0 siblings, 1 reply; 11+ messages in thread
From: Niklas Cassel @ 2025-04-18  8:40 UTC (permalink / raw)
  To: Damien Le Moal; +Cc: linux-ide, linux-scsi, Martin K . Petersen

On Fri, Apr 18, 2025 at 04:55:14PM +0900, Damien Le Moal wrote:
> For devices that do not support CDL, the subpage F2h of the control mode
> page 0Ah should not be supported. However, the function
> ata_mselect_control_ata_feature() does not fail for a device that does
> not have the ATA_DFLAG_CDL device flag set, which can lead to an invalid
> SET FEATURES command (which will be failed by the device) to be issued.
> 
> Modify ata_mselect_control_ata_feature() to return -EOPNOTSUPP if it is
> executed for a device without CDL support. This error code is checked by
> ata_scsi_mode_select_xlat() (through ata_mselect_control()) to fail the
> MODE SELECT command immediately with an ILLEGAL REQUEST / INVALID FIELD
> IN CDB asc/ascq as mandated by the SPC specifications for unsupported
> mode pages.
> 
> Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation")
> Cc: stable@vger.kernel.org
> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
> ---
>  drivers/ata/libata-scsi.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> index 24e662c837e3..15661b05cb48 100644
> --- a/drivers/ata/libata-scsi.c
> +++ b/drivers/ata/libata-scsi.c
> @@ -3896,6 +3896,15 @@ static int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc,
>  	struct ata_taskfile *tf = &qc->tf;
>  	u8 cdl_action;
>  
> +	/*
> +	 * The sub-page f2h should only be supported for devices that support
> +	 * the T2A and T2B command duration limits mode pages (note here the
> +	 * "should" which is what SAT-6 defines). So fail this command if the
> +	 * device does not support CDL.
> +	 */
> +	if (!(dev->flags & ATA_DFLAG_CDL))
> +		return -EOPNOTSUPP;
> +
>  	/*
>  	 * The first four bytes of ATA Feature Control mode page are a header,
>  	 * so offsets in mpage are off by 4 compared to buf.  Same for len.
> @@ -4101,6 +4110,8 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
>  	case CONTROL_MPAGE:
>  		ret = ata_mselect_control(qc, spg, p, pg_len, &fp);
>  		if (ret < 0) {
> +			if (ret == -EOPNOTSUPP)
> +				goto invalid_fld;
>  			fp += hdr_len + bd_len;
>  			goto invalid_param;
>  		}
> -- 

I would prefer if we did not merge this patch, as it is already handled in
higher up in the (only) calling function:
https://github.com/torvalds/linux/blob/v6.15-rc2/drivers/ata/libata-scsi.c#L2582-L2589

We only break if "dev->flags & ATA_DFLAG_CDL && pg == CONTROL_MPAGE"

if this expression is false, we do a fallthrough,
which means fp = 3; goto invalid_fld;


Kind regards,
Niklas

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

* Re: [PATCH v2 2/5] ata: libata-scsi: Fail MODE SELECT for unsupported mode pages
  2025-04-18  8:40   ` Niklas Cassel
@ 2025-04-18  9:30     ` Damien Le Moal
  2025-04-18 11:45       ` Niklas Cassel
  0 siblings, 1 reply; 11+ messages in thread
From: Damien Le Moal @ 2025-04-18  9:30 UTC (permalink / raw)
  To: Niklas Cassel; +Cc: linux-ide, linux-scsi, Martin K . Petersen

On 4/18/25 17:40, Niklas Cassel wrote:
> On Fri, Apr 18, 2025 at 04:55:14PM +0900, Damien Le Moal wrote:
>> For devices that do not support CDL, the subpage F2h of the control mode
>> page 0Ah should not be supported. However, the function
>> ata_mselect_control_ata_feature() does not fail for a device that does
>> not have the ATA_DFLAG_CDL device flag set, which can lead to an invalid
>> SET FEATURES command (which will be failed by the device) to be issued.
>>
>> Modify ata_mselect_control_ata_feature() to return -EOPNOTSUPP if it is
>> executed for a device without CDL support. This error code is checked by
>> ata_scsi_mode_select_xlat() (through ata_mselect_control()) to fail the
>> MODE SELECT command immediately with an ILLEGAL REQUEST / INVALID FIELD
>> IN CDB asc/ascq as mandated by the SPC specifications for unsupported
>> mode pages.
>>
>> Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation")
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
>> ---
>>  drivers/ata/libata-scsi.c | 11 +++++++++++
>>  1 file changed, 11 insertions(+)
>>
>> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
>> index 24e662c837e3..15661b05cb48 100644
>> --- a/drivers/ata/libata-scsi.c
>> +++ b/drivers/ata/libata-scsi.c
>> @@ -3896,6 +3896,15 @@ static int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc,
>>  	struct ata_taskfile *tf = &qc->tf;
>>  	u8 cdl_action;
>>  
>> +	/*
>> +	 * The sub-page f2h should only be supported for devices that support
>> +	 * the T2A and T2B command duration limits mode pages (note here the
>> +	 * "should" which is what SAT-6 defines). So fail this command if the
>> +	 * device does not support CDL.
>> +	 */
>> +	if (!(dev->flags & ATA_DFLAG_CDL))
>> +		return -EOPNOTSUPP;
>> +
>>  	/*
>>  	 * The first four bytes of ATA Feature Control mode page are a header,
>>  	 * so offsets in mpage are off by 4 compared to buf.  Same for len.
>> @@ -4101,6 +4110,8 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
>>  	case CONTROL_MPAGE:
>>  		ret = ata_mselect_control(qc, spg, p, pg_len, &fp);
>>  		if (ret < 0) {
>> +			if (ret == -EOPNOTSUPP)
>> +				goto invalid_fld;
>>  			fp += hdr_len + bd_len;
>>  			goto invalid_param;
>>  		}
>> -- 
> 
> I would prefer if we did not merge this patch, as it is already handled in
> higher up in the (only) calling function:
> https://github.com/torvalds/linux/blob/v6.15-rc2/drivers/ata/libata-scsi.c#L2582-L2589

This code you point to is for mode sense. This patch deals with mode select,
where we are not checking for the subpage support, which is wrong.

> 
> We only break if "dev->flags & ATA_DFLAG_CDL && pg == CONTROL_MPAGE"
> 
> if this expression is false, we do a fallthrough,
> which means fp = 3; goto invalid_fld;
> 
> 
> Kind regards,
> Niklas


-- 
Damien Le Moal
Western Digital Research

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

* Re: [PATCH v2 2/5] ata: libata-scsi: Fail MODE SELECT for unsupported mode pages
  2025-04-18  9:30     ` Damien Le Moal
@ 2025-04-18 11:45       ` Niklas Cassel
  2025-04-18 23:02         ` Damien Le Moal
  0 siblings, 1 reply; 11+ messages in thread
From: Niklas Cassel @ 2025-04-18 11:45 UTC (permalink / raw)
  To: Damien Le Moal; +Cc: linux-ide, linux-scsi, Martin K . Petersen



On 18 April 2025 11:30:35 CEST, Damien Le Moal <dlemoal@kernel.org> wrote:
>On 4/18/25 17:40, Niklas Cassel wrote:
>> On Fri, Apr 18, 2025 at 04:55:14PM +0900, Damien Le Moal wrote:
>>> For devices that do not support CDL, the subpage F2h of the control mode
>>> page 0Ah should not be supported. However, the function
>>> ata_mselect_control_ata_feature() does not fail for a device that does
>>> not have the ATA_DFLAG_CDL device flag set, which can lead to an invalid
>>> SET FEATURES command (which will be failed by the device) to be issued.
>>>
>>> Modify ata_mselect_control_ata_feature() to return -EOPNOTSUPP if it is
>>> executed for a device without CDL support. This error code is checked by
>>> ata_scsi_mode_select_xlat() (through ata_mselect_control()) to fail the
>>> MODE SELECT command immediately with an ILLEGAL REQUEST / INVALID FIELD
>>> IN CDB asc/ascq as mandated by the SPC specifications for unsupported
>>> mode pages.
>>>
>>> Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation")
>>> Cc: stable@vger.kernel.org
>>> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
>>> ---
>>>  drivers/ata/libata-scsi.c | 11 +++++++++++
>>>  1 file changed, 11 insertions(+)
>>>
>>> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
>>> index 24e662c837e3..15661b05cb48 100644
>>> --- a/drivers/ata/libata-scsi.c
>>> +++ b/drivers/ata/libata-scsi.c
>>> @@ -3896,6 +3896,15 @@ static int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc,
>>>  	struct ata_taskfile *tf = &qc->tf;
>>>  	u8 cdl_action;
>>>  
>>> +	/*
>>> +	 * The sub-page f2h should only be supported for devices that support
>>> +	 * the T2A and T2B command duration limits mode pages (note here the
>>> +	 * "should" which is what SAT-6 defines). So fail this command if the
>>> +	 * device does not support CDL.
>>> +	 */
>>> +	if (!(dev->flags & ATA_DFLAG_CDL))
>>> +		return -EOPNOTSUPP;
>>> +
>>>  	/*
>>>  	 * The first four bytes of ATA Feature Control mode page are a header,
>>>  	 * so offsets in mpage are off by 4 compared to buf.  Same for len.
>>> @@ -4101,6 +4110,8 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
>>>  	case CONTROL_MPAGE:
>>>  		ret = ata_mselect_control(qc, spg, p, pg_len, &fp);
>>>  		if (ret < 0) {
>>> +			if (ret == -EOPNOTSUPP)
>>> +				goto invalid_fld;
>>>  			fp += hdr_len + bd_len;
>>>  			goto invalid_param;
>>>  		}
>>> -- 
>> 
>> I would prefer if we did not merge this patch, as it is already handled in
>> higher up in the (only) calling function:
>> https://github.com/torvalds/linux/blob/v6.15-rc2/drivers/ata/libata-scsi.c#L2582-L2589
>
>This code you point to is for mode sense. This patch deals with mode select,
>where we are not checking for the subpage support, which is wrong.
>

I linked to the wrong line.

https://github.com/torvalds/linux/blob/v6.15-rc2/drivers/ata/libata-scsi.c#L4081

The rest of the comment is still valid.

This case that this patch tries to fix can already not happen.


Kind regards,
Niklas



>> 
>> We only break if "dev->flags & ATA_DFLAG_CDL && pg == CONTROL_MPAGE"
>> 
>> if this expression is false, we do a fallthrough,
>> which means fp = 3; goto invalid_fld;
>> 
>> 
>> Kind regards,
>> Niklas
>
>
>-- 
>Damien Le Moal
>Western Digital Research

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

* Re: [PATCH v2 2/5] ata: libata-scsi: Fail MODE SELECT for unsupported mode pages
  2025-04-18 11:45       ` Niklas Cassel
@ 2025-04-18 23:02         ` Damien Le Moal
  0 siblings, 0 replies; 11+ messages in thread
From: Damien Le Moal @ 2025-04-18 23:02 UTC (permalink / raw)
  To: Niklas Cassel; +Cc: linux-ide, linux-scsi, Martin K . Petersen

On 4/18/25 20:45, Niklas Cassel wrote:
> 
> 
> On 18 April 2025 11:30:35 CEST, Damien Le Moal <dlemoal@kernel.org> wrote:
>> On 4/18/25 17:40, Niklas Cassel wrote:
>>> On Fri, Apr 18, 2025 at 04:55:14PM +0900, Damien Le Moal wrote:
>>>> For devices that do not support CDL, the subpage F2h of the control mode
>>>> page 0Ah should not be supported. However, the function
>>>> ata_mselect_control_ata_feature() does not fail for a device that does
>>>> not have the ATA_DFLAG_CDL device flag set, which can lead to an invalid
>>>> SET FEATURES command (which will be failed by the device) to be issued.
>>>>
>>>> Modify ata_mselect_control_ata_feature() to return -EOPNOTSUPP if it is
>>>> executed for a device without CDL support. This error code is checked by
>>>> ata_scsi_mode_select_xlat() (through ata_mselect_control()) to fail the
>>>> MODE SELECT command immediately with an ILLEGAL REQUEST / INVALID FIELD
>>>> IN CDB asc/ascq as mandated by the SPC specifications for unsupported
>>>> mode pages.
>>>>
>>>> Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation")
>>>> Cc: stable@vger.kernel.org
>>>> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
>>>> ---
>>>>  drivers/ata/libata-scsi.c | 11 +++++++++++
>>>>  1 file changed, 11 insertions(+)
>>>>
>>>> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
>>>> index 24e662c837e3..15661b05cb48 100644
>>>> --- a/drivers/ata/libata-scsi.c
>>>> +++ b/drivers/ata/libata-scsi.c
>>>> @@ -3896,6 +3896,15 @@ static int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc,
>>>>  	struct ata_taskfile *tf = &qc->tf;
>>>>  	u8 cdl_action;
>>>>  
>>>> +	/*
>>>> +	 * The sub-page f2h should only be supported for devices that support
>>>> +	 * the T2A and T2B command duration limits mode pages (note here the
>>>> +	 * "should" which is what SAT-6 defines). So fail this command if the
>>>> +	 * device does not support CDL.
>>>> +	 */
>>>> +	if (!(dev->flags & ATA_DFLAG_CDL))
>>>> +		return -EOPNOTSUPP;
>>>> +
>>>>  	/*
>>>>  	 * The first four bytes of ATA Feature Control mode page are a header,
>>>>  	 * so offsets in mpage are off by 4 compared to buf.  Same for len.
>>>> @@ -4101,6 +4110,8 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
>>>>  	case CONTROL_MPAGE:
>>>>  		ret = ata_mselect_control(qc, spg, p, pg_len, &fp);
>>>>  		if (ret < 0) {
>>>> +			if (ret == -EOPNOTSUPP)
>>>> +				goto invalid_fld;
>>>>  			fp += hdr_len + bd_len;
>>>>  			goto invalid_param;
>>>>  		}
>>>> -- 
>>>
>>> I would prefer if we did not merge this patch, as it is already handled in
>>> higher up in the (only) calling function:
>>> https://github.com/torvalds/linux/blob/v6.15-rc2/drivers/ata/libata-scsi.c#L2582-L2589
>>
>> This code you point to is for mode sense. This patch deals with mode select,
>> where we are not checking for the subpage support, which is wrong.
>>
> 
> I linked to the wrong line.
> 
> https://github.com/torvalds/linux/blob/v6.15-rc2/drivers/ata/libata-scsi.c#L4081
> 
> The rest of the comment is still valid.
> 
> This case that this patch tries to fix can already not happen.

You are absolutely correct ! How did I miss that :)
Sending V3 with this patch dropped.

-- 
Damien Le Moal
Western Digital Research

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

end of thread, other threads:[~2025-04-18 23:02 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-18  7:55 [PATCH v2 0/5] CDL Feature control improvements Damien Le Moal
2025-04-18  7:55 ` [PATCH v2 1/5] ata: libata-scsi: Fix ata_mselect_control_ata_feature() return type Damien Le Moal
2025-04-18  8:14   ` Niklas Cassel
2025-04-18  7:55 ` [PATCH v2 2/5] ata: libata-scsi: Fail MODE SELECT for unsupported mode pages Damien Le Moal
2025-04-18  8:40   ` Niklas Cassel
2025-04-18  9:30     ` Damien Le Moal
2025-04-18 11:45       ` Niklas Cassel
2025-04-18 23:02         ` Damien Le Moal
2025-04-18  7:55 ` [PATCH v2 3/5] ata: libata-scsi: Fix ata_msense_control_ata_feature() Damien Le Moal
2025-04-18  7:55 ` [PATCH v2 4/5] ata: libata-scsi: Improve CDL control Damien Le Moal
2025-04-18  7:55 ` [PATCH v2 5/5] scsi: " Damien Le Moal

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).