linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@lst.de>
To: tj@kernel.org
Cc: dan.j.williams@intel.com, linux-ide@vger.kernel.org,
	linux-nvme@lists.infradead.org
Subject: [PATCH 3/3] ahci: warn about remapped NVMe devices
Date: Fri,  2 Dec 2016 19:31:03 +0100	[thread overview]
Message-ID: <1480703463-17489-4-git-send-email-hch@lst.de> (raw)
In-Reply-To: <1480703463-17489-1-git-send-email-hch@lst.de>

Some Intel ahci implementations have a completely broken remapping mode
where they hide one or more NVMe devices behind the bar of an AHCI device.

Intel refuses to let the OS reprogram the BIOS to switch out of this
mode at runtime, and so far we're not come up with another good way
to undo the mess that the Chipset people created.  So for now the only
thing we can do is to alert users about this situation and switch to the
faster and much saner so called "AHCI" mode insted of the RAID mode in
the BIOS so that the BIOS does not hide the NVMe devices from us.

The sitation is even worse as at least one vendor (thanks a lot Lenovo..)
has started hardcoding their BIOS into the "RAID" mode even for laptops
that don't use AHCI _at all_ and just have a single NVMe device.  For now
there is an unspported Linux-only BIOS that undoes this braindamage,
but we'll have to see if things are getting better or worse from here.

Based on an earlier patch from Dan Williams <dan.j.williams@intel.com>.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/ata/ahci.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index ba5f11c..516a689 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -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);
@@ -1545,6 +1581,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;
-- 
2.1.4


  parent reply	other threads:[~2016-12-02 18:31 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-02 18:31 detect and warn about ahci-remapped NVMe devices Christoph Hellwig
2016-12-02 18:31 ` [PATCH 1/3] nvme: move NVMe class code to pci_ids.h Christoph Hellwig
2016-12-02 18:31 ` [PATCH 2/3] ahci-remap.h: add ahci remapping definitions Christoph Hellwig
2016-12-03 10:57   ` Sergei Shtylyov
2016-12-05 15:31     ` Christoph Hellwig
2016-12-02 18:31 ` Christoph Hellwig [this message]
2016-12-05 19:33 ` detect and warn about ahci-remapped NVMe devices Tejun Heo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1480703463-17489-4-git-send-email-hch@lst.de \
    --to=hch@lst.de \
    --cc=dan.j.williams@intel.com \
    --cc=linux-ide@vger.kernel.org \
    --cc=linux-nvme@lists.infradead.org \
    --cc=tj@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).