From: Wei Wang Date: Tue, 8 Nov 2011 10:25:51 +0000 (+0100) Subject: ats: Add new ATS helper functions X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=67dca204c4dc1e8cf9c3a3eabd9d51d0b4906156;p=xen.git ats: Add new ATS helper functions Signed-off-by Wei Wang Committed-by: Jan Beulich --- diff --git a/xen/drivers/passthrough/ats.h b/xen/drivers/passthrough/ats.h index e1d5b4cf53..5cb09ead1a 100644 --- a/xen/drivers/passthrough/ats.h +++ b/xen/drivers/passthrough/ats.h @@ -16,6 +16,8 @@ #ifndef _ATS_H_ #define _ATS_H_ +#include + struct pci_ats_dev { struct list_head list; u16 seg; @@ -36,6 +38,28 @@ extern bool_t ats_enabled; int enable_ats_device(int seg, int bus, int devfn); void disable_ats_device(int seg, int bus, int devfn); +struct pci_ats_dev *get_ats_device(int seg, int bus, int devfn); + +static inline int pci_ats_enabled(int seg, int bus, int devfn) +{ + u32 value; + int pos; + + pos = pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS); + BUG_ON(!pos); + + value = pci_conf_read16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), + pos + ATS_REG_CTL); + return value & ATS_ENABLE; +} + +static inline int pci_ats_device(int seg, int bus, int devfn) +{ + if ( !ats_enabled ) + return 0; + + return pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS); +} #else @@ -50,6 +74,22 @@ static inline void disable_ats_device(int seg, int bus, int devfn) { BUG(); } + +static inline int pci_ats_enabled(int seg, int bus, int devfn) +{ + return 0; +} + +static inline int pci_ats_device(int seg, int bus, int devfn) +{ + return 0; +} + +static inline struct pci_ats_dev *get_ats_device(int seg, int bus, int devfn) +{ + return NULL; +} + #endif #endif /* _ATS_H_ */ diff --git a/xen/drivers/passthrough/x86/ats.c b/xen/drivers/passthrough/x86/ats.c index af6fd7a565..3aff8e1bce 100644 --- a/xen/drivers/passthrough/x86/ats.c +++ b/xen/drivers/passthrough/x86/ats.c @@ -134,3 +134,19 @@ void disable_ats_device(int seg, int bus, int devfn) dprintk(XENLOG_INFO, "%04x:%02x:%02x.%u: ATS is disabled\n", seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); } + +struct pci_ats_dev *get_ats_device(int seg, int bus, int devfn) +{ + struct pci_ats_dev *pdev; + + if ( !pci_ats_device(seg, bus, devfn) ) + return NULL; + + list_for_each_entry ( pdev, &ats_devices, list ) + { + if ( pdev->seg == seg && pdev->bus == bus && pdev->devfn == devfn ) + return pdev; + } + + return NULL; +}