WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] xend: pass-through: Common parse_pci_name

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] xend: pass-through: Common parse_pci_name()
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 19 Jun 2009 00:56:05 -0700
Delivery-date: Fri, 19 Jun 2009 01:02:44 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1245220499 -3600
# Node ID 9e36ef77f658b3b62476ea585f04d56dcd687965
# Parent  bda5ab0cb387d211bb438da5fd195496463198e9
xend: pass-through: Common parse_pci_name()

Share some parsing code between different parts of xm.

This has the side-effect that the device specification for
hot-plug may now include the VSLOT and OPTS as per device
specifictions in the domain configuration file.

  SEQ:BUS:DEV.FUNC[,OPT...]

  e.g. 0000:00:01.00@6

Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>
---
 tools/python/xen/util/pci.py            |  138 +++++++++++++++++---------------
 tools/python/xen/xend/XendDomainInfo.py |   79 +++++-------------
 tools/python/xen/xend/XendNode.py       |    3 
 tools/python/xen/xend/server/pciif.py   |   78 ++++++------------
 4 files changed, 128 insertions(+), 170 deletions(-)

diff -r bda5ab0cb387 -r 9e36ef77f658 tools/python/xen/util/pci.py
--- a/tools/python/xen/util/pci.py      Wed Jun 17 07:23:40 2009 +0100
+++ b/tools/python/xen/util/pci.py      Wed Jun 17 07:34:59 2009 +0100
@@ -15,6 +15,7 @@ import threading
 import threading
 from xen.util import utils
 from xen.xend import sxp
+from xen.xend.XendConstants import AUTO_PHP_SLOT
 
 PROC_PCI_PATH = '/proc/bus/pci/devices'
 PROC_PCI_NUM_RESOURCES = 7
@@ -35,7 +36,6 @@ LSPCI_CMD = 'lspci'
 
 PCI_DEV_REG_EXPRESS_STR = r"[0-9a-fA-F]{4}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}."+ \
             r"[0-9a-fA-F]{1}"
-PCI_DEV_FORMAT_STR = '%04x:%02x:%02x.%01x'
 
 DEV_TYPE_PCIe_ENDPOINT  = 0
 DEV_TYPE_PCIe_BRIDGE    = 1
@@ -148,22 +148,62 @@ def parse_hex(val):
     except ValueError:
         return None
 
+def parse_pci_name_extended(pci_dev_str):
+    pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" +
+                         r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" +
+                         r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" +
+                         r"(?P<func>(\*|[0-7]))" +
+                         r"(@(?P<vslot>[01]?[0-9a-fA-F]))?" +
+                         r"(,(?P<opts>.*))?$", pci_dev_str)
+
+    if pci_match == None:
+        raise PciDeviceParseError("Failed to parse pci device: %s" %
+                                  pci_dev_str)
+
+    out = {}
+    pci_dev_info = pci_match.groupdict('')
+    if pci_dev_info['domain'] == '':
+        domain = 0
+    else:
+        domain = int(pci_dev_info['domain'], 16)
+    out['domain'] = "0x%04x" % domain
+    out['bus']    = "0x%02x" % int(pci_dev_info['bus'], 16)
+    out['slot']   = "0x%02x" % int(pci_dev_info['slot'], 16)
+    out['func']   = "0x%x"   % int(pci_dev_info['func'], 16)
+    if pci_dev_info['vslot'] == '':
+        vslot = AUTO_PHP_SLOT
+    else:
+        vslot = int(pci_dev_info['vslot'], 16)
+    out['vslot'] = "0x%02x" % vslot
+    if pci_dev_info['opts'] != '':
+        out['opts'] = split_pci_opts(pci_dev_info['opts'])
+        check_pci_opts(out['opts'])
+
+    return out
+
 def parse_pci_name(pci_name_string):
