From: Niklas Cassel Date: Tue, 2 Dec 2025 12:21:31 +0000 (+0100) Subject: ata: libata: Add ATA_QUIRK_MAX_SEC and convert all device quirks X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=59b7bb3d48333889adb1dd2aac3ab0cf26714390;p=thirdparty%2Fkernel%2Flinux.git ata: libata: Add ATA_QUIRK_MAX_SEC and convert all device quirks 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 Reviewed-by: Damien Le Moal Reviewed-by: Martin K. Petersen Signed-off-by: Damien Le Moal --- diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 871ef87a02ca3..b6127fa0b5504 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -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) { /* diff --git a/include/linux/ata.h b/include/linux/ata.h index 54b416e269959..c9013e472aa3d 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -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) */ diff --git a/include/linux/libata.h b/include/linux/libata.h index 39534fafa36ae..11b6a44572acd 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -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),