f0bf933e69
- qemu-user: add device mapper and loopback ioctls, enabling kpatkx OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=40
102 lines
2.9 KiB
Diff
102 lines
2.9 KiB
Diff
From 7fe6b9bf81290f708919ffb6065daa16e5dbe7e3 Mon Sep 17 00:00:00 2001
|
|
From: David Gibson <david@gibson.dropbear.id.au>
|
|
Date: Mon, 12 Dec 2011 18:24:32 +0000
|
|
Subject: [PATCH] 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@ellerman.id.au>
|
|
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
|
|
Signed-off-by: Alexander Graf <agraf@suse.de>
|
|
|
|
[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 */
|
|
--
|
|
1.6.0.2
|
|
|