-    pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" + \
-            r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \
-            r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" + \
-            r"(?P<func>[0-7])$", pci_name_string)
-    if pci_match is None:
-        raise PciDeviceParseError(('Failed to parse pci device name: %s' %
-            pci_name_string))
-    pci_dev_info = pci_match.groupdict('0')
-
-    domain = parse_hex(pci_dev_info['domain'])
-    bus = parse_hex(pci_dev_info['bus'])
-    slot = parse_hex(pci_dev_info['slot'])
-    func = parse_hex(pci_dev_info['func'])
-
-    return (domain, bus, slot, func)
+    pci = parse_pci_name_extended(pci_name_string)
+
+    if int(pci['vslot'], 16) != AUTO_PHP_SLOT:
+        raise PciDeviceParseError(("Failed to parse pci device: %s: " +
+                                   "vslot provided where prohibited: %s") %
+                                  (pci_name_string, pci['vslot']))
+    if 'opts' in pci:
+        raise PciDeviceParseError(("Failed to parse pci device: %s: " +
+                                   "options provided where prohibited: %s") %
+                                  (pci_name_string, pci['opts']))
+
+    return pci
+
+def __pci_dict_to_fmt_str(fmt, dev):
+    return fmt % (int(dev['domain'], 16), int(dev['bus'], 16),
+                  int(dev['slot'], 16), int(dev['func'], 16))
+
+def pci_dict_to_bdf_str(dev):
+    return __pci_dict_to_fmt_str('%04x:%02x:%02x.%01x', dev)
+
+def pci_dict_to_xc_str(dev):
+    return __pci_dict_to_fmt_str('0x%x, 0x%x, 0x%x, 0x%x', dev)
 
 def extract_the_exact_pci_names(pci_names):
     result = []
@@ -198,27 +238,7 @@ def get_all_pci_names():
     return pci_names
 
 def get_all_pci_devices():
