Skip to contentSkip to conversation

ata: libata: Quirk DELLBOSS VD MV.R00-0 max_sectors

PATCH Superseded Niklas Cassel 3 participants 10 messages Nov 24, 2025 – Nov 25, 2025 libata

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Niklas Cassel

author maintainer
#0 lore raw

cover ata: libata: Quirk DELLBOSS VD MV.R00-0 max_sectors

Hello there,

a recent change:
9b8b84879d4a ("block: Increase BLK_DEF_MAX_SECTORS_CAP")

bumped the default max_sectors_kb from 1280 to 4096.

It seems like a lot for SATA controllers are buggy and don't really like this, see:
https://bugzilla.kernel.org/show_bug.cgi?id=220693

For now, we only add a DELLBOSS VD MV.R00-0 max_sectors quirk, but surely more quirks are coming, so change libata-core to allow for more quirks, since after this change, all quirks bits are used.

Niklas Cassel (3):
ata: libata: Move quirk flags to their own enum
ata: libata-core: Quirk DELLBOSS VD MV.R00-0 max_sectors
ata: libata: Allow more quirks

 drivers/ata/libata-core.c | 16 +++++++-
 include/linux/ata.h       |  1 +
 include/linux/libata.h    | 81 +++++++++++++++++++++------------------
 3 files changed, 58 insertions(+), 40 deletions(-)
Signature · 1 line
2.52.0
author maintainer
#1 lore raw

PATCH 1/3 ata: libata: Move quirk flags to their own enum

The anonymous enum in include/linux/libata.h that is used to store various global constants can currently be backed by type int.
(It contains both negative and positive constants.)

__ATA_QUIRK_MAX is currently 31.
The quirk flags in the various global constants enum are defined as "1U << quirk_flag_bit".

Thus if we simply add an additional quirk, the quirk flag will be 1 << 31, which is a value that is too large to be represented by a signed int. The various global constants enum will thus therefore be backed by type long.

This will lead to error prints like e.g.:
ata_port_err(ap, "EH pending after %d tries, giving up\n",

	     ATA_EH_MAX_TRIES);

now failing to build, with build error:
error: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘long int’ [-Werror=format=]

This is because all other constants in the various global constants enum now has to be printed as a long.

Move the quirk flags to a separate enum, so that we don't need to change the printf specifier for all other constants in the "various global constants" enum when adding an additional quirk.

---
 include/linux/libata.h | 74 ++++++++++++++++++++++--------------------
 1 file changed, 38 insertions(+), 36 deletions(-)
include/linux/libata.h +38 -36
index 7a98de1cc995..171268d65169 100644
@@ -85,6 +85,44 @@ enum ata_quirks {
 	__ATA_QUIRK_MAX,
 };
 
