1
from xen.xend.XendLogging import log
2
from xen.xend.XendError import XendError, VmError
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"
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
24
self.devid = "%04x:%04x:%04x:%04x" % (self.vendor, self.device,
25
self.subvendor, self.subdevice)
27
self.quirks = self.__getQuirksByID()
32
def __matchPCIdev( self, list ):
37
if id.startswith(self.devid[:9]): # id's vendor and device ID match
40
if (size == 2): # subvendor/subdevice not suplied
43
elif (size == 4): # check subvendor/subdevice
45
subven = '%04x' % self.subvendor
46
if ((skey[2] != 'FFFF') and
47
(skey[2] != 'ffff') and
51
subdev = '%04x' % self.subdevice
52
if ((skey[3] != 'FFFF') and
53
(skey[3] != 'ffff') and
59
log.debug("WARNING: invalid configuration entry: %s" % id)
64
def __getQuirksByID( self ):
65
if os.path.exists(QUIRK_CONFIG_FILE):
67
fin = file(QUIRK_CONFIG_FILE, 'rb')
69
pci_quirks_config = parse(fin)
72
if pci_quirks_config is None:
73
pci_quirks_config = ['xend-pci-quirks']
75
pci_quirks_config.insert(0, 'xend-pci-quirks')
76
self.pci_quirks_config = pci_quirks_config
78
raise XendError("Reading config file %s: %s" %
79
(QUIRK_CONFIG_FILE, str(ex)))
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)
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)
92
log.info("NO quirks found for PCI device [%s]" % self.devid)
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))
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) )
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):
111
fin = file(PERMISSIVE_CONFIG_FILE, 'rb')
113
pci_perm_dev_config = parse(fin)
116
if pci_perm_dev_config is None:
117
pci_perm_dev_config = ['']
119
pci_perm_dev_config.insert(0, '')
120
except Exception, ex:
121
raise XendError("Reading config file %s: %s" %
122
(PERMISSIVE_CONFIG_FILE,str(ex)))
124
log.info("Config file does not exist: %s" % PERMISSIVE_CONFIG_FILE)
125
pci_perm_dev_config = ['xend-pci-perm-devs']
127
self.pci_perm_dev_config = pci_perm_dev_config
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]" %
134
log.debug("Permissive mode NOT enabled for PCI device [%s]" %
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))
143
f = file(PERMISSIVE_SYSFS_NODE ,"w")
144
f.write( "%04x:%02x:%02x.%1x" % (self.domain, self.bus,
145
self.slot, self.func))
148
raise VmError("pci: failed to open/write/close permissive " +
149
"sysfs node: " + str(e))