-    pci_devs = []
-    for pci_name in get_all_pci_names():
-        pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" + \
-                r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \
-                r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" + \
-                r"(?P<func>[0-7])$", pci_name)
-        if pci_match is None:
-            raise PciDeviceParseError(('Failed to parse pci device name: %s' %
-                pci_name))
-        pci_dev_info = pci_match.groupdict('0')
-        domain = parse_hex(pci_dev_info['domain'])
-        bus = parse_hex(pci_dev_info['bus'])
-        slot = parse_hex(pci_dev_info['slot'])
-        func = parse_hex(pci_dev_info['func'])
-        try:
-            pci_dev = PciDevice(domain, bus, slot, func)
-        except:
-            continue
-        pci_devs.append(pci_dev)
-
-    return pci_devs
+    return map(PciDevice, map(parse_pci_name, get_all_pci_names()))
 
 def _create_lspci_info():
     """Execute 'lspci' command and parse the result.
@@ -241,7 +261,7 @@ def _create_lspci_info():
             try:
                 (opt, value) = line.split(':\t')
                 if opt == 'Slot' or (opt == 'Device' and first_device):
-                    device_name = PCI_DEV_FORMAT_STR % parse_pci_name(value)
+                    device_name = pci_dict_to_bdf_str(parse_pci_name(value))
                     first_device = False
                 else:
                     device_info[opt] = value
@@ -292,8 +312,7 @@ def find_all_devices_owned_by_pciback():
     pci_list = extract_the_exact_pci_names(pci_names)
     dev_list = []
     for pci in pci_list:
-        (dom, b, d, f) = parse_pci_name(pci)
-        dev = PciDevice(dom, b, d, f)
+        dev = PciDevice(parse_pci_name(pci))
         dev_list = dev_list + [dev]
     return dev_list
 
@@ -400,12 +419,12 @@ class PciDeviceVslotMissing(Exception):
         return 'pci: no vslot: ' + self.message
 
 class PciDevice:
-    def __init__(self, domain, bus, slot, func):
-        self.domain = domain
-        self.bus = bus
-        self.slot = slot
-        self.func = func
-        self.name = PCI_DEV_FORMAT_STR % (domain, bus, slot, func)
+    def __init__(self, dev):
+        self.domain = int(dev['domain'], 16)
+        self.bus = int(dev['bus'], 16)
+        self.slot = int(dev['slot'], 16)
+        self.func = int(dev['func'], 16)
+        self.name = pci_dict_to_bdf_str(dev)
         self.cfg_space_path = find_sysfs_mnt()+SYSFS_PCI_DEVS_PATH+'/'+ \
             self.name + SYSFS_PCI_DEV_CONFIG_PATH 
         self.irq = 0
@@ -447,14 +466,15 @@ class PciDevice:
                 # We have reached the upmost one.
                 return None
             else:
+                dev = {}
                 lst = parent.split(':')
-                dom = int(lst[0], 16)
-                bus = int(lst[1], 16)
+                dev['domain'] = int(lst[0], 16)
+                dev['bus'] = int(lst[1], 16)
                 lst = lst[2]
                 lst = lst.split('.')
-                dev =  int(lst[0], 16)
-                func =  int(lst[1], 16)
-            return (dom, bus, dev, func)
+                dev['slot'] = int(lst[0], 16)
+                dev['func'] = int(lst[1], 16)
+            return dev
         except OSError, (errno, strerr):
             raise PciDeviceParseError('Can not locate the parent of %s',
                 self.name)
@@ -464,15 +484,13 @@ class PciDevice:
         dev = self.find_parent()
         if dev is None:
             return None
-        (dom, b, d, f) = dev
-        dev = dev_parent = PciDevice(dom, b, d, f)
+        dev = dev_parent = PciDevice(dev)
         while dev_parent.dev_type != DEV_TYPE_PCIe_BRIDGE:
             parent = dev_parent.find_parent()
             if parent is None:
                 break
-            (dom, b, d, f) = parent
             dev = dev_parent
-            dev_parent = PciDevice(dom, b, d, f)
+            dev_parent = PciDevice(parent)
         return dev
 
     def find_all_devices_behind_the_bridge(self, ignore_bridge):
@@ -483,8 +501,7 @@ class PciDevice:
 
         list = [self.name]
         for pci_str in dev_list:
-            (dom, b, d, f) = parse_pci_name(pci_str)
-            dev = PciDevice(dom, b, d, f)
+            dev = PciDevice(parse_pci_name(pci_str))
             if dev.dev_type == DEV_TYPE_PCI_BRIDGE or \
                 dev.dev_type == DEV_TYPE_PCIe_BRIDGE:
                 sub_list_including_self = \
@@ -600,7 +617,7 @@ class PciDevice:
 
     def find_all_the_multi_functions(self):
         sysfs_mnt = find_sysfs_mnt()
-        parent = PCI_DEV_FORMAT_STR % self.find_parent()
+        parent = pci_dict_to_bdf_str(self.find_parent())
         pci_names = os.popen('ls ' + sysfs_mnt + SYSFS_PCI_DEVS_PATH + '/' + \
             parent + '/').read()
         funcs = extract_the_exact_pci_names(pci_names)
@@ -758,8 +775,7 @@ class PciDevice:
         if len(devs) == 0:
             return
         for pci_dev in devs:
-            (dom, b, d, f) = parse_pci_name(pci_dev)
-            dev = PciDevice(dom, b, d, f)
+            dev = PciDevice(parse_pci_name(pci_dev))
             if dev.driver == 'pciback':
                 continue
             err_msg = 'pci: %s must be co-assigned to the same guest with %s' 
+ \
@@ -785,7 +801,7 @@ class PciDevice:
                     funcs = self.find_all_the_multi_functions()
                     self.devs_check_driver(funcs)
 
-                    parent = '%04x:%02x:%02x.%01x' % self.find_parent()
+                    parent = pci_dict_to_bdf_str(self.find_parent())
 
                     # Do Secondary Bus Reset.
                     self.do_secondary_bus_reset(parent, funcs)
diff -r bda5ab0cb387 -r 9e36ef77f658 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Jun 17 07:23:40 2009 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed Jun 17 07:34:59 2009 +0100
@@ -39,7 +39,8 @@ from xen.util.blkif import blkdev_uname_
 from xen.util.blkif import blkdev_uname_to_file, blkdev_uname_to_taptype
 import xen.util.xsm.xsm as security
 from xen.util import xsconstants
-from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp
+from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp, \
+                         pci_dict_to_bdf_str, pci_dict_to_xc_str
 
 from xen.xend import balloon, sxp, uuid, image, arch
 from xen.xend import XendOptions, XendNode, XendConfig
@@ -310,9 +311,8 @@ def do_FLR(domid):
     dev_str_list = get_assigned_pci_devices(domid)
 
     for dev_str in dev_str_list:
-        (dom, b, d, f) = parse_pci_name(dev_str)
         try:
-            dev = PciDevice(dom, b, d, f)
+            dev = PciDevice(parse_pci_name(dev_str))
         except Exception, e:
             raise VmError("pci: failed to locate device and "+
                     "parse it's resources - "+str(e))
@@ -652,23 +652,15 @@ class XendDomainInfo:
                     raise VmError("device is already inserted")
 
         # Test whether the devices can be assigned with VT-d
-        pci_str = "%s, %s, %s, %s" % (new_dev['domain'],
-                new_dev['bus'],
-                new_dev['slot'],
-                new_dev['func'])
-        bdf = xc.test_assign_device(0, pci_str)
+        bdf = xc.test_assign_device(0, pci_dict_to_xc_str(new_dev))
         if bdf != 0:
             if bdf == -1:
                 raise VmError("failed to assign device: maybe the platform"
                               " doesn't support VT-d, or VT-d isn't enabled"
                               " properly?")
-            bus = (bdf >> 16) & 0xff
-            devfn = (bdf >> 8) & 0xff
-            dev = (devfn >> 3) & 0x1f
-            func = devfn & 0x7
-            raise VmError("fail to assign device(%x:%x.%x): maybe it has"
+            raise VmError("fail to assign device(%s): maybe it has"
                           " already been assigned to other domain, or maybe"
-                          " it doesn't exist." % (bus, dev, func))
+                          " it doesn't exist." % pci_dict_to_bdf_str(new_dev))
 
         # Here, we duplicate some checkings (in some cases, we mustn't allow
         # a device to be hot-plugged into an HVM guest) that are also done in
@@ -680,12 +672,8 @@ class XendDomainInfo:
         # Test whether the device is owned by pciback. For instance, we can't
         # hotplug a device being used by Dom0 itself to an HVM guest.
         from xen.xend.server.pciif import PciDevice, parse_pci_name
-        domain = int(new_dev['domain'],16)
-        bus    = int(new_dev['bus'],16)
-        dev    = int(new_dev['slot'],16)
-        func   = int(new_dev['func'],16)
         try:
-            pci_device = PciDevice(domain, bus, dev, func)
+            pci_device = PciDevice(new_dev)
         except Exception, e:
             raise VmError("pci: failed to locate device and "+
                     "parse it's resources - "+str(e))
@@ -710,9 +698,8 @@ class XendDomainInfo:
         pci_device.devs_check_driver(coassignment_list)
         assigned_pci_device_str_list = self._get_assigned_pci_devices()
         for pci_str in coassignment_list:
-            (domain, bus, dev, func) = parse_pci_name(pci_str) 
-            dev_str =  '0x%x,0x%x,0x%x,0x%x' % (domain, bus, dev, func)
-            if xc.test_assign_device(0, dev_str) == 0:
+            pci_dev = parse_pci_name(pci_str)
+            if xc.test_assign_device(0, pci_dict_to_xc_str(pci_dev)) == 0:
                 continue
             if not pci_str in assigned_pci_device_str_list:
                 raise VmError(("pci: failed to pci-attach %s to domain %s" + \
@@ -742,12 +729,9 @@ class XendDomainInfo:
             if new_dev.has_key('opts'):
                 opts = ',' + serialise_pci_opts(new_dev['opts'])
 
-            bdf_str = "%s:%s:%s.%s@%s%s" % (new_dev['domain'],
-                new_dev['bus'],
-                new_dev['slot'],
-                new_dev['func'],
-                new_dev['vslot'],
-                opts)
+            bdf_str = "%s@%02x%s" % (pci_dict_to_bdf_str(new_dev),
+                                     int(new_dev['vslot'], 16), opts)
+            log.debug("XendDomainInfo.hvm_pci_device_insert_dev: %s" % bdf_str)
             self.image.signalDeviceModel('pci-ins', 'pci-inserted', bdf_str)
 
             vslot = xstransact.Read("/local/domain/0/device-model/%i/parameter"
@@ -864,9 +848,8 @@ class XendDomainInfo:
                         vslot = x['vslot']
                         break
                 if vslot == "":
-                    raise VmError("Device %04x:%02x:%02x.%01x is not connected"
-                                  % (int(dev['domain'],16), int(dev['bus'],16),
-                                     int(dev['slot'],16), int(dev['func'],16)))
+                    raise VmError("Device %s is not connected" %
+                                  pci_dict_to_bdf_str(dev))
                 self.hvm_destroyPCIDevice(int(vslot, 16))
                 # Update vslot
                 dev['vslot'] = vslot
@@ -1152,12 +1135,8 @@ class XendDomainInfo:
         # list of D's co-assignment devices, DD is not assigned (to domN).
         # 
         from xen.xend.server.pciif import PciDevice
-        domain = int(x['domain'],16)
-        bus    = int(x['bus'],16)
-        dev    = int(x['slot'],16)
-        func   = int(x['func'],16)
         try:
-            pci_device = PciDevice(domain, bus, dev, func)
+            pci_device = PciDevice(x)
         except Exception, e:
             raise VmError("pci: failed to locate device and "+
                     "parse it's resources - "+str(e))
@@ -1172,9 +1151,8 @@ class XendDomainInfo:
                     )% (pci_device.name, self.info['name_label'], pci_str))
 
 
-        bdf_str = "%s:%s:%s.%s" % (x['domain'], x['bus'], x['slot'], x['func'])
+        bdf_str = pci_dict_to_bdf_str(x)
         log.info("hvm_destroyPCIDevice:%s:%s!", x, bdf_str)
-
         if self.domid is not None:
             self.image.signalDeviceModel('pci-rem', 'pci-removed', bdf_str)
 
@@ -1338,21 +1316,12 @@ class XendDomainInfo:
         if self.domid is not None:
             return get_assigned_pci_devices(self.domid)
 
-        dev_str_list = []
         dev_info = self._getDeviceInfo_pci(devid)
         if dev_info is None:
-            return dev_str_list
+            return []
         dev_uuid = sxp.child_value(dev_info, 'uuid')
         pci_conf = self.info['devices'][dev_uuid][1]
-        pci_devs = pci_conf['devs']
-        for pci_dev in pci_devs:
-            domain = int(pci_dev['domain'], 16)
-            bus = int(pci_dev['bus'], 16)
-            slot = int(pci_dev['slot'], 16)
-            func = int(pci_dev['func'], 16)
-            dev_str = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
-            dev_str_list = dev_str_list + [dev_str]
-        return dev_str_list 
+        return map(pci_dict_to_bdf_str, pci_conf['devs'])
 
     def setMemoryTarget(self, target):
         """Set the memory target of this domain.
