Merge branch 'topic/bjorn-trivial' into next
[firefly-linux-kernel-4.4.55.git] / drivers / pci / pci.c
index 7f1310e5853498af0d013fb88f078e4177845349..87928fde77b05614eaf50bf195a312fe00f294ed 100644 (file)
@@ -110,7 +110,7 @@ unsigned char pci_bus_max_busnr(struct pci_bus* bus)
        struct list_head *tmp;
        unsigned char max, n;
 
-       max = bus->subordinate;
+       max = bus->busn_res.end;
        list_for_each(tmp, &bus->children) {
                n = pci_bus_max_busnr(pci_bus_b(tmp));
                if(n > max)
@@ -136,30 +136,6 @@ void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)
 EXPORT_SYMBOL_GPL(pci_ioremap_bar);
 #endif
 
-#if 0
-/**
- * pci_max_busnr - returns maximum PCI bus number
- *
- * Returns the highest PCI bus number present in the system global list of
- * PCI buses.
- */
-unsigned char __devinit
-pci_max_busnr(void)
-{
-       struct pci_bus *bus = NULL;
-       unsigned char max, n;
-
-       max = 0;
-       while ((bus = pci_find_next_bus(bus)) != NULL) {
-               n = pci_bus_max_busnr(bus);
-               if(n > max)
-                       max = n;
-       }
-       return max;
-}
-
-#endif  /*  0  */
-
 #define PCI_FIND_CAP_TTL       48
 
 static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
@@ -277,6 +253,38 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
        return pos;
 }
 
+/**
+ * pci_pcie_cap2 - query for devices' PCI_CAP_ID_EXP v2 capability structure
+ * @dev: PCI device to check
+ *
+ * Like pci_pcie_cap() but also checks that the PCIe capability version is
+ * >= 2.  Note that v1 capability structures could be sparse in that not
+ * all register fields were required.  v2 requires the entire structure to
+ * be present size wise, while still allowing for non-implemented registers
+ * to exist but they must be hardwired to 0.
+ *
+ * Due to the differences in the versions of capability structures, one
+ * must be careful not to try and access non-existant registers that may
+ * exist in early versions - v1 - of Express devices.
+ *
+ * Returns the offset of the PCIe capability structure as long as the
+ * capability version is >= 2; otherwise 0 is returned.
+ */
+static int pci_pcie_cap2(struct pci_dev *dev)
+{
+       u16 flags;
+       int pos;
+
+       pos = pci_pcie_cap(dev);
+       if (pos) {
+               pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);
+               if ((flags & PCI_EXP_FLAGS_VERS) < 2)
+                       pos = 0;
+       }
+
+       return pos;
+}
+
 /**
  * pci_find_ext_capability - Find an extended capability
  * @dev: PCI device to query
@@ -329,49 +337,6 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
 }
 EXPORT_SYMBOL_GPL(pci_find_ext_capability);
 
-/**
- * pci_bus_find_ext_capability - find an extended capability
- * @bus:   the PCI bus to query
- * @devfn: PCI device to query
- * @cap:   capability code
- *
- * Like pci_find_ext_capability() but works for pci devices that do not have a
- * pci_dev structure set up yet.
- *
- * Returns the address of the requested capability structure within the
- * device's PCI configuration space or 0 in case the device does not
- * support it.
- */
-int pci_bus_find_ext_capability(struct pci_bus *bus, unsigned int devfn,
-                               int cap)
-{
-       u32 header;
-       int ttl;
-       int pos = PCI_CFG_SPACE_SIZE;
-
-       /* minimum 8 bytes per capability */
-       ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
-
-       if (!pci_bus_read_config_dword(bus, devfn, pos, &header))
-               return 0;
-       if (header == 0xffffffff || header == 0)
-               return 0;
-
-       while (ttl-- > 0) {
-               if (PCI_EXT_CAP_ID(header) == cap)
-                       return pos;
-
-               pos = PCI_EXT_CAP_NEXT(header);
-               if (pos < PCI_CFG_SPACE_SIZE)
-                       break;
-
-               if (!pci_bus_read_config_dword(bus, devfn, pos, &header))
-                       break;
-       }
-
-       return 0;
-}
-
 static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap)
 {
        int rc, ttl = PCI_FIND_CAP_TTL;
@@ -822,12 +787,6 @@ EXPORT_SYMBOL(pci_choose_state);
                ((flags & PCI_EXP_FLAGS_VERS) > 1 ||    \
                 (type == PCI_EXP_TYPE_ROOT_PORT ||     \
                  type == PCI_EXP_TYPE_RC_EC))
-#define pcie_cap_has_devctl2(type, flags)              \
-               ((flags & PCI_EXP_FLAGS_VERS) > 1)
-#define pcie_cap_has_lnkctl2(type, flags)              \
-               ((flags & PCI_EXP_FLAGS_VERS) > 1)
-#define pcie_cap_has_sltctl2(type, flags)              \
-               ((flags & PCI_EXP_FLAGS_VERS) > 1)
 
 static struct pci_cap_saved_state *pci_find_saved_cap(
        struct pci_dev *pci_dev, char cap)
@@ -870,13 +829,14 @@ static int pci_save_pcie_state(struct pci_dev *dev)
                pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
        if (pcie_cap_has_rtctl(dev->pcie_type, flags))
                pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);
