From patchwork Thu Jan 12 17:35:28 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 135665 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id DE2D0B6EFE for ; Fri, 13 Jan 2012 05:03:52 +1100 (EST) Received: from localhost ([::1]:45826 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RlOZX-0004lP-Vp for incoming@patchwork.ozlabs.org; Thu, 12 Jan 2012 12:36:19 -0500 Received: from eggs.gnu.org ([140.186.70.92]:54015) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RlOYy-0003OC-A4 for qemu-devel@nongnu.org; Thu, 12 Jan 2012 12:35:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RlOYo-0003fz-PS for qemu-devel@nongnu.org; Thu, 12 Jan 2012 12:35:44 -0500 Received: from cantor2.suse.de ([195.135.220.15]:43300 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RlOYo-0003fm-Hh; Thu, 12 Jan 2012 12:35:34 -0500 Received: from relay2.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 06C758FA98; Thu, 12 Jan 2012 18:35:33 +0100 (CET) From: Alexander Graf To: qemu-devel Developers Date: Thu, 12 Jan 2012 18:35:28 +0100 Message-Id: <1326389731-1694-5-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1326389731-1694-1-git-send-email-agraf@suse.de> References: <1326389731-1694-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 X-Received-From: 195.135.220.15 Cc: Michael Ellerman , jmforbes@linuxtx.org, qemu-stable@nongnu.org, David Gibson Subject: [Qemu-devel] [PATCH 4/7] pseries: Emit device tree nodes in reg order X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 (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 */