@@ -3909,12 +3878,12 @@ class XendDomainInfo:
         target_dev = None
         new_pci_sxp = ['pci']
         for dev in sxp.children(old_pci_sxp, 'dev'):
-            domain = int(sxp.child_value(dev, 'domain'), 16)
-            bus = int(sxp.child_value(dev, 'bus'), 16)
-            slot = int(sxp.child_value(dev, 'slot'), 16)
-            func = int(sxp.child_value(dev, 'func'), 16)
-            name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
-            if ppci.get_name() == name:
+            pci_dev = {}
+            pci_dev['domain'] = sxp.child_value(dev, 'domain')
+            pci_dev['bus'] = sxp.child_value(dev, 'bus')
+            pci_dev['slot'] = sxp.child_value(dev, 'slot')
+            pci_dev['func'] = sxp.child_value(dev, 'func')
+            if ppci.get_name() == pci_dict_to_bdf_str(pci_dev):
                 target_dev = dev
             else:
                 new_pci_sxp.append(dev)
diff -r bda5ab0cb387 -r 9e36ef77f658 tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Wed Jun 17 07:23:40 2009 +0100
+++ b/tools/python/xen/xend/XendNode.py Wed Jun 17 07:34:59 2009 +0100
@@ -340,8 +340,7 @@ class XendNode:
                 except KeyError:
                     pass
 
