]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ata: libata: Add ATA_QUIRK_MAX_SEC and convert all device quirks
authorNiklas Cassel <cassel@kernel.org>
Tue, 2 Dec 2025 12:21:31 +0000 (13:21 +0100)
committerDamien Le Moal <dlemoal@kernel.org>
Mon, 15 Dec 2025 07:32:05 +0000 (16:32 +0900)
Add a new quirk ATA_QUIRK_MAX_SEC, which has a separate table with device
specific values.

Convert all existing ATA_QUIRK_MAX_SEC_XXX device quirks in
__ata_dev_quirks to the new format.

Quirks ATA_QUIRK_MAX_SEC_128 and ATA_QUIRK_MAX_SEC_1024 cannot be removed
yet, since they are also used by libata.force, which functionally, is a
separate user of the quirks. The quirks will be removed once all users
have been converted to use the new format.

The quirk ATA_QUIRK_MAX_SEC_8191 can be removed since it has no equivalent
libata.force parameter.

Signed-off-by: Niklas Cassel <cassel@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
drivers/ata/libata-core.c
include/linux/ata.h
include/linux/libata.h

index 871ef87a02ca333ddf944ad2832890f5f894d4f6..b6127fa0b55048b538a075bb4276c2bffffb67c2 100644 (file)
@@ -77,6 +77,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev,
 static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
 static void ata_dev_xfermask(struct ata_device *dev);
 static unsigned int ata_dev_quirks(const struct ata_device *dev);
+static u64 ata_dev_get_quirk_value(struct ata_device *dev, unsigned int quirk);
 
 static DEFINE_IDA(ata_ida);
 
@@ -3164,9 +3165,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)
+               dev->max_sectors = min_t(unsigned int, dev->max_sectors,
+                                        ata_dev_get_quirk_value(dev,
+                                                        ATA_QUIRK_MAX_SEC));
 
        if (dev->quirks & ATA_QUIRK_MAX_SEC_LBA48)
                dev->max_sectors = ATA_MAX_SECTORS_LBA48;
@@ -4020,7 +4022,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_SEC]           = "maxsec",
        [__ATA_QUIRK_MAX_TRIM_128M]     = "maxtrim128m",
        [__ATA_QUIRK_NO_NCQ_ON_ATI]     = "noncqonati",
        [__ATA_QUIRK_NO_LPM_ON_ATI]     = "nolpmonati",
@@ -4065,6 +4067,21 @@ static void ata_dev_print_quirks(const struct ata_device *dev,
        kfree(str);
 }
 
+struct ata_dev_quirk_value {
+       const char      *model_num;
+       const char      *model_rev;
+       u64             val;
+};
+
+static const struct ata_dev_quirk_value __ata_dev_max_sec_quirks[] = {
+       { "TORiSAN DVD-ROM DRD-N216",   NULL,           128 },
+       { "ST380013AS",                 "3.20",         1024 },
+       { "LITEON CX1-JB*-HP",          NULL,           1024 },
+       { "LITEON EP1-*",               NULL,           1024 },
+       { "DELLBOSS VD",                "MV.R00-0",     8191 },
+       { },
+};
+
 struct ata_dev_quirks_entry {
        const char *model_num;
        const char *model_rev;
@@ -4109,7 +4126,7 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = {
        { "ASMT109x- Config",   NULL,           ATA_QUIRK_DISABLE },
 
        /* Weird ATAPI devices */
-       { "TORiSAN DVD-ROM DRD-N216", NULL,     ATA_QUIRK_MAX_SEC_128 },
+       { "TORiSAN DVD-ROM DRD-N216", NULL,     ATA_QUIRK_MAX_SEC },
        { "QUANTUM DAT    DAT72-000", NULL,     ATA_QUIRK_ATAPI_MOD16_DMA },
        { "Slimtype DVD A  DS8A8SH", NULL,      ATA_QUIRK_MAX_SEC_LBA48 },
        { "Slimtype DVD A  DS8A9SH", NULL,      ATA_QUIRK_MAX_SEC_LBA48 },
@@ -4118,20 +4135,20 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = {
         * Causes silent data corruption with higher max sects.
         * http://lkml.kernel.org/g/x49wpy40ysk.fsf@segfault.boston.devel.redhat.com
         */
-       { "ST380013AS",         "3.20",         ATA_QUIRK_MAX_SEC_1024 },
+       { "ST380013AS",         "3.20",         ATA_QUIRK_MAX_SEC },
 
        /*
         * These devices time out with higher max sects.
         * https://bugzilla.kernel.org/show_bug.cgi?id=121671
         */
-       { "LITEON CX1-JB*-HP",  NULL,           ATA_QUIRK_MAX_SEC_1024 },
-       { "LITEON EP1-*",       NULL,           ATA_QUIRK_MAX_SEC_1024 },
+       { "LITEON CX1-JB*-HP",  NULL,           ATA_QUIRK_MAX_SEC },
+       { "LITEON EP1-*",       NULL,           ATA_QUIRK_MAX_SEC },
 
        /*
         * These devices time out with higher max sects.
         * https://bugzilla.kernel.org/show_bug.cgi?id=220693
         */
-       { "DELLBOSS VD",        "MV.R00-0",     ATA_QUIRK_MAX_SEC_8191 },
+       { "DELLBOSS VD",        "MV.R00-0",     ATA_QUIRK_MAX_SEC },
 
        /* Devices we expect to fail diagnostics */
 
@@ -4381,6 +4398,39 @@ static unsigned int ata_dev_quirks(const struct ata_device *dev)
        return 0;
 }
 
+static u64 ata_dev_get_max_sec_quirk_value(struct ata_device *dev)
+{
+       unsigned char model_num[ATA_ID_PROD_LEN + 1];
+       unsigned char model_rev[ATA_ID_FW_REV_LEN + 1];
+       const struct ata_dev_quirk_value *ad = __ata_dev_max_sec_quirks;
+       u64 val = 0;
+
+       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));
+
+       while (ad->model_num) {
+               if (glob_match(ad->model_num, model_num) &&
+                   (!ad->model_rev || glob_match(ad->model_rev, model_rev))) {
+                       val = ad->val;
+                       break;
+               }
+               ad++;
+       }
+
+       ata_dev_warn(dev, "%s quirk is using value: %llu\n",
+                    ata_quirk_names[__ATA_QUIRK_MAX_SEC], val);
+
+       return val;
+}
+
+static u64 ata_dev_get_quirk_value(struct ata_device *dev, unsigned int quirk)
+{
+       if (quirk == ATA_QUIRK_MAX_SEC)
+               return ata_dev_get_max_sec_quirk_value(dev);
+
+       return 0;
+}
+
 static bool ata_dev_nodma(const struct ata_device *dev)
 {
        /*
index 54b416e2699590fe6c0f8d4bb46cb36313d94107..c9013e472aa3d508ee76484d920b7ad0f9151b2d 100644 (file)
@@ -29,7 +29,6 @@ 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) */
index 39534fafa36ae1d3259d14de63fee62961dafc7c..11b6a44572acd3cd63683a2bbaacd9a189dc5384 100644 (file)
@@ -75,7 +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_SEC,            /* Limit max sectors */
        __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 */
@@ -116,7 +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_SEC               = (1U << __ATA_QUIRK_MAX_SEC),
        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),