Skip to content

Commit

Permalink
PCI: fix ARI code to be compatible with mixed ARI/non-ARI systems
Browse files Browse the repository at this point in the history
The original ARI support code has a compatibility problem with non-ARI
devices.  If a device doesn't support ARI, turning on ARI forwarding on
its upper level bridge will cause undefined behavior.

This fix turns on ARI forwarding only when the subordinate devices
support it.

Tested-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Yu Zhao <yu.zhao@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
  • Loading branch information
Zhao, Yu authored and Jesse Barnes committed Oct 23, 2008
1 parent d2174c3 commit 8113587
Showing 1 changed file with 13 additions and 8 deletions.
21 changes: 13 additions & 8 deletions drivers/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1309,27 +1309,32 @@ void pci_enable_ari(struct pci_dev *dev)
int pos;
u32 cap;
u16 ctrl;
struct pci_dev *bridge;

if (!dev->is_pcie)
if (!dev->is_pcie || dev->devfn)
return;

if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI);
if (!pos)
return;

pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
bridge = dev->bus->self;
if (!bridge || !bridge->is_pcie)
return;

pos = pci_find_capability(bridge, PCI_CAP_ID_EXP);
if (!pos)
return;

pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap);
pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap);
if (!(cap & PCI_EXP_DEVCAP2_ARI))
return;

pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
pci_read_config_word(bridge, pos + PCI_EXP_DEVCTL2, &ctrl);
ctrl |= PCI_EXP_DEVCTL2_ARI;
pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
pci_write_config_word(bridge, pos + PCI_EXP_DEVCTL2, ctrl);

dev->ari_enabled = 1;
bridge->ari_enabled = 1;
}

int
Expand Down

0 comments on commit 8113587

Please sign in to comment.