|
@@ -277,6 +277,38 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
|
|
return pos;
|
|
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
|
|
* pci_find_ext_capability - Find an extended capability
|
|
* @dev: PCI device to query
|
|
* @dev: PCI device to query
|
|
@@ -1983,7 +2015,7 @@ void pci_enable_ari(struct pci_dev *dev)
|
|
{
|
|
{
|
|
int pos;
|
|
int pos;
|
|
u32 cap;
|
|
u32 cap;
|
|
- u16 flags, ctrl;
|
|
|
|
|
|
+ u16 ctrl;
|
|
struct pci_dev *bridge;
|
|
struct pci_dev *bridge;
|
|
|
|
|
|
if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn)
|
|
if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn)
|
|
@@ -1997,15 +2029,11 @@ void pci_enable_ari(struct pci_dev *dev)
|
|
if (!bridge)
|
|
if (!bridge)
|
|
return;
|
|
return;
|
|
|
|
|
|
- pos = pci_pcie_cap(bridge);
|
|
|
|
|
|
+ /* ARI is a PCIe cap v2 feature */
|
|
|
|
+ pos = pci_pcie_cap2(bridge);
|
|
if (!pos)
|
|
if (!pos)
|
|
return;
|
|
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);
|
|
pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap);
|
|
if (!(cap & PCI_EXP_DEVCAP2_ARI))
|
|
if (!(cap & PCI_EXP_DEVCAP2_ARI))
|
|
return;
|
|
return;
|
|
@@ -2018,7 +2046,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
|
|
* @dev: the PCI device
|
|
* @type: which types of IDO to enable
|
|
* @type: which types of IDO to enable
|
|
*
|
|
*
|
|
@@ -2031,7 +2059,8 @@ void pci_enable_ido(struct pci_dev *dev, unsigned long type)
|
|
int pos;
|
|
int pos;
|
|
u16 ctrl;
|
|
u16 ctrl;
|
|
|
|
|
|
- pos = pci_pcie_cap(dev);
|
|
|
|
|
|
+ /* ID-based Ordering is a PCIe cap v2 feature */
|
|
|
|
+ pos = pci_pcie_cap2(dev);
|
|
if (!pos)
|
|
if (!pos)
|
|
return;
|
|
return;
|
|
|
|
|
|
@@ -2054,7 +2083,8 @@ void pci_disable_ido(struct pci_dev *dev, unsigned long type)
|
|
int pos;
|
|
int pos;
|
|
u16 ctrl;
|
|
u16 ctrl;
|
|
|
|
|
|
- pos = pci_pcie_cap(dev);
|
|
|
|
|
|
+ /* ID-based Ordering is a PCIe cap v2 feature */
|
|
|
|
+ pos = pci_pcie_cap2(dev);
|
|
if (!pos)
|
|
if (!pos)
|
|
return;
|
|
return;
|
|
|
|
|
|
@@ -2093,7 +2123,8 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type)
|
|
u16 ctrl;
|
|
u16 ctrl;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- pos = pci_pcie_cap(dev);
|
|
|
|
|
|
+ /* OBFF is a PCIe cap v2 feature */
|
|
|
|
+ pos = pci_pcie_cap2(dev);
|
|
if (!pos)
|
|
if (!pos)
|
|
return -ENOTSUPP;
|
|
return -ENOTSUPP;
|
|
|
|
|
|
@@ -2143,7 +2174,8 @@ void pci_disable_obff(struct pci_dev *dev)
|
|
int pos;
|
|
int pos;
|
|
u16 ctrl;
|
|
u16 ctrl;
|
|
|
|
|
|
- pos = pci_pcie_cap(dev);
|
|
|
|
|
|
+ /* OBFF is a PCIe cap v2 feature */
|
|
|
|
+ pos = pci_pcie_cap2(dev);
|
|
if (!pos)
|
|
if (!pos)
|
|
return;
|
|
return;
|
|
|
|
|
|
@@ -2165,7 +2197,8 @@ static bool pci_ltr_supported(struct pci_dev *dev)
|
|
int pos;
|
|
int pos;
|
|
u32 cap;
|
|
u32 cap;
|
|
|
|
|
|
- pos = pci_pcie_cap(dev);
|
|
|
|
|
|
+ /* LTR is a PCIe cap v2 feature */
|
|
|
|
+ pos = pci_pcie_cap2(dev);
|
|
if (!pos)
|
|
if (!pos)
|
|
return false;
|
|
return false;
|
|
|
|
|
|
@@ -2193,7 +2226,8 @@ int pci_enable_ltr(struct pci_dev *dev)
|
|
if (!pci_ltr_supported(dev))
|
|
if (!pci_ltr_supported(dev))
|
|
return -ENOTSUPP;
|
|
return -ENOTSUPP;
|
|
|
|
|
|
- pos = pci_pcie_cap(dev);
|
|
|
|
|
|
+ /* LTR is a PCIe cap v2 feature */
|
|
|
|
+ pos = pci_pcie_cap2(dev);
|
|
if (!pos)
|
|
if (!pos)
|
|
return -ENOTSUPP;
|
|
return -ENOTSUPP;
|
|
|
|
|
|
@@ -2228,7 +2262,8 @@ void pci_disable_ltr(struct pci_dev *dev)
|
|
if (!pci_ltr_supported(dev))
|
|
if (!pci_ltr_supported(dev))
|
|
return;
|
|
return;
|
|
|
|
|
|
- pos = pci_pcie_cap(dev);
|
|
|
|
|
|
+ /* LTR is a PCIe cap v2 feature */
|
|
|
|
+ pos = pci_pcie_cap2(dev);
|
|
if (!pos)
|
|
if (!pos)
|
|
return;
|
|
return;
|
|
|
|
|