diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-05-01 10:26:58 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-05-01 10:26:58 +0100 |
commit | 154c5516cb1264c9630f6100b28a7c7ed138430a (patch) | |
tree | c8b51ea7840769c3bfdfc78afb88930911466bc3 /xen/arch/x86/pci.c | |
parent | 84aaf4530b7d495668fb2c69fdd6f5c28533c1ac (diff) | |
download | xen-154c5516cb1264c9630f6100b28a7c7ed138430a.tar.gz xen-154c5516cb1264c9630f6100b28a7c7ed138430a.tar.bz2 xen-154c5516cb1264c9630f6100b28a7c7ed138430a.zip |
MSI 1/6: Move PCI functions and headers to a common location.
Signed-off-by: Shan Haitao <haitao.shan@intel.com>
Signed-off-by: Jiang Yunhong <yunhong.jiang@intel.com>
Diffstat (limited to 'xen/arch/x86/pci.c')
-rw-r--r-- | xen/arch/x86/pci.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/xen/arch/x86/pci.c b/xen/arch/x86/pci.c index 341457b4bc..e139313e5f 100644 --- a/xen/arch/x86/pci.c +++ b/xen/arch/x86/pci.c @@ -6,6 +6,7 @@ #include <xen/config.h> #include <xen/pci.h> +#include <xen/pci_regs.h> #include <xen/spinlock.h> #include <asm/io.h> @@ -116,3 +117,60 @@ void pci_conf_write32( BUG_ON((bus > 255) || (dev > 31) || (func > 7) || (reg > 255)); pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), 0, 4, data); } + +int pci_find_cap_offset(u8 bus, u8 dev, u8 func, u8 cap) +{ + u8 id; + int max_cap = 48; + u8 pos = PCI_CAPABILITY_LIST; + u16 status; + + status = pci_conf_read16(bus, dev, func, PCI_STATUS); + if ( (status & PCI_STATUS_CAP_LIST) == 0 ) + return 0; + + while ( max_cap-- ) + { + pos = pci_conf_read8(bus, dev, func, pos); + if ( pos < 0x40 ) + break; + + pos &= ~3; + id = pci_conf_read8(bus, dev, func, pos + PCI_CAP_LIST_ID); + + if ( id == 0xff ) + break; + else if ( id == cap ) + return pos; + + pos += PCI_CAP_LIST_NEXT; + } + + return 0; +} + +int pci_find_next_cap(u8 bus, unsigned int devfn, u8 pos, int cap) +{ + u8 id; + int ttl = 48; + + while ( ttl-- ) + { + pos = pci_conf_read8(bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos); + if ( pos < 0x40 ) + break; + + pos &= ~3; + id = pci_conf_read8(bus, PCI_SLOT(devfn), PCI_FUNC(devfn), + pos + PCI_CAP_LIST_ID); + + if ( id == 0xff ) + break; + if ( id == cap ) + return pos; + + pos += PCI_CAP_LIST_NEXT; + } + return 0; +} + |