[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [qemu-upstream-unstable] pseries: Emit device tree nodes in reg order



commit e295c31e25b044acba2a48f1e7292b9fbb896367
Author: David Gibson <david@xxxxxxxxxxxxxxxxxxxxx>
Date:   Mon Dec 12 18:24:32 2011 +0000

    pseries: Emit device tree nodes in reg order
    
    Although in theory the device tree has no inherent ordering, in practice
    the order of nodes in the device tree does effect the order that devices
    are detected by software.
    
    Currently the ordering is determined by the order the devices appear on
    the QEMU command line. Although that does give the user control over the
    ordering, it is fragile, especially when the user does not generate the
    command line manually - eg. when using libvirt etc.
    
    So order the device tree based on the reg value, ie. the address of on
    the VIO bus of the devices. This gives us a sane and stable ordering.
    
    Signed-off-by: Michael Ellerman <michael@xxxxxxxxxxxxxx>
    Signed-off-by: David Gibson <david@xxxxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Alexander Graf <agraf@xxxxxxx>
    
    [agraf] add braces
    (cherry picked from commit 05c194384f836240ea4c2da5fa3be43a54bff021)
---
 hw/spapr_vio.c |   50 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 2dcc036..8bd00ca 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -749,21 +749,61 @@ static void spapr_vio_register_devices(void)
 device_init(spapr_vio_register_devices)
 
 #ifdef CONFIG_FDT
+static int compare_reg(const void *p1, const void *p2)
+{
+    VIOsPAPRDevice const *dev1, *dev2;
+
+    dev1 = (VIOsPAPRDevice *)*(DeviceState **)p1;
+    dev2 = (VIOsPAPRDevice *)*(DeviceState **)p2;
+
+    if (dev1->reg < dev2->reg) {
+        return -1;
+    }
+    if (dev1->reg == dev2->reg) {
+        return 0;
+    }
+
+    /* dev1->reg > dev2->reg */
+    return 1;
+}
+
 int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt)
 {
-    DeviceState *qdev;
-    int ret = 0;
+    DeviceState *qdev, **qdevs;
+    int i, num, ret = 0;
 
+    /* Count qdevs on the bus list */
+    num = 0;
     QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
-        VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
+        num++;
+    }
+
+    /* Copy out into an array of pointers */
+    qdevs = g_malloc(sizeof(qdev) * num);
+    num = 0;
+    QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
+        qdevs[num++] = qdev;
+    }
+
+    /* Sort the array */
+    qsort(qdevs, num, sizeof(qdev), compare_reg);
+
+    /* Hack alert. Give the devices to libfdt in reverse order, we happen
+     * to know that will mean they are in forward order in the tree. */
+    for (i = num - 1; i >= 0; i--) {
+        VIOsPAPRDevice *dev = (VIOsPAPRDevice *)(qdevs[i]);
 
         ret = vio_make_devnode(dev, fdt);
 
         if (ret < 0) {
-            return ret;
+            goto out;
         }
     }
 
-    return 0;
+    ret = 0;
+out:
+    free(qdevs);
+
+    return ret;
 }
 #endif /* CONFIG_FDT */
--
generated by git-patchbot for /home/xen/git/qemu-upstream-unstable.git

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.