+/*
+ * Quirk flags: may be set by libata or controller drivers on drives.
+ * Some quirks may be drive/controller pair dependent.
+ */
+enum {
+	ATA_QUIRK_DIAGNOSTIC		= (1U << __ATA_QUIRK_DIAGNOSTIC),
+	ATA_QUIRK_NODMA			= (1U << __ATA_QUIRK_NODMA),
+	ATA_QUIRK_NONCQ			= (1U << __ATA_QUIRK_NONCQ),
+	ATA_QUIRK_MAX_SEC_128		= (1U << __ATA_QUIRK_MAX_SEC_128),
+	ATA_QUIRK_BROKEN_HPA		= (1U << __ATA_QUIRK_BROKEN_HPA),
+	ATA_QUIRK_DISABLE		= (1U << __ATA_QUIRK_DISABLE),
+	ATA_QUIRK_HPA_SIZE		= (1U << __ATA_QUIRK_HPA_SIZE),
+	ATA_QUIRK_IVB			= (1U << __ATA_QUIRK_IVB),
+	ATA_QUIRK_STUCK_ERR		= (1U << __ATA_QUIRK_STUCK_ERR),
+	ATA_QUIRK_BRIDGE_OK		= (1U << __ATA_QUIRK_BRIDGE_OK),
+	ATA_QUIRK_ATAPI_MOD16_DMA	= (1U << __ATA_QUIRK_ATAPI_MOD16_DMA),
+	ATA_QUIRK_FIRMWARE_WARN		= (1U << __ATA_QUIRK_FIRMWARE_WARN),
+	ATA_QUIRK_1_5_GBPS		= (1U << __ATA_QUIRK_1_5_GBPS),
+	ATA_QUIRK_NOSETXFER		= (1U << __ATA_QUIRK_NOSETXFER),
+	ATA_QUIRK_BROKEN_FPDMA_AA	= (1U << __ATA_QUIRK_BROKEN_FPDMA_AA),
+	ATA_QUIRK_DUMP_ID		= (1U << __ATA_QUIRK_DUMP_ID),
+	ATA_QUIRK_MAX_SEC_LBA48		= (1U << __ATA_QUIRK_MAX_SEC_LBA48),
+	ATA_QUIRK_ATAPI_DMADIR		= (1U << __ATA_QUIRK_ATAPI_DMADIR),
+	ATA_QUIRK_NO_NCQ_TRIM		= (1U << __ATA_QUIRK_NO_NCQ_TRIM),
+	ATA_QUIRK_NOLPM			= (1U << __ATA_QUIRK_NOLPM),
+	ATA_QUIRK_WD_BROKEN_LPM		= (1U << __ATA_QUIRK_WD_BROKEN_LPM),
+	ATA_QUIRK_ZERO_AFTER_TRIM	= (1U << __ATA_QUIRK_ZERO_AFTER_TRIM),
+	ATA_QUIRK_NO_DMA_LOG		= (1U << __ATA_QUIRK_NO_DMA_LOG),
+	ATA_QUIRK_NOTRIM		= (1U << __ATA_QUIRK_NOTRIM),
+	ATA_QUIRK_MAX_SEC_1024		= (1U << __ATA_QUIRK_MAX_SEC_1024),
+	ATA_QUIRK_MAX_TRIM_128M		= (1U << __ATA_QUIRK_MAX_TRIM_128M),
+	ATA_QUIRK_NO_NCQ_ON_ATI		= (1U << __ATA_QUIRK_NO_NCQ_ON_ATI),
+	ATA_QUIRK_NO_LPM_ON_ATI		= (1U << __ATA_QUIRK_NO_LPM_ON_ATI),
+	ATA_QUIRK_NO_ID_DEV_LOG		= (1U << __ATA_QUIRK_NO_ID_DEV_LOG),
+	ATA_QUIRK_NO_LOG_DIR		= (1U << __ATA_QUIRK_NO_LOG_DIR),
+	ATA_QUIRK_NO_FUA		= (1U << __ATA_QUIRK_NO_FUA),
+};
+
 enum {
 	/* various global constants */
 	LIBATA_MAX_PRD		= ATA_MAX_PRD / 2,
@@ -390,42 +428,6 @@ enum {
 	 */
 	ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 8,
 
-	/*
-	 * Quirk flags: may be set by libata or controller drivers on drives.
-	 * Some quirks may be drive/controller pair dependent.
-	 */
-	ATA_QUIRK_DIAGNOSTIC		= (1U << __ATA_QUIRK_DIAGNOSTIC),
-	ATA_QUIRK_NODMA			= (1U << __ATA_QUIRK_NODMA),
-	ATA_QUIRK_NONCQ			= (1U << __ATA_QUIRK_NONCQ),
-	ATA_QUIRK_MAX_SEC_128		= (1U << __ATA_QUIRK_MAX_SEC_128),
-	ATA_QUIRK_BROKEN_HPA		= (1U << __ATA_QUIRK_BROKEN_HPA),
-	ATA_QUIRK_DISABLE		= (1U << __ATA_QUIRK_DISABLE),
-	ATA_QUIRK_HPA_SIZE		= (1U << __ATA_QUIRK_HPA_SIZE),
-	ATA_QUIRK_IVB			= (1U << __ATA_QUIRK_IVB),
-	ATA_QUIRK_STUCK_ERR		= (1U << __ATA_QUIRK_STUCK_ERR),
-	ATA_QUIRK_BRIDGE_OK		= (1U << __ATA_QUIRK_BRIDGE_OK),
-	ATA_QUIRK_ATAPI_MOD16_DMA	= (1U << __ATA_QUIRK_ATAPI_MOD16_DMA),
-	ATA_QUIRK_FIRMWARE_WARN		= (1U << __ATA_QUIRK_FIRMWARE_WARN),
-	ATA_QUIRK_1_5_GBPS		= (1U << __ATA_QUIRK_1_5_GBPS),
-	ATA_QUIRK_NOSETXFER		= (1U << __ATA_QUIRK_NOSETXFER),
-	ATA_QUIRK_BROKEN_FPDMA_AA	= (1U << __ATA_QUIRK_BROKEN_FPDMA_AA),
-	ATA_QUIRK_DUMP_ID		= (1U << __ATA_QUIRK_DUMP_ID),
-	ATA_QUIRK_MAX_SEC_LBA48		= (1U << __ATA_QUIRK_MAX_SEC_LBA48),
-	ATA_QUIRK_ATAPI_DMADIR		= (1U << __ATA_QUIRK_ATAPI_DMADIR),
-	ATA_QUIRK_NO_NCQ_TRIM		= (1U << __ATA_QUIRK_NO_NCQ_TRIM),
-	ATA_QUIRK_NOLPM			= (1U << __ATA_QUIRK_NOLPM),
-	ATA_QUIRK_WD_BROKEN_LPM		= (1U << __ATA_QUIRK_WD_BROKEN_LPM),
-	ATA_QUIRK_ZERO_AFTER_TRIM	= (1U << __ATA_QUIRK_ZERO_AFTER_TRIM),
-	ATA_QUIRK_NO_DMA_LOG		= (1U << __ATA_QUIRK_NO_DMA_LOG),
-	ATA_QUIRK_NOTRIM		= (1U << __ATA_QUIRK_NOTRIM),
-	ATA_QUIRK_MAX_SEC_1024		= (1U << __ATA_QUIRK_MAX_SEC_1024),
-	ATA_QUIRK_MAX_TRIM_128M		= (1U << __ATA_QUIRK_MAX_TRIM_128M),
-	ATA_QUIRK_NO_NCQ_ON_ATI		= (1U << __ATA_QUIRK_NO_NCQ_ON_ATI),
-	ATA_QUIRK_NO_LPM_ON_ATI		= (1U << __ATA_QUIRK_NO_LPM_ON_ATI),
-	ATA_QUIRK_NO_ID_DEV_LOG		= (1U << __ATA_QUIRK_NO_ID_DEV_LOG),
-	ATA_QUIRK_NO_LOG_DIR		= (1U << __ATA_QUIRK_NO_LOG_DIR),
-	ATA_QUIRK_NO_FUA		= (1U << __ATA_QUIRK_NO_FUA),
-
 	/* User visible DMA mask for DMA control. DO NOT renumber. */
 	ATA_DMA_MASK_ATA	= (1 << 0),	/* DMA on ATA Disk */
 	ATA_DMA_MASK_ATAPI	= (1 << 1),	/* DMA on ATAPI */
Signature · 1 line
2.52.0
maintainer Reviewed-by on v1 1/3
#2 lore raw

Re: [PATCH 1/3] ata: libata: Move quirk flags to their own enum

Quoted 20 lines · Niklas Cassel

The anonymous enum in include/linux/libata.h that is used to store various global constants can currently be backed by type int.
(It contains both negative and positive constants.)

__ATA_QUIRK_MAX is currently 31.
The quirk flags in the various global constants enum are defined as "1U << quirk_flag_bit".

Thus if we simply add an additional quirk, the quirk flag will be 1 << 31, which is a value that is too large to be represented by a signed int. The various global constants enum will thus therefore be backed by type long.

This will lead to error prints like e.g.:
ata_port_err(ap, "EH pending after %d tries, giving up\n",

	     ATA_EH_MAX_TRIES);

now failing to build, with build error:
error: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘long int’ [-Werror=format=]

Quoted 8 lines

This is because all other constants in the various global constants enum now has to be printed as a long.

Move the quirk flags to a separate enum, so that we don't need to change the printf specifier for all other constants in the "various global constants" enum when adding an additional quirk.

Looks good.

Signature · 2 lines
Damien Le Moal
Western Digital Research
author maintainer
#3 lore raw

PATCH 2/3 ata: libata-core: Quirk DELLBOSS VD MV.R00-0 max_sectors

In reply to Niklas Cassel

DELLBOSS VD MV.R00-0 with FW rev MV.R00-0 times out when sending I/Os of size 4096 KiB.

Add a quirk so that the SATA controller is usable again.

Fixes 9b8b84879d4a ("block: Increase BLK_DEF_MAX_SECTORS_CAP")
---
 drivers/ata/libata-core.c | 12 ++++++++++++
 include/linux/ata.h       |  1 +
 include/linux/libata.h    |  2 ++
 3 files changed, 15 insertions(+)
drivers/ata/libata-core.c +12 -0
index f48fb63d7e85..be320c3e0fef 100644
@@ -3146,6 +3146,10 @@ int ata_dev_configure(struct ata_device *dev)
 		dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_1024,
 					 dev->max_sectors);
 
+	if (dev->quirks & ATA_QUIRK_MAX_SEC_8191)
+		dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_8191,
+					 dev->max_sectors);
+
 	if (dev->quirks & ATA_QUIRK_MAX_SEC_LBA48)
 		dev->max_sectors = ATA_MAX_SECTORS_LBA48;
 
