aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorYu Zhao <yu.zhao@intel.com>2008-10-14 02:02:53 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2008-10-20 13:54:32 -0400
commit58c3a727cb73b75a9104d295f096cca12959a5a5 (patch)
tree70f1fe31f1ec12021777b6c6c49167356a864749 /drivers
parent201de56eb22f1ff3f36804bc70cbff220b50f067 (diff)
PCI: support PCIe ARI capability
This patch adds support for PCI Express Alternative Routing-ID Interpretation (ARI) capability. The ARI capability extends the Function Number field of the PCI Express Endpoint by reusing the Device Number which is otherwise hardwired to 0. With ARI, an Endpoint can have up to 256 functions. Signed-off-by: Yu Zhao <yu.zhao@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/pci.c32
-rw-r--r--drivers/pci/pci.h12
-rw-r--r--drivers/pci/probe.c3
3 files changed, 47 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 553ca6657955..4db261e13e69 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1299,6 +1299,38 @@ void pci_pm_init(struct pci_dev *dev)
1299 } 1299 }
1300} 1300}
1301 1301
1302/**
1303 * pci_enable_ari - enable ARI forwarding if hardware support it
1304 * @dev: the PCI device
1305 */
1306void pci_enable_ari(struct pci_dev *dev)
1307{
1308 int pos;
1309 u32 cap;
1310 u16 ctrl;
1311
1312 if (!dev->is_pcie)
1313 return;
1314
1315 if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
1316 dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
1317 return;
1318
1319 pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
1320 if (!pos)
1321 return;
1322
1323 pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap);
1324 if (!(cap & PCI_EXP_DEVCAP2_ARI))
1325 return;
1326
1327 pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
1328 ctrl |= PCI_EXP_DEVCTL2_ARI;
1329 pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
1330
1331 dev->ari_enabled = 1;
1332}
1333
1302int 1334int
1303pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) 1335pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
1304{ 1336{
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 601abdc8dd9f..39684c1415c5 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -151,4 +151,16 @@ struct pci_slot_attribute {
151}; 151};
152#define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr) 152#define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr)
153 153
154extern void pci_enable_ari(struct pci_dev *dev);
155/**
156 * pci_ari_enabled - query ARI forwarding status
157 * @dev: the PCI device
158 *
159 * Returns 1 if ARI forwarding is enabled, or 0 if not enabled;
160 */
161static inline int pci_ari_enabled(struct pci_dev *dev)
162{
163 return dev->ari_enabled;
164}
165
154#endif /* DRIVERS_PCI_H */ 166#endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 8c158b9abd41..3141e8deeac4 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1025,6 +1025,9 @@ static void pci_init_capabilities(struct pci_dev *dev)
1025 1025
1026 /* Vital Product Data */ 1026 /* Vital Product Data */
1027 pci_vpd_pci22_init(dev); 1027 pci_vpd_pci22_init(dev);
1028
1029 /* Alternative Routing-ID Forwarding */
1030 pci_enable_ari(dev);
1028} 1031}
1029 1032
1030void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) 1033void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)