Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
[deliverable/linux.git] / drivers / pci / quirks.c
index 80c2d014283d12c86d83ad22e98531bc8121cdc3..90acb32c85b1c637aa918a13b236c17c015b73c8 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/ktime.h>
+#include <linux/mm.h>
 #include <asm/dma.h>   /* isa_dma_bridge_buggy */
 #include "pci.h"
 
@@ -287,6 +288,25 @@ static void quirk_citrine(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM,    PCI_DEVICE_ID_IBM_CITRINE,      quirk_citrine);
 
+/*  On IBM Crocodile ipr SAS adapters, expand BAR to system page size */
+static void quirk_extend_bar_to_page(struct pci_dev *dev)
+{
+       int i;
+
+       for (i = 0; i < PCI_STD_RESOURCE_END; i++) {
+               struct resource *r = &dev->resource[i];
+
+               if (r->flags & IORESOURCE_MEM && resource_size(r) < PAGE_SIZE) {
+                       r->end = PAGE_SIZE - 1;
+                       r->start = 0;
+                       r->flags |= IORESOURCE_UNSET;
+                       dev_info(&dev->dev, "expanded BAR %d to page size: %pR\n",
+                                i, r);
+               }
+       }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, 0x034a, quirk_extend_bar_to_page);
+
 /*
  *  S3 868 and 968 chips report region size equal to 32M, but they decode 64M.
  *  If it's needed, re-allocate the region.
@@ -2985,6 +3005,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1814, 0x0601, /* Ralink RT2800 802.11n PCI */
  */
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_REALTEK, 0x8169,
                         quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, PCI_ANY_ID,
+                        quirk_broken_intx_masking);
 
 #ifdef CONFIG_ACPI
 /*
@@ -3512,57 +3534,6 @@ DECLARE_PCI_FIXUP_HEADER(0x1283, 0x8892, quirk_use_pcie_bridge_dma_alias);
 /* Intel 82801, https://bugzilla.kernel.org/show_bug.cgi?id=44881#c49 */
 DECLARE_PCI_FIXUP_HEADER(0x8086, 0x244e, quirk_use_pcie_bridge_dma_alias);
 
-static struct pci_dev *pci_func_0_dma_source(struct pci_dev *dev)
-{
-       if (!PCI_FUNC(dev->devfn))
-               return pci_dev_get(dev);
-
-       return pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
-}
-
-static const struct pci_dev_dma_source {
-       u16 vendor;
-       u16 device;
-       struct pci_dev *(*dma_source)(struct pci_dev *dev);
-} pci_dev_dma_source[] = {
-       /*
-        * https://bugzilla.redhat.com/show_bug.cgi?id=605888
-        *
-        * Some Ricoh devices use the function 0 source ID for DMA on
-        * other functions of a multifunction device.  The DMA devices
-        * is therefore function 0, which will have implications of the
-        * iommu grouping of these devices.
-        */
-       { PCI_VENDOR_ID_RICOH, 0xe822, pci_func_0_dma_source },
-       { PCI_VENDOR_ID_RICOH, 0xe230, pci_func_0_dma_source },
-       { PCI_VENDOR_ID_RICOH, 0xe832, pci_func_0_dma_source },
-       { PCI_VENDOR_ID_RICOH, 0xe476, pci_func_0_dma_source },
-       { 0 }
-};
-
-/*
- * IOMMUs with isolation capabilities need to be programmed with the
- * correct source ID of a device.  In most cases, the source ID matches
- * the device doing the DMA, but sometimes hardware is broken and will
- * tag the DMA as being sourced from a different device.  This function
- * allows that translation.  Note that the reference count of the
- * returned device is incremented on all paths.
- */
-struct pci_dev *pci_get_dma_source(struct pci_dev *dev)
-{
-       const struct pci_dev_dma_source *i;
-
-       for (i = pci_dev_dma_source; i->dma_source; i++) {
-               if ((i->vendor == dev->vendor ||
-                    i->vendor == (u16)PCI_ANY_ID) &&
-                   (i->device == dev->device ||
-                    i->device == (u16)PCI_ANY_ID))
-                       return i->dma_source(dev);
-       }
-
-       return pci_dev_get(dev);
-}
-
 /*
  * AMD has indicated that the devices below do not support peer-to-peer
  * in any system where they are found in the southbridge with an AMD
@@ -3582,6 +3553,11 @@ struct pci_dev *pci_get_dma_source(struct pci_dev *dev)
  * 1002:439d SB7x0/SB8x0/SB9x0 LPC host controller
  * 1002:4384 SBx00 PCI to PCI Bridge
  * 1002:4399 SB7x0/SB8x0/SB9x0 USB OHCI2 Controller
+ *
+ * https://bugzilla.kernel.org/show_bug.cgi?id=81841#c15
+ *
+ * 1022:780f [AMD] FCH PCI Bridge
+ * 1022:7809 [AMD] FCH USB OHCI Controller
  */
 static int pci_quirk_amd_sb_acs(struct pci_dev *dev, u16 acs_flags)
 {
@@ -3664,6 +3640,23 @@ static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags)
        return acs_flags & ~flags ? 0 : 1;
 }
 
+static int pci_quirk_mf_endpoint_acs(struct pci_dev *dev, u16 acs_flags)
+{
+       /*
+        * SV, TB, and UF are not relevant to multifunction endpoints.
+        *
+        * Multifunction devices are only required to implement RR, CR, and DT
+        * in their ACS capability if they support peer-to-peer transactions.
+        * Devices matching this quirk have been verified by the vendor to not
+        * perform peer-to-peer with other functions, allowing us to mask out
+        * these bits as if they were unimplemented in the ACS capability.
+        */
+       acs_flags &= ~(PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR |
+                      PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT);
+
+       return acs_flags ? 0 : 1;
+}
+
 static const struct pci_dev_acs_enabled {
        u16 vendor;
        u16 device;
@@ -3675,6 +3668,30 @@ static const struct pci_dev_acs_enabled {
        { PCI_VENDOR_ID_ATI, 0x439d, pci_quirk_amd_sb_acs },
        { PCI_VENDOR_ID_ATI, 0x4384, pci_quirk_amd_sb_acs },
        { PCI_VENDOR_ID_ATI, 0x4399, pci_quirk_amd_sb_acs },
+       { PCI_VENDOR_ID_AMD, 0x780f, pci_quirk_amd_sb_acs },
+       { PCI_VENDOR_ID_AMD, 0x7809, pci_quirk_amd_sb_acs },
+       { PCI_VENDOR_ID_SOLARFLARE, 0x0903, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_SOLARFLARE, 0x0923, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x10C6, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x10DB, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x10DD, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x10E1, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x10F1, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x10F7, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x10F8, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x10F9, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x10FA, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x10FB, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x10FC, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x1507, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x1514, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x151C, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x1529, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x152A, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x154D, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x154F, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x1551, pci_quirk_mf_endpoint_acs },
+       { PCI_VENDOR_ID_INTEL, 0x1558, pci_quirk_mf_endpoint_acs },
        { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs },
        { 0 }
 };
This page took 0.032461 seconds and 5 git commands to generate.