qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/8] qom: introduce non-legacy static properties
@ 2011-12-16 16:47 Paolo Bonzini
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 1/8] qapi: protect against NULL QObject in qmp_input_get_object Paolo Bonzini
                   ` (7 more replies)
  0 siblings, 8 replies; 15+ messages in thread
From: Paolo Bonzini @ 2011-12-16 16:47 UTC (permalink / raw)
  To: qemu-devel

QOM right now does not have a way to communicate values for qdev
properties except as strings.  This is bad.

This patch improves the Property implementation so that properties
export a visitor-based interface in addition to the string-based
interface.  The new interface can then be registered as a "static"
property.  It's called static because it uses a struct field for
storage and, as such, should be present in all objects of a given
class.

Patches 1-2 are bugfixes and patches 3-4 are cleanups.

Example using qmp-shell:

x86_64-softmmu/qemu-system-x86_64 \
   -hda ~/test.img -snapshot -S \
   -qmp unix:/tmp/server.sock,server,nowait \
   -netdev type=user,id=net -device virtio-net-pci,netdev=net,id=net \
   -net user,vlan=1 -device virtio-net-pci,id=net2,vlan=1 \
   -chardev id=stdio,backend=stdio -device isa-serial,chardev=stdio,id=serial

Boolean properties:

(QEMU) qom-get path=/i440fx/piix3 property=command_serr_enable
{u'return': True}
(QEMU) qom-get path=/i440fx/piix3 property=legacy<command_serr_enable>
{u'return': u'on'}

PCI address properties (perhaps will disappear later, but not yet):

(QEMU) qom-get path=/i440fx/piix3 property=addr
{u'return': u'01.0'}
(QEMU) qom-get path=/i440fx/piix3 property=legacy<addr>
{u'return': u'01.0'}

String properties (QObject does not have NULL):

(QEMU) qom-get path=/vga property=romfile
{u'return': u'vgabios-cirrus.bin'}
(QEMU) qom-get path=/vga property=legacy<romfile>
{u'return': u'"vgabios-cirrus.bin"'}
(QEMU) qom-get path=/i440fx/piix3 property=romfile
{u'return': u''}
(QEMU) qom-get path=/i440fx/piix3 property=legacy<romfile>
{u'return': u'<null>'}

MAC properties:

(QEMU) qom-get path=/peripheral/net property=mac
{u'return': u'52:54:00:12:34:56'}
(QEMU) qom-get path=/peripheral/net property=legacy<mac>
{u'return': u'52:54:00:12:34:56'}
(QEMU) qom-set path=/peripheral/net property=mac value=52-54-00-12-34-57
{u'error': {u'data': {}, u'class': u'PermissionDenied', u'desc': u'Insufficient permission to perform this operation'}}

Network properties:

(QEMU) qom-get path=/peripheral/net property=netdev
{u'return': u'net'}
(QEMU) qom-get path=/peripheral/net property=legacy<netdev>
{u'return': u'net'}

VLAN properties:

(QEMU) qom-get path=/peripheral/net property=vlan
{u'return': -1}
(QEMU) qom-get path=/peripheral/net property=legacy<vlan>
{u'return': u'<null>'}
(QEMU) qom-get path=/peripheral/net2 property=vlan
{u'return': 1}
(QEMU) qom-get path=/peripheral/net2 property=legacy<vlan>
{u'return': u'1'}

Chardev properties:

(QEMU) qom-get path=/peripheral/serial property=chardev
{u'return': u'stdio'}
(QEMU) qom-get path=/peripheral/serial property=legacy<chardev>
{u'return': u'stdio'}

Legacy hex32 properties:

(QEMU) qom-get path=/peripheral/serial property=iobase
{u'return': 1016}
(QEMU) qom-get path=/peripheral/serial property=legacy<iobase>
{u'return': u'0x3f8'}

Examples of setting properties (after disabling the DEV_STATE_CREATED
check for testing only):

(QEMU) qom-set path=/peripheral/net2 property=vlan value=-1
{u'return': {}}
(QEMU) qom-get path=/peripheral/net2 property=vlan
{u'return': -1}
(QEMU) qom-get path=/peripheral/net2 property=legacy<vlan>
{u'return': u'<null>'}

(QEMU) qom-set path=/peripheral/serial property=iobase value=760
{u'return': {}}
(QEMU) qom-get path=/peripheral/serial property=iobase
{u'return': 760}
(QEMU) qom-get path=/peripheral/serial property=legacy<iobase>
{u'return': u'0x2f8'}

v1->v2:
        New "qom: interpret the return value when setting legacy
        properties".  Always pass a value to the visitor when there
        is no error.  Handle empty strings as NULL.  Did not change
        QERR_PROPERTY_VALUE_OUT_OF_RANGE because it is consistent
        with other QERR_PROPERTY_* errors, now used by QOM too.

Paolo Bonzini (8):
  qapi: protect against NULL QObject in qmp_input_get_object
  qom: fix swapped parameters
  qom: push permission checks up into qdev_property_add_legacy
  qom: interpret the return value when setting legacy properties
  qom: introduce QERR_PROPERTY_VALUE_OUT_OF_RANGE
  qom: introduce get/set methods for Property
  qom: distinguish "legacy" property type name from QOM type name
  qom: register qdev properties also as non-legacy properties

 hw/qdev-addr.c           |   41 +++++
 hw/qdev-properties.c     |  406 +++++++++++++++++++++++++++++++++++++++++++---
 hw/qdev.c                |   84 ++++++----
 hw/qdev.h                |   14 ++-
 qapi/qmp-input-visitor.c |   10 +-
 qerror.c                 |    5 +
 qerror.h                 |    3 +
 7 files changed, 502 insertions(+), 61 deletions(-)

-- 
1.7.7.1

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 1/8] qapi: protect against NULL QObject in qmp_input_get_object
  2011-12-16 16:47 [Qemu-devel] [PATCH v2 0/8] qom: introduce non-legacy static properties Paolo Bonzini
@ 2011-12-16 16:47 ` Paolo Bonzini
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 2/8] qom: fix swapped parameters Paolo Bonzini
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Paolo Bonzini @ 2011-12-16 16:47 UTC (permalink / raw)
  To: qemu-devel

A NULL qobj can occur when a parameter is fetched via qdict_get, but
the parameter is not in the command.  By returning NULL, the caller can
choose whether to raise a missing parameter error, an invalid parameter
type error, or use a default value.  For example, qom-set could can
use this to reset a property to its default value, though at this time
it will fail with "Invalid parameter type".  In any case, anything is
better than crashing!

Reviewed-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 qapi/qmp-input-visitor.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index 8cbc0ab..c78022b 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -49,10 +49,12 @@ static const QObject *qmp_input_get_object(QmpInputVisitor *qiv,
         qobj = qiv->stack[qiv->nb_stack - 1].obj;
     }
 
-    if (name && qobject_type(qobj) == QTYPE_QDICT) {
-        return qdict_get(qobject_to_qdict(qobj), name);
-    } else if (qiv->nb_stack > 0 && qobject_type(qobj) == QTYPE_QLIST) {
-        return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry);
+    if (qobj) {
+        if (name && qobject_type(qobj) == QTYPE_QDICT) {
+            return qdict_get(qobject_to_qdict(qobj), name);
+        } else if (qiv->nb_stack > 0 && qobject_type(qobj) == QTYPE_QLIST) {
+            return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry);
+        }
     }
 
     return qobj;
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 2/8] qom: fix swapped parameters
  2011-12-16 16:47 [Qemu-devel] [PATCH v2 0/8] qom: introduce non-legacy static properties Paolo Bonzini
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 1/8] qapi: protect against NULL QObject in qmp_input_get_object Paolo Bonzini
@ 2011-12-16 16:47 ` Paolo Bonzini
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 3/8] qom: push permission checks up into qdev_property_add_legacy Paolo Bonzini
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Paolo Bonzini @ 2011-12-16 16:47 UTC (permalink / raw)
  To: qemu-devel

Reviewed-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 83913c7..bda8d6c 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1110,7 +1110,7 @@ void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
     if (!prop->set) {
         error_set(errp, QERR_PERMISSION_DENIED);
     } else {
-        prop->set(dev, prop->opaque, v, name, errp);
+        prop->set(dev, v, prop->opaque, name, errp);
     }
 }
 
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 3/8] qom: push permission checks up into qdev_property_add_legacy
  2011-12-16 16:47 [Qemu-devel] [PATCH v2 0/8] qom: introduce non-legacy static properties Paolo Bonzini
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 1/8] qapi: protect against NULL QObject in qmp_input_get_object Paolo Bonzini
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 2/8] qom: fix swapped parameters Paolo Bonzini
@ 2011-12-16 16:47 ` Paolo Bonzini
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 4/8] qom: interpret the return value when setting legacy properties Paolo Bonzini
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Paolo Bonzini @ 2011-12-16 16:47 UTC (permalink / raw)
  To: qemu-devel

qdev_property_get and qdev_property_set can generate permission
denied errors themselves.  Do not duplicate this functionality in
qdev_get/set_legacy_property, and clean up excessive indentation.

