~ubuntu-branches/ubuntu/utopic/xen/utopic

« back to all changes in this revision

Viewing changes to tools/python/xen/xend/server/pciquirk.py

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2010-05-06 15:47:38 UTC
  • mto: (1.3.1) (15.1.1 sid) (4.1.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20100506154738-agoz0rlafrh1fnq7
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
7
 
 
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"
 
12
 
 
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
 
23
 
 
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()
 
28
 
 
29
        self.__sendQuirks()
 
30
        self.__sendPermDevs()
 
31
 
 
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
 
63
        
 
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']
 
83
 
 
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
 
91
 
 
92
        log.info("NO quirks found for PCI device [%s]" % self.devid)
 
93
        return []
 
94
 
 
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))
 
107
 
 
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
            except Exception, ex:
 
121
                raise XendError("Reading config file %s: %s" %
 
122
                                (PERMISSIVE_CONFIG_FILE,str(ex)))
 
123
        else:
 
124
            log.info("Config file does not exist: %s" % PERMISSIVE_CONFIG_FILE)
 
125
            pci_perm_dev_config = ['xend-pci-perm-devs']
 
126
 
 
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]" %
 
132
                      self.devid)
 
133
            return True
 
134
        log.debug("Permissive mode NOT enabled for PCI device [%s]" %
 
135
                  self.devid)
 
136
        return False
 
137
 
 
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))