-        (domain, bus, slot, func) = PciUtil.parse_pci_name(pci_name)
-        pci_dev = PciUtil.PciDevice(domain, bus, slot, func)
+        pci_dev = PciUtil.PciDevice(PciUtil.parse_pci_name(pci_name))
         ppci_record = {
             'domain':                   pci_dev.domain,
             'bus':                      pci_dev.bus,
diff -r bda5ab0cb387 -r 9e36ef77f658 tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py     Wed Jun 17 07:23:40 2009 +0100
+++ b/tools/python/xen/xend/server/pciif.py     Wed Jun 17 07:34:59 2009 +0100
@@ -130,13 +130,7 @@ class PciController(DevController):
                     log.debug('Reconfiguring PCI device %s.' % dev)
                     attaching = False
 
-                (domain, bus, slotfunc) = dev.split(':')
-                (slot, func) = slotfunc.split('.')
-                domain = parse_hex(domain)
-                bus = parse_hex(bus)
-                slot = parse_hex(slot)
-                func = parse_hex(func)
-                self.setupOneDevice(domain, bus, slot, func)
+                self.setupOneDevice(parse_pci_name(dev))
 
                 self.writeBackend(devid, 'dev-%i' % devno, dev)
                 self.writeBackend(devid, 'state-%i' % devno,
@@ -248,15 +242,13 @@ class PciController(DevController):
             return
 
         #group string format xx:xx.x,xx:xx.x,
-        devstr_len = group_str.find(',')
-        for i in range(0, len(group_str), devstr_len + 1):
-            (bus, slotfunc) = group_str[i:i + devstr_len].split(':')
-            (slot, func) = slotfunc.split('.')
-            b = parse_hex(bus)
-            d = parse_hex(slot)
-            f = parse_hex(func)
+        for i in group_str.split(','):
+            if i == '':
+                continue
+            pci_dev = parse_pci_name(i)
+            pci_dev['domain'] = '%04x' % dev.domain
             try:
-                sdev = PciDevice(dev.domain, b, d, f)
+                sdev = PciDevice(pci_dev)
             except Exception, e:
                 #no dom0 drivers bound to sdev
                 continue
@@ -270,13 +262,13 @@ class PciController(DevController):
                     )%(sdev.name, dev.name))
         return
 
