PCI: fix ARI code to be compatible with mixed ARI/non-ARI systems

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>

authored by Zhao, Yu and committed by Jesse Barnes 8113587c d2174c3c

+15 -10
+15 -10
drivers/pci/pci.c
··· 1309 1309 int pos; 1310 1310 u32 cap; 1311 1311 u16 ctrl; 1312 + struct pci_dev *bridge; 1312 1313 1313 - if (!dev->is_pcie) 1314 + if (!dev->is_pcie || dev->devfn) 1314 1315 return; 1315 1316 1316 - if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && 1317 - dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) 1318 - return; 1319 - 1320 - pos = pci_find_capability(dev, PCI_CAP_ID_EXP); 1317 + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); 1321 1318 if (!pos) 1322 1319 return; 1323 1320 1324 - pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap); 1321 + bridge = dev->bus->self; 1322 + if (!bridge || !bridge->is_pcie) 1323 + return; 1324 + 1325 + pos = pci_find_capability(bridge, PCI_CAP_ID_EXP); 1326 + if (!pos) 1327 + return; 1328 + 1329 + pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap); 1325 1330 if (!(cap & PCI_EXP_DEVCAP2_ARI)) 1326 1331 return; 1327 1332 1328 - pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); 1333 + pci_read_config_word(bridge, pos + PCI_EXP_DEVCTL2, &ctrl); 1329 1334 ctrl |= PCI_EXP_DEVCTL2_ARI; 1330 - pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); 1335 + pci_write_config_word(bridge, pos + PCI_EXP_DEVCTL2, ctrl); 1331 1336 1332 - dev->ari_enabled = 1; 1337 + bridge->ari_enabled = 1; 1333 1338 } 1334 1339 1335 1340 int