@@ -3998,6 +4002,7 @@ static const char * const ata_quirk_names[] = {
 	[__ATA_QUIRK_NO_DMA_LOG]	= "nodmalog",
 	[__ATA_QUIRK_NOTRIM]		= "notrim",
 	[__ATA_QUIRK_MAX_SEC_1024]	= "maxsec1024",
+	[__ATA_QUIRK_MAX_SEC_8191]	= "maxsec8191",
 	[__ATA_QUIRK_MAX_TRIM_128M]	= "maxtrim128m",
 	[__ATA_QUIRK_NO_NCQ_ON_ATI]	= "noncqonati",
 	[__ATA_QUIRK_NO_LPM_ON_ATI]	= "nolpmonati",
@@ -4104,6 +4109,12 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = {
 	{ "LITEON CX1-JB*-HP",	NULL,		ATA_QUIRK_MAX_SEC_1024 },
 	{ "LITEON EP1-*",	NULL,		ATA_QUIRK_MAX_SEC_1024 },
 
+	/*
+	 * These devices time out with higher max sects.
+	 * https://bugzilla.kernel.org/show_bug.cgi?id=220693
+	 */
+	{ "DELLBOSS VD MV.R00-0", "MV.R00-0",	ATA_QUIRK_MAX_SEC_8191 },
+
 	/* Devices we expect to fail diagnostics */
 
 	/* Devices where NCQ should be avoided */
@@ -6455,6 +6466,7 @@ static const struct ata_force_param force_tbl[] __initconst = {
 
 	force_quirk_on(max_sec_128,	ATA_QUIRK_MAX_SEC_128),
 	force_quirk_on(max_sec_1024,	ATA_QUIRK_MAX_SEC_1024),
+	force_quirk_on(max_sec_8191,	ATA_QUIRK_MAX_SEC_8191),
 	force_quirk_on(max_sec_lba48,	ATA_QUIRK_MAX_SEC_LBA48),
 
 	force_quirk_onoff(lpm,		ATA_QUIRK_NOLPM),
include/linux/ata.h +1 -0
index c9013e472aa3..54b416e26995 100644
@@ -29,6 +29,7 @@ enum {
 	ATA_MAX_SECTORS_128	= 128,
 	ATA_MAX_SECTORS		= 256,
 	ATA_MAX_SECTORS_1024    = 1024,
+	ATA_MAX_SECTORS_8191    = 8191,
 	ATA_MAX_SECTORS_LBA48	= 65535,/* avoid count to be 0000h */
 	ATA_MAX_SECTORS_TAPE	= 65535,
 	ATA_MAX_TRIM_RNUM	= 64,	/* 512-byte payload / (6-byte LBA + 2-byte range per entry) */
include/linux/libata.h +2 -0
index 171268d65169..39534fafa36a 100644
@@ -75,6 +75,7 @@ enum ata_quirks {
 	__ATA_QUIRK_NO_DMA_LOG,		/* Do not use DMA for log read */
 	__ATA_QUIRK_NOTRIM,		/* Do not use TRIM */
 	__ATA_QUIRK_MAX_SEC_1024,	/* Limit max sects to 1024 */
+	__ATA_QUIRK_MAX_SEC_8191,	/* Limit max sects to 8191 */
 	__ATA_QUIRK_MAX_TRIM_128M,	/* Limit max trim size to 128M */
 	__ATA_QUIRK_NO_NCQ_ON_ATI,	/* Disable NCQ on ATI chipset */
 	__ATA_QUIRK_NO_LPM_ON_ATI,	/* Disable LPM on ATI chipset */
@@ -115,6 +116,7 @@ enum {
 	ATA_QUIRK_NO_DMA_LOG		= (1U << __ATA_QUIRK_NO_DMA_LOG),
 	ATA_QUIRK_NOTRIM		= (1U << __ATA_QUIRK_NOTRIM),
 	ATA_QUIRK_MAX_SEC_1024		= (1U << __ATA_QUIRK_MAX_SEC_1024),
+	ATA_QUIRK_MAX_SEC_8191		= (1U << __ATA_QUIRK_MAX_SEC_8191),
 	ATA_QUIRK_MAX_TRIM_128M		= (1U << __ATA_QUIRK_MAX_TRIM_128M),
 	ATA_QUIRK_NO_NCQ_ON_ATI		= (1U << __ATA_QUIRK_NO_NCQ_ON_ATI),
 	ATA_QUIRK_NO_LPM_ON_ATI		= (1U << __ATA_QUIRK_NO_LPM_ON_ATI),
Signature · 1 line
2.52.0
author maintainer
#4 lore raw

Re: [PATCH 2/3] ata: libata-core: Quirk DELLBOSS VD MV.R00-0 max_sectors

Quoted 8 lines · Niklas Cassel

DELLBOSS VD MV.R00-0 with FW rev MV.R00-0 times out when sending I/Os of size 4096 KiB.

Add a quirk so that the SATA controller is usable again.

Fixes 9b8b84879d4a ("block: Increase BLK_DEF_MAX_SECTORS_CAP")

---

Jack, it would be helpful if you could test this series.

We know that your hardware chokes on 8192 sectors (one sector is always 512 bytes in Linux kernel code) 8192 * 512 = 4194304 bytes = 4096 KiB == 4 MiB.

When you write 4095 to max_sectors, we will set the limit to 8190 sectors.

My guess is that your hardware chokes when receiving an I/O of anything larger than 8191 sectors.

If your hardware still chokes with this patch applied, then we need to change the quirk to limit the I/Os to 8190 sectors (which, thanks to your testing, we already know works).

Kind regards,
Niklas

#5 lore raw

Re: [PATCH 2/3] ata: libata-core: Quirk DELLBOSS VD MV.R00-0 max_sectors

Is there a way to test by setting the value on the cmdline or setting a /sys variable?

Quoted 31 lines · Niklas Cassel
Quoted 8 lines · Niklas Cassel

DELLBOSS VD MV.R00-0 with FW rev MV.R00-0 times out when sending I/Os of size 4096 KiB.

Add a quirk so that the SATA controller is usable again.

Fixes 9b8b84879d4a ("block: Increase BLK_DEF_MAX_SECTORS_CAP")

---

Jack, it would be helpful if you could test this series.

We know that your hardware chokes on 8192 sectors (one sector is always 512 bytes in Linux kernel code) 8192 * 512 = 4194304 bytes = 4096 KiB == 4 MiB.

When you write 4095 to max_sectors, we will set the limit to 8190 sectors.

My guess is that your hardware chokes when receiving an I/O of anything larger than 8191 sectors.

If your hardware still chokes with this patch applied, then we need to change the quirk to limit the I/Os to 8190 sectors (which, thanks to your testing, we already know works).

Kind regards,
Niklas

#6 lore raw

Re: [PATCH 2/3] ata: libata-core: Quirk DELLBOSS VD MV.R00-0 max_sectors

In reply to Niklas Cassel

Applying the patch did not match the correct disk but after modifying the line to
{ "DELLBOSS VD", "MV.R00-0", ATA_QUIRK_MAX_SEC_8191 },
booting up the system results in
kernel: ata15.00: Model 'DELLBOSS VD', rev 'MV.R00-0', applying
quirks: maxsec8191
and the disks isn't erroring with initial testing.

Quoted 31 lines · Niklas Cassel
Quoted 8 lines · Niklas Cassel

DELLBOSS VD MV.R00-0 with FW rev MV.R00-0 times out when sending I/Os of size 4096 KiB.

Add a quirk so that the SATA controller is usable again.

Fixes 9b8b84879d4a ("block: Increase BLK_DEF_MAX_SECTORS_CAP")

---

Jack, it would be helpful if you could test this series.

We know that your hardware chokes on 8192 sectors (one sector is always 512 bytes in Linux kernel code) 8192 * 512 = 4194304 bytes = 4096 KiB == 4 MiB.

When you write 4095 to max_sectors, we will set the limit to 8190 sectors.

My guess is that your hardware chokes when receiving an I/O of anything larger than 8191 sectors.

If your hardware still chokes with this patch applied, then we need to change the quirk to limit the I/Os to 8190 sectors (which, thanks to your testing, we already know works).

Kind regards,
Niklas

maintainer
#7 lore raw

Re: [PATCH 2/3] ata: libata-core: Quirk DELLBOSS VD MV.R00-0 max_sectors

In reply to Niklas Cassel
Quoted 4 lines · Niklas Cassel

DELLBOSS VD MV.R00-0 with FW rev MV.R00-0 times out when sending I/Os of size 4096 KiB.

Add a quirk so that the SATA controller is usable again.

Please name the quirk here and describe it.

Quoted 25 lines
Fixes 9b8b84879d4a ("block: Increase BLK_DEF_MAX_SECTORS_CAP")
---
 drivers/ata/libata-core.c | 12 ++++++++++++
 include/linux/ata.h       |  1 +
 include/linux/libata.h    |  2 ++
 3 files changed, 15 insertions(+)
drivers/ata/libata-core.c +4 -0
index f48fb63d7e85..be320c3e0fef 100644
@@ -3146,6 +3146,10 @@ int ata_dev_configure(struct ata_device *dev)
 		dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_1024,
 					 dev->max_sectors);
 
+	if (dev->quirks & ATA_QUIRK_MAX_SEC_8191)
+		dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_8191,
+					 dev->max_sectors);
+
 	if (dev->quirks & ATA_QUIRK_MAX_SEC_LBA48)
 		dev->max_sectors = ATA_MAX_SECTORS_LBA48;
 

drivers/ata/libata-core.c static const char * const ata_quirk_names[] = { · line 4005

Quoted 4 lines
drivers/ata/libata-core.c +1 -0
@@ -3998,6 +4002,7 @@ static const char * const ata_quirk_names[] = {
 	[__ATA_QUIRK_NO_DMA_LOG]	= "nodmalog",
 	[__ATA_QUIRK_NOTRIM]		= "notrim",
 	[__ATA_QUIRK_MAX_SEC_1024]	= "maxsec1024",
+	[__ATA_QUIRK_MAX_SEC_8191]	= "maxsec8191",

It would be a lot better if we could have a definition for this a little more generic, that is, add a value to a generic "maxsec" quirk. E.g.:

	[__ATA_QUIRK_MAX_SEC_8191]	= { "maxsec", 8191 },

That would avoid the need for more of these if other drives have different limits. We already have 2 maxsec limit, this is the 3rd one...

Quoted 56 lines
drivers/ata/libata-core.c +7 -0
 	[__ATA_QUIRK_MAX_TRIM_128M]	= "maxtrim128m",
 	[__ATA_QUIRK_NO_NCQ_ON_ATI]	= "noncqonati",
 	[__ATA_QUIRK_NO_LPM_ON_ATI]	= "nolpmonati",
@@ -4104,6 +4109,12 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = {
 	{ "LITEON CX1-JB*-HP",	NULL,		ATA_QUIRK_MAX_SEC_1024 },
 	{ "LITEON EP1-*",	NULL,		ATA_QUIRK_MAX_SEC_1024 },
 
+	/*
+	 * These devices time out with higher max sects.
+	 * https://bugzilla.kernel.org/show_bug.cgi?id=220693
+	 */
+	{ "DELLBOSS VD MV.R00-0", "MV.R00-0",	ATA_QUIRK_MAX_SEC_8191 },
+
 	/* Devices we expect to fail diagnostics */
 
 	/* Devices where NCQ should be avoided */
@@ -6455,6 +6466,7 @@ static const struct ata_force_param force_tbl[] __initconst = {
 
 	force_quirk_on(max_sec_128,	ATA_QUIRK_MAX_SEC_128),
 	force_quirk_on(max_sec_1024,	ATA_QUIRK_MAX_SEC_1024),
+	force_quirk_on(max_sec_8191,	ATA_QUIRK_MAX_SEC_8191),
 	force_quirk_on(max_sec_lba48,	ATA_QUIRK_MAX_SEC_LBA48),
 
 	force_quirk_onoff(lpm,		ATA_QUIRK_NOLPM),
include/linux/ata.h +1 -0
index c9013e472aa3..54b416e26995 100644
@@ -29,6 +29,7 @@ enum {
 	ATA_MAX_SECTORS_128	= 128,
 	ATA_MAX_SECTORS		= 256,
 	ATA_MAX_SECTORS_1024    = 1024,
+	ATA_MAX_SECTORS_8191    = 8191,
 	ATA_MAX_SECTORS_LBA48	= 65535,/* avoid count to be 0000h */
 	ATA_MAX_SECTORS_TAPE	= 65535,
 	ATA_MAX_TRIM_RNUM	= 64,	/* 512-byte payload / (6-byte LBA + 2-byte range per entry) */
include/linux/libata.h +2 -0
index 171268d65169..39534fafa36a 100644
@@ -75,6 +75,7 @@ enum ata_quirks {
 	__ATA_QUIRK_NO_DMA_LOG,		/* Do not use DMA for log read */
 	__ATA_QUIRK_NOTRIM,		/* Do not use TRIM */
 	__ATA_QUIRK_MAX_SEC_1024,	/* Limit max sects to 1024 */
+	__ATA_QUIRK_MAX_SEC_8191,	/* Limit max sects to 8191 */
 	__ATA_QUIRK_MAX_TRIM_128M,	/* Limit max trim size to 128M */
 	__ATA_QUIRK_NO_NCQ_ON_ATI,	/* Disable NCQ on ATI chipset */
 	__ATA_QUIRK_NO_LPM_ON_ATI,	/* Disable LPM on ATI chipset */
@@ -115,6 +116,7 @@ enum {
 	ATA_QUIRK_NO_DMA_LOG		= (1U << __ATA_QUIRK_NO_DMA_LOG),
 	ATA_QUIRK_NOTRIM		= (1U << __ATA_QUIRK_NOTRIM),
 	ATA_QUIRK_MAX_SEC_1024		= (1U << __ATA_QUIRK_MAX_SEC_1024),
+	ATA_QUIRK_MAX_SEC_8191		= (1U << __ATA_QUIRK_MAX_SEC_8191),
 	ATA_QUIRK_MAX_TRIM_128M		= (1U << __ATA_QUIRK_MAX_TRIM_128M),
 	ATA_QUIRK_NO_NCQ_ON_ATI		= (1U << __ATA_QUIRK_NO_NCQ_ON_ATI),
 	ATA_QUIRK_NO_LPM_ON_ATI		= (1U << __ATA_QUIRK_NO_LPM_ON_ATI),
Signature · 2 lines
Damien Le Moal
Western Digital Research
author maintainer
#8 lore raw

PATCH 3/3 ata: libata: Allow more quirks

In reply to Niklas Cassel

We have currently used up all 32-bits in the struct ata_device struct member quirks. Thus, it is currently not possible to add another quirk.

Change the struct ata_device struct member quirks from an unsigned int to an unsigned long long.

Doing this core level change now, will make it easier for whoever needs to add another quirk, as they will not need to also do core level changes.

---
 drivers/ata/libata-core.c | 4 ++--
 include/linux/libata.h    | 5 +++--
 2 files changed, 5 insertions(+), 4 deletions(-)
drivers/ata/libata-core.c +2 -2
index be320c3e0fef..d8ab5bc56fc6 100644
@@ -4341,8 +4341,8 @@ static unsigned int ata_dev_quirks(const struct ata_device *dev)
 	unsigned char model_rev[ATA_ID_FW_REV_LEN + 1];
 	const struct ata_dev_quirks_entry *ad = __ata_dev_quirks;
 
-	/* dev->quirks is an unsigned int. */
-	BUILD_BUG_ON(__ATA_QUIRK_MAX > 32);
+	/* dev->quirks is an unsigned long long. */
+	BUILD_BUG_ON(__ATA_QUIRK_MAX > 64);
 
 	ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
 	ata_id_c_string(dev->id, model_rev, ATA_ID_FW_REV, sizeof(model_rev));
include/linux/libata.h +3 -2
index 39534fafa36a..4ed7bca91691 100644
@@ -46,7 +46,8 @@
 
 /*
  * Quirk flags bits.
- * ata_device->quirks is an unsigned int, so __ATA_QUIRK_MAX must not exceed 32.
+ * ata_device->quirks is an unsigned long long, so __ATA_QUIRK_MAX must not
+ * exceed 64.
  */
 enum ata_quirks {
 	__ATA_QUIRK_DIAGNOSTIC,		/* Failed boot diag */
@@ -723,7 +724,7 @@ struct ata_cdl {
 struct ata_device {
 	struct ata_link		*link;
 	unsigned int		devno;		/* 0 or 1 */
-	unsigned int		quirks;		/* List of broken features */
+	unsigned long long	quirks;		/* List of broken features */
 	unsigned long		flags;		/* ATA_DFLAG_xxx */
 	struct scsi_device	*sdev;		/* attached SCSI device */
 	void			*private_data;
Signature · 1 line
2.52.0
maintainer Reviewed-by on v1 3/3
#9 lore raw

Re: [PATCH 3/3] ata: libata: Allow more quirks

Quoted 10 lines · Niklas Cassel

We have currently used up all 32-bits in the struct ata_device struct member quirks. Thus, it is currently not possible to add another quirk.

Change the struct ata_device struct member quirks from an unsigned int to an unsigned long long.

Doing this core level change now, will make it easier for whoever needs to add another quirk, as they will not need to also do core level changes.

Looks good.

Signature · 2 lines
Damien Le Moal
Western Digital Research