-    def setupOneDevice(self, domain, bus, slot, func):
+    def setupOneDevice(self, pci_dev):
         """ Attach I/O resources for device to frontend domain
         """
         fe_domid = self.getDomid()
 
         try:
-            dev = PciDevice(domain, bus, slot, func)
+            dev = PciDevice(pci_dev)
         except Exception, e:
             raise VmError("pci: failed to locate device and "+
                     "parse it's resources - "+str(e))
@@ -305,12 +297,11 @@ class PciController(DevController):
 
         if not self.vm.info.is_hvm():
             # Setup IOMMU device assignment
-            pci_str = "0x%x, 0x%x, 0x%x, 0x%x" % (domain, bus, slot, func)
-            bdf = xc.assign_device(fe_domid, pci_str)
+            bdf = xc.assign_device(fe_domid, pci_dict_to_xc_str(pci_dev))
+            pci_str = pci_dict_to_bdf_str(pci_dev)
             if bdf > 0:
-                raise VmError("Failed to assign device to IOMMU (%x:%x.%x)"
-                              % (bus, slot, func))
-            log.debug("pci: assign device %x:%x.%x" % (bus, slot, func))
+                raise VmError("Failed to assign device to IOMMU (%s)" % 
pci_str)
+            log.debug("pci: assign device %s" % pci_str)
 
         for (start, size) in dev.ioports:
             log.debug('pci: enabling ioport 0x%x/0x%x'%(start,size))
@@ -366,23 +357,15 @@ class PciController(DevController):
     def setupDevice(self, config):
         """Setup devices from config
         """
