ia64/xen-unstable

view tools/python/xen/util/pci.py @ 10844:8cd577110904

[PCI] xend parses the user-space PCI backend policy files and sends
the corresponding fields to the PCI bus manager via sysfs nodes:

/sys/bus/pci/drivers/pciback/quirks
/sys/bus/pci/drivers/pciback/permissive

xend reads the policy file every time it creates a new domain that was
assigned a PCI device.

Signed-off-by: Chris Bookholt <hap10@tycho.ncsc.mil>
author kfraser@localhost.localdomain
date Fri Jul 28 12:57:55 2006 +0100 (2006-07-28)
parents 7c720ccec00a
children a0ebceaf41ff
line source
1 #!/usr/bin/env python
2 #
3 # PCI Device Information Class
4 # - Helps obtain information about which I/O resources a PCI device needs
5 #
6 # Author: Ryan Wilson <hap9@epoch.ncsc.mil>
8 import sys
9 import os, os.path
11 PROC_MNT_PATH = '/proc/mounts'
12 PROC_PCI_PATH = '/proc/bus/pci/devices'
13 PROC_PCI_NUM_RESOURCES = 7
15 SYSFS_PCI_DEVS_PATH = '/bus/pci/devices'
16 SYSFS_PCI_DEV_RESOURCE_PATH = '/resource'
17 SYSFS_PCI_DEV_IRQ_PATH = '/irq'
18 SYSFS_PCI_DEV_DRIVER_DIR_PATH = '/driver'
19 SYSFS_PCI_DEV_VENDOR_PATH = '/vendor'
20 SYSFS_PCI_DEV_DEVICE_PATH = '/device'
21 SYSFS_PCI_DEV_SUBVENDOR_PATH = '/subsystem_vendor'
22 SYSFS_PCI_DEV_SUBDEVICE_PATH = '/subsystem_device'
24 PCI_BAR_IO = 0x01
25 PCI_BAR_IO_MASK = ~0x03
26 PCI_BAR_MEM_MASK = ~0x0f
28 # Definitions from Linux: include/linux/pci.h
29 def PCI_DEVFN(slot, func):
30 return ((((slot) & 0x1f) << 3) | ((func) & 0x07))
32 def find_sysfs_mnt():
33 mounts_file = open(PROC_MNT_PATH,'r')
35 for line in mounts_file:
36 sline = line.split()
37 if len(sline)<3:
38 continue
40 if sline[2]=='sysfs':
41 return sline[1]
43 return None
45 class PciDeviceNotFoundError(Exception):
46 def __init__(self,domain,bus,slot,func):
47 self.domain = domain
48 self.bus = bus
49 self.slot = slot
50 self.func = func
51 self.name = "%04x:%02x:%02x.%01x"%(domain, bus, slot, func)
53 def __str__(self):
54 return ('PCI Device %s Not Found' % (self.name))
56 class PciDeviceParseError(Exception):
57 def __init__(self,msg):
58 self.message = msg
59 def __str__(self):
60 return 'Error Parsing PCI Device Info: '+self.message
62 class PciDevice:
63 def __init__(self, domain, bus, slot, func):
64 self.domain = domain
65 self.bus = bus
66 self.slot = slot
67 self.func = func
68 self.name = "%04x:%02x:%02x.%01x"%(domain, bus, slot, func)
69 self.irq = 0
70 self.iomem = []
71 self.ioports = []
72 self.driver = None
73 self.vendor = None
74 self.device = None
75 self.subvendor = None
76 self.subdevice = None
78 self.get_info_from_sysfs()
80 def get_info_from_sysfs(self):
81 try:
82 sysfs_mnt = find_sysfs_mnt()
83 except IOError, (errno, strerr):
84 raise PciDeviceParseError(('Failed to locate sysfs mount: %s (%d)' %
85 (PROC_PCI_PATH, strerr, errno)))
87 if sysfs_mnt == None:
88 return False
90 path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
91 self.name+SYSFS_PCI_DEV_RESOURCE_PATH
92 try:
93 resource_file = open(path,'r')
95 for i in range(PROC_PCI_NUM_RESOURCES):
96 line = resource_file.readline()
97 sline = line.split()
98 if len(sline)<3:
99 continue
101 start = int(sline[0],16)
102 end = int(sline[1],16)
103 flags = int(sline[2],16)
104 size = end-start+1
106 if start!=0:
107 if flags&PCI_BAR_IO:
108 self.ioports.append( (start,size) )
109 else:
110 self.iomem.append( (start,size) )
112 except IOError, (errno, strerr):
113 raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %
114 (path, strerr, errno)))
116 path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
117 self.name+SYSFS_PCI_DEV_IRQ_PATH
118 try:
119 self.irq = int(open(path,'r').readline())
120 except IOError, (errno, strerr):
121 raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %
122 (path, strerr, errno)))
124 path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
125 self.name+SYSFS_PCI_DEV_DRIVER_DIR_PATH
126 try:
127 self.driver = os.path.basename(os.readlink(path))
128 except IOError, (errno, strerr):
129 raise PciDeviceParseError(('Failed to read %s: %s (%d)' %
130 (path, strerr, errno)))
132 path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
133 self.name+SYSFS_PCI_DEV_VENDOR_PATH
134 try:
135 self.vendor = int(open(path,'r').readline(), 16)
136 except IOError, (errno, strerr):
137 raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %
138 (path, strerr, errno)))
140 path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
141 self.name+SYSFS_PCI_DEV_DEVICE_PATH
142 try:
143 self.device = int(open(path,'r').readline(), 16)
144 except IOError, (errno, strerr):
145 raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %
146 (path, strerr, errno)))
148 path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
149 self.name+SYSFS_PCI_DEV_SUBVENDOR_PATH
150 try:
151 self.subvendor = int(open(path,'r').readline(), 16)
152 except IOError, (errno, strerr):
153 raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %
154 (path, strerr, errno)))
156 path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
157 self.name+SYSFS_PCI_DEV_SUBDEVICE_PATH
158 try:
159 self.subdevice = int(open(path,'r').readline(), 16)
160 except IOError, (errno, strerr):
161 raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %
162 (path, strerr, errno)))
164 return True
166 def __str__(self):
167 str = "PCI Device %s\n" % (self.name)
168 for (start,size) in self.ioports:
169 str = str + "IO Port 0x%02x [size=%d]\n"%(start,size)
170 for (start,size) in self.iomem:
171 str = str + "IO Mem 0x%02x [size=%d]\n"%(start,size)
172 str = str + "IRQ %d\n"%(self.irq)
173 str = str + "Vendor ID 0x%04x\n"%(self.vendor)
174 str = str + "Device ID 0x%04x\n"%(self.device)
175 str = str + "Sybsystem Vendor ID 0x%04x\n"%(self.subvendor)
176 str = str + "Subsystem Device ID 0x%04x"%(self.subdevice)
177 return str
179 def main():
180 if len(sys.argv)<5:
181 print "Usage: %s <domain> <bus> <slot> <func>\n"
182 sys.exit(2)
184 dev = PciDevice(int(sys.argv[1],16), int(sys.argv[2],16),
185 int(sys.argv[3],16), int(sys.argv[4],16))
186 print str(dev)
188 if __name__=='__main__':
189 main()