From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:55801) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RvV30-0002X1-GK for qemu-devel@nongnu.org; Thu, 09 Feb 2012 09:32:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RvV2w-0004LK-4q for qemu-devel@nongnu.org; Thu, 09 Feb 2012 09:32:30 -0500 Received: from mail-pw0-f45.google.com ([209.85.160.45]:55650) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RvV2v-0004Go-TZ for qemu-devel@nongnu.org; Thu, 09 Feb 2012 09:32:26 -0500 Received: by mail-pw0-f45.google.com with SMTP id ro12so1788490pbb.4 for ; Thu, 09 Feb 2012 06:32:25 -0800 (PST) Sender: Paolo Bonzini From: Paolo Bonzini Date: Thu, 9 Feb 2012 15:31:55 +0100 Message-Id: <1328797918-1316-7-git-send-email-pbonzini@redhat.com> In-Reply-To: <1328797918-1316-1-git-send-email-pbonzini@redhat.com> References: <1328797918-1316-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 6/9] qdev: accept both strings and integers for PCI addresses List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aliguori@us.ibm.com Visitors allow a limited form of polymorphism. Exploit it to support setting the non-legacy PCI address property both as a DD.F string and as an 8-bit integer. The 8-bit integer form is just too clumsy, it is unlikely that we will ever drop it. Signed-off-by: Paolo Bonzini --- hw/qdev-properties.c | 36 +++++++++++++++++++++++++----------- 1 files changed, 25 insertions(+), 11 deletions(-) diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index b6d6fcf..9a838b0 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -943,25 +943,40 @@ PropertyInfo qdev_prop_losttickpolicy = { /* * bus-local address, i.e. "$slot" or "$slot.$fn" */ -static int parse_pci_devfn(DeviceState *dev, Property *prop, const char *str) +static void set_pci_devfn(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; uint32_t *ptr = qdev_get_prop_ptr(dev, prop); unsigned int slot, fn, n; + Error *local_err = NULL; + char *str = (char *)""; + + if (dev->state != DEV_STATE_CREATED) { + error_set(errp, QERR_PERMISSION_DENIED); + return; + } + + visit_type_str(v, &str, name, &local_err); + if (local_err) { + return set_int32(obj, v, opaque, name, errp); + } if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) { fn = 0; if (sscanf(str, "%x%n", &slot, &n) != 1) { - return -EINVAL; + goto invalid; } } - if (str[n] != '\0') - return -EINVAL; - if (fn > 7) - return -EINVAL; - if (slot > 31) - return -EINVAL; + if (str[n] != '\0' || fn > 7 || slot > 31) { + goto invalid; + } *ptr = slot << 3 | fn; - return 0; + return; + +invalid: + error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); } static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len) @@ -978,10 +993,9 @@ static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t PropertyInfo qdev_prop_pci_devfn = { .name = "int32", .legacy_name = "pci-devfn", - .parse = parse_pci_devfn, .print = print_pci_devfn, .get = get_int32, - .set = set_int32, + .set = set_pci_devfn, /* FIXME: this should be -1...255, but the address is stored * into an uint32_t rather than int32_t. */ -- 1.7.7.6