]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/ata/ahci.c
Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / drivers / ata / ahci.c
index 74f4c662f776ecf546d4c61a7de4190a61870b5c..2fc52407306c15c27b9fb0b11c2db4ef4641aeba 100644 (file)
@@ -46,6 +46,8 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <linux/libata.h>
+#include <linux/ahci-remap.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 #include "ahci.h"
 
 #define DRV_NAME       "ahci"
@@ -1400,6 +1402,40 @@ static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance)
 }
 #endif
 
+static void ahci_remap_check(struct pci_dev *pdev, int bar,
+               struct ahci_host_priv *hpriv)
+{
+       int i, count = 0;
+       u32 cap;
+
+       /*
+        * Check if this device might have remapped nvme devices.
+        */
+       if (pdev->vendor != PCI_VENDOR_ID_INTEL ||
+           pci_resource_len(pdev, bar) < SZ_512K ||
+           bar != AHCI_PCI_BAR_STANDARD ||
+           !(readl(hpriv->mmio + AHCI_VSCAP) & 1))
+               return;
+
+       cap = readq(hpriv->mmio + AHCI_REMAP_CAP);
+       for (i = 0; i < AHCI_MAX_REMAP; i++) {
+               if ((cap & (1 << i)) == 0)
+                       continue;
+               if (readl(hpriv->mmio + ahci_remap_dcc(i))
+                               != PCI_CLASS_STORAGE_EXPRESS)
+                       continue;
+
+               /* We've found a remapped device */
+               count++;
+       }
+
+       if (!count)
+               return;
+
+       dev_warn(&pdev->dev, "Found %d remapped NVMe devices.\n", count);
+       dev_warn(&pdev->dev, "Switch your BIOS from RAID to AHCI mode to use them.\n");
+}
+
 static int ahci_get_irq_vector(struct ata_host *host, int port)
 {
        return pci_irq_vector(to_pci_dev(host->dev), port);
@@ -1541,6 +1577,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar];
 
+       /* detect remapped nvme devices */
+       ahci_remap_check(pdev, ahci_pci_bar, hpriv);
+
        /* must set flag prior to save config in order to take effect */
        if (ahci_broken_devslp(pdev))
                hpriv->flags |= AHCI_HFLAG_NO_DEVSLP;