Reviewed-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev.c |   46 +++++++++++++++++++---------------------------
 1 files changed, 19 insertions(+), 27 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index bda8d6c..c020a6f 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1135,46 +1135,38 @@ static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
 {
     Property *prop = opaque;
 
-    if (prop->info->print) {
-        char buffer[1024];
-        char *ptr = buffer;
+    char buffer[1024];
+    char *ptr = buffer;
 
-        prop->info->print(dev, prop, buffer, sizeof(buffer));
-        visit_type_str(v, &ptr, name, errp);
-    } else {
-        error_set(errp, QERR_PERMISSION_DENIED);
-    }
+    prop->info->print(dev, prop, buffer, sizeof(buffer));
+    visit_type_str(v, &ptr, name, errp);
 }
 
 static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
                                      const char *name, Error **errp)
 {
     Property *prop = opaque;
+    Error *local_err = NULL;
+    char *ptr = NULL;
+    int ret;
 
     if (dev->state != DEV_STATE_CREATED) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
 
-    if (prop->info->parse) {
-        Error *local_err = NULL;
-        char *ptr = NULL;
+    visit_type_str(v, &ptr, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
 
-        visit_type_str(v, &ptr, name, &local_err);
-        if (!local_err) {
-            int ret;
-            ret = prop->info->parse(dev, prop, ptr);
-            if (ret != 0) {
-                error_set(errp, QERR_INVALID_PARAMETER_VALUE,
-                          name, prop->info->name);
-            }
-            g_free(ptr);
-        } else {
-            error_propagate(errp, local_err);
-        }
-    } else {
-        error_set(errp, QERR_PERMISSION_DENIED);
+    ret = prop->info->parse(dev, prop, ptr);
+    if (ret != 0) {
+        error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+                  name, prop->info->name);
     }
+    g_free(ptr);
 }
 
 /**
@@ -1194,8 +1186,8 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
     type = g_strdup_printf("legacy<%s>", prop->info->name);
 
     qdev_property_add(dev, prop->name, type,
-                      qdev_get_legacy_property,
-                      qdev_set_legacy_property,
+                      prop->info->print ? qdev_get_legacy_property : NULL,
+                      prop->info->parse ? qdev_set_legacy_property : NULL,
                       NULL,
                       prop, errp);
 
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 4/8] qom: interpret the return value when setting legacy properties
  2011-12-16 16:47 [Qemu-devel] [PATCH v2 0/8] qom: introduce non-legacy static properties Paolo Bonzini
                   ` (2 preceding siblings ...)
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 3/8] qom: push permission checks up into qdev_property_add_legacy Paolo Bonzini
@ 2011-12-16 16:47 ` Paolo Bonzini
  2011-12-16 17:00   ` Anthony Liguori
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 5/8] qom: introduce QERR_PROPERTY_VALUE_OUT_OF_RANGE Paolo Bonzini
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: Paolo Bonzini @ 2011-12-16 16:47 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev-properties.c |   39 ++++++++++++++++++++++++---------------
 hw/qdev.c            |    3 +--
 hw/qdev.h            |    2 ++
 3 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index f0b811c..76ecb38 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -614,6 +614,26 @@ int qdev_prop_exists(DeviceState *dev, const char *name)
     return qdev_prop_find(dev, name) ? true : false;
 }
 
+void qdev_prop_error(Error **errp, int ret,
+                     DeviceState *dev, Property *prop, const char *value)
+{
+    switch (ret) {
+    case -EEXIST:
+        error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
+                  dev->info->name, prop->name, value);
+        break;
+    default:
+    case -EINVAL:
+        error_set(errp, QERR_PROPERTY_VALUE_BAD,
+                  dev->info->name, prop->name, value);
+        break;
+    case -ENOENT:
+        error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
+                  dev->info->name, prop->name, value);
+        break;
+    }
+}
+
 int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
 {
     Property *prop;
@@ -632,21 +652,10 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
     }
     ret = prop->info->parse(dev, prop, value);
     if (ret < 0) {
-        switch (ret) {
-        case -EEXIST:
-            qerror_report(QERR_PROPERTY_VALUE_IN_USE,
-                          dev->info->name, name, value);
-            break;
-        default:
-        case -EINVAL:
-            qerror_report(QERR_PROPERTY_VALUE_BAD,
-                          dev->info->name, name, value);
-            break;
-        case -ENOENT:
-            qerror_report(QERR_PROPERTY_VALUE_NOT_FOUND,
-                          dev->info->name, name, value);
-            break;
-        }
+        Error *err;
+        qdev_prop_error(&err, ret, dev, prop, value);
+        qerror_report_err(err);
+        error_free(err);
         return -1;
     }
     return 0;
diff --git a/hw/qdev.c b/hw/qdev.c
index c020a6f..c8ab7b7 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1163,8 +1163,7 @@ static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
 
     ret = prop->info->parse(dev, prop, ptr);
     if (ret != 0) {
-        error_set(errp, QERR_INVALID_PARAMETER_VALUE,
-                  name, prop->info->name);
+        qdev_prop_error(errp, ret, dev, prop, ptr);
     }
     g_free(ptr);
 }
diff --git a/hw/qdev.h b/hw/qdev.h
index 6e18427..828d811 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -370,6 +370,8 @@ void qdev_prop_set_defaults(DeviceState *dev, Property *props);
 
 void qdev_prop_register_global_list(GlobalProperty *props);
 void qdev_prop_set_globals(DeviceState *dev);
+void qdev_prop_error(Error **errp, int ret, DeviceState *name,
+                     Property *prop, const char *value);
 
 static inline const char *qdev_fw_name(DeviceState *dev)
 {
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 5/8] qom: introduce QERR_PROPERTY_VALUE_OUT_OF_RANGE
  2011-12-16 16:47 [Qemu-devel] [PATCH v2 0/8] qom: introduce non-legacy static properties Paolo Bonzini
                   ` (3 preceding siblings ...)
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 4/8] qom: interpret the return value when setting legacy properties Paolo Bonzini
@ 2011-12-16 16:47 ` Paolo Bonzini
  2011-12-16 17:00   ` Anthony Liguori
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 6/8] qom: introduce get/set methods for Property Paolo Bonzini
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: Paolo Bonzini @ 2011-12-16 16:47 UTC (permalink / raw)
  To: qemu-devel

This will be used when reject invalid values for integer fields that
are less than 64-bits wide.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 qerror.c |    5 +++++
 qerror.h |    3 +++
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/qerror.c b/qerror.c
index adde8a5..9a75d06 100644
--- a/qerror.c
+++ b/qerror.c
@@ -206,6 +206,11 @@ static const QErrorStringTable qerror_table[] = {
         .desc      = "Property '%(device).%(property)' can't find value '%(value)'",
     },
     {
+        .error_fmt = QERR_PROPERTY_VALUE_OUT_OF_RANGE,
+        .desc      = "Property '%(device).%(property)' doesn't take "
+                     "value %(value) (minimum: %(min), maximum: %(max)'",
+    },
+    {
         .error_fmt = QERR_QMP_BAD_INPUT_OBJECT,
         .desc      = "Expected '%(expected)' in QMP input",
     },
diff --git a/qerror.h b/qerror.h
index 9190b02..efda232 100644
--- a/qerror.h
+++ b/qerror.h
@@ -171,6 +171,9 @@ QError *qobject_to_qerror(const QObject *obj);
 #define QERR_PROPERTY_VALUE_NOT_FOUND \
     "{ 'class': 'PropertyValueNotFound', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
 
+#define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
+    "{ 'class': 'PropertyValueOutOfRange', 'data': { 'device': %s, 'property': %s, 'value': %"PRId64", 'min': %"PRId64", 'max': %"PRId64" } }"
+
 #define QERR_QMP_BAD_INPUT_OBJECT \
     "{ 'class': 'QMPBadInputObject', 'data': { 'expected': %s } }"
 
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 6/8] qom: introduce get/set methods for Property
  2011-12-16 16:47 [Qemu-devel] [PATCH v2 0/8] qom: introduce non-legacy static properties Paolo Bonzini
                   ` (4 preceding siblings ...)
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 5/8] qom: introduce QERR_PROPERTY_VALUE_OUT_OF_RANGE Paolo Bonzini
@ 2011-12-16 16:47 ` Paolo Bonzini
  2011-12-16 17:02   ` Anthony Liguori
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 7/8] qom: distinguish "legacy" property type name from QOM type name Paolo Bonzini
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 8/8] qom: register qdev properties also as non-legacy properties Paolo Bonzini
  7 siblings, 1 reply; 15+ messages in thread
From: Paolo Bonzini @ 2011-12-16 16:47 UTC (permalink / raw)
  To: qemu-devel

This patch adds a visitor interface to Property.  This way, QOM will be
able to expose Properties that access a fixed field in a struct without
exposing also the everything-is-a-string "feature" of qdev properties.

Whenever the printed representation in both QOM and qdev (which is
typically the case for device backends), parse/print code can be reused
via get_generic/set_generic.  Dually, whenever multiple PropertyInfos
have the same representation in both the struct and the visitors the
code can be reused (for example among all of int32/uint32/hex32).

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev-addr.c       |   41 ++++++
 hw/qdev-properties.c |  355 ++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/qdev.h            |    4 +
 3 files changed, 400 insertions(+), 0 deletions(-)

diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
index 305c2d3..5ddda2d 100644
--- a/hw/qdev-addr.c
+++ b/hw/qdev-addr.c
@@ -18,12 +18,53 @@ static int print_taddr(DeviceState *dev, Property *prop, char *dest, size_t len)
     return snprintf(dest, len, "0x" TARGET_FMT_plx, *ptr);
 }
 
+static void get_taddr(DeviceState *dev, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int64_t value;
+
+    value = *ptr;
+    visit_type_int(v, &value, name, errp);
+}
+
+static void set_taddr(DeviceState *dev, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    int64_t value;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_int(v, &value, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if ((uint64_t)value <= (uint64_t) ~(target_phys_addr_t)0) {
+        *ptr = value;
+    } else {
+        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
+                  dev->id?:"", name, value, (uint64_t) 0,
+                  (uint64_t) ~(target_phys_addr_t)0);
+    }
+}
+
+
 PropertyInfo qdev_prop_taddr = {
     .name  = "taddr",
     .type  = PROP_TYPE_TADDR,
     .size  = sizeof(target_phys_addr_t),
     .parse = parse_taddr,
     .print = print_taddr,
+    .get   = get_taddr,
+    .set   = set_taddr,
 };
 
 void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 76ecb38..f7aa3cb 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -55,12 +55,44 @@ static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
     return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
 }
 
+static void get_bit(DeviceState *dev, Visitor *v, void *opaque,
+                    const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    uint32_t *p = qdev_get_prop_ptr(dev, prop);
+    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
+
+    visit_type_bool(v, &value, name, errp);
+}
+
+static void set_bit(DeviceState *dev, Visitor *v, void *opaque,
+                    const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    Error *local_err = NULL;
+    bool value;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_bool(v, &value, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    bit_prop_set(dev, prop, value);
+}
+
 PropertyInfo qdev_prop_bit = {
     .name  = "on/off",
     .type  = PROP_TYPE_BIT,
     .size  = sizeof(uint32_t),
     .parse = parse_bit,
     .print = print_bit,
+    .get   = get_bit,
+    .set   = set_bit,
 };
 
 /* --- 8bit integer --- */
@@ -85,12 +117,54 @@ static int print_uint8(DeviceState *dev, Property *prop, char *dest, size_t len)
     return snprintf(dest, len, "%" PRIu8, *ptr);
 }
 
