source: trunk/packages/xen-3.1/xen-3.1/tools/python/xen/util/pci.py @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

  • Property svn:mime-type set to text/script
File size: 6.1 KB
Line 
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>
7
8import sys
9import os, os.path
10
11PROC_MNT_PATH = '/proc/mounts'
12PROC_PCI_PATH = '/proc/bus/pci/devices'
13PROC_PCI_NUM_RESOURCES = 7
14
15SYSFS_PCI_DEVS_PATH = '/bus/pci/devices'
16SYSFS_PCI_DEV_RESOURCE_PATH = '/resource'
17SYSFS_PCI_DEV_IRQ_PATH = '/irq'
18SYSFS_PCI_DEV_DRIVER_DIR_PATH = '/driver'
19SYSFS_PCI_DEV_VENDOR_PATH = '/vendor'
20SYSFS_PCI_DEV_DEVICE_PATH = '/device'
21SYSFS_PCI_DEV_SUBVENDOR_PATH = '/subsystem_vendor'
22SYSFS_PCI_DEV_SUBDEVICE_PATH = '/subsystem_device'
23
24PCI_BAR_IO = 0x01
25PCI_BAR_IO_MASK = ~0x03
26PCI_BAR_MEM_MASK = ~0x0f
27
28# Definitions from Linux: include/linux/pci.h
29def PCI_DEVFN(slot, func):
30    return ((((slot) & 0x1f) << 3) | ((func) & 0x07))
31
32def find_sysfs_mnt():
33    mounts_file = open(PROC_MNT_PATH,'r')
34
35    for line in mounts_file:
36        sline = line.split()
37        if len(sline)<3:
38            continue
39
40        if sline[2]=='sysfs':
41            return sline[1]
42
43    return None
44
45class 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)
52   
53    def __str__(self):
54        return ('PCI Device %s Not Found' % (self.name))
55
56class PciDeviceParseError(Exception):
57    def __init__(self,msg):
58        self.message = msg
59    def __str__(self):
60        return 'Error Parsing PCI Device Info: '+self.message
61
62class 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
77
78        self.get_info_from_sysfs()
79
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)))
86
87        if sysfs_mnt == None:
88            return False
89
90        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
91                self.name+SYSFS_PCI_DEV_RESOURCE_PATH
92        try:
93            resource_file = open(path,'r')
94
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
100
101                start = int(sline[0],16)
102                end = int(sline[1],16)
103                flags = int(sline[2],16)
104                size = end-start+1
105
106                if start!=0:
107                    if flags&PCI_BAR_IO:
108                        self.ioports.append( (start,size) )
109                    else:
110                        self.iomem.append( (start,size) )
111
112        except IOError, (errno, strerr):
113            raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %
114                (path, strerr, errno)))
115
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)))
123
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)))
131
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)))
139
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)))
147
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)))
155
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)))
163
164        return True
165
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
178
179def main():
180    if len(sys.argv)<5:
181        print "Usage: %s <domain> <bus> <slot> <func>\n"
182        sys.exit(2)
183
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)
187
188if __name__=='__main__':
189    main()
Note: See TracBrowser for help on using the repository browser.