PCI: Delay after FLR of Intel DC P3700 NVMe
authorAlex Williamson <alex.williamson@redhat.com>
Thu, 9 Aug 2018 20:04:31 +0000 (14:04 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 9 Aug 2018 20:20:52 +0000 (15:20 -0500)
Add a device-specific reset for Intel DC P3700 NVMe device which exhibits a
timeout failure in drivers waiting for the ready status to update after
NVMe enable if the driver interacts with the device too soon after FLR.  As
this has been observed in device assignment scenarios, resolve this with a
device-specific reset quirk to add an additional, heuristically determined,
delay after the FLR completes.

Link: https://bugzilla.redhat.com/show_bug.cgi?id=1592654
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/quirks.c

index e249676fbf042d7d45c77754339c7b30277c4a2c..deb051583eda849ea7332e3aa9c362449a73bbd8 100644 (file)
@@ -3746,6 +3746,27 @@ static int nvme_disable_and_flr(struct pci_dev *dev, int probe)
        return 0;
 }
 
+/*
+ * Intel DC P3700 NVMe controller will timeout waiting for ready status
+ * to change after NVMe enable if the driver starts interacting with the
+ * device too soon after FLR.  A 250ms delay after FLR has heuristically
+ * proven to produce reliably working results for device assignment cases.
+ */
+static int delay_250ms_after_flr(struct pci_dev *dev, int probe)
+{
+       if (!pcie_has_flr(dev))
+               return -ENOTTY;
+
+       if (probe)
+               return 0;
+
+       pcie_flr(dev);
+
+       msleep(250);
+
+       return 0;
+}
+
 static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF,
                 reset_intel_82599_sfp_virtfn },
@@ -3754,6 +3775,7 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M2_VGA,
                reset_ivb_igd },
        { PCI_VENDOR_ID_SAMSUNG, 0xa804, nvme_disable_and_flr },
+       { PCI_VENDOR_ID_INTEL, 0x0953, delay_250ms_after_flr },
        { PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,
                reset_chelsio_generic_dev },
        { 0 }