+static void get_int8(DeviceState *dev, Visitor *v, void *opaque,
+                     const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    int8_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int64_t value;
+
+    value = *ptr;
+    visit_type_int(v, &value, name, errp);
+}
+
+static void set_int8(DeviceState *dev, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    int8_t *ptr = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    int64_t value;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_int(v, &value, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (value > prop->info->min && value <= prop->info->max) {
+        *ptr = value;
+    } else {
+        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
+                  dev->id?:"", name, value, prop->info->min,
+                  prop->info->max);
+    }
+}
+
 PropertyInfo qdev_prop_uint8 = {
     .name  = "uint8",
     .type  = PROP_TYPE_UINT8,
     .size  = sizeof(uint8_t),
     .parse = parse_uint8,
     .print = print_uint8,
+    .get   = get_int8,
+    .set   = set_int8,
+    .min   = 0,
+    .max   = 255,
 };
 
 /* --- 8bit hex value --- */
@@ -120,6 +194,10 @@ PropertyInfo qdev_prop_hex8 = {
     .size  = sizeof(uint8_t),
     .parse = parse_hex8,
     .print = print_hex8,
+    .get   = get_int8,
+    .set   = set_int8,
+    .min   = 0,
+    .max   = 255,
 };
 
 /* --- 16bit integer --- */
@@ -144,12 +222,54 @@ static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len
     return snprintf(dest, len, "%" PRIu16, *ptr);
 }
 
+static void get_int16(DeviceState *dev, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    int16_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int64_t value;
+
+    value = *ptr;
+    visit_type_int(v, &value, name, errp);
+}
+
+static void set_int16(DeviceState *dev, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    int16_t *ptr = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    int64_t value;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_int(v, &value, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (value > prop->info->min && value <= prop->info->max) {
+        *ptr = value;
+    } else {
+        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
+                  dev->id?:"", name, value, prop->info->min,
+                  prop->info->max);
+    }
+}
+
 PropertyInfo qdev_prop_uint16 = {
     .name  = "uint16",
     .type  = PROP_TYPE_UINT16,
     .size  = sizeof(uint16_t),
     .parse = parse_uint16,
     .print = print_uint16,
+    .get   = get_int16,
+    .set   = set_int16,
+    .min   = 0,
+    .max   = 65535,
 };
 
 /* --- 32bit integer --- */
@@ -174,12 +294,54 @@ static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len
     return snprintf(dest, len, "%" PRIu32, *ptr);
 }
 
+static void get_int32(DeviceState *dev, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int64_t value;
+
+    value = *ptr;
+    visit_type_int(v, &value, name, errp);
+}
+
+static void set_int32(DeviceState *dev, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    int64_t value;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_int(v, &value, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (value > prop->info->min && value <= prop->info->max) {
+        *ptr = value;
+    } else {
+        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
+                  dev->id?:"", name, value, prop->info->min,
+                  prop->info->max);
+    }
+}
+
 PropertyInfo qdev_prop_uint32 = {
     .name  = "uint32",
     .type  = PROP_TYPE_UINT32,
     .size  = sizeof(uint32_t),
     .parse = parse_uint32,
     .print = print_uint32,
+    .get   = get_int32,
+    .set   = set_int32,
+    .min   = 0,
+    .max   = 0xFFFFFFFFULL,
 };
 
 static int parse_int32(DeviceState *dev, Property *prop, const char *str)
@@ -207,6 +369,10 @@ PropertyInfo qdev_prop_int32 = {
     .size  = sizeof(int32_t),
     .parse = parse_int32,
     .print = print_int32,
+    .get   = get_int32,
+    .set   = set_int32,
+    .min   = -0x80000000LL,
+    .max   = 0x7FFFFFFFLL,
 };
 
 /* --- 32bit hex value --- */
@@ -236,6 +402,10 @@ PropertyInfo qdev_prop_hex32 = {
     .size  = sizeof(uint32_t),
     .parse = parse_hex32,
     .print = print_hex32,
+    .get   = get_int32,
+    .set   = set_int32,
+    .min   = 0,
+    .max   = 0xFFFFFFFFULL,
 };
 
 /* --- 64bit integer --- */
@@ -260,12 +430,37 @@ static int print_uint64(DeviceState *dev, Property *prop, char *dest, size_t len
     return snprintf(dest, len, "%" PRIu64, *ptr);
 }
 
+static void get_int64(DeviceState *dev, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    int64_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+    visit_type_int(v, ptr, name, errp);
+}
+
+static void set_int64(DeviceState *dev, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    int64_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_int(v, ptr, name, errp);
+}
+
 PropertyInfo qdev_prop_uint64 = {
     .name  = "uint64",
     .type  = PROP_TYPE_UINT64,
     .size  = sizeof(uint64_t),
     .parse = parse_uint64,
     .print = print_uint64,
+    .get   = get_int64,
+    .set   = set_int64,
 };
 
 /* --- 64bit hex value --- */
@@ -295,6 +490,8 @@ PropertyInfo qdev_prop_hex64 = {
     .size  = sizeof(uint64_t),
     .parse = parse_hex64,
     .print = print_hex64,
+    .get   = get_int64,
+    .set   = set_int64,
 };
 
 /* --- string --- */
@@ -322,6 +519,48 @@ static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len
     return snprintf(dest, len, "\"%s\"", *ptr);
 }
 
+static void get_string(DeviceState *dev, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    char **ptr = qdev_get_prop_ptr(dev, prop);
+
+    if (!*ptr) {
+        char *str = (char *)"";
+        visit_type_str(v, &str, name, errp);
+    } else {
+        visit_type_str(v, ptr, name, errp);
+    }
+}
+
+static void set_string(DeviceState *dev, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    char **ptr = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    char *str;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_str(v, &str, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (!*str) {
+        g_free(str);
+        str = NULL;
+    }
+    if (*ptr) {
+        g_free(*ptr);
+    }
+    *ptr = str;
+}
+
 PropertyInfo qdev_prop_string = {
     .name  = "string",
     .type  = PROP_TYPE_STRING,
@@ -329,6 +568,8 @@ PropertyInfo qdev_prop_string = {
     .parse = parse_string,
     .print = print_string,
     .free  = free_string,
+    .get   = get_string,
+    .set   = set_string,
 };
 
 /* --- drive --- */
@@ -364,12 +605,59 @@ static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len)
                     *ptr ? bdrv_get_device_name(*ptr) : "<null>");
 }
 
