aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/pci.h
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2012-06-11 01:27:07 -0400
committerBjorn Helgaas <bhelgaas@google.com>2012-06-12 11:21:42 -0400
commitad805758c0eb25bce7b2e3b298d63dc62a1bc71c (patch)
tree031c42d1537e9ee25b7392a652a7799c3914c972 /include/linux/pci.h
parent12ea6cad1c7d046e21decc18b0e2170c6794dc51 (diff)
PCI: add ACS validation utility
In a PCI environment, transactions aren't always required to reach the root bus before being re-routed. Intermediate switches between an endpoint and the root bus can redirect DMA back downstream before things like IOMMUs have a chance to intervene. Legacy PCI is always susceptible to this as it operates on a shared bus. PCIe added a new capability to describe and control this behavior, Access Control Services, or ACS. The utility function pci_acs_enabled() allows us to test the ACS capabilities of an individual devices against a set of flags while pci_acs_path_enabled() tests a complete path from a given downstream device up to the specified upstream device. We also include the ability to add device specific tests as it's likely we'll see devices that do not implement ACS, but want to indicate support for various capabilities in this space. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'include/linux/pci.h')
-rw-r--r--include/linux/pci.h10
1 files changed, 9 insertions, 1 deletions
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 39983be7b25b..dd7af0f37b3a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1490,6 +1490,7 @@ enum pci_fixup_pass {
1490#ifdef CONFIG_PCI_QUIRKS 1490#ifdef CONFIG_PCI_QUIRKS
1491void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); 1491void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
1492struct pci_dev *pci_get_dma_source(struct pci_dev *dev); 1492struct pci_dev *pci_get_dma_source(struct pci_dev *dev);
1493int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags);
1493#else 1494#else
1494static inline void pci_fixup_device(enum pci_fixup_pass pass, 1495static inline void pci_fixup_device(enum pci_fixup_pass pass,
1495 struct pci_dev *dev) {} 1496 struct pci_dev *dev) {}
@@ -1497,6 +1498,11 @@ static inline struct pci_dev *pci_get_dma_source(struct pci_dev *dev)
1497{ 1498{
1498 return pci_dev_get(dev); 1499 return pci_dev_get(dev);
1499} 1500}
1501static inline int pci_dev_specific_acs_enabled(struct pci_dev *dev,
1502 u16 acs_flags)
1503{
1504 return -ENOTTY;
1505}
1500#endif 1506#endif
1501 1507
1502void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen); 1508void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);
@@ -1599,7 +1605,9 @@ static inline bool pci_is_pcie(struct pci_dev *dev)
1599} 1605}
1600 1606
1601void pci_request_acs(void); 1607void pci_request_acs(void);
1602 1608bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags);
1609bool pci_acs_path_enabled(struct pci_dev *start,
1610 struct pci_dev *end, u16 acs_flags);
1603 1611
1604#define PCI_VPD_LRDT 0x80 /* Large Resource Data Type */ 1612#define PCI_VPD_LRDT 0x80 /* Large Resource Data Type */
1605#define PCI_VPD_LRDT_ID(x) (x | PCI_VPD_LRDT) 1613#define PCI_VPD_LRDT_ID(x) (x | PCI_VPD_LRDT)