From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:44022) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ri5ko-00024b-8H for qemu-devel@nongnu.org; Tue, 03 Jan 2012 09:54:22 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ri5kl-0000ZK-CS for qemu-devel@nongnu.org; Tue, 03 Jan 2012 09:54:18 -0500 Received: from cantor2.suse.de ([195.135.220.15]:40901 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ri5kl-0000Z2-3q for qemu-devel@nongnu.org; Tue, 03 Jan 2012 09:54:15 -0500 From: Alexander Graf Date: Tue, 3 Jan 2012 16:08:18 +0100 Message-Id: <1325603302-12412-7-git-send-email-agraf@suse.de> In-Reply-To: <1325603302-12412-1-git-send-email-agraf@suse.de> References: <1325603302-12412-1-git-send-email-agraf@suse.de> Subject: [Qemu-devel] [PATCH 06/10] pseries: Emit device tree nodes in reg order List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "qemu-devel@nongnu.org Developers" Cc: Blue Swirl , Michael Ellerman , Aurelien Jarno , David Gibson From: David Gibson 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 Signed-off-by: David Gibson Signed-off-by: Alexander Graf [agraf] add braces --- 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 5a35541..2cce421 100644 --- a/hw/spapr_vio.c +++ b/hw/spapr_vio.c @@ -736,21 +736,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