-        pci_str_list = []
-        pci_dev_list = []
-        for pci_config in config.get('devs', []):
-            domain = parse_hex(pci_config.get('domain', 0))
-            bus = parse_hex(pci_config.get('bus', 0))
-            slot = parse_hex(pci_config.get('slot', 0))
-            func = parse_hex(pci_config.get('func', 0))            
-            pci_str = '%04x:%02x:%02x.%01x' % (domain, bus, slot, func)
-            pci_str_list = pci_str_list + [pci_str]
-            pci_dev_list = pci_dev_list + [(domain, bus, slot, func)]
+        pci_dev_list = config.get('devs', [])
+        pci_str_list = map(pci_dict_to_bdf_str, pci_dev_list)
 
         if len(pci_str_list) != len(set(pci_str_list)):
             raise VmError('pci: duplicate devices specified in guest config?')
 
-        for (domain, bus, slot, func) in pci_dev_list:
+        for pci_dev in pci_dev_list:
             try:
-                dev = PciDevice(domain, bus, slot, func)
+                dev = PciDevice(pci_dev)
             except Exception, e:
                 raise VmError("pci: failed to locate device and "+
                         "parse it's resources - "+str(e))
@@ -427,9 +410,7 @@ class PciController(DevController):
                     dev.devs_check_driver(devs_str)
                     for s in devs_str:
                         if not s in pci_str_list:
-                            (s_dom, s_bus, s_slot, s_func) = parse_pci_name(s)
-                            s_pci_str = '0x%x,0x%x,0x%x,0x%x' % \
-                                (s_dom, s_bus, s_slot, s_func)
+                            s_pci_str = pci_dict_to_bdf_str(parse_pci_name(s))
                             # s has been assigned to other guest?
                             if xc.test_assign_device(0, s_pci_str) != 0:
                                 err_msg = 'pci: %s must be co-assigned to 
the'+\
@@ -453,13 +434,13 @@ class PciController(DevController):
         return True
 
 
-    def cleanupOneDevice(self, domain, bus, slot, func):
+    def cleanupOneDevice(self, pci_dev):
         """ Detach I/O resources for device from frontend domain
         """
         fe_domid = self.getDomid()
 
         try:
-            dev = PciDevice(domain, bus, slot, func)
+            dev = PciDevice(pci_dev)
         except Exception, e:
             raise VmError("pci: failed to locate device and "+
                     "parse it's resources - "+str(e))
@@ -476,12 +457,11 @@ class PciController(DevController):
         # DMA transaction, etc
         dev.do_FLR()
 
-        pci_str = "0x%x, 0x%x, 0x%x, 0x%x" % (domain, bus, slot, func)
-        bdf = xc.deassign_device(fe_domid, pci_str)
+        bdf = xc.deassign_device(fe_domid, pci_dict_to_xc_str(pci_dev))
+        pci_str = pci_dict_to_bdf_str(pci_dev)
         if bdf > 0:
-            raise VmError("Failed to deassign device from IOMMU (%x:%x.%x)"
-                          % (bus, slot, func))
-        log.debug("pci: Deassign device %x:%x.%x" % (bus, slot, func))
+            raise VmError("Failed to deassign device from IOMMU (%s)" % 
pci_str)
+        log.debug("pci: Deassign device %s" % pci_str)
 
         for (start, size) in dev.ioports:
             log.debug('pci: disabling ioport 0x%x/0x%x'%(start,size))
@@ -530,15 +510,9 @@ class PciController(DevController):
             state = int(self.readBackend(devid, 'state-%i' % i))
             if state == xenbusState['Closing']:
                 # Detach I/O resources.
-                dev = self.readBackend(devid, 'dev-%i' % i)
-                (domain, bus, slotfunc) = dev.split(':')
-                (slot, func) = slotfunc.split('.')
-                domain = parse_hex(domain)
-                bus = parse_hex(bus)
-                slot = parse_hex(slot)
-                func = parse_hex(func)            
+                pci_dev = parse_pci_name(self.readBackend(devid, 'dev-%i' % i))
                 # In HVM case, I/O resources are disabled in ioemu.
-                self.cleanupOneDevice(domain, bus, slot, func)
+                self.cleanupOneDevice(pci_dev)
                 # Remove xenstore nodes.
                 list = ['dev', 'vdev', 'state', 'uuid', 'vslot']
                 if self.readBackend(devid, 'opts-%i' % i) is not None:

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] xend: pass-through: Common parse_pci_name(), Xen patchbot-unstable <=