+static void get_generic(DeviceState *dev, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    void **ptr = qdev_get_prop_ptr(dev, prop);
+    char buffer[1024];
+    char *p = buffer;
+
+    buffer[0] = 0;
+    if (*ptr) {
+        prop->info->print(dev, prop, buffer, sizeof(buffer));
+    }
+    visit_type_str(v, &p, name, errp);
+}
+
+static void set_generic(DeviceState *dev, Visitor *v, void *opaque,
+                        const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    Error *local_err = NULL;
+    char *str;
+    int ret;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_str(v, &str, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (!*str) {
+        g_free(str);
+        qdev_prop_error(errp, EINVAL, dev, prop, str);
+        return;
+    }
+    ret = prop->info->parse(dev, prop, str);
+    if (ret != 0) {
+        qdev_prop_error(errp, ret, dev, prop, str);
+    }
+    g_free(str);
+}
+
 PropertyInfo qdev_prop_drive = {
     .name  = "drive",
     .type  = PROP_TYPE_DRIVE,
     .size  = sizeof(BlockDriverState *),
     .parse = parse_drive,
     .print = print_drive,
+    .get   = get_generic,
+    .set   = set_generic,
     .free  = free_drive,
 };
 
@@ -407,6 +695,8 @@ PropertyInfo qdev_prop_chr = {
     .size  = sizeof(CharDriverState*),
     .parse = parse_chr,
     .print = print_chr,
+    .get   = get_generic,
+    .set   = set_generic,
 };
 
 /* --- netdev device --- */
@@ -441,6 +731,8 @@ PropertyInfo qdev_prop_netdev = {
     .size  = sizeof(VLANClientState*),
     .parse = parse_netdev,
     .print = print_netdev,
+    .get   = get_generic,
+    .set   = set_generic,
 };
 
 /* --- vlan --- */
@@ -469,12 +761,57 @@ static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
     }
 }
 
+static void get_vlan(DeviceState *dev, Visitor *v, void *opaque,
+                     const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    VLANState **ptr = qdev_get_prop_ptr(dev, prop);
+    int64_t id;
+
+    id = *ptr ? (*ptr)->id : -1;
+    visit_type_int(v, &id, name, errp);
+}
+
+static void set_vlan(DeviceState *dev, Visitor *v, void *opaque,
+                     const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    VLANState **ptr = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    int64_t id;
+    VLANState *vlan;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_int(v, &id, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (id == -1) {
+        *ptr = NULL;
+        return;
+    }
+    vlan = qemu_find_vlan(id, 1);
+    if (!vlan) {
+        error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+                  name, prop->info->name);
+        return;
+    }
+    *ptr = vlan;
+}
+
 PropertyInfo qdev_prop_vlan = {
     .name  = "vlan",
     .type  = PROP_TYPE_VLAN,
     .size  = sizeof(VLANClientState*),
     .parse = parse_vlan,
     .print = print_vlan,
+    .get   = get_vlan,
+    .set   = set_vlan,
 };
 
 /* --- pointer --- */
@@ -531,6 +867,8 @@ PropertyInfo qdev_prop_macaddr = {
     .size  = sizeof(MACAddr),
     .parse = parse_mac,
     .print = print_mac,
+    .get   = get_generic,
+    .set   = set_generic,
 };
 
 /* --- pci address --- */
@@ -570,12 +908,29 @@ static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t
     }
 }
 
+static void get_pci_devfn(DeviceState *dev, Visitor *v, void *opaque,
+                          const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    char buffer[32];
+    char *p = buffer;
+
+    buffer[0] = 0;
+    if (*ptr != -1) {
+        snprintf(buffer, sizeof(buffer), "%02x.%x", *ptr >> 3, *ptr & 7);
+    }
+    visit_type_str(v, &p, name, errp);
+}
+
 PropertyInfo qdev_prop_pci_devfn = {
     .name  = "pci-devfn",
     .type  = PROP_TYPE_UINT32,
     .size  = sizeof(uint32_t),
     .parse = parse_pci_devfn,
     .print = print_pci_devfn,
+    .get   = get_pci_devfn,
+    .set   = set_generic,
 };
 
 /* --- public helpers --- */
diff --git a/hw/qdev.h b/hw/qdev.h
index 828d811..a1cce37 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -158,9 +158,13 @@ struct PropertyInfo {
     const char *name;
     size_t size;
     enum PropertyType type;
+    int64_t min;
+    int64_t max;
     int (*parse)(DeviceState *dev, Property *prop, const char *str);
     int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
     void (*free)(DeviceState *dev, Property *prop);
+    DevicePropertyAccessor *get;
+    DevicePropertyAccessor *set;
 };
 
 typedef struct GlobalProperty {
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 7/8] qom: distinguish "legacy" property type name from QOM type name
  2011-12-16 16:47 [Qemu-devel] [PATCH v2 0/8] qom: introduce non-legacy static properties Paolo Bonzini
                   ` (5 preceding siblings ...)
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 6/8] qom: introduce get/set methods for Property Paolo Bonzini
@ 2011-12-16 16:47 ` Paolo Bonzini
  2011-12-16 17:03   ` Anthony Liguori
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 8/8] qom: register qdev properties also as non-legacy properties Paolo Bonzini
  7 siblings, 1 reply; 15+ messages in thread
From: Paolo Bonzini @ 2011-12-16 16:47 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev-properties.c |   12 ++++++++----
 hw/qdev.c            |    9 ++++++---
 hw/qdev.h            |    1 +
 3 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index f7aa3cb..dd41e5a 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -86,7 +86,8 @@ static void set_bit(DeviceState *dev, Visitor *v, void *opaque,
 }
 
 PropertyInfo qdev_prop_bit = {
-    .name  = "on/off",
+    .name  = "boolean",
+    .legacy_name  = "on/off",
     .type  = PROP_TYPE_BIT,
     .size  = sizeof(uint32_t),
     .parse = parse_bit,
@@ -189,7 +190,8 @@ static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
 }
 
 PropertyInfo qdev_prop_hex8 = {
-    .name  = "hex8",
+    .name  = "uint8",
+    .legacy_name  = "hex8",
     .type  = PROP_TYPE_UINT8,
     .size  = sizeof(uint8_t),
     .parse = parse_hex8,
@@ -397,7 +399,8 @@ static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
 }
 
 PropertyInfo qdev_prop_hex32 = {
-    .name  = "hex32",
+    .name  = "uint32",
+    .legacy_name  = "hex32",
     .type  = PROP_TYPE_UINT32,
     .size  = sizeof(uint32_t),
     .parse = parse_hex32,
@@ -485,7 +488,8 @@ static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
 }
 
 PropertyInfo qdev_prop_hex64 = {
-    .name  = "hex64",
+    .name  = "uint64",
+    .legacy_name  = "hex64",
     .type  = PROP_TYPE_UINT64,
     .size  = sizeof(uint64_t),
     .parse = parse_hex64,
diff --git a/hw/qdev.c b/hw/qdev.c
index c8ab7b7..426ea71 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -218,13 +218,15 @@ int qdev_device_help(QemuOpts *opts)
         if (!prop->info->parse) {
             continue;           /* no way to set it, don't show */
         }
-        error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
+        error_printf("%s.%s=%s\n", info->name, prop->name,
+                     prop->info->legacy_name ?: prop->info->name);
     }
     for (prop = info->bus_info->props; prop && prop->name; prop++) {
         if (!prop->info->parse) {
             continue;           /* no way to set it, don't show */
         }
-        error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
+        error_printf("%s.%s=%s\n", info->name, prop->name,
+                     prop->info->legacy_name ?: prop->info->name);
     }
     return 1;
 }
@@ -1182,7 +1184,8 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
 {
     gchar *type;
 
-    type = g_strdup_printf("legacy<%s>", prop->info->name);
+    type = g_strdup_printf("legacy<%s>",
+                           prop->info->legacy_name ?: prop->info->name);
 
     qdev_property_add(dev, prop->name, type,
                       prop->info->print ? qdev_get_legacy_property : NULL,
diff --git a/hw/qdev.h b/hw/qdev.h
index a1cce37..8002644 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -156,6 +156,7 @@ enum PropertyType {
 
 struct PropertyInfo {
     const char *name;
+    const char *legacy_name;
     size_t size;
     enum PropertyType type;
     int64_t min;
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 8/8] qom: register qdev properties also as non-legacy properties
  2011-12-16 16:47 [Qemu-devel] [PATCH v2 0/8] qom: introduce non-legacy static properties Paolo Bonzini
                   ` (6 preceding siblings ...)
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 7/8] qom: distinguish "legacy" property type name from QOM type name Paolo Bonzini
@ 2011-12-16 16:47 ` Paolo Bonzini
  2011-12-16 17:05   ` Anthony Liguori
  7 siblings, 1 reply; 15+ messages in thread
From: Paolo Bonzini @ 2011-12-16 16:47 UTC (permalink / raw)
  To: qemu-devel

Push legacy properties into a legacy<...> namespace, and make them
available with correct types too.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev.c |   28 +++++++++++++++++++++++++---
 hw/qdev.h |    7 +++----
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 426ea71..2f7defc 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -80,6 +80,9 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
     return NULL;
 }
 
+static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
+                                     Error **errp);
+
 static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
 {
     DeviceState *dev;
@@ -104,10 +107,12 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
 
     for (prop = dev->info->props; prop && prop->name; prop++) {
         qdev_property_add_legacy(dev, prop, NULL);
+        qdev_property_add_static(dev, prop, NULL);
     }
 
     for (prop = dev->info->bus_info->props; prop && prop->name; prop++) {
         qdev_property_add_legacy(dev, prop, NULL);
+        qdev_property_add_static(dev, prop, NULL);
     }
 
     qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL);
@@ -1174,7 +1179,7 @@ static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
  * @qdev_add_legacy_property - adds a legacy property
  *
  * Do not use this is new code!  Properties added through this interface will
- * be given types in the "legacy<>" type namespace.
+ * be given names and types in the "legacy<>" type namespace.
  *
  * Legacy properties are always processed as strings.  The format of the string
  * depends on the property type.