-       if (pcie_cap_has_devctl2(dev->pcie_type, flags))
-               pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]);
-       if (pcie_cap_has_lnkctl2(dev->pcie_type, flags))
-               pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]);
-       if (pcie_cap_has_sltctl2(dev->pcie_type, flags))
-               pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]);
 
+       pos = pci_pcie_cap2(dev);
+       if (!pos)
+               return 0;
+
+       pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]);
+       pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]);
+       pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]);
        return 0;
 }
 
@@ -903,12 +863,14 @@ static void pci_restore_pcie_state(struct pci_dev *dev)
                pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]);
        if (pcie_cap_has_rtctl(dev->pcie_type, flags))
                pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]);
-       if (pcie_cap_has_devctl2(dev->pcie_type, flags))
-               pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]);
-       if (pcie_cap_has_lnkctl2(dev->pcie_type, flags))
-               pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]);
-       if (pcie_cap_has_sltctl2(dev->pcie_type, flags))
-               pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]);
+
+       pos = pci_pcie_cap2(dev);
+       if (!pos)
+               return;
+
+       pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]);
+       pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]);
+       pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]);
 }
 
 
@@ -1983,7 +1945,7 @@ void pci_enable_ari(struct pci_dev *dev)
 {
        int pos;
        u32 cap;
-       u16 flags, ctrl;
+       u16 ctrl;
        struct pci_dev *bridge;
 
        if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn)
@@ -1994,18 +1956,14 @@ void pci_enable_ari(struct pci_dev *dev)
                return;
 
        bridge = dev->bus->self;
-       if (!bridge || !pci_is_pcie(bridge))
+       if (!bridge)
                return;
 
-       pos = pci_pcie_cap(bridge);
+       /* ARI is a PCIe cap v2 feature */
+       pos = pci_pcie_cap2(bridge);
        if (!pos)
                return;
 
-       /* ARI is a PCIe v2 feature */
-       pci_read_config_word(bridge, pos + PCI_EXP_FLAGS, &flags);
-       if ((flags & PCI_EXP_FLAGS_VERS) < 2)
-               return;
-
        pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap);
        if (!(cap & PCI_EXP_DEVCAP2_ARI))
                return;
@@ -2018,7 +1976,7 @@ void pci_enable_ari(struct pci_dev *dev)
 }
 
 /**
- * pci_enable_ido - enable ID-based ordering on a device
+ * pci_enable_ido - enable ID-based Ordering on a device
  * @dev: the PCI device
  * @type: which types of IDO to enable
  *
@@ -2031,7 +1989,8 @@ void pci_enable_ido(struct pci_dev *dev, unsigned long type)
        int pos;
        u16 ctrl;
 
-       pos = pci_pcie_cap(dev);
+       /* ID-based Ordering is a PCIe cap v2 feature */
+       pos = pci_pcie_cap2(dev);
        if (!pos)
                return;
 
@@ -2054,10 +2013,8 @@ void pci_disable_ido(struct pci_dev *dev, unsigned long type)
        int pos;
        u16 ctrl;
 
-       if (!pci_is_pcie(dev))
-               return;
-
-       pos = pci_pcie_cap(dev);
+       /* ID-based Ordering is a PCIe cap v2 feature */
+       pos = pci_pcie_cap2(dev);
        if (!pos)
                return;
 
@@ -2096,10 +2053,8 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type)
        u16 ctrl;
        int ret;
 
-       if (!pci_is_pcie(dev))
-               return -ENOTSUPP;
-
-       pos = pci_pcie_cap(dev);
+       /* OBFF is a PCIe cap v2 feature */
+       pos = pci_pcie_cap2(dev);
        if (!pos)
                return -ENOTSUPP;
 
@@ -2149,10 +2104,8 @@ void pci_disable_obff(struct pci_dev *dev)
        int pos;
        u16 ctrl;
 
