diff options
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 533aeb5fcbe4..21f2ac639cab 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1309,27 +1309,32 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1309 | int pos; | 1309 | int pos; |
1310 | u32 cap; | 1310 | u32 cap; |
1311 | u16 ctrl; | 1311 | u16 ctrl; |
1312 | struct pci_dev *bridge; | ||
1312 | 1313 | ||
1313 | if (!dev->is_pcie) | 1314 | if (!dev->is_pcie || dev->devfn) |
1314 | return; | 1315 | return; |
1315 | 1316 | ||
1316 | if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | 1317 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); |
1317 | dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) | 1318 | if (!pos) |
1318 | return; | 1319 | return; |
1319 | 1320 | ||
1320 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 1321 | bridge = dev->bus->self; |
1322 | if (!bridge || !bridge->is_pcie) | ||
1323 | return; | ||
1324 | |||
1325 | pos = pci_find_capability(bridge, PCI_CAP_ID_EXP); | ||
1321 | if (!pos) | 1326 | if (!pos) |
1322 | return; | 1327 | return; |
1323 | 1328 | ||
1324 | pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap); | 1329 | pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap); |
1325 | if (!(cap & PCI_EXP_DEVCAP2_ARI)) | 1330 | if (!(cap & PCI_EXP_DEVCAP2_ARI)) |
1326 | return; | 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 | ctrl |= PCI_EXP_DEVCTL2_ARI; | 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 | int | 1340 | int |