@@ -1182,18 +1187,35 @@ static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
 void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                               Error **errp)
 {
-    gchar *type;
+    gchar *name, *type;
 
+    name = g_strdup_printf("legacy<%s>", prop->name);
     type = g_strdup_printf("legacy<%s>",
                            prop->info->legacy_name ?: prop->info->name);
 
-    qdev_property_add(dev, prop->name, type,
+    qdev_property_add(dev, name, type,
                       prop->info->print ? qdev_get_legacy_property : NULL,
                       prop->info->parse ? qdev_set_legacy_property : NULL,
                       NULL,
                       prop, errp);
 
     g_free(type);
+    g_free(name);
+}
+
+/**
+ * @qdev_property_add_static - add a @Property to a device.
+ *
+ * Static properties access data in a struct.  The actual type of the
+ * property and the field depends on the property type.
+ */
+void qdev_property_add_static(DeviceState *dev, Property *prop,
+                              Error **errp)
+{
+    qdev_property_add(dev, prop->name, prop->info->name,
+                      prop->info->get, prop->info->set,
+                      NULL,
+                      prop, errp);
 }
 
 DeviceState *qdev_get_root(void)
diff --git a/hw/qdev.h b/hw/qdev.h
index 8002644..3410e77 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -487,11 +487,10 @@ const char *qdev_property_get_type(DeviceState *dev, const char *name,
                                    Error **errp);
 
 /**
- * @qdev_property_add_legacy - add a legacy @Property to a device
- *
- * DO NOT USE THIS IN NEW CODE!
+ * @qdev_property_add_static - add a @Property to a device referencing a
+ * field in a struct.
  */
-void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp);
+void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp);
 
 /**
  * @qdev_get_root - returns the root device of the composition tree
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH v2 4/8] qom: interpret the return value when setting legacy properties
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 4/8] qom: interpret the return value when setting legacy properties Paolo Bonzini
@ 2011-12-16 17:00   ` Anthony Liguori
  2011-12-16 17:19     ` Paolo Bonzini
  0 siblings, 1 reply; 15+ messages in thread
From: Anthony Liguori @ 2011-12-16 17:00 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On 12/16/2011 10:47 AM, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> ---
>   hw/qdev-properties.c |   39 ++++++++++++++++++++++++---------------
>   hw/qdev.c            |    3 +--
>   hw/qdev.h            |    2 ++
>   3 files changed, 27 insertions(+), 17 deletions(-)
>
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index f0b811c..76ecb38 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -614,6 +614,26 @@ int qdev_prop_exists(DeviceState *dev, const char *name)
>       return qdev_prop_find(dev, name) ? true : false;
>   }
>
> +void qdev_prop_error(Error **errp, int ret,
> +                     DeviceState *dev, Property *prop, const char *value)
> +{
> +    switch (ret) {
> +    case -EEXIST:
> +        error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
> +                  dev->info->name, prop->name, value);
> +        break;
> +    default:
> +    case -EINVAL:
> +        error_set(errp, QERR_PROPERTY_VALUE_BAD,
> +                  dev->info->name, prop->name, value);
> +        break;
> +    case -ENOENT:
> +        error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
> +                  dev->info->name, prop->name, value);
> +        break;
> +    }
> +}
> +
>   int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
>   {
>       Property *prop;
> @@ -632,21 +652,10 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
>       }
>       ret = prop->info->parse(dev, prop, value);
>       if (ret<  0) {
> -        switch (ret) {
> -        case -EEXIST:
> -            qerror_report(QERR_PROPERTY_VALUE_IN_USE,
> -                          dev->info->name, name, value);
> -            break;
> -        default:
> -        case -EINVAL:
> -            qerror_report(QERR_PROPERTY_VALUE_BAD,
> -                          dev->info->name, name, value);
> -            break;
> -        case -ENOENT:
> -            qerror_report(QERR_PROPERTY_VALUE_NOT_FOUND,
> -                          dev->info->name, name, value);
> -            break;
> -        }
> +        Error *err;
> +        qdev_prop_error(&err, ret, dev, prop, value);
> +        qerror_report_err(err);
> +        error_free(err);
>           return -1;
>       }
>       return 0;
> diff --git a/hw/qdev.c b/hw/qdev.c
> index c020a6f..c8ab7b7 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -1163,8 +1163,7 @@ static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
>
>       ret = prop->info->parse(dev, prop, ptr);
>       if (ret != 0) {
> -        error_set(errp, QERR_INVALID_PARAMETER_VALUE,
> -                  name, prop->info->name);
> +        qdev_prop_error(errp, ret, dev, prop, ptr);
>       }
>       g_free(ptr);
>   }
> diff --git a/hw/qdev.h b/hw/qdev.h
> index 6e18427..828d811 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -370,6 +370,8 @@ void qdev_prop_set_defaults(DeviceState *dev, Property *props);
>
>   void qdev_prop_register_global_list(GlobalProperty *props);
>   void qdev_prop_set_globals(DeviceState *dev);
> +void qdev_prop_error(Error **errp, int ret, DeviceState *name,
> +                     Property *prop, const char *value);

s/name/dev

And perhaps it would make more sense to return Error * and make the function 
name be a constructor:

Error *error_from_qdev_prop_err(int ret, DeviceState *dev,
                                 Property *prop, const char *value);

I was fairly confused about what was going on here at first.

Reards,

Anthony Liguori

>
>   static inline const char *qdev_fw_name(DeviceState *dev)
>   {

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH v2 5/8] qom: introduce QERR_PROPERTY_VALUE_OUT_OF_RANGE
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 5/8] qom: introduce QERR_PROPERTY_VALUE_OUT_OF_RANGE Paolo Bonzini
@ 2011-12-16 17:00   ` Anthony Liguori
  0 siblings, 0 replies; 15+ messages in thread
From: Anthony Liguori @ 2011-12-16 17:00 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On 12/16/2011 10:47 AM, Paolo Bonzini wrote:
> This will be used when reject invalid values for integer fields that
> are less than 64-bits wide.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>

VALUE_OUT_OF_RANGE?

Regards,

Anthony Liguori

> ---
>   qerror.c |    5 +++++
>   qerror.h |    3 +++
>   2 files changed, 8 insertions(+), 0 deletions(-)
>
> diff --git a/qerror.c b/qerror.c
> index adde8a5..9a75d06 100644
> --- a/qerror.c
> +++ b/qerror.c
> @@ -206,6 +206,11 @@ static const QErrorStringTable qerror_table[] = {
>           .desc      = "Property '%(device).%(property)' can't find value '%(value)'",
>       },
>       {
> +        .error_fmt = QERR_PROPERTY_VALUE_OUT_OF_RANGE,
> +        .desc      = "Property '%(device).%(property)' doesn't take "
> +                     "value %(value) (minimum: %(min), maximum: %(max)'",
> +    },
> +    {
>           .error_fmt = QERR_QMP_BAD_INPUT_OBJECT,
>           .desc      = "Expected '%(expected)' in QMP input",
>       },
> diff --git a/qerror.h b/qerror.h
> index 9190b02..efda232 100644
> --- a/qerror.h
> +++ b/qerror.h
> @@ -171,6 +171,9 @@ QError *qobject_to_qerror(const QObject *obj);
>   #define QERR_PROPERTY_VALUE_NOT_FOUND \
>       "{ 'class': 'PropertyValueNotFound', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
>
> +#define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
> +    "{ 'class': 'PropertyValueOutOfRange', 'data': { 'device': %s, 'property': %s, 'value': %"PRId64", 'min': %"PRId64", 'max': %"PRId64" } }"
> +
>   #define QERR_QMP_BAD_INPUT_OBJECT \
>       "{ 'class': 'QMPBadInputObject', 'data': { 'expected': %s } }"
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH v2 6/8] qom: introduce get/set methods for Property
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 6/8] qom: introduce get/set methods for Property Paolo Bonzini
@ 2011-12-16 17:02   ` Anthony Liguori
  0 siblings, 0 replies; 15+ messages in thread
From: Anthony Liguori @ 2011-12-16 17:02 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On 12/16/2011 10:47 AM, Paolo Bonzini wrote:
> This patch adds a visitor interface to Property.  This way, QOM will be
> able to expose Properties that access a fixed field in a struct without
> exposing also the everything-is-a-string "feature" of qdev properties.
>
> Whenever the printed representation in both QOM and qdev (which is
> typically the case for device backends), parse/print code can be reused
> via get_generic/set_generic.  Dually, whenever multiple PropertyInfos
> have the same representation in both the struct and the visitors the
> code can be reused (for example among all of int32/uint32/hex32).
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>


Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>

Regards,

Anthony Liguori

> ---
>   hw/qdev-addr.c       |   41 ++++++
>   hw/qdev-properties.c |  355 ++++++++++++++++++++++++++++++++++++++++++++++++++
>   hw/qdev.h            |    4 +
>   3 files changed, 400 insertions(+), 0 deletions(-)
>
> diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
> index 305c2d3..5ddda2d 100644
> --- a/hw/qdev-addr.c
> +++ b/hw/qdev-addr.c
> @@ -18,12 +18,53 @@ static int print_taddr(DeviceState *dev, Property *prop, char *dest, size_t len)
>       return snprintf(dest, len, "0x" TARGET_FMT_plx, *ptr);
>   }
>
> +static void get_taddr(DeviceState *dev, Visitor *v, void *opaque,
> +                      const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    int64_t value;
> +
> +    value = *ptr;
> +    visit_type_int(v,&value, name, errp);
> +}
> +
> +static void set_taddr(DeviceState *dev, Visitor *v, void *opaque,
> +                      const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    Error *local_err = NULL;
> +    int64_t value;
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_int(v,&value, name,&local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +    if ((uint64_t)value<= (uint64_t) ~(target_phys_addr_t)0) {
> +        *ptr = value;
> +    } else {
> +        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
> +                  dev->id?:"", name, value, (uint64_t) 0,
> +                  (uint64_t) ~(target_phys_addr_t)0);
> +    }
> +}
> +
> +
>   PropertyInfo qdev_prop_taddr = {
>       .name  = "taddr",
>       .type  = PROP_TYPE_TADDR,
>       .size  = sizeof(target_phys_addr_t),
>       .parse = parse_taddr,
>       .print = print_taddr,
> +    .get   = get_taddr,
> +    .set   = set_taddr,
>   };
>
>   void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value)
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 76ecb38..f7aa3cb 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -55,12 +55,44 @@ static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
>       return snprintf(dest, len, (*p&  qdev_get_prop_mask(prop)) ? "on" : "off");
>   }
>
> +static void get_bit(DeviceState *dev, Visitor *v, void *opaque,
> +                    const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint32_t *p = qdev_get_prop_ptr(dev, prop);
> +    bool value = (*p&  qdev_get_prop_mask(prop)) != 0;
> +
> +    visit_type_bool(v,&value, name, errp);
> +}
> +
> +static void set_bit(DeviceState *dev, Visitor *v, void *opaque,
> +                    const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    Error *local_err = NULL;
> +    bool value;
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_bool(v,&value, name,&local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +    bit_prop_set(dev, prop, value);
> +}
> +
>   PropertyInfo qdev_prop_bit = {
>       .name  = "on/off",
>       .type  = PROP_TYPE_BIT,
>       .size  = sizeof(uint32_t),
>       .parse = parse_bit,
>       .print = print_bit,
> +    .get   = get_bit,
> +    .set   = set_bit,
>   };
>
>   /* --- 8bit integer --- */
> @@ -85,12 +117,54 @@ static int print_uint8(DeviceState *dev, Property *prop, char *dest, size_t len)
>       return snprintf(dest, len, "%" PRIu8, *ptr);
>   }
>
> +static void get_int8(DeviceState *dev, Visitor *v, void *opaque,
> +                     const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    int8_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    int64_t value;
> +
> +    value = *ptr;
> +    visit_type_int(v,&value, name, errp);
> +}
> +
> +static void set_int8(DeviceState *dev, Visitor *v, void *opaque,
> +                      const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    int8_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    Error *local_err = NULL;
> +    int64_t value;
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_int(v,&value, name,&local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +    if (value>  prop->info->min&&  value<= prop->info->max) {
> +        *ptr = value;
> +    } else {
> +        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
> +                  dev->id?:"", name, value, prop->info->min,
> +                  prop->info->max);
> +    }
> +}
> +
>   PropertyInfo qdev_prop_uint8 = {
>       .name  = "uint8",
>       .type  = PROP_TYPE_UINT8,
>       .size  = sizeof(uint8_t),
>       .parse = parse_uint8,
>       .print = print_uint8,
> +    .get   = get_int8,
> +    .set   = set_int8,
> +    .min   = 0,
> +    .max   = 255,
>   };
>
>   /* --- 8bit hex value --- */
> @@ -120,6 +194,10 @@ PropertyInfo qdev_prop_hex8 = {
>       .size  = sizeof(uint8_t),
>       .parse = parse_hex8,
>       .print = print_hex8,
> +    .get   = get_int8,
> +    .set   = set_int8,
> +    .min   = 0,
> +    .max   = 255,
>   };
>
>   /* --- 16bit integer --- */
> @@ -144,12 +222,54 @@ static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len
>       return snprintf(dest, len, "%" PRIu16, *ptr);
>   }
>
> +static void get_int16(DeviceState *dev, Visitor *v, void *opaque,
> +                      const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    int16_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    int64_t value;
> +
> +    value = *ptr;
> +    visit_type_int(v,&value, name, errp);
> +}
> +
> +static void set_int16(DeviceState *dev, Visitor *v, void *opaque,
> +                      const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    int16_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    Error *local_err = NULL;
> +    int64_t value;
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_int(v,&value, name,&local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +    if (value>  prop->info->min&&  value<= prop->info->max) {
> +        *ptr = value;
> +    } else {
> +        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
> +                  dev->id?:"", name, value, prop->info->min,
> +                  prop->info->max);
> +    }
> +}
> +
>   PropertyInfo qdev_prop_uint16 = {
>       .name  = "uint16",
>       .type  = PROP_TYPE_UINT16,
>       .size  = sizeof(uint16_t),
>       .parse = parse_uint16,
>       .print = print_uint16,
> +    .get   = get_int16,
> +    .set   = set_int16,
> +    .min   = 0,
> +    .max   = 65535,
>   };
>
>   /* --- 32bit integer --- */
> @@ -174,12 +294,54 @@ static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len
>       return snprintf(dest, len, "%" PRIu32, *ptr);
>   }
>
> +static void get_int32(DeviceState *dev, Visitor *v, void *opaque,
> +                      const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    int64_t value;
> +
> +    value = *ptr;
> +    visit_type_int(v,&value, name, errp);
> +}
> +
> +static void set_int32(DeviceState *dev, Visitor *v, void *opaque,
> +                      const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    Error *local_err = NULL;
> +    int64_t value;
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_int(v,&value, name,&local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +    if (value>  prop->info->min&&  value<= prop->info->max) {
> +        *ptr = value;
> +    } else {
> +        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
> +                  dev->id?:"", name, value, prop->info->min,
> +                  prop->info->max);
> +    }
> +}
> +
>   PropertyInfo qdev_prop_uint32 = {
>       .name  = "uint32",
>       .type  = PROP_TYPE_UINT32,
>       .size  = sizeof(uint32_t),
>       .parse = parse_uint32,
>       .print = print_uint32,
> +    .get   = get_int32,
> +    .set   = set_int32,
> +    .min   = 0,
> +    .max   = 0xFFFFFFFFULL,
>   };
>
>   static int parse_int32(DeviceState *dev, Property *prop, const char *str)
> @@ -207,6 +369,10 @@ PropertyInfo qdev_prop_int32 = {
>       .size  = sizeof(int32_t),
>       .parse = parse_int32,
>       .print = print_int32,
> +    .get   = get_int32,
> +    .set   = set_int32,
> +    .min   = -0x80000000LL,
> +    .max   = 0x7FFFFFFFLL,
>   };
>
>   /* --- 32bit hex value --- */
> @@ -236,6 +402,10 @@ PropertyInfo qdev_prop_hex32 = {
>       .size  = sizeof(uint32_t),
>       .parse = parse_hex32,
>       .print = print_hex32,
> +    .get   = get_int32,
> +    .set   = set_int32,
> +    .min   = 0,
> +    .max   = 0xFFFFFFFFULL,
>   };
>
>   /* --- 64bit integer --- */
> @@ -260,12 +430,37 @@ static int print_uint64(DeviceState *dev, Property *prop, char *dest, size_t len
>       return snprintf(dest, len, "%" PRIu64, *ptr);
>   }
>
> +static void get_int64(DeviceState *dev, Visitor *v, void *opaque,
> +                      const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    int64_t *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    visit_type_int(v, ptr, name, errp);
> +}
> +
> +static void set_int64(DeviceState *dev, Visitor *v, void *opaque,
> +                      const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    int64_t *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_int(v, ptr, name, errp);
> +}
> +
>   PropertyInfo qdev_prop_uint64 = {
>       .name  = "uint64",
>       .type  = PROP_TYPE_UINT64,
>       .size  = sizeof(uint64_t),
>       .parse = parse_uint64,
>       .print = print_uint64,
> +    .get   = get_int64,
> +    .set   = set_int64,
>   };
>
>   /* --- 64bit hex value --- */
> @@ -295,6 +490,8 @@ PropertyInfo qdev_prop_hex64 = {
>       .size  = sizeof(uint64_t),
>       .parse = parse_hex64,
>       .print = print_hex64,
> +    .get   = get_int64,
> +    .set   = set_int64,
>   };
>
>   /* --- string --- */
> @@ -322,6 +519,48 @@ static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len
>       return snprintf(dest, len, "\"%s\"", *ptr);
>   }
>
> +static void get_string(DeviceState *dev, Visitor *v, void *opaque,
> +                       const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    char **ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    if (!*ptr) {
> +        char *str = (char *)"";
> +        visit_type_str(v,&str, name, errp);
> +    } else {
> +        visit_type_str(v, ptr, name, errp);
> +    }
> +}
> +
> +static void set_string(DeviceState *dev, Visitor *v, void *opaque,
> +                       const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    char **ptr = qdev_get_prop_ptr(dev, prop);
> +    Error *local_err = NULL;
> +    char *str;
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_str(v,&str, name,&local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +    if (!*str) {
> +        g_free(str);
> +        str = NULL;
> +    }
> +    if (*ptr) {
> +        g_free(*ptr);
> +    }
> +    *ptr = str;
> +}
> +
>   PropertyInfo qdev_prop_string = {
>       .name  = "string",
>       .type  = PROP_TYPE_STRING,
> @@ -329,6 +568,8 @@ PropertyInfo qdev_prop_string = {
>       .parse = parse_string,
>       .print = print_string,
>       .free  = free_string,
> +    .get   = get_string,
> +    .set   = set_string,
>   };
>
>   /* --- drive --- */
> @@ -364,12 +605,59 @@ static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len)
>                       *ptr ? bdrv_get_device_name(*ptr) : "<null>");
>   }
>
> +static void get_generic(DeviceState *dev, Visitor *v, void *opaque,
> +                       const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    void **ptr = qdev_get_prop_ptr(dev, prop);
> +    char buffer[1024];
> +    char *p = buffer;
> +
> +    buffer[0] = 0;
> +    if (*ptr) {
> +        prop->info->print(dev, prop, buffer, sizeof(buffer));
> +    }
> +    visit_type_str(v,&p, name, errp);
> +}
> +
> +static void set_generic(DeviceState *dev, Visitor *v, void *opaque,
> +                        const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    Error *local_err = NULL;
> +    char *str;
> +    int ret;
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_str(v,&str, name,&local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +    if (!*str) {
> +        g_free(str);
> +        qdev_prop_error(errp, EINVAL, dev, prop, str);
> +        return;
> +    }
> +    ret = prop->info->parse(dev, prop, str);
> +    if (ret != 0) {
> +        qdev_prop_error(errp, ret, dev, prop, str);
> +    }
> +    g_free(str);
> +}
> +
>   PropertyInfo qdev_prop_drive = {
>       .name  = "drive",
>       .type  = PROP_TYPE_DRIVE,
>       .size  = sizeof(BlockDriverState *),
>       .parse = parse_drive,
>       .print = print_drive,
> +    .get   = get_generic,
> +    .set   = set_generic,
>       .free  = free_drive,
>   };
>
> @@ -407,6 +695,8 @@ PropertyInfo qdev_prop_chr = {
>       .size  = sizeof(CharDriverState*),
>       .parse = parse_chr,
>       .print = print_chr,
> +    .get   = get_generic,
> +    .set   = set_generic,
>   };
>
>   /* --- netdev device --- */
> @@ -441,6 +731,8 @@ PropertyInfo qdev_prop_netdev = {
>       .size  = sizeof(VLANClientState*),
>       .parse = parse_netdev,
>       .print = print_netdev,
> +    .get   = get_generic,
> +    .set   = set_generic,
>   };
>
>   /* --- vlan --- */
> @@ -469,12 +761,57 @@ static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
>       }
>   }
>
> +static void get_vlan(DeviceState *dev, Visitor *v, void *opaque,
> +                     const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    VLANState **ptr = qdev_get_prop_ptr(dev, prop);
> +    int64_t id;
> +
> +    id = *ptr ? (*ptr)->id : -1;
> +    visit_type_int(v,&id, name, errp);
> +}
> +
> +static void set_vlan(DeviceState *dev, Visitor *v, void *opaque,
> +                     const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    VLANState **ptr = qdev_get_prop_ptr(dev, prop);
> +    Error *local_err = NULL;
> +    int64_t id;
> +    VLANState *vlan;
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_int(v,&id, name,&local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +    if (id == -1) {
> +        *ptr = NULL;
> +        return;
> +    }
> +    vlan = qemu_find_vlan(id, 1);
> +    if (!vlan) {
> +        error_set(errp, QERR_INVALID_PARAMETER_VALUE,
> +                  name, prop->info->name);
> +        return;
> +    }
> +    *ptr = vlan;
> +}
> +
>   PropertyInfo qdev_prop_vlan = {
>       .name  = "vlan",
>       .type  = PROP_TYPE_VLAN,
>       .size  = sizeof(VLANClientState*),
>       .parse = parse_vlan,
>       .print = print_vlan,
> +    .get   = get_vlan,
> +    .set   = set_vlan,
>   };
>
>   /* --- pointer --- */
> @@ -531,6 +867,8 @@ PropertyInfo qdev_prop_macaddr = {
>       .size  = sizeof(MACAddr),
>       .parse = parse_mac,
>       .print = print_mac,
> +    .get   = get_generic,
> +    .set   = set_generic,
>   };
>
>   /* --- pci address --- */
> @@ -570,12 +908,29 @@ static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t
>       }
>   }
>
> +static void get_pci_devfn(DeviceState *dev, Visitor *v, void *opaque,
> +                          const char *name, Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    char buffer[32];
> +    char *p = buffer;
> +
> +    buffer[0] = 0;
> +    if (*ptr != -1) {
> +        snprintf(buffer, sizeof(buffer), "%02x.%x", *ptr>>  3, *ptr&  7);
> +    }
> +    visit_type_str(v,&p, name, errp);
> +}
> +
>   PropertyInfo qdev_prop_pci_devfn = {
>       .name  = "pci-devfn",
>       .type  = PROP_TYPE_UINT32,
>       .size  = sizeof(uint32_t),
>       .parse = parse_pci_devfn,
>       .print = print_pci_devfn,
> +    .get   = get_pci_devfn,
> +    .set   = set_generic,
>   };
>
>   /* --- public helpers --- */
> diff --git a/hw/qdev.h b/hw/qdev.h
> index 828d811..a1cce37 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -158,9 +158,13 @@ struct PropertyInfo {
>       const char *name;
>       size_t size;
>       enum PropertyType type;
> +    int64_t min;
> +    int64_t max;
>       int (*parse)(DeviceState *dev, Property *prop, const char *str);
>       int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
>       void (*free)(DeviceState *dev, Property *prop);
> +    DevicePropertyAccessor *get;
> +    DevicePropertyAccessor *set;
>   };
>
>   typedef struct GlobalProperty {

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/8] qom: distinguish "legacy" property type name from QOM type name
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 7/8] qom: distinguish "legacy" property type name from QOM type name Paolo Bonzini
@ 2011-12-16 17:03   ` Anthony Liguori
  0 siblings, 0 replies; 15+ messages in thread
From: Anthony Liguori @ 2011-12-16 17:03 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On 12/16/2011 10:47 AM, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>

Regards,

Anthony Liguori

> ---
>   hw/qdev-properties.c |   12 ++++++++----
>   hw/qdev.c            |    9 ++++++---
>   hw/qdev.h            |    1 +
>   3 files changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index f7aa3cb..dd41e5a 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -86,7 +86,8 @@ static void set_bit(DeviceState *dev, Visitor *v, void *opaque,
>   }
>
>   PropertyInfo qdev_prop_bit = {
> -    .name  = "on/off",
> +    .name  = "boolean",
> +    .legacy_name  = "on/off",
>       .type  = PROP_TYPE_BIT,
>       .size  = sizeof(uint32_t),
>       .parse = parse_bit,
> @@ -189,7 +190,8 @@ static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
>   }
>
>   PropertyInfo qdev_prop_hex8 = {
> -    .name  = "hex8",
> +    .name  = "uint8",
> +    .legacy_name  = "hex8",
>       .type  = PROP_TYPE_UINT8,
>       .size  = sizeof(uint8_t),
>       .parse = parse_hex8,
> @@ -397,7 +399,8 @@ static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
>   }
>
>   PropertyInfo qdev_prop_hex32 = {
> -    .name  = "hex32",
> +    .name  = "uint32",
> +    .legacy_name  = "hex32",
>       .type  = PROP_TYPE_UINT32,
>       .size  = sizeof(uint32_t),
>       .parse = parse_hex32,
> @@ -485,7 +488,8 @@ static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
>   }
>
>   PropertyInfo qdev_prop_hex64 = {
> -    .name  = "hex64",
> +    .name  = "uint64",
> +    .legacy_name  = "hex64",
>       .type  = PROP_TYPE_UINT64,
>       .size  = sizeof(uint64_t),
>       .parse = parse_hex64,
> diff --git a/hw/qdev.c b/hw/qdev.c
> index c8ab7b7..426ea71 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -218,13 +218,15 @@ int qdev_device_help(QemuOpts *opts)
>           if (!prop->info->parse) {
>               continue;           /* no way to set it, don't show */
>           }
> -        error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
> +        error_printf("%s.%s=%s\n", info->name, prop->name,
> +                     prop->info->legacy_name ?: prop->info->name);
>       }
>       for (prop = info->bus_info->props; prop&&  prop->name; prop++) {
>           if (!prop->info->parse) {
>               continue;           /* no way to set it, don't show */
>           }
> -        error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
> +        error_printf("%s.%s=%s\n", info->name, prop->name,
> +                     prop->info->legacy_name ?: prop->info->name);
>       }
>       return 1;
>   }
> @@ -1182,7 +1184,8 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
>   {
>       gchar *type;
>
> -    type = g_strdup_printf("legacy<%s>", prop->info->name);
> +    type = g_strdup_printf("legacy<%s>",
> +                           prop->info->legacy_name ?: prop->info->name);
>
>       qdev_property_add(dev, prop->name, type,
>                         prop->info->print ? qdev_get_legacy_property : NULL,
> diff --git a/hw/qdev.h b/hw/qdev.h
> index a1cce37..8002644 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -156,6 +156,7 @@ enum PropertyType {
>
>   struct PropertyInfo {
>       const char *name;
> +    const char *legacy_name;
>       size_t size;
>       enum PropertyType type;
>       int64_t min;

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH v2 8/8] qom: register qdev properties also as non-legacy properties
  2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 8/8] qom: register qdev properties also as non-legacy properties Paolo Bonzini
@ 2011-12-16 17:05   ` Anthony Liguori
  0 siblings, 0 replies; 15+ messages in thread
