ia64/xen-unstable

view tools/python/xen/xend/server/pciquirk.py @ 19760:4bc1347b9b86

xend: pass-through: Use PCIDevice as the parameter for the constructor for PCIQuirk

Signed-off-by: Simon Horman <horms@verge.net.au>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jun 16 11:39:02 2009 +0100 (2009-06-16)
parents 23f9857f642f
children
line source
1 from xen.xend.XendLogging import log
2 from xen.xend.XendError import XendError, VmError
3 import sys
4 import os.path
5 from xen.xend.sxp import *
6 from xen.util import auxbin
8 QUIRK_SYSFS_NODE = "/sys/bus/pci/drivers/pciback/quirks"
9 QUIRK_CONFIG_FILE = auxbin.xen_configdir() + "/xend-pci-quirks.sxp"
10 PERMISSIVE_CONFIG_FILE = auxbin.xen_configdir() + "/xend-pci-permissive.sxp"
11 PERMISSIVE_SYSFS_NODE = "/sys/bus/pci/drivers/pciback/permissive"
13 class PCIQuirk:
14 def __init__(self, dev):
15 self.vendor = dev.vendor
16 self.device = dev.device
17 self.subvendor = dev.subvendor
18 self.subdevice = dev.subdevice
19 self.domain = dev.domain
20 self.bus = dev.bus
21 self.slot = dev.slot
22 self.func = dev.func
24 self.devid = "%04x:%04x:%04x:%04x" % (self.vendor, self.device,
25 self.subvendor, self.subdevice)
26 self.pciid = dev.name
27 self.quirks = self.__getQuirksByID()
29 self.__sendQuirks()
30 self.__sendPermDevs()
32 def __matchPCIdev( self, list ):
33 ret = False
34 if list == None:
35 return False
36 for id in list:
37 if id.startswith(self.devid[:9]): # id's vendor and device ID match
38 skey = id.split(':')
39 size = len(skey)
40 if (size == 2): # subvendor/subdevice not suplied
41 ret = True
42 break
43 elif (size == 4): # check subvendor/subdevice
44 # check subvendor
45 subven = '%04x' % self.subvendor
46 if ((skey[2] != 'FFFF') and
47 (skey[2] != 'ffff') and
48 (skey[2] != subven)):
49 continue
50 # check subdevice
51 subdev = '%04x' % self.subdevice
52 if ((skey[3] != 'FFFF') and
53 (skey[3] != 'ffff') and
54 (skey[3] != subdev)):
55 continue
56 ret = True
57 break
58 else:
59 log.debug("WARNING: invalid configuration entry: %s" % id)
60 ret = False
61 break
62 return ret
64 def __getQuirksByID( self ):
65 if os.path.exists(QUIRK_CONFIG_FILE):
66 try:
67 fin = file(QUIRK_CONFIG_FILE, 'rb')
68 try:
69 pci_quirks_config = parse(fin)
70 finally:
71 fin.close()
72 if pci_quirks_config is None:
73 pci_quirks_config = ['xend-pci-quirks']
74 else:
75 pci_quirks_config.insert(0, 'xend-pci-quirks')
76 self.pci_quirks_config = pci_quirks_config
77 except Exception, ex:
78 raise XendError("Reading config file %s: %s" %
79 (QUIRK_CONFIG_FILE, str(ex)))
80 else:
81 log.info("Config file does not exist: %s" % QUIRK_CONFIG_FILE)
82 self.pci_quirks_config = ['xend-pci-quirks']
84 devices = children(self.pci_quirks_config)
85 for dev in devices:
86 ids = child_at(child(dev,'pci_ids'),0)
87 fields = child_at(child(dev,'pci_config_space_fields'),0)
88 if self.__matchPCIdev( ids ):
89 log.info("Quirks found for PCI device [%s]" % self.devid)
90 return fields
92 log.info("NO quirks found for PCI device [%s]" % self.devid)
93 return []
95 def __sendQuirks(self):
96 for quirk in self.quirks:
97 log.debug("Quirk Info: %04x:%02x:%02x.%1x-%s" % (self.domain,
98 self.bus, self.slot, self.func, quirk))
99 try:
100 f = file(QUIRK_SYSFS_NODE ,"w")
101 f.write( "%04x:%02x:%02x.%1x-%s" % (self.domain, self.bus,
102 self.slot, self.func, quirk) )
103 f.close()
104 except Exception, e:
105 raise VmError("pci: failed to open/write/close quirks " +
106 "sysfs node - " + str(e))
108 def __devIsUnconstrained( self ):
109 if os.path.exists(PERMISSIVE_CONFIG_FILE):
110 try:
111 fin = file(PERMISSIVE_CONFIG_FILE, 'rb')
112 try:
113 pci_perm_dev_config = parse(fin)
114 finally:
115 fin.close()
116 if pci_perm_dev_config is None:
117 pci_perm_dev_config = ['']
118 else:
119 pci_perm_dev_config.insert(0, '')
120 self.pci_perm_dev_config = pci_perm_dev_config
121 except Exception, ex:
122 raise XendError("Reading config file %s: %s" %
123 (PERMISSIVE_CONFIG_FILE,str(ex)))
124 else:
125 log.info("Config file does not exist: %s" % PERMISSIVE_CONFIG_FILE)
126 self.pci_perm_dev_config = ['xend-pci-perm-devs']
128 devices = child_at(child(self.pci_perm_dev_config,
129 'unconstrained_dev_ids'),0)
130 if self.__matchPCIdev( devices ):
131 log.debug("Permissive mode enabled for PCI device [%s]" %
132 self.devid)
133 return True
134 log.debug("Permissive mode NOT enabled for PCI device [%s]" %
135 self.devid)
136 return False
138 def __sendPermDevs(self):
139 if self.__devIsUnconstrained( ):
140 log.debug("Unconstrained device: %04x:%02x:%02x.%1x" %
141 (self.domain, self.bus, self.slot, self.func))
142 try:
143 f = file(PERMISSIVE_SYSFS_NODE ,"w")
144 f.write( "%04x:%02x:%02x.%1x" % (self.domain, self.bus,
145 self.slot, self.func))
146 f.close()
147 except Exception, e:
148 raise VmError("pci: failed to open/write/close permissive " +
149 "sysfs node: " + str(e))