-       if (!pci_is_pcie(dev))
-               return;
-
-       pos = pci_pcie_cap(dev);
+       /* OBFF is a PCIe cap v2 feature */
+       pos = pci_pcie_cap2(dev);
        if (!pos)
                return;
 
@@ -2169,15 +2122,13 @@ EXPORT_SYMBOL(pci_disable_obff);
  * RETURNS:
  * True if @dev supports latency tolerance reporting, false otherwise.
  */
-bool pci_ltr_supported(struct pci_dev *dev)
+static bool pci_ltr_supported(struct pci_dev *dev)
 {
        int pos;
        u32 cap;
 
-       if (!pci_is_pcie(dev))
-               return false;
-
-       pos = pci_pcie_cap(dev);
+       /* LTR is a PCIe cap v2 feature */
+       pos = pci_pcie_cap2(dev);
        if (!pos)
                return false;
 
@@ -2185,7 +2136,6 @@ bool pci_ltr_supported(struct pci_dev *dev)
 
        return cap & PCI_EXP_DEVCAP2_LTR;
 }
-EXPORT_SYMBOL(pci_ltr_supported);
 
 /**
  * pci_enable_ltr - enable latency tolerance reporting
@@ -2206,7 +2156,8 @@ int pci_enable_ltr(struct pci_dev *dev)
        if (!pci_ltr_supported(dev))
                return -ENOTSUPP;
 
-       pos = pci_pcie_cap(dev);
+       /* LTR is a PCIe cap v2 feature */
+       pos = pci_pcie_cap2(dev);
        if (!pos)
                return -ENOTSUPP;
 
@@ -2241,7 +2192,8 @@ void pci_disable_ltr(struct pci_dev *dev)
        if (!pci_ltr_supported(dev))
                return;
 
-       pos = pci_pcie_cap(dev);
+       /* LTR is a PCIe cap v2 feature */
+       pos = pci_pcie_cap2(dev);
        if (!pos)
                return;
 
@@ -2359,6 +2311,75 @@ void pci_enable_acs(struct pci_dev *dev)
        pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
 }
 
+/**
+ * pci_acs_enabled - test ACS against required flags for a given device
+ * @pdev: device to test
+ * @acs_flags: required PCI ACS flags
+ *
+ * Return true if the device supports the provided flags.  Automatically
+ * filters out flags that are not implemented on multifunction devices.
+ */
+bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags)
+{
+       int pos, ret;
+       u16 ctrl;
+
+       ret = pci_dev_specific_acs_enabled(pdev, acs_flags);
+       if (ret >= 0)
+               return ret > 0;
+
+       if (!pci_is_pcie(pdev))
+               return false;
+
+       /* Filter out flags not applicable to multifunction */
+       if (pdev->multifunction)
+               acs_flags &= (PCI_ACS_RR | PCI_ACS_CR |
+                             PCI_ACS_EC | PCI_ACS_DT);
+
+       if (pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM ||
+           pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
+           pdev->multifunction) {
+               pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ACS);
+               if (!pos)
+                       return false;
+
+               pci_read_config_word(pdev, pos + PCI_ACS_CTRL, &ctrl);
+               if ((ctrl & acs_flags) != acs_flags)
+                       return false;
+       }
+
+       return true;
+}
+
+/**
+ * pci_acs_path_enable - test ACS flags from start to end in a hierarchy
+ * @start: starting downstream device
+ * @end: ending upstream device or NULL to search to the root bus
+ * @acs_flags: required flags
+ *
+ * Walk up a device tree from start to end testing PCI ACS support.  If
+ * any step along the way does not support the required flags, return false.
+ */
+bool pci_acs_path_enabled(struct pci_dev *start,
+                         struct pci_dev *end, u16 acs_flags)
+{
+       struct pci_dev *pdev, *parent = start;
+
+       do {
+               pdev = parent;
+
+               if (!pci_acs_enabled(pdev, acs_flags))
+                       return false;
+
+               if (pci_is_root_bus(pdev->bus))
+                       return (end == NULL);
+
+               parent = pdev->bus->self;
+       } while (pdev != end);
+
+       return true;
+}
+
 /**
  * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
  * @dev: the PCI device
@@ -2876,6 +2897,9 @@ bool pci_intx_mask_supported(struct pci_dev *dev)
        bool mask_supported = false;
        u16 orig, new;
 
+       if (dev->broken_intx_masking)
+               return false;
+
        pci_cfg_access_lock(dev);
 
        pci_read_config_word(dev, PCI_COMMAND, &orig);