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-devel

[Xen-devel] [patch 09/17] xend: pass-through: Common parse_pci_name()

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [patch 09/17] xend: pass-through: Common parse_pci_name()
From: Simon Horman <horms@xxxxxxxxxxxx>
Date: Wed, 17 Jun 2009 12:56:21 +1000
Cc: Zhigang Wang <zhigang.x.wang@xxxxxxxxxx>, Akio Takebe <takebe_akio@xxxxxxxxxxxxxx>, Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>, Dexuan Cui <dexuan.cui@xxxxxxxxx>
Delivery-date: Tue, 16 Jun 2009 20:34:50 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20090617025612.786241401@xxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: quilt/0.46-1
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

Cc: Dexuan Cui <dexuan.cui@xxxxxxxxx>
Cc: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>
Cc: Akio Takebe <takebe_akio@xxxxxxxxxxxxxx>
Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>

--- 

Wed, 20 May 2009 23:07:42 +1000
* Fix syntax errors in parse_pci_name() and parse_pci_name_bdf6()
  - unnoticed as they were resolved by the subsequent patch
    "xm: Allow multi-function device specifications to be parsed
* Enhanced error reporting in parse_pci_name()
* Have parse_pci_name_bdf6() return an int rather than a string for vslot in
  keeping with the other integer elements of the bdf6 tuple

Fri, 22 May 2009 15:52:50 +1000
* Consolidate get_all_pci_bdf6() and get_all_pci_devices()

Thu, 28 May 2009 23:56:14 +1000
* Up-port

Tue, 16 Jun 2009 18:37:05 +1000
* In find_parent(), dev['dom'] should be dev['domain'].
  Pointed out by Takebe-san.

Wed, 17 Jun 2009 12:12:05 +1000
* Up-port to xen-unstable.hg 19745:55ca7ef865b4


Index: xen-unstable.hg/tools/python/xen/util/pci.py
===================================================================
--- xen-unstable.hg.orig/tools/python/xen/util/pci.py   2009-06-17 
13:07:51.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/util/pci.py        2009-06-17 
13:10:00.000000000 +1000
@@ -15,6 +15,7 @@ import time
 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'])
+    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))
 
-    return (domain, bus, slot, func)
+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)
Index: xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-unstable.hg.orig/tools/python/xen/xend/XendDomainInfo.py        
2009-06-17 13:07:51.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py     2009-06-17 
13:10:00.000000000 +1000
@@ -39,7 +39,8 @@ from xen.util import asserts, auxbin
 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)
Index: xen-unstable.hg/tools/python/xen/xend/XendNode.py
===================================================================
--- xen-unstable.hg.orig/tools/python/xen/xend/XendNode.py      2009-06-17 
12:12:46.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendNode.py   2009-06-17 
13:10:00.000000000 +1000
@@ -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,
Index: xen-unstable.hg/tools/python/xen/xend/server/pciif.py
===================================================================
--- xen-unstable.hg.orig/tools/python/xen/xend/server/pciif.py  2009-06-17 
13:07:51.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/server/pciif.py       2009-06-17 
13:10:00.000000000 +1000
@@ -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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>