From: Anthony Liguori @ 2011-12-16 17:05 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On 12/16/2011 10:47 AM, Paolo Bonzini wrote:
> Push legacy properties into a legacy<...>  namespace, and make them
> available with correct types too.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> ---
>   hw/qdev.c |   28 +++++++++++++++++++++++++---
>   hw/qdev.h |    7 +++----
>   2 files changed, 28 insertions(+), 7 deletions(-)
>
> diff --git a/hw/qdev.c b/hw/qdev.c
> index 426ea71..2f7defc 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -80,6 +80,9 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
>       return NULL;
>   }
>
> +static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
> +                                     Error **errp);
> +
>   static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
>   {
>       DeviceState *dev;
> @@ -104,10 +107,12 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
>
>       for (prop = dev->info->props; prop&&  prop->name; prop++) {
>           qdev_property_add_legacy(dev, prop, NULL);
> +        qdev_property_add_static(dev, prop, NULL);
>       }
>
>       for (prop = dev->info->bus_info->props; prop&&  prop->name; prop++) {
>           qdev_property_add_legacy(dev, prop, NULL);
> +        qdev_property_add_static(dev, prop, NULL);
>       }
>
>       qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL);
> @@ -1174,7 +1179,7 @@ static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
>    * @qdev_add_legacy_property - adds a legacy property
>    *
>    * Do not use this is new code!  Properties added through this interface will
> - * be given types in the "legacy<>" type namespace.
> + * be given names and types in the "legacy<>" type namespace.
>    *
>    * Legacy properties are always processed as strings.  The format of the string
>    * depends on the property type.
> @@ -1182,18 +1187,35 @@ static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
>   void qdev_property_add_legacy(DeviceState *dev, Property *prop,
>                                 Error **errp)
>   {
> -    gchar *type;
> +    gchar *name, *type;
>
> +    name = g_strdup_printf("legacy<%s>", prop->name);

Okay, let's make this name legacy-%s to make it clear that it's not type. 
Otherwise, the patch looks good.

Regards,

Anthony Liguori


>       type = g_strdup_printf("legacy<%s>",
>                              prop->info->legacy_name ?: prop->info->name);
>
> -    qdev_property_add(dev, prop->name, type,
> +    qdev_property_add(dev, name, type,
>                         prop->info->print ? qdev_get_legacy_property : NULL,
>                         prop->info->parse ? qdev_set_legacy_property : NULL,
>                         NULL,
>                         prop, errp);
>
>       g_free(type);
> +    g_free(name);
> +}
> +
> +/**
> + * @qdev_property_add_static - add a @Property to a device.
> + *
> + * Static properties access data in a struct.  The actual type of the
> + * property and the field depends on the property type.
> + */
> +void qdev_property_add_static(DeviceState *dev, Property *prop,
> +                              Error **errp)
> +{
> +    qdev_property_add(dev, prop->name, prop->info->name,
> +                      prop->info->get, prop->info->set,
> +                      NULL,
> +                      prop, errp);
>   }
>
>   DeviceState *qdev_get_root(void)
> diff --git a/hw/qdev.h b/hw/qdev.h
> index 8002644..3410e77 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -487,11 +487,10 @@ const char *qdev_property_get_type(DeviceState *dev, const char *name,
>                                      Error **errp);
>
>   /**
> - * @qdev_property_add_legacy - add a legacy @Property to a device
> - *
> - * DO NOT USE THIS IN NEW CODE!
> + * @qdev_property_add_static - add a @Property to a device referencing a
> + * field in a struct.
>    */
> -void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp);
> +void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp);
>
>   /**
>    * @qdev_get_root - returns the root device of the composition tree

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH v2 4/8] qom: interpret the return value when setting legacy properties
  2011-12-16 17:00   ` Anthony Liguori
@ 2011-12-16 17:19     ` Paolo Bonzini
  0 siblings, 0 replies; 15+ messages in thread
From: Paolo Bonzini @ 2011-12-16 17:19 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 636 bytes --]

On 12/16/2011 06:00 PM, Anthony Liguori wrote:
>
> And perhaps it would make more sense to return Error * and make the
> function name be a constructor:
>
> Error *error_from_qdev_prop_err(int ret, DeviceState *dev,
>                                  Property *prop, const char *value);

That doesn't work too well when calling it from setters.  However, 
error_set_from_qdev_prop_error is definitely an improvement (no matter 
what a mouthful it is).

I need to rush now.  I placed this at git://github.com/qemu/bonzini.git 
qom-props (commit 263e8c5), so you can play on top of it or pull it.  I 
attach the interdiff from v2.

Paolo

[-- Attachment #2: interdiff.patch --]
[-- Type: text/x-patch, Size: 3619 bytes --]

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index dd41e5a..80115b3 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -644,13 +644,11 @@ static void set_generic(DeviceState *dev, Visitor *v, void *opaque,
     }
     if (!*str) {
         g_free(str);
-        qdev_prop_error(errp, EINVAL, dev, prop, str);
+        error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
         return;
     }
     ret = prop->info->parse(dev, prop, str);
-    if (ret != 0) {
-        qdev_prop_error(errp, ret, dev, prop, str);
-    }
+    error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
     g_free(str);
 }
 
@@ -973,8 +972,8 @@ int qdev_prop_exists(DeviceState *dev, const char *name)
     return qdev_prop_find(dev, name) ? true : false;
 }
 
-void qdev_prop_error(Error **errp, int ret,
-                     DeviceState *dev, Property *prop, const char *value)
+void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
+                                    Property *prop, const char *value)
 {
     switch (ret) {
     case -EEXIST:
@@ -990,6 +989,10 @@ void qdev_prop_error(Error **errp, int ret,
         error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
                   dev->info->name, prop->name, value);
         break;
+    case 0:
+        break;
+    default:
+        abort();
     }
 }
 
@@ -1012,7 +1015,7 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
     ret = prop->info->parse(dev, prop, value);
     if (ret < 0) {
         Error *err;
-        qdev_prop_error(&err, ret, dev, prop, value);
+        error_set_from_qdev_prop_error(&err, ret, dev, prop, value);
         qerror_report_err(err);
         error_free(err);
         return -1;
diff --git a/hw/qdev.c b/hw/qdev.c
index 2f7defc..0465632 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1169,9 +1169,7 @@ static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
     }
 
     ret = prop->info->parse(dev, prop, ptr);
-    if (ret != 0) {
-        qdev_prop_error(errp, ret, dev, prop, ptr);
-    }
+    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
     g_free(ptr);
 }
 
@@ -1179,7 +1177,7 @@ static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
  * @qdev_add_legacy_property - adds a legacy property
  *
  * Do not use this is new code!  Properties added through this interface will
- * be given names and types in the "legacy<>" type namespace.
+ * be given names and types in the "legacy" namespace.
  *
  * Legacy properties are always processed as strings.  The format of the string
  * depends on the property type.
@@ -1189,7 +1187,7 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
 {
     gchar *name, *type;
 
-    name = g_strdup_printf("legacy<%s>", prop->name);
+    name = g_strdup_printf("legacy-%s", prop->name);
     type = g_strdup_printf("legacy<%s>",
                            prop->info->legacy_name ?: prop->info->name);
 
diff --git a/hw/qdev.h b/hw/qdev.h
index 3410e77..d5896be 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -375,8 +375,8 @@ void qdev_prop_set_defaults(DeviceState *dev, Property *props);
 
 void qdev_prop_register_global_list(GlobalProperty *props);
 void qdev_prop_set_globals(DeviceState *dev);
-void qdev_prop_error(Error **errp, int ret, DeviceState *name,
-                     Property *prop, const char *value);
+void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
+                                    Property *prop, const char *value);
 
 static inline const char *qdev_fw_name(DeviceState *dev)
 {

^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2011-12-16 17:19 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-16 16:47 [Qemu-devel] [PATCH v2 0/8] qom: introduce non-legacy static properties Paolo Bonzini
2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 1/8] qapi: protect against NULL QObject in qmp_input_get_object Paolo Bonzini
2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 2/8] qom: fix swapped parameters Paolo Bonzini
2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 3/8] qom: push permission checks up into qdev_property_add_legacy Paolo Bonzini
2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 4/8] qom: interpret the return value when setting legacy properties Paolo Bonzini
2011-12-16 17:00   ` Anthony Liguori
2011-12-16 17:19     ` Paolo Bonzini
2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 5/8] qom: introduce QERR_PROPERTY_VALUE_OUT_OF_RANGE Paolo Bonzini
2011-12-16 17:00   ` Anthony Liguori
2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 6/8] qom: introduce get/set methods for Property Paolo Bonzini
2011-12-16 17:02   ` Anthony Liguori
2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 7/8] qom: distinguish "legacy" property type name from QOM type name Paolo Bonzini
2011-12-16 17:03   ` Anthony Liguori
2011-12-16 16:47 ` [Qemu-devel] [PATCH v2 8/8] qom: register qdev properties also as non-legacy properties Paolo Bonzini
2011-12-16 17:05   ` Anthony Liguori

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).