From patchwork Tue Jun 16 18:30:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laszlo Ersek X-Patchwork-Id: 485110 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id B36611401B5 for ; Wed, 17 Jun 2015 04:31:45 +1000 (AEST) Received: from localhost ([::1]:42185 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z4veB-00050J-JA for incoming@patchwork.ozlabs.org; Tue, 16 Jun 2015 14:31:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49714) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z4vdY-0003qo-Kn for qemu-devel@nongnu.org; Tue, 16 Jun 2015 14:31:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z4vdX-0000Fb-Hs for qemu-devel@nongnu.org; Tue, 16 Jun 2015 14:31:04 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41506) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z4vdX-0000FV-B9 for qemu-devel@nongnu.org; Tue, 16 Jun 2015 14:31:03 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 08E942931FE for ; Tue, 16 Jun 2015 18:31:03 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com ([10.10.116.42]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t5GIUqSC031614; Tue, 16 Jun 2015 14:31:01 -0400 From: Laszlo Ersek To: qemu-devel@nongnu.org, lersek@redhat.com Date: Tue, 16 Jun 2015 20:30:44 +0200 Message-Id: <1434479445-22477-4-git-send-email-lersek@redhat.com> In-Reply-To: <1434479445-22477-1-git-send-email-lersek@redhat.com> References: <1434479445-22477-1-git-send-email-lersek@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Marcel Apfelbaum , Markus Armbruster , "Michael S. Tsirkin" Subject: [Qemu-devel] [PATCH v5 3/4] hw/core: explicit OFW unit address callback for SysBusDeviceClass 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 The sysbus_get_fw_dev_path() function formats OpenFirmware device path nodes ("driver-name@unit-address") for sysbus devices. The first choice for "unit-address" is the base address of the device's first MMIO region. The second choice is its first IO port. However, if two sysbus devices with the same "driver-name" lack both MMIO and PIO resources, then there is no good way to distinguish them based on their OFW nodes, because in this case unit-address is omitted completely for both devices. An example is TYPE_PXB_HOST ("pxb-host"). For the sake of such devices, introduce the explicit_ofw_unit_address() "virtual member function". With this function, each sysbus device in the same SysBusDeviceClass can state its own address. Cc: Markus Armbruster Cc: Marcel Apfelbaum Cc: Michael S. Tsirkin Signed-off-by: Laszlo Ersek Reviewed-by: Marcel Apfelbaum Tested-by: Marcel Apfelbaum Reviewed-by: Markus Armbruster --- Notes: v5: - mention "pxb-host" as an example device in the commit message [Markus] - reword documentation on explicit_ofw_unit_address(), specifying headline, preconditions / goal, side effects, retval, errors separately. [Markus] - constify parameter of explicit_ofw_unit_address(), after focusing on side effects [Markus] - move declaration of "addr" and "fw_dev_path" to the top level block in sysbus_get_fw_dev_path() [Markus] - no functional changes, add / keep Markus's R-b v4: - Yet another approach. Instead of allowing the creator of the device to set a string property statically, introduce a class level callback. v3: - new in v3 - new approach include/hw/sysbus.h | 17 +++++++++++++++++ hw/core/sysbus.c | 11 +++++++++++ 2 files changed, 28 insertions(+) diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h index d1f3f00..34f93c3 100644 --- a/include/hw/sysbus.h +++ b/include/hw/sysbus.h @@ -41,6 +41,23 @@ typedef struct SysBusDeviceClass { /*< public >*/ int (*init)(SysBusDevice *dev); + + /* + * Let the sysbus device format its own non-PIO, non-MMIO unit address. + * + * Sometimes a class of SysBusDevices has neither MMIO nor PIO resources, + * yet instances of it would like to distinguish themselves, in + * OpenFirmware device paths, from other instances of the same class on the + * sysbus. For that end we expose this callback. + * + * The implementation is not supposed to change *@dev, or incur other + * observable change. + * + * The function returns a dynamically allocated string. On error, NULL + * should be returned; the unit address portion of the OFW node will be + * omitted then. (This is not considered a fatal error.) + */ + char *(*explicit_ofw_unit_address)(const SysBusDevice *dev); } SysBusDeviceClass; struct SysBusDevice { diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c index 92eced9..278a2d1 100644 --- a/hw/core/sysbus.c +++ b/hw/core/sysbus.c @@ -281,6 +281,9 @@ static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent) static char *sysbus_get_fw_dev_path(DeviceState *dev) { SysBusDevice *s = SYS_BUS_DEVICE(dev); + SysBusDeviceClass *sbc = SYS_BUS_DEVICE_GET_CLASS(s); + /* for the explicit unit address fallback case: */ + char *addr, *fw_dev_path; if (s->num_mmio) { return g_strdup_printf("%s@" TARGET_FMT_plx, qdev_fw_name(dev), @@ -289,6 +292,14 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev) if (s->num_pio) { return g_strdup_printf("%s@i%04x", qdev_fw_name(dev), s->pio[0]); } + if (sbc->explicit_ofw_unit_address) { + addr = sbc->explicit_ofw_unit_address(s); + if (addr) { + fw_dev_path = g_strdup_printf("%s@%s", qdev_fw_name(dev), addr); + g_free(addr); + return fw_dev_path; + } + } return g_strdup(qdev_fw_name(dev)); }