From: Niklas Cassel <niklas.cassel@wdc.com>
To: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Cc: Christoph Hellwig <hch@lst.de>, Hannes Reinecke <hare@suse.de>,
linux-scsi@vger.kernel.org, linux-ide@vger.kernel.org,
linux-block@vger.kernel.org,
Niklas Cassel <niklas.cassel@wdc.com>
Subject: [PATCH v4 14/19] ata: libata: detect support for command duration limits
Date: Thu, 9 Mar 2023 22:55:06 +0100 [thread overview]
Message-ID: <20230309215516.3800571-15-niklas.cassel@wdc.com> (raw)
In-Reply-To: <20230309215516.3800571-1-niklas.cassel@wdc.com>
From: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Use the supported capabilities identify device data log page to detect
if a device supports the command duration limits feature. For devices
supporting this feature, set the device flag ATA_DFLAG_CDL. To support
scsi-ata translation, retrieve the command duration limits log page 18h
and cache this page content using the cdl array added to the ata_device
data structure.
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Co-developed-by: Niklas Cassel <niklas.cassel@wdc.com>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
---
drivers/ata/libata-core.c | 52 ++++++++++++++++++++++++++++++++++++++-
drivers/ata/libata-scsi.c | 17 ++++++-------
include/linux/ata.h | 5 +++-
include/linux/libata.h | 29 +++++++++++++---------
4 files changed, 80 insertions(+), 23 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 14c17c3bda4e..78e53f4fa741 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2367,6 +2367,54 @@ static void ata_dev_config_trusted(struct ata_device *dev)
dev->flags |= ATA_DFLAG_TRUSTED;
}
+static void ata_dev_config_cdl(struct ata_device *dev)
+{
+ struct ata_port *ap = dev->link->ap;
+ unsigned int err_mask;
+ u64 val;
+
+ if (ata_id_major_version(dev->id) < 12)
+ goto not_supported;
+
+ if (!ata_log_supported(dev, ATA_LOG_IDENTIFY_DEVICE) ||
+ !ata_identify_page_supported(dev, ATA_LOG_SUPPORTED_CAPABILITIES))
+ goto not_supported;
+
+ err_mask = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE,
+ ATA_LOG_SUPPORTED_CAPABILITIES,
+ ap->sector_buf, 1);
+ if (err_mask)
+ goto not_supported;
+
+ /* Check Command Duration Limit Supported bits */
+ val = get_unaligned_le64(&ap->sector_buf[168]);
+ if (!(val & BIT_ULL(63)) || !(val & BIT_ULL(0)))
+ goto not_supported;
+
+ /* Warn the user if command duration guideline is not supported */
+ if (!(val & BIT_ULL(1)))
+ ata_dev_warn(dev,
+ "Command duration guideline is not supported\n");
+
+ /*
+ * Command duration limits is supported: cache the CDL log page 18h
+ * (command duration descriptors).
+ */
+ err_mask = ata_read_log_page(dev, ATA_LOG_CDL, 0, ap->sector_buf, 1);
+ if (err_mask) {
+ ata_dev_warn(dev, "Read Command Duration Limits log failed\n");
+ goto not_supported;
+ }
+
+ memcpy(dev->cdl, ap->sector_buf, ATA_LOG_CDL_SIZE);
+ dev->flags |= ATA_DFLAG_CDL;
+
+ return;
+
+not_supported:
+ dev->flags &= ~ATA_DFLAG_CDL;
+}
+
static int ata_dev_config_lba(struct ata_device *dev)
{
const u16 *id = dev->id;
@@ -2534,13 +2582,14 @@ static void ata_dev_print_features(struct ata_device *dev)
return;
ata_dev_info(dev,
- "Features:%s%s%s%s%s%s%s\n",
+ "Features:%s%s%s%s%s%s%s%s\n",
dev->flags & ATA_DFLAG_FUA ? " FUA" : "",
dev->flags & ATA_DFLAG_TRUSTED ? " Trust" : "",
dev->flags & ATA_DFLAG_DA ? " Dev-Attention" : "",
dev->flags & ATA_DFLAG_DEVSLP ? " Dev-Sleep" : "",
dev->flags & ATA_DFLAG_NCQ_SEND_RECV ? " NCQ-sndrcv" : "",
dev->flags & ATA_DFLAG_NCQ_PRIO ? " NCQ-prio" : "",
+ dev->flags & ATA_DFLAG_CDL ? " CDL" : "",
dev->cpr_log ? " CPR" : "");
}
@@ -2702,6 +2751,7 @@ int ata_dev_configure(struct ata_device *dev)
ata_dev_config_zac(dev);
ata_dev_config_trusted(dev);
ata_dev_config_cpr(dev);
+ ata_dev_config_cdl(dev);
dev->cdb_len = 32;
if (print_info)
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 26746609bf76..716c33af999c 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -47,15 +47,14 @@ typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc);
static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
const struct scsi_device *scsidev);
-#define RW_RECOVERY_MPAGE 0x1
-#define RW_RECOVERY_MPAGE_LEN 12
-#define CACHE_MPAGE 0x8
-#define CACHE_MPAGE_LEN 20
-#define CONTROL_MPAGE 0xa
-#define CONTROL_MPAGE_LEN 12
-#define ALL_MPAGES 0x3f
-#define ALL_SUB_MPAGES 0xff
-
+#define RW_RECOVERY_MPAGE 0x1
+#define RW_RECOVERY_MPAGE_LEN 12
+#define CACHE_MPAGE 0x8
+#define CACHE_MPAGE_LEN 20
+#define CONTROL_MPAGE 0xa
+#define CONTROL_MPAGE_LEN 12
+#define ALL_MPAGES 0x3f
+#define ALL_SUB_MPAGES 0xff
static const u8 def_rw_recovery_mpage[RW_RECOVERY_MPAGE_LEN] = {
RW_RECOVERY_MPAGE,
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 0c18499f60b6..b01e2cebe1fe 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -323,15 +323,18 @@ enum {
ATA_LOG_SATA_NCQ = 0x10,
ATA_LOG_NCQ_NON_DATA = 0x12,
ATA_LOG_NCQ_SEND_RECV = 0x13,
+ ATA_LOG_CDL = 0x18,
+ ATA_LOG_CDL_SIZE = ATA_SECT_SIZE,
ATA_LOG_IDENTIFY_DEVICE = 0x30,
ATA_LOG_CONCURRENT_POSITIONING_RANGES = 0x47,
/* Identify device log pages: */
+ ATA_LOG_SUPPORTED_CAPABILITIES = 0x03,
ATA_LOG_SECURITY = 0x06,
ATA_LOG_SATA_SETTINGS = 0x08,
ATA_LOG_ZONED_INFORMATION = 0x09,
- /* Identify device SATA settings log:*/
+ /* Identify device SATA settings log: */
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 a759dfbdcc91..2b17d6c99a37 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -94,17 +94,18 @@ enum {
ATA_DFLAG_DMADIR = (1 << 10), /* device requires DMADIR */
ATA_DFLAG_NCQ_SEND_RECV = (1 << 11), /* device supports NCQ SEND and RECV */
ATA_DFLAG_NCQ_PRIO = (1 << 12), /* device supports NCQ priority */
- ATA_DFLAG_CFG_MASK = (1 << 13) - 1,
-
- ATA_DFLAG_PIO = (1 << 13), /* device limited to PIO mode */
- ATA_DFLAG_NCQ_OFF = (1 << 14), /* device limited to non-NCQ mode */
- ATA_DFLAG_SLEEPING = (1 << 15), /* device is sleeping */
- ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */
- ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */
- ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */
- ATA_DFLAG_INIT_MASK = (1 << 19) - 1,
-
- ATA_DFLAG_NCQ_PRIO_ENABLED = (1 << 19), /* Priority cmds sent to dev */
+ ATA_DFLAG_CDL = (1 << 13), /* supports cmd duration limits */
+ ATA_DFLAG_CFG_MASK = (1 << 14) - 1,
+
+ ATA_DFLAG_PIO = (1 << 14), /* device limited to PIO mode */
+ ATA_DFLAG_NCQ_OFF = (1 << 15), /* device limited to non-NCQ mode */
+ ATA_DFLAG_SLEEPING = (1 << 16), /* device is sleeping */
+ ATA_DFLAG_DUBIOUS_XFER = (1 << 17), /* data transfer not verified */
+ ATA_DFLAG_NO_UNLOAD = (1 << 18), /* device doesn't support unload */
+ ATA_DFLAG_UNLOCK_HPA = (1 << 19), /* unlock HPA */
+ ATA_DFLAG_INIT_MASK = (1 << 20) - 1,
+
+ ATA_DFLAG_NCQ_PRIO_ENABLED = (1 << 20), /* Priority cmds sent to dev */
ATA_DFLAG_DETACH = (1 << 24),
ATA_DFLAG_DETACHED = (1 << 25),
ATA_DFLAG_DA = (1 << 26), /* device supports Device Attention */
@@ -115,7 +116,8 @@ enum {
ATA_DFLAG_FEATURES_MASK = (ATA_DFLAG_TRUSTED | ATA_DFLAG_DA | \
ATA_DFLAG_DEVSLP | ATA_DFLAG_NCQ_SEND_RECV | \
- ATA_DFLAG_NCQ_PRIO | ATA_DFLAG_FUA),
+ ATA_DFLAG_NCQ_PRIO | ATA_DFLAG_FUA | \
+ ATA_DFLAG_CDL),
ATA_DEV_UNKNOWN = 0, /* unknown device */
ATA_DEV_ATA = 1, /* ATA device */
@@ -709,6 +711,9 @@ struct ata_device {
/* Concurrent positioning ranges */
struct ata_cpr_log *cpr_log;
+ /* Command Duration Limits log support */
+ u8 cdl[ATA_LOG_CDL_SIZE];
+
/* error history */
int spdn_cnt;
/* ering is CLEAR_END, read comment above CLEAR_END */
--
2.39.2
next prev parent reply other threads:[~2023-03-09 21:58 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-09 21:54 [PATCH v4 00/19] Add Command Duration Limits support Niklas Cassel
2023-03-09 21:54 ` [PATCH v4 01/19] ioprio: cleanup interface definition Niklas Cassel
2023-03-16 17:58 ` Bart Van Assche
2023-03-16 18:09 ` Bart Van Assche
2023-03-09 21:54 ` [PATCH v4 02/19] block: introduce ioprio hints Niklas Cassel
2023-03-16 2:00 ` Damien Le Moal
2023-03-16 18:41 ` Bart Van Assche
2023-03-17 9:23 ` Niklas Cassel
2023-03-17 16:56 ` Bart Van Assche
2023-03-09 21:54 ` [PATCH v4 03/19] block: introduce BLK_STS_DURATION_LIMIT Niklas Cassel
2023-03-09 21:54 ` [PATCH v4 04/19] scsi: core: allow libata to complete successful commands via EH Niklas Cassel
2023-03-09 21:54 ` [PATCH v4 05/19] scsi: rename and move get_scsi_ml_byte() Niklas Cassel
2023-03-09 21:54 ` [PATCH v4 06/19] scsi: support retrieving sub-pages of mode pages Niklas Cassel
2023-03-09 21:54 ` [PATCH v4 07/19] scsi: support service action in scsi_report_opcode() Niklas Cassel
2023-03-09 21:55 ` [PATCH v4 08/19] scsi: detect support for command duration limits Niklas Cassel
2023-03-09 21:55 ` [PATCH v4 09/19] scsi: allow enabling and disabling " Niklas Cassel
2023-03-09 21:55 ` [PATCH v4 10/19] scsi: sd: set read/write commands CDL index Niklas Cassel
2023-03-09 21:55 ` [PATCH v4 11/19] scsi: sd: handle read/write CDL timeout failures Niklas Cassel
2023-03-09 21:55 ` [PATCH v4 12/19] ata: libata-scsi: remove unnecessary !cmd checks Niklas Cassel
2023-03-09 21:55 ` [PATCH v4 13/19] ata: libata: change ata_eh_request_sense() to not set CHECK_CONDITION Niklas Cassel
2023-03-09 21:55 ` Niklas Cassel [this message]
2023-03-09 21:55 ` [PATCH v4 15/19] ata: libata-scsi: handle CDL bits in ata_scsiop_maint_in() Niklas Cassel
2023-03-09 21:55 ` [PATCH v4 16/19] ata: libata-scsi: add support for CDL pages mode sense Niklas Cassel
2023-03-09 21:55 ` [PATCH v4 17/19] ata: libata: add ATA feature control sub-page translation Niklas Cassel
2023-03-09 21:55 ` [PATCH v4 18/19] ata: libata: set read/write commands CDL index Niklas Cassel
2023-03-09 21:55 ` [PATCH v4 19/19] ata: libata: handle completion of CDL commands using policy 0xD Niklas Cassel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230309215516.3800571-15-niklas.cassel@wdc.com \
--to=niklas.cassel@wdc.com \
--cc=damien.lemoal@opensource.wdc.com \
--cc=hare@suse.de \
--cc=hch@lst.de \
--cc=linux-block@vger.kernel.org \
--cc=linux-ide@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox