Merge tag 'libata-5.15-2021-09-05' of git://git.kernel.dk/linux-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 6 Sep 2021 16:51:42 +0000 (09:51 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 6 Sep 2021 16:51:42 +0000 (09:51 -0700)
Pull libata fixes from Jens Axboe:
 "Fixes for queued trim on certain Samsung SSDs, in conjunction with
  certain ATI controllers"

* tag 'libata-5.15-2021-09-05' of git://git.kernel.dk/linux-block:
  libata: Add ATA_HORKAGE_NO_NCQ_ON_ATI for Samsung 860 and 870 SSD.
  libata: add ATA_HORKAGE_NO_NCQ_TRIM for Samsung 860 and 870 SSDs

drivers/ata/libata-core.c
include/linux/libata.h

index b8459c5..eed6531 100644 (file)
@@ -2186,6 +2186,25 @@ not_supported:
        dev->flags &= ~ATA_DFLAG_NCQ_PRIO;
 }
 
+static bool ata_dev_check_adapter(struct ata_device *dev,
+                                 unsigned short vendor_id)
+{
+       struct pci_dev *pcidev = NULL;
+       struct device *parent_dev = NULL;
+
+       for (parent_dev = dev->tdev.parent; parent_dev != NULL;
+            parent_dev = parent_dev->parent) {
+               if (dev_is_pci(parent_dev)) {
+                       pcidev = to_pci_dev(parent_dev);
+                       if (pcidev->vendor == vendor_id)
+                               return true;
+                       break;
+               }
+       }
+
+       return false;
+}
+
 static int ata_dev_config_ncq(struct ata_device *dev,
                               char *desc, size_t desc_sz)
 {
@@ -2204,6 +2223,13 @@ static int ata_dev_config_ncq(struct ata_device *dev,
                snprintf(desc, desc_sz, "NCQ (not used)");
                return 0;
        }
+
+       if (dev->horkage & ATA_HORKAGE_NO_NCQ_ON_ATI &&
+           ata_dev_check_adapter(dev, PCI_VENDOR_ID_ATI)) {
+               snprintf(desc, desc_sz, "NCQ (not used)");
+               return 0;
+       }
+
        if (ap->flags & ATA_FLAG_NCQ) {
                hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE);
                dev->flags |= ATA_DFLAG_NCQ;
@@ -3970,6 +3996,12 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
                                                ATA_HORKAGE_ZERO_AFTER_TRIM, },
        { "Samsung SSD 850*",           NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
                                                ATA_HORKAGE_ZERO_AFTER_TRIM, },
+       { "Samsung SSD 860*",           NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
+                                               ATA_HORKAGE_ZERO_AFTER_TRIM |
+                                               ATA_HORKAGE_NO_NCQ_ON_ATI, },
+       { "Samsung SSD 870*",           NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
+                                               ATA_HORKAGE_ZERO_AFTER_TRIM |
+                                               ATA_HORKAGE_NO_NCQ_ON_ATI, },
        { "FCCT*M500*",                 NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
                                                ATA_HORKAGE_ZERO_AFTER_TRIM, },
 
@@ -6124,6 +6156,8 @@ static int __init ata_parse_force_one(char **cur,
                { "ncq",        .horkage_off    = ATA_HORKAGE_NONCQ },
                { "noncqtrim",  .horkage_on     = ATA_HORKAGE_NO_NCQ_TRIM },
                { "ncqtrim",    .horkage_off    = ATA_HORKAGE_NO_NCQ_TRIM },
+               { "noncqati",   .horkage_on     = ATA_HORKAGE_NO_NCQ_ON_ATI },
+               { "ncqati",     .horkage_off    = ATA_HORKAGE_NO_NCQ_ON_ATI },
                { "dump_id",    .horkage_on     = ATA_HORKAGE_DUMP_ID },
                { "pio0",       .xfer_mask      = 1 << (ATA_SHIFT_PIO + 0) },
                { "pio1",       .xfer_mask      = 1 << (ATA_SHIFT_PIO + 1) },
index 860e63f..c0c64f0 100644 (file)
@@ -426,6 +426,7 @@ enum {
        ATA_HORKAGE_NOTRIM      = (1 << 24),    /* don't use TRIM */
        ATA_HORKAGE_MAX_SEC_1024 = (1 << 25),   /* Limit max sects to 1024 */
        ATA_HORKAGE_MAX_TRIM_128M = (1 << 26),  /* Limit max trim size to 128M */
+       ATA_HORKAGE_NO_NCQ_ON_ATI = (1 << 27),  /* Disable NCQ on ATI chipset */
 
         /* DMA mask for user DMA control: User visible values; DO NOT
            renumber */