Upstream commit b0cc6020e1cc62f1253215f189611b34be4a83c7
PCI: Enable ARI if dev and upstream bridge support it; disable otherwise
Hi Greg, Bjorn
This patch fix the ARI device issue when doing pci hotplug, this issue
also exists in 3.4 stable. Because this patch use the accessors for PCI
Express Capability which introudced by Jiangliu after Linux 3.4. So it
can not be applied to 3.4 stable directly. I rework this patch based 3.4
stable and test result is ok.
--------------------------------------------
PCI: Enable ARI if dev and upstream bridge support it; disable otherwise
commit b0cc6020e1cc62f1253215f189611b34be4a83c7 upstream
Currently, we enable ARI in a device's upstream bridge if the bridge and
the device support it. But we never disable ARI, even if the device is
removed and replaced with a device that doesn't support ARI.
This means that if we hot-remove an ARI device and replace it with a
non-ARI multi-function device, we find only function 0 of the new device
because the upstream bridge still has ARI enabled, and next_ari_fn()
only returns function 0 for the new non-ARI device.
This patch disables ARI in the upstream bridge if the device doesn't
support ARI. See the PCIe spec, r3.0, sec 6.13.
[bhelgaas: changelog, function comment]
[yijing: replace PCIe Cap accessor with legacy PCI accessor]
Signed-off-by: Yijing Wang <[email protected]>
Signed-off-by: Jiang Liu <[email protected]>
Signed-off-by: Bjorn Helgaas <[email protected]>
---
drivers/pci/pci.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 9e3fa0c..2851879 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1984,10 +1984,6 @@ void pci_enable_ari(struct pci_dev *dev)
if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn)
return;
- pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI);
- if (!pos)
- return;
-
bridge = dev->bus->self;
if (!bridge || !pci_is_pcie(bridge))
return;
@@ -2006,10 +2002,14 @@ void pci_enable_ari(struct pci_dev *dev)
return;
pci_read_config_word(bridge, pos + PCI_EXP_DEVCTL2, &ctrl);
- ctrl |= PCI_EXP_DEVCTL2_ARI;
+ if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) {
+ ctrl |= PCI_EXP_DEVCTL2_ARI;
+ bridge->ari_enabled = 1;
+ } else {
+ ctrl &= ~PCI_EXP_DEVCTL2_ARI;
+ bridge->ari_enabled = 0;
+ }
pci_write_config_word(bridge, pos + PCI_EXP_DEVCTL2, ctrl);
-
- bridge->ari_enabled = 1;
}
/**
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html