qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH qom-next v2 0/7] QOM realize, revised again
@ 2012-06-10  1:09 Andreas Färber
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 1/7] make_device_config.sh: Fix target path in generated dependency file Andreas Färber
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Andreas Färber @ 2012-06-10  1:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Jan Kiszka, Andreas Färber, Anthony Liguori,
	Peter Maydell

Hello Anthony and Paolo,

This is our QOM remainder from the freeze, please review.

v1 -> v2:
* Reverted Object state enum to bool realized, as requested by Anthony.
  This means we have no way of detecting if an object was initialized,
  but that feature was unused so far.
* Use gtk-doc Returns: in object_is_realized() documentation.
* Reordered realize next, so that it can be applied w/o static properties
  in case issues remain with my get_id workaround.
* Reverted object_get_realize() to use bool realized directly.
* Fixed typo in object_unrealize_children() documentation.

* Dropped get_id patch nack'ed by Anthony.
* Rebased following patches, resorting to "" or object_get_typename().
* Dropped two hunks in QERR_... patch mistakenly added by Paolo.

One observation I make is that object_[un]realize_children() are made public.
Hard to judge whether that is really necessary in lack of follow-up patches.
I thus left that unchanged; for CPU reset I was instructed not to expose such
base methods but to save them in the class (e.g., ARMCPUClass::parent_reset).
That could still be cleaned up in a later patch.

Available for viewing/testing at:
https://github.com/afaerber/qemu-cpu/commits/realize

Regards,
Andreas

Cc: Anthony Liguori <anthony@codemonkey.ws>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Maydell <peter.maydell@linaro.org>

Cc: Jan Kiszka <jan.kiszka@siemens.com> (FYI)

Andreas Färber (2):
  make_device_config.sh: Fix target path in generated dependency file
  qom: Add "realized" property

Paolo Bonzini (4):
  qdev: Push state up to Object
  qdev: Generalize properties to Objects
  qdev: Move bulk of qdev-properties.c to qom/object-properties.c
  qom: Push static properties to Object

Peter Maydell (1):
  qom: Add QERR_PROPERTY_SET_AFTER_REALIZE

 hw/9pfs/virtio-9p-device.c    |    2 +-
 hw/a15mpcore.c                |    3 +-
 hw/a9mpcore.c                 |    2 +-
 hw/ac97.c                     |    2 +-
 hw/acpi_piix4.c               |    2 +-
 hw/apic_common.c              |    2 +-
 hw/applesmc.c                 |    2 +-
 hw/arm11mpcore.c              |    6 +-
 hw/arm_gic.c                  |    2 +-
 hw/arm_l2x0.c                 |    2 +-
 hw/arm_mptimer.c              |    2 +-
 hw/arm_sysctl.c               |    2 +-
 hw/arm_timer.c                |    3 +-
 hw/armv7m.c                   |    3 +-
 hw/armv7m_nvic.c              |    2 +-
 hw/cadence_gem.c              |    2 +-
 hw/ccid-card-emulated.c       |    2 +-
 hw/ccid-card-passthru.c       |    2 +-
 hw/cs4231.c                   |    2 +-
 hw/cs4231a.c                  |    2 +-
 hw/debugcon.c                 |    3 +-
 hw/ds1225y.c                  |    2 +-
 hw/e1000.c                    |    2 +-
 hw/eccmemctl.c                |    2 +-
 hw/eepro100.c                 |    2 +-
 hw/escc.c                     |    2 +-
 hw/esp.c                      |    2 +-
 hw/etraxfs_eth.c              |    3 +-
 hw/etraxfs_pic.c              |    3 +-
 hw/exynos4210_combiner.c      |    2 +-
 hw/exynos4210_gic.c           |    3 +-
 hw/exynos4210_uart.c          |    2 +-
 hw/fdc.c                      |    6 +-
 hw/fw_cfg.c                   |    2 +-
 hw/g364fb.c                   |    2 +-
 hw/grlib_apbuart.c            |    3 +-
 hw/grlib_gptimer.c            |    2 +-
 hw/grlib_irqmp.c              |    2 +-
 hw/gus.c                      |    2 +-
 hw/hda-audio.c                |    6 +-
 hw/hpet.c                     |    2 +-
 hw/i2c.c                      |    2 +-
 hw/i82374.c                   |    2 +-
 hw/i82378.c                   |    2 +-
 hw/i8254.c                    |    2 +-
 hw/i8259_common.c             |    2 +-
 hw/ide/ahci.c                 |    2 +-
 hw/ide/cmd646.c               |    3 +-
 hw/ide/isa.c                  |    2 +-
 hw/ide/qdev.c                 |    8 +-
 hw/integratorcp.c             |    3 +-
 hw/intel-hda.c                |    4 +-
 hw/ioh3420.c                  |    2 +-
 hw/ivshmem.c                  |    2 +-
 hw/kvm/i8254.c                |    2 +-
 hw/kvm/ioapic.c               |    2 +-
 hw/lan9118.c                  |    2 +-
 hw/lance.c                    |    2 +-
 hw/lm32_sys.c                 |    2 +-
 hw/lm32_timer.c               |    2 +-
 hw/m48t59.c                   |    4 +-
 hw/marvell_88w8618_audio.c    |    2 +-
 hw/mc146818rtc.c              |    2 +-
 hw/milkymist-minimac2.c       |    2 +-
 hw/milkymist-softusb.c        |    2 +-
 hw/milkymist-sysctl.c         |    2 +-
 hw/milkymist-vgafb.c          |    2 +-
 hw/mipsnet.c                  |    2 +-
 hw/musicpal.c                 |    2 +-
 hw/nand.c                     |    2 +-
 hw/ne2000-isa.c               |    3 +-
 hw/ne2000.c                   |    2 +-
 hw/omap_gpio.c                |    4 +-
 hw/omap_i2c.c                 |    2 +-
 hw/omap_intc.c                |    4 +-
 hw/onenand.c                  |    2 +-
 hw/opencores_eth.c            |    2 +-
 hw/parallel.c                 |    3 +-
 hw/pc_sysfw.c                 |    2 +-
 hw/pci.c                      |    2 +-
 hw/pci_bridge_dev.c           |    2 +-
 hw/pcnet-pci.c                |    2 +-
 hw/pcspk.c                    |    2 +-
 hw/pl041.c                    |    2 +-
 hw/pxa2xx.c                   |    2 +-
 hw/pxa2xx_dma.c               |    2 +-
 hw/pxa2xx_gpio.c              |    2 +-
 hw/pxa2xx_timer.c             |    4 +-
 hw/qdev-addr.c                |   22 +-
 hw/qdev-monitor.c             |    4 +-
 hw/qdev-properties.c          |  602 +++++++----------------------------------
 hw/qdev.c                     |   78 +-----
 hw/qdev.h                     |   98 +-------
 hw/qxl.c                      |    4 +-
 hw/rtl8139.c                  |    2 +-
 hw/s390-virtio-bus.c          |   12 +-
 hw/sb16.c                     |    2 +-
 hw/scsi-bus.c                 |    2 +-
 hw/scsi-disk.c                |    8 +-
 hw/scsi-generic.c             |    2 +-
 hw/serial.c                   |    2 +-
 hw/slavio_timer.c             |    2 +-
 hw/smbus_eeprom.c             |    3 +-
 hw/smc91c111.c                |    2 +-
 hw/spapr_llan.c               |    3 +-
 hw/spapr_pci.c                |    3 +-
 hw/spapr_vio.c                |    2 +-
 hw/spapr_vscsi.c              |    3 +-
 hw/spapr_vty.c                |    3 +-
 hw/sparc32_dma.c              |    2 +-
 hw/spitz.c                    |    4 +-
 hw/stellaris_enet.c           |    3 +-
 hw/strongarm.c                |    2 +-
 hw/sun4m.c                    |    6 +-
 hw/sun4m_iommu.c              |    2 +-
 hw/sun4u.c                    |    6 +-
 hw/tcx.c                      |    2 +-
 hw/usb/bus.c                  |    2 +-
 hw/usb/dev-audio.c            |    2 +-
 hw/usb/dev-network.c          |    2 +-
 hw/usb/dev-serial.c           |    4 +-
 hw/usb/dev-smartcard-reader.c |    4 +-
 hw/usb/dev-storage.c          |    2 +-
 hw/usb/hcd-ehci.c             |    4 +-
 hw/usb/hcd-ohci.c             |    4 +-
 hw/usb/hcd-uhci.c             |   12 +-
 hw/usb/hcd-xhci.c             |    2 +-
 hw/usb/host-linux.c           |    2 +-
 hw/usb/redirect.c             |    2 +-
 hw/virtio-console.c           |    6 +-
 hw/virtio-pci.c               |   10 +-
 hw/virtio-serial-bus.c        |    2 +-
 hw/vmmouse.c                  |    2 +-
 hw/vt82c686.c                 |    2 +-
 hw/xgmac.c                    |    2 +-
 hw/xilinx_axidma.c            |    3 +-
 hw/xilinx_axienet.c           |    3 +-
 hw/xilinx_ethlite.c           |    3 +-
 hw/xilinx_intc.c              |    3 +-
 hw/xilinx_timer.c             |    3 +-
 hw/xio3130_downstream.c       |    2 +-
 hw/xio3130_upstream.c         |    2 +-
 hw/zaurus.c                   |    2 +-
 include/qemu/object.h         |  130 +++++++++
 qerror.c                      |    4 +
 qerror.h                      |    3 +
 qom/Makefile.objs             |    2 +-
 qom/object-properties.c       |  469 ++++++++++++++++++++++++++++++++
 qom/object.c                  |  116 ++++++++
 scripts/make_device_config.sh |    2 +-
 150 files changed, 1015 insertions(+), 900 deletions(-)
 create mode 100644 qom/object-properties.c

-- 
1.7.7

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

* [Qemu-devel] [PATCH qom-next v2 1/7] make_device_config.sh: Fix target path in generated dependency file
  2012-06-10  1:09 [Qemu-devel] [PATCH qom-next v2 0/7] QOM realize, revised again Andreas Färber
@ 2012-06-10  1:09 ` Andreas Färber
  2012-06-10  1:50   ` Andreas Färber
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 2/7] qdev: Push state up to Object Andreas Färber
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 9+ messages in thread
From: Andreas Färber @ 2012-06-10  1:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Färber, Anthony Liguori

config-devices.mak.d is included from Makefile.target, i.e. from inside
the *-softmmu/ directory. It included the directory path, so never
applied to the actual config-devices.mak. Symptoms were spurious
dependency issues with default-configs/pci.mak.

Fix by using `basename` to strip the directory path.

Reported-by: Gerhard Wiesinger <lists@wiesinger.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 scripts/make_device_config.sh |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/scripts/make_device_config.sh b/scripts/make_device_config.sh
index 5d14885..0778fe2 100644
--- a/scripts/make_device_config.sh
+++ b/scripts/make_device_config.sh
@@ -25,4 +25,4 @@ done
 process_includes $src > $dest
 
 cat $src $all_includes | grep -v '^include' > $dest
-echo "$1: $all_includes" > $dep
+echo "`basename $1`: $all_includes" > $dep
-- 
1.7.7

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

* [Qemu-devel] [PATCH qom-next v2 2/7] qdev: Push state up to Object
  2012-06-10  1:09 [Qemu-devel] [PATCH qom-next v2 0/7] QOM realize, revised again Andreas Färber
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 1/7] make_device_config.sh: Fix target path in generated dependency file Andreas Färber
@ 2012-06-10  1:09 ` Andreas Färber
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 3/7] qom: Add "realized" property Andreas Färber
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Andreas Färber @ 2012-06-10  1:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Färber, Anthony Liguori

From: Paolo Bonzini <pbonzini@redhat.com>

qdev properties use the state member (an embryo of the "realized"
property) in order to disable setting them after a device has been
initialized.  So, in order to push qdev properties up to Object
we need to push this bit there too.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[AF: Replace state enum by realized boolean, requested by Anthony.]
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 hw/qdev-addr.c        |    3 ++-
 hw/qdev-properties.c  |   26 +++++++++++++-------------
 hw/qdev.c             |   11 +++++------
 hw/qdev.h             |    6 ------
 include/qemu/object.h |    9 +++++++++
 qom/object.c          |    5 +++++
 6 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
index b711b6b..a3796bd 100644
--- a/hw/qdev-addr.c
+++ b/hw/qdev-addr.c
@@ -1,3 +1,4 @@
+#include "qemu/object.h"
 #include "qdev.h"
 #include "qdev-addr.h"
 #include "targphys.h"
@@ -39,7 +40,7 @@ static void set_taddr(Object *obj, Visitor *v, void *opaque,
     Error *local_err = NULL;
     int64_t value;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 099a7aa..fcc0bed 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -53,7 +53,7 @@ static void set_bit(Object *obj, Visitor *v, void *opaque,
     Error *local_err = NULL;
     bool value;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -93,7 +93,7 @@ static void set_uint8(Object *obj, Visitor *v, void *opaque,
     Property *prop = opaque;
     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -160,7 +160,7 @@ static void set_uint16(Object *obj, Visitor *v, void *opaque,
     Property *prop = opaque;
     uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -193,7 +193,7 @@ static void set_uint32(Object *obj, Visitor *v, void *opaque,
     Property *prop = opaque;
     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -218,7 +218,7 @@ static void set_int32(Object *obj, Visitor *v, void *opaque,
     Property *prop = opaque;
     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -291,7 +291,7 @@ static void set_uint64(Object *obj, Visitor *v, void *opaque,
     Property *prop = opaque;
     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -379,7 +379,7 @@ static void set_string(Object *obj, Visitor *v, void *opaque,
     Error *local_err = NULL;
     char *str;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -457,7 +457,7 @@ static void set_pointer(Object *obj, Visitor *v, Property *prop,
     char *str;
     int ret;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -626,7 +626,7 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque,
     int64_t id;
     VLANState *vlan;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -696,7 +696,7 @@ static void set_mac(Object *obj, Visitor *v, void *opaque,
     int i, pos;
     char *str, *p;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -766,7 +766,7 @@ static void set_enum(Object *obj, Visitor *v, void *opaque,
     Property *prop = opaque;
     int *ptr = qdev_get_prop_ptr(dev, prop);
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -797,7 +797,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
     Error *local_err = NULL;
     char *str;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -867,7 +867,7 @@ static void set_blocksize(Object *obj, Visitor *v, void *opaque,
     const int64_t min = 512;
     const int64_t max = 32768;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
diff --git a/hw/qdev.c b/hw/qdev.c
index b20b34d..5580fc1 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -155,7 +155,7 @@ int qdev_init(DeviceState *dev)
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
     int rc;
 
-    assert(dev->state == DEV_STATE_CREATED);
+    assert(!object_is_realized(OBJECT(dev)));
 
     rc = dc->init(dev);
     if (rc < 0) {
@@ -178,7 +178,7 @@ int qdev_init(DeviceState *dev)
                                        dev->instance_id_alias,
                                        dev->alias_required_for_version);
     }
-    dev->state = DEV_STATE_INITIALIZED;
+    OBJECT(dev)->realized = true;
     if (dev->hotplugged) {
         device_reset(dev);
     }
@@ -188,7 +188,7 @@ int qdev_init(DeviceState *dev)
 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
                                  int required_for_version)
 {
-    assert(dev->state == DEV_STATE_CREATED);
+    assert(!object_is_realized(OBJECT(dev)));
     dev->instance_id_alias = alias_id;
     dev->alias_required_for_version = required_for_version;
 }
@@ -567,7 +567,7 @@ static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
     char *ptr = NULL;
     int ret;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -674,7 +674,6 @@ static void device_initfn(Object *obj)
     }
 
     dev->instance_id_alias = -1;
-    dev->state = DEV_STATE_CREATED;
 
     class = object_get_class(OBJECT(dev));
     do {
@@ -697,7 +696,7 @@ static void device_finalize(Object *obj)
     BusState *bus;
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
 
-    if (dev->state == DEV_STATE_INITIALIZED) {
+    if (object_is_realized(obj)) {
         while (dev->num_child_bus) {
             bus = QLIST_FIRST(&dev->child_bus);
             qbus_free(bus);
diff --git a/hw/qdev.h b/hw/qdev.h
index ae1d281..a1e40c5 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -19,11 +19,6 @@ typedef struct BusState BusState;
 
 typedef struct BusClass BusClass;
 
-enum DevState {
-    DEV_STATE_CREATED = 1,
-    DEV_STATE_INITIALIZED,
-};
-
 enum {
     DEV_NVECTORS_UNSPECIFIED = -1,
 };
@@ -64,7 +59,6 @@ struct DeviceState {
     Object parent_obj;
 
     const char *id;
-    enum DevState state;
     QemuOpts *opts;
     int hotplugged;
     BusState *parent_bus;
diff --git a/include/qemu/object.h b/include/qemu/object.h
index 8b17776..0a3828d 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -264,6 +264,7 @@ struct Object
     QTAILQ_HEAD(, ObjectProperty) properties;
     uint32_t ref;
     Object *parent;
+    bool realized;
 };
 
 /**
@@ -812,6 +813,14 @@ const char *object_property_get_type(Object *obj, const char *name,
 Object *object_get_root(void);
 
 /**
+ * object_is_realized:
+ * @obj: the object
+ *
+ * Returns: Whether @obj has been realized (i.e., completely constructed).
+ */
+bool object_is_realized(Object *obj);
+
+/**
  * object_get_canonical_path:
  *
  * Returns: The canonical path for a object.  This is the path within the
diff --git a/qom/object.c b/qom/object.c
index 00bb3b0..8d10a27 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1237,6 +1237,11 @@ static char *qdev_get_type(Object *obj, Error **errp)
     return g_strdup(object_get_typename(obj));
 }
 
+bool object_is_realized(Object *obj)
+{
+    return obj->realized;
+}
+
 static void object_instance_init(Object *obj)
 {
     object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
-- 
1.7.7

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

* [Qemu-devel] [PATCH qom-next v2 3/7] qom: Add "realized" property
  2012-06-10  1:09 [Qemu-devel] [PATCH qom-next v2 0/7] QOM realize, revised again Andreas Färber
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 1/7] make_device_config.sh: Fix target path in generated dependency file Andreas Färber
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 2/7] qdev: Push state up to Object Andreas Färber
@ 2012-06-10  1:09 ` Andreas Färber
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 4/7] qdev: Generalize properties to Objects Andreas Färber
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Andreas Färber @ 2012-06-10  1:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Färber, Anthony Liguori

Since we had to move the state field from DeviceState to Object, we cannot
delay the implementation of the "realized" property.  The property is
a trigger for two actions that propagate through the composition tree.
"Realize" is called when the property becomes true, and propagates in
pre-order; realize can fail if the values of the properties are not valid.
"Unrealize" is called when the property becomes false, and propagates in
post-order; unrealize cannot fail.

Realize/unrealize is separate from reset.  Reset propagation is a thorny
issue of its own.  We expect classes that care to implement a reset method
and call it from realize or realize_children, depending on whether
pre-order or post-order is more appropriate.

This patch adds four methods (realize, realize_children, unrealize,
unrealize_children) to ObjectClass, together with a default implementation
of realize_children and unrealize_children.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[PB: Added unrealize and (un)realize_children]
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 include/qemu/object.h |   22 ++++++++++++
 qom/object.c          |   91 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 113 insertions(+), 0 deletions(-)

diff --git a/include/qemu/object.h b/include/qemu/object.h
index 0a3828d..274c839 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -239,6 +239,12 @@ struct ObjectClass
 {
     /*< private >*/
     Type type;
+
+    /*< public >*/
+    void (*realize)(Object *obj, struct Error **errp);
+    void (*realize_children)(Object *obj, struct Error **errp);
+    void (*unrealize)(Object *obj);
+    void (*unrealize_children)(Object *obj);
 };
 
 /**
@@ -452,6 +458,22 @@ Object *object_new_with_type(Type type);
 void object_delete(Object *obj);
 
 /**
+ * object_realize_children:
+ * @obj: The object whose children should be realized.
+ *
+ * The default implementation of realize_children.
+ */
+void object_realize_children(Object *obj, struct Error **errp);
+
+/**
+ * object_unrealize_children:
+ * @obj: The object whose children should be unrealized.
+ *
+ * The default implementation of unrealize_children.
+ */
+void object_unrealize_children(Object *obj);
+
+/**
  * object_initialize_with_type:
  * @obj: A pointer to the memory to be used for the object.
  * @type: The type of the object to instantiate.
diff --git a/qom/object.c b/qom/object.c
index 8d10a27..c1f1bb4 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -265,6 +265,85 @@ static void object_interface_init(Object *obj, InterfaceImpl *iface)
     obj->interfaces = g_slist_prepend(obj->interfaces, iface_obj);
 }
 
+static void object_get_realized(Object *obj, Visitor *v, void *opaque,
+                                const char *name, Error **errp)
+{
+    visit_type_bool(v, &obj->realized, name, errp);
+}
+
+static void object_unrealize(Object *obj)
+{
+    ObjectClass *klass = object_get_class(obj);
+
+    if (klass->unrealize_children) {
+        klass->unrealize_children(obj);
+    }
+    if (obj->realized && klass->unrealize) {
+        klass->unrealize(obj);
+    }
+    obj->realized = false;
+}
+
+static int object_unrealize_one(Object *obj, void *unused)
+{
+    object_unrealize(obj);
+    return 0;
+}
+
+void object_unrealize_children(Object *obj)
+{
+    object_child_foreach(obj, object_unrealize_one, NULL);
+}
+
+static void object_realize(Object *obj, Error **errp)
+{
+    ObjectClass *klass = object_get_class(obj);
+
+    if (!obj->realized && klass->realize) {
+        klass->realize(obj, errp);
+    }
+    obj->realized = true;
+    if (klass->realize_children) {
+        klass->realize_children(obj, errp);
+    }
+}
+
+static int object_realize_one(Object *obj, void *errp)
+{
+    Error *err = NULL;
+    object_realize(obj, &err);
+    if (err) {
+        error_propagate((Error **)errp, err);
+        return 1;
+    }
+
+    return 0;
+}
+
+void object_realize_children(Object *obj, Error **errp)
+{
+    object_child_foreach(obj, object_realize_one, errp);
+}
+
+static void object_set_realized(Object *obj, Visitor *v, void *opaque,
+                                const char *name, Error **errp)
+{
+    bool value;
+    Error *err = NULL;
+
+    visit_type_bool(v, &value, name, &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    if (value) {
+        object_realize(obj, errp);
+    } else {
+        object_unrealize(obj);
+    }
+}
+
 static void object_init_with_type(Object *obj, TypeImpl *ti)
 {
     int i;
@@ -353,6 +432,8 @@ void object_unparent(Object *obj)
 
 static void object_deinit(Object *obj, TypeImpl *type)
 {
+    object_property_set_bool(obj, false, "realized", NULL);
+
     if (type->instance_finalize) {
         type->instance_finalize(obj);
     }
@@ -1245,6 +1326,15 @@ bool object_is_realized(Object *obj)
 static void object_instance_init(Object *obj)
 {
     object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
+
+    object_property_add(obj, "realized", "bool", object_get_realized,
+                        object_set_realized, NULL, NULL, NULL);
+}
+
+static void object_class_init(ObjectClass *klass, void *class_data)
+{
+    klass->realize_children = object_realize_children;
+    klass->unrealize_children = object_unrealize_children;
 }
 
 static void register_types(void)
@@ -1258,6 +1348,7 @@ static void register_types(void)
     static TypeInfo object_info = {
         .name = TYPE_OBJECT,
         .instance_size = sizeof(Object),
+        .class_init = object_class_init,
         .instance_init = object_instance_init,
         .abstract = true,
     };
-- 
1.7.7

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

* [Qemu-devel] [PATCH qom-next v2 4/7] qdev: Generalize properties to Objects
  2012-06-10  1:09 [Qemu-devel] [PATCH qom-next v2 0/7] QOM realize, revised again Andreas Färber
                   ` (2 preceding siblings ...)
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 3/7] qom: Add "realized" property Andreas Färber
@ 2012-06-10  1:09 ` Andreas Färber
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 5/7] qdev: Move bulk of qdev-properties.c to qom/object-properties.c Andreas Färber
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Andreas Färber @ 2012-06-10  1:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Färber, Anthony Liguori

From: Paolo Bonzini <pbonzini@redhat.com>

The property machinery uses DeviceState arguments in a few places.
Replace this with Object so that we can push properties up.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[AF: Fixed indentation in set_taddr(), drop use of object_get_id().]
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 hw/qdev-addr.c       |   19 ++---
 hw/qdev-properties.c |  180 +++++++++++++++++++++----------------------------
 hw/qdev.c            |    8 +--
 hw/qdev.h            |   10 ++--
 4 files changed, 93 insertions(+), 124 deletions(-)

diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
index a3796bd..cecae59 100644
--- a/hw/qdev-addr.c
+++ b/hw/qdev-addr.c
@@ -5,26 +5,25 @@
 
 /* --- target physical address --- */
 
-static int parse_taddr(DeviceState *dev, Property *prop, const char *str)
+static int parse_taddr(Object *obj, Property *prop, const char *str)
 {
-    target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop);
+    target_phys_addr_t *ptr = object_get_prop_ptr(obj, prop);
 
     *ptr = strtoull(str, NULL, 16);
     return 0;
 }
 
-static int print_taddr(DeviceState *dev, Property *prop, char *dest, size_t len)
+static int print_taddr(Object *obj, Property *prop, char *dest, size_t len)
 {
-    target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop);
+    target_phys_addr_t *ptr = object_get_prop_ptr(obj, prop);
     return snprintf(dest, len, "0x" TARGET_FMT_plx, *ptr);
 }
 
 static void get_taddr(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop);
+    target_phys_addr_t *ptr = object_get_prop_ptr(obj, prop);
     int64_t value;
 
     value = *ptr;
@@ -34,9 +33,8 @@ static void get_taddr(Object *obj, Visitor *v, void *opaque,
 static void set_taddr(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop);
+    target_phys_addr_t *ptr = object_get_prop_ptr(obj, prop);
     Error *local_err = NULL;
     int64_t value;
 
@@ -53,9 +51,8 @@ static void set_taddr(Object *obj, Visitor *v, void *opaque,
     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);
+        error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+                  name, "target_phys_addr_t");
     }
 }
 
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index fcc0bed..8dc9de1 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -3,23 +3,23 @@
 #include "qerror.h"
 #include "blockdev.h"
 
-void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
+void *object_get_prop_ptr(Object *obj, Property *prop)
 {
-    void *ptr = dev;
+    void *ptr = obj;
     ptr += prop->offset;
     return ptr;
 }
 
-static uint32_t qdev_get_prop_mask(Property *prop)
+static uint32_t get_prop_mask(Property *prop)
 {
     assert(prop->info == &qdev_prop_bit);
     return 0x1 << prop->bitnr;
 }
 
-static void bit_prop_set(DeviceState *dev, Property *props, bool val)
+static void bit_prop_set(Object *obj, Property *props, bool val)
 {
-    uint32_t *p = qdev_get_prop_ptr(dev, props);
-    uint32_t mask = qdev_get_prop_mask(props);
+    uint32_t *p = object_get_prop_ptr(obj, props);
+    uint32_t mask = get_prop_mask(props);
     if (val)
         *p |= mask;
     else
@@ -28,19 +28,18 @@ static void bit_prop_set(DeviceState *dev, Property *props, bool val)
 
 /* Bit */
 
-static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
+static int print_bit(Object *obj, Property *prop, char *dest, size_t len)
 {
-    uint32_t *p = qdev_get_prop_ptr(dev, prop);
-    return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
+    uint32_t *p = object_get_prop_ptr(obj, prop);
+    return snprintf(dest, len, (*p & get_prop_mask(prop)) ? "on" : "off");
 }
 
 static void get_bit(Object *obj, Visitor *v, void *opaque,
                     const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *p = qdev_get_prop_ptr(dev, prop);
-    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
+    uint32_t *p = object_get_prop_ptr(obj, prop);
+    bool value = (*p & get_prop_mask(prop)) != 0;
 
     visit_type_bool(v, &value, name, errp);
 }
@@ -48,7 +47,6 @@ static void get_bit(Object *obj, Visitor *v, void *opaque,
 static void set_bit(Object *obj, Visitor *v, void *opaque,
                     const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     Error *local_err = NULL;
     bool value;
@@ -63,7 +61,7 @@ static void set_bit(Object *obj, Visitor *v, void *opaque,
         error_propagate(errp, local_err);
         return;
     }
-    bit_prop_set(dev, prop, value);
+    bit_prop_set(obj, prop, value);
 }
 
 PropertyInfo qdev_prop_bit = {
@@ -79,9 +77,8 @@ PropertyInfo qdev_prop_bit = {
 static void get_uint8(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint8_t *ptr = object_get_prop_ptr(obj, prop);
 
     visit_type_uint8(v, ptr, name, errp);
 }
@@ -89,9 +86,8 @@ static void get_uint8(Object *obj, Visitor *v, void *opaque,
 static void set_uint8(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint8_t *ptr = object_get_prop_ptr(obj, prop);
 
     if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
@@ -109,9 +105,9 @@ PropertyInfo qdev_prop_uint8 = {
 
 /* --- 8bit hex value --- */
 
-static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
+static int parse_hex8(Object *obj, Property *prop, const char *str)
 {
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint8_t *ptr = object_get_prop_ptr(obj, prop);
     char *end;
 
     if (str[0] != '0' || str[1] != 'x') {
@@ -126,9 +122,9 @@ static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
     return 0;
 }
 
-static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
+static int print_hex8(Object *obj, Property *prop, char *dest, size_t len)
 {
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint8_t *ptr = object_get_prop_ptr(obj, prop);
     return snprintf(dest, len, "0x%" PRIx8, *ptr);
 }
 
@@ -146,9 +142,8 @@ PropertyInfo qdev_prop_hex8 = {
 static void get_uint16(Object *obj, Visitor *v, void *opaque,
                        const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint16_t *ptr = object_get_prop_ptr(obj, prop);
 
     visit_type_uint16(v, ptr, name, errp);
 }
@@ -156,9 +151,8 @@ static void get_uint16(Object *obj, Visitor *v, void *opaque,
 static void set_uint16(Object *obj, Visitor *v, void *opaque,
                        const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint16_t *ptr = object_get_prop_ptr(obj, prop);
 
     if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
@@ -179,9 +173,8 @@ PropertyInfo qdev_prop_uint16 = {
 static void get_uint32(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);
+    uint32_t *ptr = object_get_prop_ptr(obj, prop);
 
     visit_type_uint32(v, ptr, name, errp);
 }
@@ -189,9 +182,8 @@ static void get_uint32(Object *obj, Visitor *v, void *opaque,
 static void set_uint32(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);
+    uint32_t *ptr = object_get_prop_ptr(obj, prop);
 
     if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
@@ -204,9 +196,8 @@ static void set_uint32(Object *obj, Visitor *v, void *opaque,
 static void get_int32(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t *ptr = object_get_prop_ptr(obj, prop);
 
     visit_type_int32(v, ptr, name, errp);
 }
@@ -214,9 +205,8 @@ static void get_int32(Object *obj, Visitor *v, void *opaque,
 static void set_int32(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t *ptr = object_get_prop_ptr(obj, prop);
 
     if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
@@ -240,9 +230,9 @@ PropertyInfo qdev_prop_int32 = {
 
 /* --- 32bit hex value --- */
 
-static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
+static int parse_hex32(Object *obj, Property *prop, const char *str)
 {
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *ptr = object_get_prop_ptr(obj, prop);
     char *end;
 
     if (str[0] != '0' || str[1] != 'x') {
@@ -257,9 +247,9 @@ static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
     return 0;
 }
 
-static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
+static int print_hex32(Object *obj, Property *prop, char *dest, size_t len)
 {
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *ptr = object_get_prop_ptr(obj, prop);
     return snprintf(dest, len, "0x%" PRIx32, *ptr);
 }
 
@@ -277,9 +267,8 @@ PropertyInfo qdev_prop_hex32 = {
 static void get_uint64(Object *obj, Visitor *v, void *opaque,
                        const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint64_t *ptr = object_get_prop_ptr(obj, prop);
 
     visit_type_uint64(v, ptr, name, errp);
 }
@@ -287,9 +276,8 @@ static void get_uint64(Object *obj, Visitor *v, void *opaque,
 static void set_uint64(Object *obj, Visitor *v, void *opaque,
                        const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint64_t *ptr = object_get_prop_ptr(obj, prop);
 
     if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
@@ -307,9 +295,9 @@ PropertyInfo qdev_prop_uint64 = {
 
 /* --- 64bit hex value --- */
 
-static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
+static int parse_hex64(Object *obj, Property *prop, const char *str)
 {
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint64_t *ptr = object_get_prop_ptr(obj, prop);
     char *end;
 
     if (str[0] != '0' || str[1] != 'x') {
@@ -324,9 +312,9 @@ static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
     return 0;
 }
 
-static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
+static int print_hex64(Object *obj, Property *prop, char *dest, size_t len)
 {
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint64_t *ptr = object_get_prop_ptr(obj, prop);
     return snprintf(dest, len, "0x%" PRIx64, *ptr);
 }
 
@@ -344,12 +332,12 @@ PropertyInfo qdev_prop_hex64 = {
 static void release_string(Object *obj, const char *name, void *opaque)
 {
     Property *prop = opaque;
-    g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
+    g_free(*(char **)object_get_prop_ptr(obj, prop));
 }
 
-static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
+static int print_string(Object *obj, Property *prop, char *dest, size_t len)
 {
-    char **ptr = qdev_get_prop_ptr(dev, prop);
+    char **ptr = object_get_prop_ptr(obj, prop);
     if (!*ptr)
         return snprintf(dest, len, "<null>");
     return snprintf(dest, len, "\"%s\"", *ptr);
@@ -358,9 +346,8 @@ static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len
 static void get_string(Object *obj, Visitor *v, void *opaque,
                        const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    char **ptr = qdev_get_prop_ptr(dev, prop);
+    char **ptr = object_get_prop_ptr(obj, prop);
 
     if (!*ptr) {
         char *str = (char *)"";
@@ -373,9 +360,8 @@ static void get_string(Object *obj, Visitor *v, void *opaque,
 static void set_string(Object *obj, Visitor *v, void *opaque,
                        const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    char **ptr = qdev_get_prop_ptr(dev, prop);
+    char **ptr = object_get_prop_ptr(obj, prop);
     Error *local_err = NULL;
     char *str;
 
@@ -405,14 +391,14 @@ PropertyInfo qdev_prop_string = {
 
 /* --- drive --- */
 
-static int parse_drive(DeviceState *dev, const char *str, void **ptr)
+static int parse_drive(Object *obj, const char *str, void **ptr)
 {
     BlockDriverState *bs;
 
     bs = bdrv_find(str);
     if (bs == NULL)
         return -ENOENT;
-    if (bdrv_attach_dev(bs, dev) < 0)
+    if (bdrv_attach_dev(bs, obj) < 0)
         return -EEXIST;
     *ptr = bs;
     return 0;
@@ -420,12 +406,11 @@ static int parse_drive(DeviceState *dev, const char *str, void **ptr)
 
 static void release_drive(Object *obj, const char *name, void *opaque)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
+    BlockDriverState **ptr = object_get_prop_ptr(obj, prop);
 
     if (*ptr) {
-        bdrv_detach_dev(*ptr, dev);
+        bdrv_detach_dev(*ptr, obj);
         blockdev_auto_del(*ptr);
     }
 }
@@ -439,8 +424,7 @@ static void get_pointer(Object *obj, Visitor *v, Property *prop,
                         const char *(*print)(void *ptr),
                         const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
-    void **ptr = qdev_get_prop_ptr(dev, prop);
+    void **ptr = object_get_prop_ptr(obj, prop);
     char *p;
 
     p = (char *) (*ptr ? print(*ptr) : "");
@@ -448,12 +432,11 @@ static void get_pointer(Object *obj, Visitor *v, Property *prop,
 }
 
 static void set_pointer(Object *obj, Visitor *v, Property *prop,
-                        int (*parse)(DeviceState *dev, const char *str, void **ptr),
+                        int (*parse)(Object *obj, const char *str, void **ptr),
                         const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Error *local_err = NULL;
-    void **ptr = qdev_get_prop_ptr(dev, prop);
+    void **ptr = object_get_prop_ptr(obj, prop);
     char *str;
     int ret;
 
@@ -472,8 +455,8 @@ static void set_pointer(Object *obj, Visitor *v, Property *prop,
         *ptr = NULL;
         return;
     }
-    ret = parse(dev, str, ptr);
-    error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
+    ret = parse(obj, str, ptr);
+    error_set_from_prop_error(errp, ret, obj, prop, str);
     g_free(str);
 }
 
@@ -498,7 +481,7 @@ PropertyInfo qdev_prop_drive = {
 
 /* --- character device --- */
 
-static int parse_chr(DeviceState *dev, const char *str, void **ptr)
+static int parse_chr(Object *obj, const char *str, void **ptr)
 {
     CharDriverState *chr = qemu_chr_find(str);
     if (chr == NULL) {
@@ -514,9 +497,8 @@ static int parse_chr(DeviceState *dev, const char *str, void **ptr)
 
 static void release_chr(Object *obj, const char *name, void *opaque)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
+    CharDriverState **ptr = object_get_prop_ptr(obj, prop);
 
     if (*ptr) {
         qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL);
@@ -552,7 +534,7 @@ PropertyInfo qdev_prop_chr = {
 
 /* --- netdev device --- */
 
-static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
+static int parse_netdev(Object *obj, const char *str, void **ptr)
 {
     VLANClientState *netdev = qemu_find_netdev(str);
 
@@ -593,9 +575,9 @@ PropertyInfo qdev_prop_netdev = {
 
 /* --- vlan --- */
 
-static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
+static int print_vlan(Object *obj, Property *prop, char *dest, size_t len)
 {
-    VLANState **ptr = qdev_get_prop_ptr(dev, prop);
+    VLANState **ptr = object_get_prop_ptr(obj, prop);
 
     if (*ptr) {
         return snprintf(dest, len, "%d", (*ptr)->id);
@@ -607,9 +589,8 @@ static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
 static void get_vlan(Object *obj, Visitor *v, void *opaque,
                      const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    VLANState **ptr = qdev_get_prop_ptr(dev, prop);
+    VLANState **ptr = object_get_prop_ptr(obj, prop);
     int64_t id;
 
     id = *ptr ? (*ptr)->id : -1;
@@ -619,9 +600,8 @@ static void get_vlan(Object *obj, Visitor *v, void *opaque,
 static void set_vlan(Object *obj, Visitor *v, void *opaque,
                      const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    VLANState **ptr = qdev_get_prop_ptr(dev, prop);
+    VLANState **ptr = object_get_prop_ptr(obj, prop);
     Error *local_err = NULL;
     int64_t id;
     VLANState *vlan;
@@ -673,9 +653,8 @@ PropertyInfo qdev_prop_ptr = {
 static void get_mac(Object *obj, Visitor *v, void *opaque,
                     const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+    MACAddr *mac = object_get_prop_ptr(obj, prop);
     char buffer[2 * 6 + 5 + 1];
     char *p = buffer;
 
@@ -689,9 +668,8 @@ static void get_mac(Object *obj, Visitor *v, void *opaque,
 static void set_mac(Object *obj, Visitor *v, void *opaque,
                     const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+    MACAddr *mac = object_get_prop_ptr(obj, prop);
     Error *local_err = NULL;
     int i, pos;
     char *str, *p;
@@ -725,7 +703,7 @@ static void set_mac(Object *obj, Visitor *v, void *opaque,
     return;
 
 inval:
-    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+    error_set_from_prop_error(errp, EINVAL, obj, prop, str);
     g_free(str);
 }
 
@@ -751,9 +729,8 @@ QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
 static void get_enum(Object *obj, Visitor *v, void *opaque,
                      const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int *ptr = qdev_get_prop_ptr(dev, prop);
+    int *ptr = object_get_prop_ptr(obj, prop);
 
     visit_type_enum(v, ptr, prop->info->enum_table,
                     prop->info->name, prop->name, errp);
@@ -762,9 +739,8 @@ static void get_enum(Object *obj, Visitor *v, void *opaque,
 static void set_enum(Object *obj, Visitor *v, void *opaque,
                      const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int *ptr = qdev_get_prop_ptr(dev, prop);
+    int *ptr = object_get_prop_ptr(obj, prop);
 
     if (object_is_realized(obj)) {
         error_set(errp, QERR_PERMISSION_DENIED);
@@ -790,9 +766,8 @@ PropertyInfo qdev_prop_losttickpolicy = {
 static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
                           const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t value, *ptr = object_get_prop_ptr(obj, prop);
     unsigned int slot, fn, n;
     Error *local_err = NULL;
     char *str;
@@ -832,13 +807,13 @@ static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
     return;
 
 invalid:
-    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+    error_set_from_prop_error(errp, EINVAL, obj, prop, str);
     g_free(str);
 }
 
-static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
+static int print_pci_devfn(Object *obj, Property *prop, char *dest, size_t len)
 {
-    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t *ptr = object_get_prop_ptr(obj, prop);
 
     if (*ptr == -1) {
         return snprintf(dest, len, "<unset>");
@@ -860,9 +835,8 @@ PropertyInfo qdev_prop_pci_devfn = {
 static void set_blocksize(Object *obj, Visitor *v, void *opaque,
                           const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
+    uint16_t value, *ptr = object_get_prop_ptr(obj, prop);
     Error *local_err = NULL;
     const int64_t min = 512;
     const int64_t max = 32768;
@@ -879,14 +853,14 @@ static void set_blocksize(Object *obj, Visitor *v, void *opaque,
     }
     if (value < min || value > max) {
         error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
-                  dev->id?:"", name, (int64_t)value, min, max);
+                  "", name, (int64_t)value, min, max);
         return;
     }
 
     /* We rely on power-of-2 blocksizes for bitmasks */
     if ((value & (value - 1)) != 0) {
         error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
-                  dev->id?:"", name, (int64_t)value);
+                  "", name, (int64_t)value);
         return;
     }
 
@@ -913,13 +887,13 @@ static Property *qdev_prop_walk(Property *props, const char *name)
     return NULL;
 }
 
-static Property *qdev_prop_find(DeviceState *dev, const char *name)
+static Property *qdev_prop_find(Object *obj, const char *name)
 {
     ObjectClass *class;
     Property *prop;
 
     /* device properties */
-    class = object_get_class(OBJECT(dev));
+    class = object_get_class(obj);
     do {
         prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
         if (prop) {
@@ -931,22 +905,22 @@ static Property *qdev_prop_find(DeviceState *dev, const char *name)
     return NULL;
 }
 
-void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
-                                    Property *prop, const char *value)
+void error_set_from_prop_error(Error **errp, int ret, Object *obj,
+                               Property *prop, const char *value)
 {
     switch (ret) {
     case -EEXIST:
         error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
-                  object_get_typename(OBJECT(dev)), prop->name, value);
+                  object_get_typename(obj), prop->name, value);
         break;
     default:
     case -EINVAL:
         error_set(errp, QERR_PROPERTY_VALUE_BAD,
-                  object_get_typename(OBJECT(dev)), prop->name, value);
+                  object_get_typename(obj), prop->name, value);
         break;
     case -ENOENT:
         error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
-                  object_get_typename(OBJECT(dev)), prop->name, value);
+                  object_get_typename(obj), prop->name, value);
         break;
     case 0:
         break;
@@ -1084,7 +1058,7 @@ void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
     Property *prop;
     Error *errp = NULL;
 
-    prop = qdev_prop_find(dev, name);
+    prop = qdev_prop_find(OBJECT(dev), name);
     object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
                             name, &errp);
     assert_no_error(errp);
@@ -1095,9 +1069,9 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
     Property *prop;
     void **ptr;
 
-    prop = qdev_prop_find(dev, name);
+    prop = qdev_prop_find(OBJECT(dev), name);
     assert(prop && prop->info == &qdev_prop_ptr);
-    ptr = qdev_get_prop_ptr(dev, prop);
+    ptr = object_get_prop_ptr(OBJECT(dev), prop);
     *ptr = value;
 }
 
diff --git a/hw/qdev.c b/hw/qdev.c
index 5580fc1..a82fec8 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -548,20 +548,18 @@ char *qdev_get_dev_path(DeviceState *dev)
 static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
                                      const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
 
     char buffer[1024];
     char *ptr = buffer;
 
-    prop->info->print(dev, prop, buffer, sizeof(buffer));
+    prop->info->print(obj, prop, buffer, sizeof(buffer));
     visit_type_str(v, &ptr, name, errp);
 }
 
 static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
                                      const char *name, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     Error *local_err = NULL;
     char *ptr = NULL;
@@ -578,8 +576,8 @@ static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
         return;
     }
 
-    ret = prop->info->parse(dev, prop, ptr);
-    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
+    ret = prop->info->parse(obj, prop, ptr);
+    error_set_from_prop_error(errp, ret, obj, prop, ptr);
     g_free(ptr);
 }
 
diff --git a/hw/qdev.h b/hw/qdev.h
index a1e40c5..bfa8620 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -130,8 +130,8 @@ struct PropertyInfo {
     const char *name;
     const char *legacy_name;
     const char **enum_table;
-    int (*parse)(DeviceState *dev, Property *prop, const char *str);
-    int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
+    int (*parse)(Object *obj, Property *prop, const char *str);
+    int (*print)(Object *obj, Property *prop, char *dest, size_t len);
     ObjectPropertyAccessor *get;
     ObjectPropertyAccessor *set;
     ObjectPropertyRelease *release;
@@ -299,7 +299,7 @@ extern PropertyInfo qdev_prop_blocksize;
     {}
 
 /* Set properties between creation and init.  */
-void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
+void *object_get_prop_ptr(Object *obj, Property *prop);
 int qdev_prop_parse(DeviceState *dev, const char *name, const char *value);
 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value);
 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value);
@@ -320,8 +320,8 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
 
 void qdev_prop_register_global_list(GlobalProperty *props);
 void qdev_prop_set_globals(DeviceState *dev);
-void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
-                                    Property *prop, const char *value);
+void error_set_from_prop_error(Error **errp, int ret, Object *obj,
+                               Property *prop, const char *value);
 
 char *qdev_get_fw_dev_path(DeviceState *dev);
 
-- 
1.7.7

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

* [Qemu-devel] [PATCH qom-next v2 5/7] qdev: Move bulk of qdev-properties.c to qom/object-properties.c
  2012-06-10  1:09 [Qemu-devel] [PATCH qom-next v2 0/7] QOM realize, revised again Andreas Färber
                   ` (3 preceding siblings ...)
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 4/7] qdev: Generalize properties to Objects Andreas Färber
@ 2012-06-10  1:09 ` Andreas Färber
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 6/7] qom: Push static properties to Object Andreas Färber
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 7/7] qom: Add QERR_PROPERTY_SET_AFTER_REALIZE Andreas Färber
  6 siblings, 0 replies; 9+ messages in thread
From: Andreas Färber @ 2012-06-10  1:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Färber, Anthony Liguori

From: Paolo Bonzini <pbonzini@redhat.com>

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[AF: Move to new qom/object-properties.c, update documentation.]
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 hw/qdev-properties.c    |  487 +++++------------------------------------------
 hw/qdev.c               |   47 +-----
 hw/qdev.h               |   87 ---------
 include/qemu/object.h   |   98 ++++++++++
 qom/Makefile.objs       |    2 +-
 qom/object-properties.c |  461 ++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 607 insertions(+), 575 deletions(-)
 create mode 100644 qom/object-properties.c

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 8dc9de1..8651141 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -3,392 +3,27 @@
 #include "qerror.h"
 #include "blockdev.h"
 
-void *object_get_prop_ptr(Object *obj, Property *prop)
-{
-    void *ptr = obj;
-    ptr += prop->offset;
-    return ptr;
-}
-
-static uint32_t get_prop_mask(Property *prop)
-{
-    assert(prop->info == &qdev_prop_bit);
-    return 0x1 << prop->bitnr;
-}
-
-static void bit_prop_set(Object *obj, Property *props, bool val)
-{
-    uint32_t *p = object_get_prop_ptr(obj, props);
-    uint32_t mask = get_prop_mask(props);
-    if (val)
-        *p |= mask;
-    else
-        *p &= ~mask;
-}
-
-/* Bit */
-
-static int print_bit(Object *obj, Property *prop, char *dest, size_t len)
-{
-    uint32_t *p = object_get_prop_ptr(obj, prop);
-    return snprintf(dest, len, (*p & get_prop_mask(prop)) ? "on" : "off");
-}
-
-static void get_bit(Object *obj, Visitor *v, void *opaque,
-                    const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    uint32_t *p = object_get_prop_ptr(obj, prop);
-    bool value = (*p & get_prop_mask(prop)) != 0;
-
-    visit_type_bool(v, &value, name, errp);
-}
-
-static void set_bit(Object *obj, Visitor *v, void *opaque,
-                    const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    Error *local_err = NULL;
-    bool value;
-
-    if (object_is_realized(obj)) {
-        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(obj, prop, value);
-}
-
-PropertyInfo qdev_prop_bit = {
-    .name  = "boolean",
-    .legacy_name  = "on/off",
-    .print = print_bit,
-    .get   = get_bit,
-    .set   = set_bit,
-};
-
-/* --- 8bit integer --- */
-
-static void get_uint8(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    uint8_t *ptr = object_get_prop_ptr(obj, prop);
-
-    visit_type_uint8(v, ptr, name, errp);
-}
-
-static void set_uint8(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    uint8_t *ptr = object_get_prop_ptr(obj, prop);
-
-    if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_uint8(v, ptr, name, errp);
-}
-
-PropertyInfo qdev_prop_uint8 = {
-    .name  = "uint8",
-    .get   = get_uint8,
-    .set   = set_uint8,
-};
-
-/* --- 8bit hex value --- */
-
-static int parse_hex8(Object *obj, Property *prop, const char *str)
-{
-    uint8_t *ptr = object_get_prop_ptr(obj, prop);
-    char *end;
-
-    if (str[0] != '0' || str[1] != 'x') {
-        return -EINVAL;
-    }
-
-    *ptr = strtoul(str, &end, 16);
-    if ((*end != '\0') || (end == str)) {
-        return -EINVAL;
-    }
-
-    return 0;
-}
-
-static int print_hex8(Object *obj, Property *prop, char *dest, size_t len)
-{
-    uint8_t *ptr = object_get_prop_ptr(obj, prop);
-    return snprintf(dest, len, "0x%" PRIx8, *ptr);
-}
-
-PropertyInfo qdev_prop_hex8 = {
-    .name  = "uint8",
-    .legacy_name  = "hex8",
-    .parse = parse_hex8,
-    .print = print_hex8,
-    .get   = get_uint8,
-    .set   = set_uint8,
-};
-
-/* --- 16bit integer --- */
-
-static void get_uint16(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    uint16_t *ptr = object_get_prop_ptr(obj, prop);
-
-    visit_type_uint16(v, ptr, name, errp);
-}
-
-static void set_uint16(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    uint16_t *ptr = object_get_prop_ptr(obj, prop);
-
-    if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_uint16(v, ptr, name, errp);
-}
-
-PropertyInfo qdev_prop_uint16 = {
-    .name  = "uint16",
-    .get   = get_uint16,
-    .set   = set_uint16,
-};
-
-/* --- 32bit integer --- */
-
-static void get_uint32(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    uint32_t *ptr = object_get_prop_ptr(obj, prop);
-
-    visit_type_uint32(v, ptr, name, errp);
-}
-
-static void set_uint32(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    uint32_t *ptr = object_get_prop_ptr(obj, prop);
-
-    if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_uint32(v, ptr, name, errp);
-}
-
-static void get_int32(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    int32_t *ptr = object_get_prop_ptr(obj, prop);
-
-    visit_type_int32(v, ptr, name, errp);
-}
-
-static void set_int32(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    int32_t *ptr = object_get_prop_ptr(obj, prop);
-
-    if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_int32(v, ptr, name, errp);
-}
-
-PropertyInfo qdev_prop_uint32 = {
-    .name  = "uint32",
-    .get   = get_uint32,
-    .set   = set_uint32,
-};
-
-PropertyInfo qdev_prop_int32 = {
-    .name  = "int32",
-    .get   = get_int32,
-    .set   = set_int32,
-};
-
-/* --- 32bit hex value --- */
-
-static int parse_hex32(Object *obj, Property *prop, const char *str)
-{
-    uint32_t *ptr = object_get_prop_ptr(obj, prop);
-    char *end;
-
-    if (str[0] != '0' || str[1] != 'x') {
-        return -EINVAL;
-    }
-
-    *ptr = strtoul(str, &end, 16);
-    if ((*end != '\0') || (end == str)) {
-        return -EINVAL;
-    }
-
-    return 0;
-}
-
-static int print_hex32(Object *obj, Property *prop, char *dest, size_t len)
-{
-    uint32_t *ptr = object_get_prop_ptr(obj, prop);
-    return snprintf(dest, len, "0x%" PRIx32, *ptr);
-}
-
-PropertyInfo qdev_prop_hex32 = {
-    .name  = "uint32",
-    .legacy_name  = "hex32",
-    .parse = parse_hex32,
-    .print = print_hex32,
-    .get   = get_uint32,
-    .set   = set_uint32,
-};
-
-/* --- 64bit integer --- */
-
-static void get_uint64(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    uint64_t *ptr = object_get_prop_ptr(obj, prop);
-
-    visit_type_uint64(v, ptr, name, errp);
-}
-
-static void set_uint64(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    uint64_t *ptr = object_get_prop_ptr(obj, prop);
-
-    if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_uint64(v, ptr, name, errp);
-}
-
-PropertyInfo qdev_prop_uint64 = {
-    .name  = "uint64",
-    .get   = get_uint64,
-    .set   = set_uint64,
-};
-
-/* --- 64bit hex value --- */
-
-static int parse_hex64(Object *obj, Property *prop, const char *str)
-{
-    uint64_t *ptr = object_get_prop_ptr(obj, prop);
-    char *end;
-
-    if (str[0] != '0' || str[1] != 'x') {
-        return -EINVAL;
-    }
-
-    *ptr = strtoull(str, &end, 16);
-    if ((*end != '\0') || (end == str)) {
-        return -EINVAL;
-    }
-
-    return 0;
-}
-
-static int print_hex64(Object *obj, Property *prop, char *dest, size_t len)
-{
-    uint64_t *ptr = object_get_prop_ptr(obj, prop);
-    return snprintf(dest, len, "0x%" PRIx64, *ptr);
-}
-
-PropertyInfo qdev_prop_hex64 = {
-    .name  = "uint64",
-    .legacy_name  = "hex64",
-    .parse = parse_hex64,
-    .print = print_hex64,
-    .get   = get_uint64,
-    .set   = set_uint64,
-};
-
-/* --- string --- */
-
-static void release_string(Object *obj, const char *name, void *opaque)
-{
-    Property *prop = opaque;
-    g_free(*(char **)object_get_prop_ptr(obj, prop));
-}
-
-static int print_string(Object *obj, Property *prop, char *dest, size_t len)
-{
-    char **ptr = object_get_prop_ptr(obj, prop);
-    if (!*ptr)
-        return snprintf(dest, len, "<null>");
-    return snprintf(dest, len, "\"%s\"", *ptr);
-}
-
-static void get_string(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    char **ptr = object_get_prop_ptr(obj, 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(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
+void error_set_from_prop_error(Error **errp, int ret, Object *obj,
+                               Property *prop, const char *value)
 {
-    Property *prop = opaque;
-    char **ptr = object_get_prop_ptr(obj, prop);
-    Error *local_err = NULL;
-    char *str;
-
-    if (object_is_realized(obj)) {
-        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 (*ptr) {
-        g_free(*ptr);
+    switch (ret) {
+    case -EEXIST:
+        error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
+                  object_get_typename(obj), prop->name, value);
+        break;
+    default:
+    case -EINVAL:
+        error_set(errp, QERR_PROPERTY_VALUE_BAD,
+                  object_get_typename(obj), prop->name, value);
+        break;
+    case -ENOENT:
+        error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
+                  object_get_typename(obj), prop->name, value);
+        break;
+    case 0:
+        break;
     }
-    *ptr = str;
 }
-
-PropertyInfo qdev_prop_string = {
-    .name  = "string",
-    .print = print_string,
-    .release = release_string,
-    .get   = get_string,
-    .set   = set_string,
-};
-
 /* --- drive --- */
 
 static int parse_drive(Object *obj, const char *str, void **ptr)
@@ -636,13 +271,6 @@ PropertyInfo qdev_prop_vlan = {
     .set   = set_vlan,
 };
 
-/* --- pointer --- */
-
-/* Not a proper property, just for dirty hacks.  TODO Remove it!  */
-PropertyInfo qdev_prop_ptr = {
-    .name  = "ptr",
-};
-
 /* --- mac address --- */
 
 /*
@@ -713,6 +341,12 @@ PropertyInfo qdev_prop_macaddr = {
     .set   = set_mac,
 };
 
+/* --- pointer --- */
+
+/* Not a proper property, just for dirty hacks.  TODO Remove it!  */
+PropertyInfo qdev_prop_ptr = {
+    .name  = "ptr",
+};
 
 /* --- lost tick policy --- */
 
@@ -726,40 +360,24 @@ static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
 
 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
 
-static void get_enum(Object *obj, Visitor *v, void *opaque,
-                     const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    int *ptr = object_get_prop_ptr(obj, prop);
-
-    visit_type_enum(v, ptr, prop->info->enum_table,
-                    prop->info->name, prop->name, errp);
-}
-
-static void set_enum(Object *obj, Visitor *v, void *opaque,
-                     const char *name, Error **errp)
-{
-    Property *prop = opaque;
-    int *ptr = object_get_prop_ptr(obj, prop);
-
-    if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_enum(v, ptr, prop->info->enum_table,
-                    prop->info->name, prop->name, errp);
-}
-
 PropertyInfo qdev_prop_losttickpolicy = {
     .name  = "LostTickPolicy",
     .enum_table  = lost_tick_policy_table,
-    .get   = get_enum,
-    .set   = set_enum,
+    .get   = property_get_enum,
+    .set   = property_set_enum,
 };
 
 /* --- pci address --- */
 
+static void get_pci_devfn(Object *obj, Visitor *v, void *opaque,
+                          const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    int32_t *ptr = object_get_prop_ptr(obj, prop);
+
+    visit_type_int32(v, ptr, name, errp);
+}
+
 /*
  * bus-local address, i.e. "$slot" or "$slot.$fn"
  */
@@ -826,12 +444,21 @@ PropertyInfo qdev_prop_pci_devfn = {
     .name  = "int32",
     .legacy_name  = "pci-devfn",
     .print = print_pci_devfn,
-    .get   = get_int32,
+    .get   = get_pci_devfn,
     .set   = set_pci_devfn,
 };
 
 /* --- blocksize --- */
 
+static void get_blocksize(Object *obj, Visitor *v, void *opaque,
+                          const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    uint16_t *ptr = object_get_prop_ptr(obj, prop);
+
+    visit_type_uint16(v, ptr, name, errp);
+}
+
 static void set_blocksize(Object *obj, Visitor *v, void *opaque,
                           const char *name, Error **errp)
 {
@@ -869,7 +496,7 @@ static void set_blocksize(Object *obj, Visitor *v, void *opaque,
 
 PropertyInfo qdev_prop_blocksize = {
     .name  = "blocksize",
-    .get   = get_uint16,
+    .get   = get_blocksize,
     .set   = set_blocksize,
 };
 
@@ -905,28 +532,6 @@ static Property *qdev_prop_find(Object *obj, const char *name)
     return NULL;
 }
 
-void error_set_from_prop_error(Error **errp, int ret, Object *obj,
-                               Property *prop, const char *value)
-{
-    switch (ret) {
-    case -EEXIST:
-        error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
-                  object_get_typename(obj), prop->name, value);
-        break;
-    default:
-    case -EINVAL:
-        error_set(errp, QERR_PROPERTY_VALUE_BAD,
-                  object_get_typename(obj), prop->name, value);
-        break;
-    case -ENOENT:
-        error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
-                  object_get_typename(obj), prop->name, value);
-        break;
-    case 0:
-        break;
-    }
-}
-
 int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
 {
     char *legacy_name;
diff --git a/hw/qdev.c b/hw/qdev.c
index a82fec8..9aaa60b 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -615,51 +615,6 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
     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)
-{
-    Error *local_err = NULL;
-    Object *obj = OBJECT(dev);
-
-    /*
-     * TODO qdev_prop_ptr does not have getters or setters.  It must
-     * go now that it can be replaced with links.  The test should be
-     * removed along with it: all static properties are read/write.
-     */
-    if (!prop->info->get && !prop->info->set) {
-        return;
-    }
-
-    object_property_add(obj, prop->name, prop->info->name,
-                        prop->info->get, prop->info->set,
-                        prop->info->release,
-                        prop, &local_err);
-
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-    if (prop->qtype == QTYPE_NONE) {
-        return;
-    }
-
-    if (prop->qtype == QTYPE_QBOOL) {
-        object_property_set_bool(obj, prop->defval, prop->name, &local_err);
-    } else if (prop->info->enum_table) {
-        object_property_set_str(obj, prop->info->enum_table[prop->defval],
-                                prop->name, &local_err);
-    } else if (prop->qtype == QTYPE_QINT) {
-        object_property_set_int(obj, prop->defval, prop->name, &local_err);
-    }
-    assert_no_error(local_err);
-}
-
 static void device_initfn(Object *obj)
 {
     DeviceState *dev = DEVICE(obj);
@@ -677,7 +632,7 @@ static void device_initfn(Object *obj)
     do {
         for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
             qdev_property_add_legacy(dev, prop, NULL);
-            qdev_property_add_static(dev, prop, NULL);
+            object_property_add_static(OBJECT(dev), prop, NULL);
         }
         class = object_class_get_parent(class);
     } while (class != object_class_by_name(TYPE_DEVICE));
diff --git a/hw/qdev.h b/hw/qdev.h
index bfa8620..c810d43 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -9,10 +9,6 @@
 #include "qemu/object.h"
 #include "error.h"
 
-typedef struct Property Property;
-
-typedef struct PropertyInfo PropertyInfo;
-
 typedef struct CompatProperty CompatProperty;
 
 typedef struct BusState BusState;
@@ -117,26 +113,6 @@ struct BusState {
     QLIST_ENTRY(BusState) sibling;
 };
 
-struct Property {
-    const char   *name;
-    PropertyInfo *info;
-    int          offset;
-    uint8_t      bitnr;
-    uint8_t      qtype;
-    int64_t      defval;
-};
-
-struct PropertyInfo {
-    const char *name;
-    const char *legacy_name;
-    const char **enum_table;
-    int (*parse)(Object *obj, Property *prop, const char *str);
-    int (*print)(Object *obj, Property *prop, char *dest, size_t len);
-    ObjectPropertyAccessor *get;
-    ObjectPropertyAccessor *set;
-    ObjectPropertyRelease *release;
-};
-
 typedef struct GlobalProperty {
     const char *driver;
     const char *property;
@@ -212,16 +188,6 @@ int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
 
 /*** qdev-properties.c ***/
 
-extern PropertyInfo qdev_prop_bit;
-extern PropertyInfo qdev_prop_uint8;
-extern PropertyInfo qdev_prop_uint16;
-extern PropertyInfo qdev_prop_uint32;
-extern PropertyInfo qdev_prop_int32;
-extern PropertyInfo qdev_prop_uint64;
-extern PropertyInfo qdev_prop_hex8;
-extern PropertyInfo qdev_prop_hex32;
-extern PropertyInfo qdev_prop_hex64;
-extern PropertyInfo qdev_prop_string;
 extern PropertyInfo qdev_prop_chr;
 extern PropertyInfo qdev_prop_ptr;
 extern PropertyInfo qdev_prop_macaddr;
@@ -232,55 +198,12 @@ extern PropertyInfo qdev_prop_vlan;
 extern PropertyInfo qdev_prop_pci_devfn;
 extern PropertyInfo qdev_prop_blocksize;
 
-#define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
-        .name      = (_name),                                    \
-        .info      = &(_prop),                                   \
-        .offset    = offsetof(_state, _field)                    \
-            + type_check(_type,typeof_field(_state, _field)),    \
-        }
-#define DEFINE_PROP_DEFAULT(_name, _state, _field, _defval, _prop, _type) { \
-        .name      = (_name),                                           \
-        .info      = &(_prop),                                          \
-        .offset    = offsetof(_state, _field)                           \
-            + type_check(_type,typeof_field(_state, _field)),           \
-        .qtype     = QTYPE_QINT,                                        \
-        .defval    = (_type)_defval,                                    \
-        }
-#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
-        .name      = (_name),                                    \
-        .info      = &(qdev_prop_bit),                           \
-        .bitnr    = (_bit),                                      \
-        .offset    = offsetof(_state, _field)                    \
-            + type_check(uint32_t,typeof_field(_state, _field)), \
-        .qtype     = QTYPE_QBOOL,                                \
-        .defval    = (bool)_defval,                              \
-        }
-
-#define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
-#define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
-#define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
-#define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_int32, int32_t)
-#define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
-#define DEFINE_PROP_HEX8(_n, _s, _f, _d)                       \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex8, uint8_t)
-#define DEFINE_PROP_HEX32(_n, _s, _f, _d)                       \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex32, uint32_t)
-#define DEFINE_PROP_HEX64(_n, _s, _f, _d)                       \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex64, uint64_t)
 #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d)                   \
     DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
-
 #define DEFINE_PROP_PTR(_n, _s, _f)             \
     DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*)
 #define DEFINE_PROP_CHR(_n, _s, _f)             \
     DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharDriverState*)
-#define DEFINE_PROP_STRING(_n, _s, _f)             \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
 #define DEFINE_PROP_NETDEV(_n, _s, _f)             \
     DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, VLANClientState*)
 #define DEFINE_PROP_VLAN(_n, _s, _f)             \
@@ -295,11 +218,7 @@ extern PropertyInfo qdev_prop_blocksize;
 #define DEFINE_PROP_BLOCKSIZE(_n, _s, _f, _d) \
     DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t)
 
-#define DEFINE_PROP_END_OF_LIST()               \
-    {}
-
 /* Set properties between creation and init.  */
-void *object_get_prop_ptr(Object *obj, Property *prop);
 int qdev_prop_parse(DeviceState *dev, const char *name, const char *value);
 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value);
 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value);
@@ -326,12 +245,6 @@ void error_set_from_prop_error(Error **errp, int ret, Object *obj,
 char *qdev_get_fw_dev_path(DeviceState *dev);
 
 /**
- * @qdev_property_add_static - add a @Property to a device referencing a
- * field in a struct.
- */
-void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp);
-
-/**
  * @qdev_machine_init
  *
  * Initialize platform devices before machine init.  This is a hack until full
diff --git a/include/qemu/object.h b/include/qemu/object.h
index 274c839..048ac86 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -989,5 +989,103 @@ int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
  */
 Object *container_get(Object *root, const char *path);
 
+typedef struct Property Property;
+typedef struct PropertyInfo PropertyInfo;
+
+struct Property {
+    const char   *name;
+    PropertyInfo *info;
+    int          offset;
+    uint8_t      bitnr;
+    uint8_t      qtype;
+    int64_t      defval;
+};
+
+struct PropertyInfo {
+    const char *name;
+    const char *legacy_name;
+    const char **enum_table;
+    int (*parse)(Object *obj, Property *prop, const char *str);
+    int (*print)(Object *obj, Property *prop, char *dest, size_t len);
+    ObjectPropertyAccessor *get;
+    ObjectPropertyAccessor *set;
+    ObjectPropertyRelease *release;
+};
+
+extern PropertyInfo qdev_prop_bit;
+extern PropertyInfo qdev_prop_uint8;
+extern PropertyInfo qdev_prop_uint16;
+extern PropertyInfo qdev_prop_uint32;
+extern PropertyInfo qdev_prop_int32;
+extern PropertyInfo qdev_prop_uint64;
+extern PropertyInfo qdev_prop_hex8;
+extern PropertyInfo qdev_prop_hex32;
+extern PropertyInfo qdev_prop_hex64;
+extern PropertyInfo qdev_prop_string;
+
+#define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
+        .name      = (_name),                                    \
+        .info      = &(_prop),                                   \
+        .offset    = offsetof(_state, _field)                    \
+            + type_check(_type,typeof_field(_state, _field)),    \
+        }
+#define DEFINE_PROP_DEFAULT(_name, _state, _field, _defval, _prop, _type) { \
+        .name      = (_name),                                           \
+        .info      = &(_prop),                                          \
+        .offset    = offsetof(_state, _field)                           \
+            + type_check(_type,typeof_field(_state, _field)),           \
+        .qtype     = QTYPE_QINT,                                        \
+        .defval    = (_type)_defval,                                    \
+        }
+#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
+        .name      = (_name),                                    \
+        .info      = &(qdev_prop_bit),                           \
+        .bitnr    = (_bit),                                      \
+        .offset    = offsetof(_state, _field)                    \
+            + type_check(uint32_t,typeof_field(_state, _field)), \
+        .qtype     = QTYPE_QBOOL,                                \
+        .defval    = (bool)_defval,                              \
+        }
+
+#define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
+#define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
+#define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
+#define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_int32, int32_t)
+#define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
+#define DEFINE_PROP_HEX8(_n, _s, _f, _d)                       \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex8, uint8_t)
+#define DEFINE_PROP_HEX32(_n, _s, _f, _d)                       \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex32, uint32_t)
+#define DEFINE_PROP_HEX64(_n, _s, _f, _d)                       \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex64, uint64_t)
+#define DEFINE_PROP_STRING(_n, _s, _f)             \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
+
+#define DEFINE_PROP_END_OF_LIST()               \
+    {}
+
+void property_get_enum(Object *obj, struct Visitor *v, void *opaque,
+                       const char *name, struct Error **errp);
+void property_set_enum(Object *obj, struct Visitor *v, void *opaque,
+                       const char *name, struct Error **errp);
+
+void *object_get_prop_ptr(Object *obj, Property *prop);
+
+/**
+ * object_property_add_static:
+ * @obj: the object to add the property to
+ * @prop: the property to be added
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add a #Property to an object referencing a field in a struct.
+ */
+void object_property_add_static(Object *obj, Property *prop,
+                                struct Error **errp);
+
 
 #endif
diff --git a/qom/Makefile.objs b/qom/Makefile.objs
index 5ef060a..bacddf6 100644
--- a/qom/Makefile.objs
+++ b/qom/Makefile.objs
@@ -1,4 +1,4 @@
-qom-obj-y = object.o container.o qom-qobject.o
+qom-obj-y = object.o object-properties.o container.o qom-qobject.o
 qom-obj-twice-y = cpu.o
 common-obj-y = $(qom-obj-twice-y)
 user-obj-y = $(qom-obj-twice-y)
diff --git a/qom/object-properties.c b/qom/object-properties.c
new file mode 100644
index 0000000..6765e90
--- /dev/null
+++ b/qom/object-properties.c
@@ -0,0 +1,461 @@
+#include "qemu/object.h"
+#include "qapi/qapi-visit-core.h"
+
+void *object_get_prop_ptr(Object *obj, Property *prop)
+{
+    void *ptr = obj;
+    ptr += prop->offset;
+    return ptr;
+}
+
+static uint32_t get_prop_mask(Property *prop)
+{
+    assert(prop->info == &qdev_prop_bit);
+    return 0x1 << prop->bitnr;
+}
+
+static void bit_prop_set(Object *obj, Property *props, bool val)
+{
+    uint32_t *p = object_get_prop_ptr(obj, props);
+    uint32_t mask = get_prop_mask(props);
+    if (val)
+        *p |= mask;
+    else
+        *p &= ~mask;
+}
+
+/* Bit */
+
+static int print_bit(Object *obj, Property *prop, char *dest, size_t len)
+{
+    uint32_t *p = object_get_prop_ptr(obj, prop);
+    return snprintf(dest, len, (*p & get_prop_mask(prop)) ? "on" : "off");
+}
+
+static void get_bit(Object *obj, Visitor *v, void *opaque,
+                    const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    uint32_t *p = object_get_prop_ptr(obj, prop);
+    bool value = (*p & get_prop_mask(prop)) != 0;
+
+    visit_type_bool(v, &value, name, errp);
+}
+
+static void set_bit(Object *obj, Visitor *v, void *opaque,
+                    const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    Error *local_err = NULL;
+    bool value;
+
+    if (object_is_realized(obj)) {
+        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(obj, prop, value);
+}
+
+PropertyInfo qdev_prop_bit = {
+    .name  = "boolean",
+    .legacy_name  = "on/off",
+    .print = print_bit,
+    .get   = get_bit,
+    .set   = set_bit,
+};
+
+/* --- 8bit integer --- */
+
+static void get_uint8(Object *obj, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    uint8_t *ptr = object_get_prop_ptr(obj, prop);
+
+    visit_type_uint8(v, ptr, name, errp);
+}
+
+static void set_uint8(Object *obj, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    uint8_t *ptr = object_get_prop_ptr(obj, prop);
+
+    if (object_is_realized(obj)) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_uint8(v, ptr, name, errp);
+}
+
+PropertyInfo qdev_prop_uint8 = {
+    .name  = "uint8",
+    .get   = get_uint8,
+    .set   = set_uint8,
+};
+
+/* --- 8bit hex value --- */
+
+static int parse_hex8(Object *obj, Property *prop, const char *str)
+{
+    uint8_t *ptr = object_get_prop_ptr(obj, prop);
+    char *end;
+
+    if (str[0] != '0' || str[1] != 'x') {
+        return -EINVAL;
+    }
+
+    *ptr = strtoul(str, &end, 16);
+    if ((*end != '\0') || (end == str)) {
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+static int print_hex8(Object *obj, Property *prop, char *dest, size_t len)
+{
+    uint8_t *ptr = object_get_prop_ptr(obj, prop);
+    return snprintf(dest, len, "0x%" PRIx8, *ptr);
+}
+
+PropertyInfo qdev_prop_hex8 = {
+    .name  = "uint8",
+    .legacy_name  = "hex8",
+    .parse = parse_hex8,
+    .print = print_hex8,
+    .get   = get_uint8,
+    .set   = set_uint8,
+};
+
+/* --- 16bit integer --- */
+
+static void get_uint16(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    uint16_t *ptr = object_get_prop_ptr(obj, prop);
+
+    visit_type_uint16(v, ptr, name, errp);
+}
+
+static void set_uint16(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    uint16_t *ptr = object_get_prop_ptr(obj, prop);
+
+    if (object_is_realized(obj)) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_uint16(v, ptr, name, errp);
+}
+
+PropertyInfo qdev_prop_uint16 = {
+    .name  = "uint16",
+    .get   = get_uint16,
+    .set   = set_uint16,
+};
+
+/* --- 32bit integer --- */
+
+static void get_uint32(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    uint32_t *ptr = object_get_prop_ptr(obj, prop);
+
+    visit_type_uint32(v, ptr, name, errp);
+}
+
+static void set_uint32(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    uint32_t *ptr = object_get_prop_ptr(obj, prop);
+
+    if (object_is_realized(obj)) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_uint32(v, ptr, name, errp);
+}
+
+static void get_int32(Object *obj, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    int32_t *ptr = object_get_prop_ptr(obj, prop);
+
+    visit_type_int32(v, ptr, name, errp);
+}
+
+static void set_int32(Object *obj, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    int32_t *ptr = object_get_prop_ptr(obj, prop);
+
+    if (object_is_realized(obj)) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_int32(v, ptr, name, errp);
+}
+
+PropertyInfo qdev_prop_uint32 = {
+    .name  = "uint32",
+    .get   = get_uint32,
+    .set   = set_uint32,
+};
+
+PropertyInfo qdev_prop_int32 = {
+    .name  = "int32",
+    .get   = get_int32,
+    .set   = set_int32,
+};
+
+/* --- 32bit hex value --- */
+
+static int parse_hex32(Object *obj, Property *prop, const char *str)
+{
+    uint32_t *ptr = object_get_prop_ptr(obj, prop);
+    char *end;
+
+    if (str[0] != '0' || str[1] != 'x') {
+        return -EINVAL;
+    }
+
+    *ptr = strtoul(str, &end, 16);
+    if ((*end != '\0') || (end == str)) {
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+static int print_hex32(Object *obj, Property *prop, char *dest, size_t len)
+{
+    uint32_t *ptr = object_get_prop_ptr(obj, prop);
+    return snprintf(dest, len, "0x%" PRIx32, *ptr);
+}
+
+PropertyInfo qdev_prop_hex32 = {
+    .name  = "uint32",
+    .legacy_name  = "hex32",
+    .parse = parse_hex32,
+    .print = print_hex32,
+    .get   = get_uint32,
+    .set   = set_uint32,
+};
+
+/* --- 64bit integer --- */
+
+static void get_uint64(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    uint64_t *ptr = object_get_prop_ptr(obj, prop);
+
+    visit_type_uint64(v, ptr, name, errp);
+}
+
+static void set_uint64(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    uint64_t *ptr = object_get_prop_ptr(obj, prop);
+
+    if (object_is_realized(obj)) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_uint64(v, ptr, name, errp);
+}
+
+PropertyInfo qdev_prop_uint64 = {
+    .name  = "uint64",
+    .get   = get_uint64,
+    .set   = set_uint64,
+};
+
+/* --- 64bit hex value --- */
+
+static int parse_hex64(Object *obj, Property *prop, const char *str)
+{
+    uint64_t *ptr = object_get_prop_ptr(obj, prop);
+    char *end;
+
+    if (str[0] != '0' || str[1] != 'x') {
+        return -EINVAL;
+    }
+
+    *ptr = strtoull(str, &end, 16);
+    if ((*end != '\0') || (end == str)) {
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+static int print_hex64(Object *obj, Property *prop, char *dest, size_t len)
+{
+    uint64_t *ptr = object_get_prop_ptr(obj, prop);
+    return snprintf(dest, len, "0x%" PRIx64, *ptr);
+}
+
+PropertyInfo qdev_prop_hex64 = {
+    .name  = "uint64",
+    .legacy_name  = "hex64",
+    .parse = parse_hex64,
+    .print = print_hex64,
+    .get   = get_uint64,
+    .set   = set_uint64,
+};
+
+/* --- string --- */
+
+static void release_string(Object *obj, const char *name, void *opaque)
+{
+    Property *prop = opaque;
+    g_free(*(char **)object_get_prop_ptr(obj, prop));
+}
+
+static int print_string(Object *obj, Property *prop, char *dest, size_t len)
+{
+    char **ptr = object_get_prop_ptr(obj, prop);
+    if (!*ptr)
+        return snprintf(dest, len, "<null>");
+    return snprintf(dest, len, "\"%s\"", *ptr);
+}
+
+static void get_string(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    char **ptr = object_get_prop_ptr(obj, 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(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    char **ptr = object_get_prop_ptr(obj, prop);
+    Error *local_err = NULL;
+    char *str;
+
+    if (object_is_realized(obj)) {
+        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 (*ptr) {
+        g_free(*ptr);
+    }
+    *ptr = str;
+}
+
+PropertyInfo qdev_prop_string = {
+    .name  = "string",
+    .print = print_string,
+    .release = release_string,
+    .get   = get_string,
+    .set   = set_string,
+};
+
+
+/* --- enums --- */
+
+void property_get_enum(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    int *ptr = object_get_prop_ptr(obj, prop);
+
+    visit_type_enum(v, ptr, prop->info->enum_table,
+                    prop->info->name, prop->name, errp);
+}
+
+void property_set_enum(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    Property *prop = opaque;
+    int *ptr = object_get_prop_ptr(obj, prop);
+
+    if (object_is_realized(obj)) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_enum(v, ptr, prop->info->enum_table,
+                    prop->info->name, prop->name, errp);
+}
+
+
+/**
+ * @object_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 object_property_add_static(Object *obj, Property *prop,
+                                Error **errp)
+{
+    Error *local_err = NULL;
+
+    /*
+     * TODO qdev_prop_ptr does not have getters or setters.  It must
+     * go now that it can be replaced with links.  The test should be
+     * removed along with it: all static properties are read/write.
+     */
+    if (!prop->info->get && !prop->info->set) {
+        return;
+    }
+
+    object_property_add(obj, prop->name, prop->info->name,
+                        prop->info->get, prop->info->set,
+                        prop->info->release,
+                        prop, &local_err);
+
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (prop->qtype == QTYPE_NONE) {
+        return;
+    }
+
+    if (prop->qtype == QTYPE_QBOOL) {
+        object_property_set_bool(obj, prop->defval, prop->name, &local_err);
+    } else if (prop->info->enum_table) {
+        object_property_set_str(obj, prop->info->enum_table[prop->defval],
+                                prop->name, &local_err);
+    } else if (prop->qtype == QTYPE_QINT) {
+        object_property_set_int(obj, prop->defval, prop->name, &local_err);
+    }
+    assert_no_error(local_err);
+}
-- 
1.7.7

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

* [Qemu-devel] [PATCH qom-next v2 6/7] qom: Push static properties to Object
  2012-06-10  1:09 [Qemu-devel] [PATCH qom-next v2 0/7] QOM realize, revised again Andreas Färber
                   ` (4 preceding siblings ...)
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 5/7] qdev: Move bulk of qdev-properties.c to qom/object-properties.c Andreas Färber
@ 2012-06-10  1:09 ` Andreas Färber
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 7/7] qom: Add QERR_PROPERTY_SET_AFTER_REALIZE Andreas Färber
  6 siblings, 0 replies; 9+ messages in thread
From: Andreas Färber @ 2012-06-10  1:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Gerd Hoffmann, Igor Mitsyanko,
	Mark Langsdorf, Evgeny Voevodin, Michael S. Tsirkin, Paul Brook,
	Alexander Graf, Anthony Liguori, Peter Crosthwaite, Blue Swirl,
	Jan Kiszka, Aneesh Kumar K.V, Anthony Liguori, Amit Shah,
	Paolo Bonzini, Maksim Kozlov, Andreas Färber,
	Dmitry Solodkiy

From: Paolo Bonzini <pbonzini@redhat.com>

This patch is made much larger by the need to touch all assignments
of props.  The interesting changes are in hw/qdev-monitor.c,
hw/qdev-properties.c, hw/qdev.c, hw/qdev.h, include/qemu/object.h,
qom/object.c.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[AF: Convert arm_gic_properties as well]
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 hw/9pfs/virtio-9p-device.c    |    2 +-
 hw/a15mpcore.c                |    3 +--
 hw/a9mpcore.c                 |    2 +-
 hw/ac97.c                     |    2 +-
 hw/acpi_piix4.c               |    2 +-
 hw/apic_common.c              |    2 +-
 hw/applesmc.c                 |    2 +-
 hw/arm11mpcore.c              |    6 ++----
 hw/arm_gic.c                  |    2 +-
 hw/arm_l2x0.c                 |    2 +-
 hw/arm_mptimer.c              |    2 +-
 hw/arm_sysctl.c               |    2 +-
 hw/arm_timer.c                |    3 +--
 hw/armv7m.c                   |    3 +--
 hw/armv7m_nvic.c              |    2 +-
 hw/cadence_gem.c              |    2 +-
 hw/ccid-card-emulated.c       |    2 +-
 hw/ccid-card-passthru.c       |    2 +-
 hw/cs4231.c                   |    2 +-
 hw/cs4231a.c                  |    2 +-
 hw/debugcon.c                 |    3 +--
 hw/ds1225y.c                  |    2 +-
 hw/e1000.c                    |    2 +-
 hw/eccmemctl.c                |    2 +-
 hw/eepro100.c                 |    2 +-
 hw/escc.c                     |    2 +-
 hw/esp.c                      |    2 +-
 hw/etraxfs_eth.c              |    3 +--
 hw/etraxfs_pic.c              |    3 +--
 hw/exynos4210_combiner.c      |    2 +-
 hw/exynos4210_gic.c           |    3 +--
 hw/exynos4210_uart.c          |    2 +-
 hw/fdc.c                      |    6 +++---
 hw/fw_cfg.c                   |    2 +-
 hw/g364fb.c                   |    2 +-
 hw/grlib_apbuart.c            |    3 +--
 hw/grlib_gptimer.c            |    2 +-
 hw/grlib_irqmp.c              |    2 +-
 hw/gus.c                      |    2 +-
 hw/hda-audio.c                |    6 +++---
 hw/hpet.c                     |    2 +-
 hw/i2c.c                      |    2 +-
 hw/i82374.c                   |    2 +-
 hw/i82378.c                   |    2 +-
 hw/i8254.c                    |    2 +-
 hw/i8259_common.c             |    2 +-
 hw/ide/ahci.c                 |    2 +-
 hw/ide/cmd646.c               |    3 +--
 hw/ide/isa.c                  |    2 +-
 hw/ide/qdev.c                 |    8 ++++----
 hw/integratorcp.c             |    3 +--
 hw/intel-hda.c                |    4 ++--
 hw/ioh3420.c                  |    2 +-
 hw/ivshmem.c                  |    2 +-
 hw/kvm/i8254.c                |    2 +-
 hw/kvm/ioapic.c               |    2 +-
 hw/lan9118.c                  |    2 +-
 hw/lance.c                    |    2 +-
 hw/lm32_sys.c                 |    2 +-
 hw/lm32_timer.c               |    2 +-
 hw/m48t59.c                   |    4 ++--
 hw/marvell_88w8618_audio.c    |    2 +-
 hw/mc146818rtc.c              |    2 +-
 hw/milkymist-minimac2.c       |    2 +-
 hw/milkymist-softusb.c        |    2 +-
 hw/milkymist-sysctl.c         |    2 +-
 hw/milkymist-vgafb.c          |    2 +-
 hw/mipsnet.c                  |    2 +-
 hw/musicpal.c                 |    2 +-
 hw/nand.c                     |    2 +-
 hw/ne2000-isa.c               |    3 +--
 hw/ne2000.c                   |    2 +-
 hw/omap_gpio.c                |    4 ++--
 hw/omap_i2c.c                 |    2 +-
 hw/omap_intc.c                |    4 ++--
 hw/onenand.c                  |    2 +-
 hw/opencores_eth.c            |    2 +-
 hw/parallel.c                 |    3 +--
 hw/pc_sysfw.c                 |    2 +-
 hw/pci.c                      |    2 +-
 hw/pci_bridge_dev.c           |    2 +-
 hw/pcnet-pci.c                |    2 +-
 hw/pcspk.c                    |    2 +-
 hw/pl041.c                    |    2 +-
 hw/pxa2xx.c                   |    2 +-
 hw/pxa2xx_dma.c               |    2 +-
 hw/pxa2xx_gpio.c              |    2 +-
 hw/pxa2xx_timer.c             |    4 ++--
 hw/qdev-monitor.c             |    4 ++--
 hw/qdev-properties.c          |    2 +-
 hw/qdev.c                     |   14 +-------------
 hw/qdev.h                     |    1 -
 hw/qxl.c                      |    4 ++--
 hw/rtl8139.c                  |    2 +-
 hw/s390-virtio-bus.c          |   12 ++++--------
 hw/sb16.c                     |    2 +-
 hw/scsi-bus.c                 |    2 +-
 hw/scsi-disk.c                |    8 ++++----
 hw/scsi-generic.c             |    2 +-
 hw/serial.c                   |    2 +-
 hw/slavio_timer.c             |    2 +-
 hw/smbus_eeprom.c             |    3 +--
 hw/smc91c111.c                |    2 +-
 hw/spapr_llan.c               |    3 +--
 hw/spapr_pci.c                |    3 +--
 hw/spapr_vio.c                |    2 +-
 hw/spapr_vscsi.c              |    3 +--
 hw/spapr_vty.c                |    3 +--
 hw/sparc32_dma.c              |    2 +-
 hw/spitz.c                    |    4 ++--
 hw/stellaris_enet.c           |    3 +--
 hw/strongarm.c                |    2 +-
 hw/sun4m.c                    |    6 ++----
 hw/sun4m_iommu.c              |    2 +-
 hw/sun4u.c                    |    6 ++----
 hw/tcx.c                      |    2 +-
 hw/usb/bus.c                  |    2 +-
 hw/usb/dev-audio.c            |    2 +-
 hw/usb/dev-network.c          |    2 +-
 hw/usb/dev-serial.c           |    4 ++--
 hw/usb/dev-smartcard-reader.c |    4 ++--
 hw/usb/dev-storage.c          |    2 +-
 hw/usb/hcd-ehci.c             |    4 ++--
 hw/usb/hcd-ohci.c             |    4 ++--
 hw/usb/hcd-uhci.c             |   12 ++++++------
 hw/usb/hcd-xhci.c             |    2 +-
 hw/usb/host-linux.c           |    2 +-
 hw/usb/redirect.c             |    2 +-
 hw/virtio-console.c           |    6 ++----
 hw/virtio-pci.c               |   10 +++++-----
 hw/virtio-serial-bus.c        |    2 +-
 hw/vmmouse.c                  |    2 +-
 hw/vt82c686.c                 |    2 +-
 hw/xgmac.c                    |    2 +-
 hw/xilinx_axidma.c            |    3 +--
 hw/xilinx_axienet.c           |    3 +--
 hw/xilinx_ethlite.c           |    3 +--
 hw/xilinx_intc.c              |    3 +--
 hw/xilinx_timer.c             |    3 +--
 hw/xio3130_downstream.c       |    2 +-
 hw/xio3130_upstream.c         |    2 +-
 hw/zaurus.c                   |    2 +-
 include/qemu/object.h         |    7 ++++---
 qom/object.c                  |   20 ++++++++++++++++++++
 144 files changed, 203 insertions(+), 230 deletions(-)

diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index b8220ab..83e1495 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -173,7 +173,7 @@ static void virtio_9p_class_init(ObjectClass *klass, void *data)
     k->device_id = 0x1009;
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = 0x2;
-    dc->props = virtio_9p_properties;
+    klass->props = virtio_9p_properties;
     dc->reset = virtio_pci_reset;
 }
 
diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
index 5a7b365..a330166 100644
--- a/hw/a15mpcore.c
+++ b/hw/a15mpcore.c
@@ -85,10 +85,9 @@ static Property a15mp_priv_properties[] = {
 
 static void a15mp_priv_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
     k->init = a15mp_priv_init;
-    dc->props = a15mp_priv_properties;
+    klass->props = a15mp_priv_properties;
     /* We currently have no savable state */
 }
 
diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index c2ff74d..ee35483 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -222,7 +222,7 @@ static void a9mp_priv_class_init(ObjectClass *klass, void *data)
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = a9mp_priv_init;
-    dc->props = a9mp_priv_properties;
+    klass->props = a9mp_priv_properties;
     dc->vmsd = &vmstate_a9mp_priv;
     dc->reset = a9mp_priv_reset;
 }
diff --git a/hw/ac97.c b/hw/ac97.c
index e791b9d..8842b22 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -1352,7 +1352,7 @@ static void ac97_class_init (ObjectClass *klass, void *data)
     k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
     dc->desc = "Intel 82801AA AC97 Audio";
     dc->vmsd = &vmstate_ac97;
-    dc->props = ac97_properties;
+    klass->props = ac97_properties;
 }
 
 static TypeInfo ac97_info = {
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index a11c8e7..0b1acfa 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -463,7 +463,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
     dc->desc = "PM";
     dc->no_user = 1;
     dc->vmsd = &vmstate_acpi;
-    dc->props = piix4_pm_properties;
+    klass->props = piix4_pm_properties;
 }
 
 static TypeInfo piix4_pm_info = {
diff --git a/hw/apic_common.c b/hw/apic_common.c
index 60b8259..9774cf6 100644
--- a/hw/apic_common.c
+++ b/hw/apic_common.c
@@ -370,7 +370,7 @@ static void apic_common_class_init(ObjectClass *klass, void *data)
     dc->vmsd = &vmstate_apic_common;
     dc->reset = apic_reset_common;
     dc->no_user = 1;
-    dc->props = apic_properties_common;
+    klass->props = apic_properties_common;
     sc->init = apic_init_common;
 }
 
diff --git a/hw/applesmc.c b/hw/applesmc.c
index 8bedaad..b8f1855 100644
--- a/hw/applesmc.c
+++ b/hw/applesmc.c
@@ -233,7 +233,7 @@ static void qdev_applesmc_class_init(ObjectClass *klass, void *data)
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = applesmc_isa_init;
     dc->reset = qdev_applesmc_isa_reset;
-    dc->props = applesmc_isa_properties;
+    klass->props = applesmc_isa_properties;
 }
 
 static TypeInfo applesmc_isa_info = {
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index c528d7a..8f47c8b 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -210,11 +210,10 @@ static Property mpcore_rirq_properties[] = {
 
 static void mpcore_rirq_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = realview_mpcore_init;
-    dc->props = mpcore_rirq_properties;
+    klass->props = mpcore_rirq_properties;
 }
 
 static TypeInfo mpcore_rirq_info = {
@@ -240,11 +239,10 @@ static Property mpcore_priv_properties[] = {
 
 static void mpcore_priv_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = mpcore_priv_init;
-    dc->props = mpcore_priv_properties;
+    klass->props = mpcore_priv_properties;
 }
 
 static TypeInfo mpcore_priv_info = {
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 72298b4..fbfd06e 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -945,7 +945,7 @@ static void arm_gic_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
     sbc->init = arm_gic_init;
-    dc->props = arm_gic_properties;
+    klass->props = arm_gic_properties;
     dc->reset = gic_reset;
     dc->no_user = 1;
 }
diff --git a/hw/arm_l2x0.c b/hw/arm_l2x0.c
index de6a086..c8e9460 100644
--- a/hw/arm_l2x0.c
+++ b/hw/arm_l2x0.c
@@ -173,7 +173,7 @@ static void l2x0_class_init(ObjectClass *klass, void *data)
     k->init = l2x0_priv_init;
     dc->vmsd = &vmstate_l2x0;
     dc->no_user = 1;
-    dc->props = l2x0_properties;
+    klass->props = l2x0_properties;
     dc->reset = l2x0_priv_reset;
 }
 
diff --git a/hw/arm_mptimer.c b/hw/arm_mptimer.c
index fe43cbb..4ffc491 100644
--- a/hw/arm_mptimer.c
+++ b/hw/arm_mptimer.c
@@ -326,7 +326,7 @@ static void arm_mptimer_class_init(ObjectClass *klass, void *data)
     dc->vmsd = &vmstate_arm_mptimer;
     dc->reset = arm_mptimer_reset;
     dc->no_user = 1;
-    dc->props = arm_mptimer_properties;
+    klass->props = arm_mptimer_properties;
 }
 
 static TypeInfo arm_mptimer_info = {
diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index 5f1237b..7aa449c 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -403,7 +403,7 @@ static void arm_sysctl_class_init(ObjectClass *klass, void *data)
     k->init = arm_sysctl_init;
     dc->reset = arm_sysctl_reset;
     dc->vmsd = &vmstate_arm_sysctl;
-    dc->props = arm_sysctl_properties;
+    klass->props = arm_sysctl_properties;
 }
 
 static TypeInfo arm_sysctl_info = {
diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index e3ecce2..d14166a 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -370,10 +370,9 @@ static Property sp804_properties[] = {
 static void sp804_class_init(ObjectClass *klass, void *data)
 {
     SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
-    DeviceClass *k = DEVICE_CLASS(klass);
 
     sdc->init = sp804_init;
-    k->props = sp804_properties;
+    klass->props = sp804_properties;
 }
 
 static TypeInfo sp804_info = {
diff --git a/hw/armv7m.c b/hw/armv7m.c
index 418139a..10908e1 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -257,11 +257,10 @@ static Property bitband_properties[] = {
 
 static void bitband_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = bitband_init;
-    dc->props = bitband_properties;
+    klass->props = bitband_properties;
 }
 
 static TypeInfo bitband_info = {
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 986a6bb..a375342 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -415,7 +415,7 @@ static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
     sdc->init = armv7m_nvic_init;
     dc->vmsd  = &vmstate_nvic;
     dc->reset = armv7m_nvic_reset;
-    dc->props = armv7m_nvic_properties;
+    klass->props = armv7m_nvic_properties;
 }
 
 static TypeInfo armv7m_nvic_info = {
diff --git a/hw/cadence_gem.c b/hw/cadence_gem.c
index e2140ae..a065168 100644
--- a/hw/cadence_gem.c
+++ b/hw/cadence_gem.c
@@ -1213,7 +1213,7 @@ static void gem_class_init(ObjectClass *klass, void *data)
     SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
 
     sdc->init = gem_init;
-    dc->props = gem_properties;
+    klass->props = gem_properties;
     dc->vmsd = &vmstate_cadence_gem;
     dc->reset = gem_reset;
 }
diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c
index f4a6da4..db27ec5 100644
--- a/hw/ccid-card-emulated.c
+++ b/hw/ccid-card-emulated.c
@@ -584,7 +584,7 @@ static void emulated_class_initfn(ObjectClass *klass, void *data)
     cc->get_atr = emulated_get_atr;
     cc->apdu_from_guest = emulated_apdu_from_guest;
     dc->desc = "emulated smartcard";
-    dc->props = emulated_card_properties;
+    klass->props = emulated_card_properties;
 }
 
 static TypeInfo emulated_card_info = {
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
index bd6c777..856ee19 100644
--- a/hw/ccid-card-passthru.c
+++ b/hw/ccid-card-passthru.c
@@ -333,7 +333,7 @@ static void passthru_class_initfn(ObjectClass *klass, void *data)
     cc->apdu_from_guest = passthru_apdu_from_guest;
     dc->desc = "passthrough smartcard";
     dc->vmsd = &passthru_vmstate;
-    dc->props = passthru_card_properties;
+    klass->props = passthru_card_properties;
 }
 
 static TypeInfo passthru_card_info = {
diff --git a/hw/cs4231.c b/hw/cs4231.c
index cfec1d9..06467cd 100644
--- a/hw/cs4231.c
+++ b/hw/cs4231.c
@@ -163,7 +163,7 @@ static void cs4231_class_init(ObjectClass *klass, void *data)
     k->init = cs4231_init1;
     dc->reset = cs_reset;
     dc->vmsd = &vmstate_cs4231;
-    dc->props = cs4231_properties;
+    klass->props = cs4231_properties;
 }
 
 static TypeInfo cs4231_info = {
diff --git a/hw/cs4231a.c b/hw/cs4231a.c
index e07b9d6..7e4d03c 100644
--- a/hw/cs4231a.c
+++ b/hw/cs4231a.c
@@ -679,7 +679,7 @@ static void cs4231a_class_initfn (ObjectClass *klass, void *data)
     ic->init = cs4231a_initfn;
     dc->desc = "Crystal Semiconductor CS4231A";
     dc->vmsd = &vmstate_cs4231a;
-    dc->props = cs4231a_properties;
+    klass->props = cs4231a_properties;
 }
 
 static TypeInfo cs4231a_info = {
diff --git a/hw/debugcon.c b/hw/debugcon.c
index 14ab326..4dffebd 100644
--- a/hw/debugcon.c
+++ b/hw/debugcon.c
@@ -96,10 +96,9 @@ static Property debugcon_isa_properties[] = {
 
 static void debugcon_isa_class_initfn(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = debugcon_isa_initfn;
-    dc->props = debugcon_isa_properties;
+    klass->props = debugcon_isa_properties;
 }
 
 static TypeInfo debugcon_isa_info = {
diff --git a/hw/ds1225y.c b/hw/ds1225y.c
index 2cd355b..d3d349c 100644
--- a/hw/ds1225y.c
+++ b/hw/ds1225y.c
@@ -147,7 +147,7 @@ static void nvram_sysbus_class_init(ObjectClass *klass, void *data)
 
     k->init = nvram_sysbus_initfn;
     dc->vmsd = &vmstate_nvram;
-    dc->props = nvram_sysbus_properties;
+    klass->props = nvram_sysbus_properties;
 }
 
 static TypeInfo nvram_sysbus_info = {
diff --git a/hw/e1000.c b/hw/e1000.c
index 4573f13..7cabd99 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1284,7 +1284,7 @@ static void e1000_class_init(ObjectClass *klass, void *data)
     dc->desc = "Intel Gigabit Ethernet";
     dc->reset = qdev_e1000_reset;
     dc->vmsd = &vmstate_e1000;
-    dc->props = e1000_properties;
+    klass->props = e1000_properties;
 }
 
 static TypeInfo e1000_info = {
diff --git a/hw/eccmemctl.c b/hw/eccmemctl.c
index fe1cd90..82e4a4d 100644
--- a/hw/eccmemctl.c
+++ b/hw/eccmemctl.c
@@ -321,7 +321,7 @@ static void ecc_class_init(ObjectClass *klass, void *data)
     k->init = ecc_init1;
     dc->reset = ecc_reset;
     dc->vmsd = &vmstate_ecc;
-    dc->props = ecc_properties;
+    klass->props = ecc_properties;
 }
 
 static TypeInfo ecc_info = {
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 6279ae3..ac42d85 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -2075,7 +2075,7 @@ static void eepro100_class_init(ObjectClass *klass, void *data)
 
     info = eepro100_get_class_by_name(object_class_get_name(klass));
 
-    dc->props = e100_properties;
+    klass->props = e100_properties;
     dc->desc = info->desc;
     k->vendor_id = PCI_VENDOR_ID_INTEL;
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
diff --git a/hw/escc.c b/hw/escc.c
index 4d8a8e8..16ef823 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -921,7 +921,7 @@ static void escc_class_init(ObjectClass *klass, void *data)
     k->init = escc_init1;
     dc->reset = escc_reset;
     dc->vmsd = &vmstate_escc;
-    dc->props = escc_properties;
+    klass->props = escc_properties;
 }
 
 static TypeInfo escc_info = {
diff --git a/hw/esp.c b/hw/esp.c
index 8d73e56..b20d6a3 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -766,7 +766,7 @@ static void esp_class_init(ObjectClass *klass, void *data)
     k->init = esp_init1;
     dc->reset = esp_hard_reset;
     dc->vmsd = &vmstate_esp;
-    dc->props = esp_properties;
+    klass->props = esp_properties;
 }
 
 static TypeInfo esp_info = {
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 16a0637..30ad08e 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -623,11 +623,10 @@ static Property etraxfs_eth_properties[] = {
 
 static void etraxfs_eth_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = fs_eth_init;
-    dc->props = etraxfs_eth_properties;
+    klass->props = etraxfs_eth_properties;
 }
 
 static TypeInfo etraxfs_eth_info = {
diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c
index dc27f88..ad8c537 100644
--- a/hw/etraxfs_pic.c
+++ b/hw/etraxfs_pic.c
@@ -158,11 +158,10 @@ static Property etraxfs_pic_properties[] = {
 
 static void etraxfs_pic_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = etraxfs_pic_init;
-    dc->props = etraxfs_pic_properties;
+    klass->props = etraxfs_pic_properties;
 }
 
 static TypeInfo etraxfs_pic_info = {
diff --git a/hw/exynos4210_combiner.c b/hw/exynos4210_combiner.c
index 80af22c..265f511 100644
--- a/hw/exynos4210_combiner.c
+++ b/hw/exynos4210_combiner.c
@@ -440,7 +440,7 @@ static void exynos4210_combiner_class_init(ObjectClass *klass, void *data)
 
     k->init = exynos4210_combiner_init;
     dc->reset = exynos4210_combiner_reset;
-    dc->props = exynos4210_combiner_properties;
+    klass->props = exynos4210_combiner_properties;
     dc->vmsd = &vmstate_exynos4210_combiner;
 }
 
diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
index e1b215e..b9e2167 100644
--- a/hw/exynos4210_gic.c
+++ b/hw/exynos4210_gic.c
@@ -341,11 +341,10 @@ static Property exynos4210_gic_properties[] = {
 
 static void exynos4210_gic_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = exynos4210_gic_init;
-    dc->props = exynos4210_gic_properties;
+    klass->props = exynos4210_gic_properties;
 }
 
 static TypeInfo exynos4210_gic_info = {
diff --git a/hw/exynos4210_uart.c b/hw/exynos4210_uart.c
index ccc4780..9115f0b 100644
--- a/hw/exynos4210_uart.c
+++ b/hw/exynos4210_uart.c
@@ -657,7 +657,7 @@ static void exynos4210_uart_class_init(ObjectClass *klass, void *data)
 
     k->init = exynos4210_uart_init;
     dc->reset = exynos4210_uart_reset;
-    dc->props = exynos4210_uart_properties;
+    klass->props = exynos4210_uart_properties;
     dc->vmsd = &vmstate_exynos4210_uart;
 }
 
diff --git a/hw/fdc.c b/hw/fdc.c
index 30d34e3..da30323 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -2062,7 +2062,7 @@ static void isabus_fdc_class_init1(ObjectClass *klass, void *data)
     dc->no_user = 1;
     dc->reset = fdctrl_external_reset_isa;
     dc->vmsd = &vmstate_isa_fdc;
-    dc->props = isa_fdc_properties;
+    klass->props = isa_fdc_properties;
 }
 
 static TypeInfo isa_fdc_info = {
@@ -2096,7 +2096,7 @@ static void sysbus_fdc_class_init(ObjectClass *klass, void *data)
     k->init = sysbus_fdc_init1;
     dc->reset = fdctrl_external_reset_sysbus;
     dc->vmsd = &vmstate_sysbus_fdc;
-    dc->props = sysbus_fdc_properties;
+    klass->props = sysbus_fdc_properties;
 }
 
 static TypeInfo sysbus_fdc_info = {
@@ -2119,7 +2119,7 @@ static void sun4m_fdc_class_init(ObjectClass *klass, void *data)
     k->init = sun4m_fdc_init1;
     dc->reset = fdctrl_external_reset_sysbus;
     dc->vmsd = &vmstate_sysbus_fdc;
-    dc->props = sun4m_fdc_properties;
+    klass->props = sun4m_fdc_properties;
 }
 
 static TypeInfo sun4m_fdc_info = {
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 7b3b576..5c3a388 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -546,7 +546,7 @@ static void fw_cfg_class_init(ObjectClass *klass, void *data)
     dc->no_user = 1;
     dc->reset = fw_cfg_reset;
     dc->vmsd = &vmstate_fw_cfg;
-    dc->props = fw_cfg_properties;
+    klass->props = fw_cfg_properties;
 }
 
 static TypeInfo fw_cfg_info = {
diff --git a/hw/g364fb.c b/hw/g364fb.c
index 3a0b68f..597f004 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -564,7 +564,7 @@ static void g364fb_sysbus_class_init(ObjectClass *klass, void *data)
     dc->desc = "G364 framebuffer";
     dc->reset = g364fb_sysbus_reset;
     dc->vmsd = &vmstate_g364fb;
-    dc->props = g364fb_sysbus_properties;
+    klass->props = g364fb_sysbus_properties;
 }
 
 static TypeInfo g364fb_sysbus_info = {
diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
index 73fc989..f64747d 100644
--- a/hw/grlib_apbuart.c
+++ b/hw/grlib_apbuart.c
@@ -249,11 +249,10 @@ static Property grlib_gptimer_properties[] = {
 
 static void grlib_gptimer_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = grlib_apbuart_init;
-    dc->props = grlib_gptimer_properties;
+    klass->props = grlib_gptimer_properties;
 }
 
 static TypeInfo grlib_gptimer_info = {
diff --git a/hw/grlib_gptimer.c b/hw/grlib_gptimer.c
index 41770a9..c44b1fd 100644
--- a/hw/grlib_gptimer.c
+++ b/hw/grlib_gptimer.c
@@ -386,7 +386,7 @@ static void grlib_gptimer_class_init(ObjectClass *klass, void *data)
 
     k->init = grlib_gptimer_init;
     dc->reset = grlib_gptimer_reset;
-    dc->props = grlib_gptimer_properties;
+    klass->props = grlib_gptimer_properties;
 }
 
 static TypeInfo grlib_gptimer_info = {
diff --git a/hw/grlib_irqmp.c b/hw/grlib_irqmp.c
index 0f6e65c..3bbfcec 100644
--- a/hw/grlib_irqmp.c
+++ b/hw/grlib_irqmp.c
@@ -367,7 +367,7 @@ static void grlib_irqmp_class_init(ObjectClass *klass, void *data)
 
     k->init = grlib_irqmp_init;
     dc->reset = grlib_irqmp_reset;
-    dc->props = grlib_irqmp_properties;
+    klass->props = grlib_irqmp_properties;
 }
 
 static TypeInfo grlib_irqmp_info = {
diff --git a/hw/gus.c b/hw/gus.c
index 840d098..1bc81a9 100644
--- a/hw/gus.c
+++ b/hw/gus.c
@@ -314,7 +314,7 @@ static void gus_class_initfn (ObjectClass *klass, void *data)
     ic->init = gus_initfn;
     dc->desc = "Gravis Ultrasound GF1";
     dc->vmsd = &vmstate_gus;
-    dc->props = gus_properties;
+    klass->props = gus_properties;
 }
 
 static TypeInfo gus_info = {
diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index 36761dd..d457a7c 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -1036,7 +1036,7 @@ static void hda_audio_output_class_init(ObjectClass *klass, void *data)
     k->stream = hda_audio_stream;
     dc->desc = "HDA Audio Codec, output-only (line-out)";
     dc->vmsd = &vmstate_hda_audio;
-    dc->props = hda_audio_properties;
+    klass->props = hda_audio_properties;
 }
 
 static TypeInfo hda_audio_output_info = {
@@ -1057,7 +1057,7 @@ static void hda_audio_duplex_class_init(ObjectClass *klass, void *data)
     k->stream = hda_audio_stream;
     dc->desc = "HDA Audio Codec, duplex (line-out, line-in)";
     dc->vmsd = &vmstate_hda_audio;
-    dc->props = hda_audio_properties;
+    klass->props = hda_audio_properties;
 }
 
 static TypeInfo hda_audio_duplex_info = {
@@ -1078,7 +1078,7 @@ static void hda_audio_micro_class_init(ObjectClass *klass, void *data)
     k->stream = hda_audio_stream;
     dc->desc = "HDA Audio Codec, duplex (speaker, microphone)";
     dc->vmsd = &vmstate_hda_audio;
-    dc->props = hda_audio_properties;
+    klass->props = hda_audio_properties;
 }
 
 static TypeInfo hda_audio_micro_info = {
diff --git a/hw/hpet.c b/hw/hpet.c
index fd3ddca..126e78b 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -742,7 +742,7 @@ static void hpet_device_class_init(ObjectClass *klass, void *data)
     dc->no_user = 1;
     dc->reset = hpet_reset;
     dc->vmsd = &vmstate_hpet;
-    dc->props = hpet_device_properties;
+    klass->props = hpet_device_properties;
 }
 
 static TypeInfo hpet_device_info = {
diff --git a/hw/i2c.c b/hw/i2c.c
index 296bece..1a83dda 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -225,7 +225,7 @@ static void i2c_slave_class_init(ObjectClass *klass, void *data)
     DeviceClass *k = DEVICE_CLASS(klass);
     k->init = i2c_slave_qdev_init;
     k->bus_type = TYPE_I2C_BUS;
-    k->props = i2c_props;
+    klass->props = i2c_props;
 }
 
 static TypeInfo i2c_slave_type_info = {
diff --git a/hw/i82374.c b/hw/i82374.c
index 4a922c3..278ff2c 100644
--- a/hw/i82374.c
+++ b/hw/i82374.c
@@ -150,7 +150,7 @@ static void i82374_class_init(ObjectClass *klass, void *data)
     
     k->init  = i82374_isa_init;
     dc->vmsd = &vmstate_isa_i82374;
-    dc->props = i82374_properties;
+    klass->props = i82374_properties;
 }
 
 static TypeInfo i82374_isa_info = {
diff --git a/hw/i82378.c b/hw/i82378.c
index 9b11d90..25c3ad2 100644
--- a/hw/i82378.c
+++ b/hw/i82378.c
@@ -260,7 +260,7 @@ static void pci_i82378_class_init(ObjectClass *klass, void *data)
     k->subsystem_vendor_id = 0x0;
     k->subsystem_id = 0x0;
     dc->vmsd = &vmstate_pci_i82378;
-    dc->props = i82378_properties;
+    klass->props = i82378_properties;
 }
 
 static TypeInfo pci_i82378_info = {
diff --git a/hw/i8254.c b/hw/i8254.c
index 77bd5e8..9be9dbc 100644
--- a/hw/i8254.c
+++ b/hw/i8254.c
@@ -342,7 +342,7 @@ static void pit_class_initfn(ObjectClass *klass, void *data)
     k->get_channel_info = pit_get_channel_info_common;
     k->post_load = pit_post_load;
     dc->reset = pit_reset;
-    dc->props = pit_properties;
+    klass->props = pit_properties;
 }
 
 static TypeInfo pit_info = {
diff --git a/hw/i8259_common.c b/hw/i8259_common.c
index ab3d98b..a91d1e5 100644
--- a/hw/i8259_common.c
+++ b/hw/i8259_common.c
@@ -140,7 +140,7 @@ static void pic_common_class_init(ObjectClass *klass, void *data)
 
     dc->vmsd = &vmstate_pic_common;
     dc->no_user = 1;
-    dc->props = pic_properties_common;
+    klass->props = pic_properties_common;
     ic->init = pic_init_common;
 }
 
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 2d7d03d..082b639 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1202,7 +1202,7 @@ static void sysbus_ahci_class_init(ObjectClass *klass, void *data)
 
     sbc->init = sysbus_ahci_init;
     dc->vmsd = &vmstate_sysbus_ahci;
-    dc->props = sysbus_ahci_properties;
+    klass->props = sysbus_ahci_properties;
 }
 
 static TypeInfo sysbus_ahci_info = {
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index bf8ece4..ab4cfdd 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -332,7 +332,6 @@ static Property cmd646_ide_properties[] = {
 
 static void cmd646_ide_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = pci_cmd646_ide_initfn;
@@ -341,7 +340,7 @@ static void cmd646_ide_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_CMD_646;
     k->revision = 0x07;
     k->class_id = PCI_CLASS_STORAGE_IDE;
-    dc->props = cmd646_ide_properties;
+    klass->props = cmd646_ide_properties;
 }
 
 static TypeInfo cmd646_ide_info = {
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 8ab2718..c2faba9 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -108,7 +108,7 @@ static void isa_ide_class_initfn(ObjectClass *klass, void *data)
     ic->init = isa_ide_initfn;
     dc->fw_name = "ide";
     dc->reset = isa_ide_reset;
-    dc->props = isa_ide_properties;
+    klass->props = isa_ide_properties;
 }
 
 static TypeInfo isa_ide_info = {
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index c122395..7a92be8 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -199,7 +199,7 @@ static void ide_hd_class_init(ObjectClass *klass, void *data)
     k->init = ide_hd_initfn;
     dc->fw_name = "drive";
     dc->desc = "virtual IDE disk";
-    dc->props = ide_hd_properties;
+    klass->props = ide_hd_properties;
 }
 
 static TypeInfo ide_hd_info = {
@@ -221,7 +221,7 @@ static void ide_cd_class_init(ObjectClass *klass, void *data)
     k->init = ide_cd_initfn;
     dc->fw_name = "drive";
     dc->desc = "virtual IDE CD-ROM";
-    dc->props = ide_cd_properties;
+    klass->props = ide_cd_properties;
 }
 
 static TypeInfo ide_cd_info = {
@@ -243,7 +243,7 @@ static void ide_drive_class_init(ObjectClass *klass, void *data)
     k->init = ide_drive_initfn;
     dc->fw_name = "drive";
     dc->desc = "virtual IDE disk or CD-ROM (legacy)";
-    dc->props = ide_drive_properties;
+    klass->props = ide_drive_properties;
 }
 
 static TypeInfo ide_drive_info = {
@@ -258,7 +258,7 @@ static void ide_device_class_init(ObjectClass *klass, void *data)
     DeviceClass *k = DEVICE_CLASS(klass);
     k->init = ide_qdev_init;
     k->bus_type = TYPE_IDE_BUS;
-    k->props = ide_props;
+    klass->props = ide_props;
 }
 
 static TypeInfo ide_device_type_info = {
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index 9bdb9e6..3dd8661 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -524,11 +524,10 @@ static Property core_properties[] = {
 
 static void core_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = integratorcm_init;
-    dc->props = core_properties;
+    klass->props = core_properties;
 }
 
 static TypeInfo core_info = {
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index c11fd30..766fc91 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -1265,7 +1265,7 @@ static void intel_hda_class_init(ObjectClass *klass, void *data)
     dc->desc = "Intel HD Audio Controller";
     dc->reset = intel_hda_reset;
     dc->vmsd = &vmstate_intel_hda;
-    dc->props = intel_hda_properties;
+    klass->props = intel_hda_properties;
 }
 
 static TypeInfo intel_hda_info = {
@@ -1281,7 +1281,7 @@ static void hda_codec_device_class_init(ObjectClass *klass, void *data)
     k->init = hda_codec_dev_init;
     k->exit = hda_codec_dev_exit;
     k->bus_type = TYPE_HDA_BUS;
-    k->props = hda_props;
+    klass->props = hda_props;
 }
 
 static TypeInfo hda_codec_device_type_info = {
diff --git a/hw/ioh3420.c b/hw/ioh3420.c
index 1632d31..cfb8507 100644
--- a/hw/ioh3420.c
+++ b/hw/ioh3420.c
@@ -227,7 +227,7 @@ static void ioh3420_class_init(ObjectClass *klass, void *data)
     dc->desc = "Intel IOH device id 3420 PCIE Root Port";
     dc->reset = ioh3420_reset;
     dc->vmsd = &vmstate_ioh3420;
-    dc->props = ioh3420_properties;
+    klass->props = ioh3420_properties;
 }
 
 static TypeInfo ioh3420_info = {
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index d48e5f9..ccb08dc 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -806,7 +806,7 @@ static void ivshmem_class_init(ObjectClass *klass, void *data)
     k->device_id = 0x1110;
     k->class_id = PCI_CLASS_MEMORY_RAM;
     dc->reset = ivshmem_reset;
-    dc->props = ivshmem_properties;
+    klass->props = ivshmem_properties;
 }
 
 static TypeInfo ivshmem_info = {
diff --git a/hw/kvm/i8254.c b/hw/kvm/i8254.c
index bb5fe07..9e7dba9 100644
--- a/hw/kvm/i8254.c
+++ b/hw/kvm/i8254.c
@@ -236,7 +236,7 @@ static void kvm_pit_class_init(ObjectClass *klass, void *data)
     k->pre_save = kvm_pit_get;
     k->post_load = kvm_pit_put;
     dc->reset = kvm_pit_reset;
-    dc->props = kvm_pit_properties;
+    klass->props = kvm_pit_properties;
 }
 
 static TypeInfo kvm_pit_info = {
diff --git a/hw/kvm/ioapic.c b/hw/kvm/ioapic.c
index 3ae3175..d57b11b 100644
--- a/hw/kvm/ioapic.c
+++ b/hw/kvm/ioapic.c
@@ -107,7 +107,7 @@ static void kvm_ioapic_class_init(ObjectClass *klass, void *data)
     k->pre_save  = kvm_ioapic_get;
     k->post_load = kvm_ioapic_put;
     dc->reset    = kvm_ioapic_reset;
-    dc->props    = kvm_ioapic_properties;
+    klass->props = kvm_ioapic_properties;
 }
 
 static TypeInfo kvm_ioapic_info = {
diff --git a/hw/lan9118.c b/hw/lan9118.c
index 7b4fe87..dbefefb 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -1362,7 +1362,7 @@ static void lan9118_class_init(ObjectClass *klass, void *data)
 
     k->init = lan9118_init1;
     dc->reset = lan9118_reset;
-    dc->props = lan9118_properties;
+    klass->props = lan9118_properties;
     dc->vmsd = &vmstate_lan9118;
 }
 
diff --git a/hw/lance.c b/hw/lance.c
index ce3d46c..a7e3dca 100644
--- a/hw/lance.c
+++ b/hw/lance.c
@@ -152,7 +152,7 @@ static void lance_class_init(ObjectClass *klass, void *data)
     dc->fw_name = "ethernet";
     dc->reset = lance_reset;
     dc->vmsd = &vmstate_lance;
-    dc->props = lance_properties;
+    klass->props = lance_properties;
 }
 
 static TypeInfo lance_info = {
diff --git a/hw/lm32_sys.c b/hw/lm32_sys.c
index bbe03c4..99fef79 100644
--- a/hw/lm32_sys.c
+++ b/hw/lm32_sys.c
@@ -154,7 +154,7 @@ static void lm32_sys_class_init(ObjectClass *klass, void *data)
     k->init = lm32_sys_init;
     dc->reset = sys_reset;
     dc->vmsd = &vmstate_lm32_sys;
-    dc->props = lm32_sys_properties;
+    klass->props = lm32_sys_properties;
 }
 
 static TypeInfo lm32_sys_info = {
diff --git a/hw/lm32_timer.c b/hw/lm32_timer.c
index e9450a0..f3a20ff 100644
--- a/hw/lm32_timer.c
+++ b/hw/lm32_timer.c
@@ -212,7 +212,7 @@ static void lm32_timer_class_init(ObjectClass *klass, void *data)
     k->init = lm32_timer_init;
     dc->reset = timer_reset;
     dc->vmsd = &vmstate_lm32_timer;
-    dc->props = lm32_timer_properties;
+    klass->props = lm32_timer_properties;
 }
 
 static TypeInfo lm32_timer_info = {
diff --git a/hw/m48t59.c b/hw/m48t59.c
index dd6cb37..6540f80 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -738,7 +738,7 @@ static void m48t59_init_class_isa1(ObjectClass *klass, void *data)
     ic->init = m48t59_init_isa1;
     dc->no_user = 1;
     dc->reset = m48t59_reset_isa;
-    dc->props = m48t59_isa_properties;
+    klass->props = m48t59_isa_properties;
 }
 
 static TypeInfo m48t59_isa_info = {
@@ -762,7 +762,7 @@ static void m48t59_class_init(ObjectClass *klass, void *data)
 
     k->init = m48t59_init1;
     dc->reset = m48t59_reset_sysbus;
-    dc->props = m48t59_properties;
+    klass->props = m48t59_properties;
 }
 
 static TypeInfo m48t59_info = {
diff --git a/hw/marvell_88w8618_audio.c b/hw/marvell_88w8618_audio.c
index f6f1937..9cb70f2 100644
--- a/hw/marvell_88w8618_audio.c
+++ b/hw/marvell_88w8618_audio.c
@@ -285,7 +285,7 @@ static void mv88w8618_audio_class_init(ObjectClass *klass, void *data)
     k->init = mv88w8618_audio_init;
     dc->reset = mv88w8618_audio_reset;
     dc->vmsd = &mv88w8618_audio_vmsd;
-    dc->props = mv88w8618_audio_properties;
+    klass->props = mv88w8618_audio_properties;
 }
 
 static TypeInfo mv88w8618_audio_info = {
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index 3777f85..9c9b23c 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -697,7 +697,7 @@ static void rtc_class_initfn(ObjectClass *klass, void *data)
     ic->init = rtc_initfn;
     dc->no_user = 1;
     dc->vmsd = &vmstate_rtc;
-    dc->props = mc146818rtc_properties;
+    klass->props = mc146818rtc_properties;
 }
 
 static TypeInfo mc146818rtc_info = {
diff --git a/hw/milkymist-minimac2.c b/hw/milkymist-minimac2.c
index 70bf336..5bdb5e5 100644
--- a/hw/milkymist-minimac2.c
+++ b/hw/milkymist-minimac2.c
@@ -532,7 +532,7 @@ static void milkymist_minimac2_class_init(ObjectClass *klass, void *data)
     k->init = milkymist_minimac2_init;
     dc->reset = milkymist_minimac2_reset;
     dc->vmsd = &vmstate_milkymist_minimac2;
-    dc->props = milkymist_minimac2_properties;
+    klass->props = milkymist_minimac2_properties;
 }
 
 static TypeInfo milkymist_minimac2_info = {
diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c
index ecc2be9..e44d007 100644
--- a/hw/milkymist-softusb.c
+++ b/hw/milkymist-softusb.c
@@ -313,7 +313,7 @@ static void milkymist_softusb_class_init(ObjectClass *klass, void *data)
     k->init = milkymist_softusb_init;
     dc->reset = milkymist_softusb_reset;
     dc->vmsd = &vmstate_milkymist_softusb;
-    dc->props = milkymist_softusb_properties;
+    klass->props = milkymist_softusb_properties;
 }
 
 static TypeInfo milkymist_softusb_info = {
diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c
index 8878d2b..6caabd9 100644
--- a/hw/milkymist-sysctl.c
+++ b/hw/milkymist-sysctl.c
@@ -320,7 +320,7 @@ static void milkymist_sysctl_class_init(ObjectClass *klass, void *data)
     k->init = milkymist_sysctl_init;
     dc->reset = milkymist_sysctl_reset;
     dc->vmsd = &vmstate_milkymist_sysctl;
-    dc->props = milkymist_sysctl_properties;
+    klass->props = milkymist_sysctl_properties;
 }
 
 static TypeInfo milkymist_sysctl_info = {
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index cd4365d..7cf00ef 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -316,7 +316,7 @@ static void milkymist_vgafb_class_init(ObjectClass *klass, void *data)
     k->init = milkymist_vgafb_init;
     dc->reset = milkymist_vgafb_reset;
     dc->vmsd = &vmstate_milkymist_vgafb;
-    dc->props = milkymist_vgafb_properties;
+    klass->props = milkymist_vgafb_properties;
 }
 
 static TypeInfo milkymist_vgafb_info = {
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index 3107246..50876bc 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -266,7 +266,7 @@ static void mipsnet_class_init(ObjectClass *klass, void *data)
     dc->desc = "MIPS Simulator network device";
     dc->reset = mipsnet_sysbus_reset;
     dc->vmsd = &vmstate_mipsnet;
-    dc->props = mipsnet_properties;
+    klass->props = mipsnet_properties;
 }
 
 static TypeInfo mipsnet_info = {
diff --git a/hw/musicpal.c b/hw/musicpal.c
index c9f845a..7f186a9 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -424,7 +424,7 @@ static void mv88w8618_eth_class_init(ObjectClass *klass, void *data)
 
     k->init = mv88w8618_eth_init;
     dc->vmsd = &mv88w8618_eth_vmsd;
-    dc->props = mv88w8618_eth_properties;
+    klass->props = mv88w8618_eth_properties;
 }
 
 static TypeInfo mv88w8618_eth_info = {
diff --git a/hw/nand.c b/hw/nand.c
index e9501ae..460f2fe 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -432,7 +432,7 @@ static void nand_class_init(ObjectClass *klass, void *data)
     k->init = nand_device_init;
     dc->reset = nand_reset;
     dc->vmsd = &vmstate_nand;
-    dc->props = nand_properties;
+    klass->props = nand_properties;
 }
 
 static TypeInfo nand_info = {
diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c
index a4a783a..a38da68 100644
--- a/hw/ne2000-isa.c
+++ b/hw/ne2000-isa.c
@@ -91,10 +91,9 @@ static Property ne2000_isa_properties[] = {
 
 static void isa_ne2000_class_initfn(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = isa_ne2000_initfn;
-    dc->props = ne2000_isa_properties;
+    klass->props = ne2000_isa_properties;
 }
 
 static TypeInfo ne2000_isa_info = {
diff --git a/hw/ne2000.c b/hw/ne2000.c
index d02e60c..f5eab22 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -771,7 +771,7 @@ static void ne2000_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_REALTEK_8029;
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
     dc->vmsd = &vmstate_pci_ne2000;
-    dc->props = ne2000_properties;
+    klass->props = ne2000_properties;
 }
 
 static TypeInfo ne2000_info = {
diff --git a/hw/omap_gpio.c b/hw/omap_gpio.c
index 201ff77..b4fba0b 100644
--- a/hw/omap_gpio.c
+++ b/hw/omap_gpio.c
@@ -744,7 +744,7 @@ static void omap_gpio_class_init(ObjectClass *klass, void *data)
 
     k->init = omap_gpio_init;
     dc->reset = omap_gpif_reset;
-    dc->props = omap_gpio_properties;
+    klass->props = omap_gpio_properties;
 }
 
 static TypeInfo omap_gpio_info = {
@@ -773,7 +773,7 @@ static void omap2_gpio_class_init(ObjectClass *klass, void *data)
 
     k->init = omap2_gpio_init;
     dc->reset = omap2_gpif_reset;
-    dc->props = omap2_gpio_properties;
+    klass->props = omap2_gpio_properties;
 }
 
 static TypeInfo omap2_gpio_info = {
diff --git a/hw/omap_i2c.c b/hw/omap_i2c.c
index 20bc82e..280c622 100644
--- a/hw/omap_i2c.c
+++ b/hw/omap_i2c.c
@@ -467,7 +467,7 @@ static void omap_i2c_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
     k->init = omap_i2c_init;
-    dc->props = omap_i2c_properties;
+    klass->props = omap_i2c_properties;
     dc->reset = omap_i2c_reset;
 }
 
diff --git a/hw/omap_intc.c b/hw/omap_intc.c
index 5076e07..7f98a3e 100644
--- a/hw/omap_intc.c
+++ b/hw/omap_intc.c
@@ -386,7 +386,7 @@ static void omap_intc_class_init(ObjectClass *klass, void *data)
 
     k->init = omap_intc_init;
     dc->reset = omap_inth_reset;
-    dc->props = omap_intc_properties;
+    klass->props = omap_intc_properties;
 }
 
 static TypeInfo omap_intc_info = {
@@ -630,7 +630,7 @@ static void omap2_intc_class_init(ObjectClass *klass, void *data)
 
     k->init = omap2_intc_init;
     dc->reset = omap_inth_reset;
-    dc->props = omap2_intc_properties;
+    klass->props = omap2_intc_properties;
 }
 
 static TypeInfo omap2_intc_info = {
diff --git a/hw/onenand.c b/hw/onenand.c
index db6af68..05126dc 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -818,7 +818,7 @@ static void onenand_class_init(ObjectClass *klass, void *data)
 
     k->init = onenand_initfn;
     dc->reset = onenand_system_reset;
-    dc->props = onenand_properties;
+    klass->props = onenand_properties;
 }
 
 static TypeInfo onenand_info = {
diff --git a/hw/opencores_eth.c b/hw/opencores_eth.c
index 350f731..1007f46 100644
--- a/hw/opencores_eth.c
+++ b/hw/opencores_eth.c
@@ -715,7 +715,7 @@ static void open_eth_class_init(ObjectClass *klass, void *data)
     k->init = sysbus_open_eth_init;
     dc->desc = "Opencores 10/100 Mbit Ethernet";
     dc->reset = qdev_open_eth_reset;
-    dc->props = open_eth_properties;
+    klass->props = open_eth_properties;
 }
 
 static TypeInfo open_eth_info = {
diff --git a/hw/parallel.c b/hw/parallel.c
index 219f384..f3fdbdb 100644
--- a/hw/parallel.c
+++ b/hw/parallel.c
@@ -593,10 +593,9 @@ static Property parallel_isa_properties[] = {
 
 static void parallel_isa_class_initfn(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = parallel_isa_initfn;
-    dc->props = parallel_isa_properties;
+    klass->props = parallel_isa_properties;
 }
 
 static TypeInfo parallel_isa_info = {
diff --git a/hw/pc_sysfw.c b/hw/pc_sysfw.c
index f0d7c21..d861c16 100644
--- a/hw/pc_sysfw.c
+++ b/hw/pc_sysfw.c
@@ -246,7 +246,7 @@ static void pcsysfw_class_init (ObjectClass *klass, void *data)
 
     dc->desc = "PC System Firmware";
     dc->init = pcsysfw_init;
-    dc->props = pcsysfw_properties;
+    klass->props = pcsysfw_properties;
 }
 
 static TypeInfo pcsysfw_info = {
diff --git a/hw/pci.c b/hw/pci.c
index d6ce9a5..4068e07 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -2010,7 +2010,7 @@ static void pci_device_class_init(ObjectClass *klass, void *data)
     k->unplug = pci_unplug_device;
     k->exit = pci_unregister_device;
     k->bus_type = TYPE_PCI_BUS;
-    k->props = pci_props;
+    klass->props = pci_props;
 }
 
 static TypeInfo pci_device_type_info = {
diff --git a/hw/pci_bridge_dev.c b/hw/pci_bridge_dev.c
index eccaa58..25ef263 100644
--- a/hw/pci_bridge_dev.c
+++ b/hw/pci_bridge_dev.c
@@ -155,8 +155,8 @@ static void pci_bridge_dev_class_init(ObjectClass *klass, void *data)
     k->is_bridge = 1,
     dc->desc = "Standard PCI Bridge";
     dc->reset = qdev_pci_bridge_dev_reset;
-    dc->props = pci_bridge_dev_properties;
     dc->vmsd = &pci_bridge_dev_vmstate;
+    klass->props = pci_bridge_dev_properties;
 }
 
 static TypeInfo pci_bridge_dev_info = {
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 34d73aa..a322046 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -359,7 +359,7 @@ static void pcnet_class_init(ObjectClass *klass, void *data)
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
     dc->reset = pci_reset;
     dc->vmsd = &vmstate_pci_pcnet;
-    dc->props = pcnet_properties;
+    klass->props = pcnet_properties;
 }
 
 static TypeInfo pcnet_info = {
diff --git a/hw/pcspk.c b/hw/pcspk.c
index e430324..f33eac2 100644
--- a/hw/pcspk.c
+++ b/hw/pcspk.c
@@ -184,7 +184,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data)
 
     ic->init = pcspk_initfn;
     dc->no_user = 1;
-    dc->props = pcspk_properties;
+    klass->props = pcspk_properties;
 }
 
 static TypeInfo pcspk_info = {
diff --git a/hw/pl041.c b/hw/pl041.c
index b6723be..5a035e1 100644
--- a/hw/pl041.c
+++ b/hw/pl041.c
@@ -628,7 +628,7 @@ static void pl041_device_class_init(ObjectClass *klass, void *data)
     dc->no_user = 1;
     dc->reset = pl041_device_reset;
     dc->vmsd = &vmstate_pl041;
-    dc->props = pl041_device_properties;
+    klass->props = pl041_device_properties;
 }
 
 static TypeInfo pl041_device_info = {
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 5f8f226..559f295 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1556,7 +1556,7 @@ static void pxa2xx_i2c_class_init(ObjectClass *klass, void *data)
     k->init = pxa2xx_i2c_initfn;
     dc->desc = "PXA2xx I2C Bus Controller";
     dc->vmsd = &vmstate_pxa2xx_i2c;
-    dc->props = pxa2xx_i2c_properties;
+    klass->props = pxa2xx_i2c_properties;
 }
 
 static TypeInfo pxa2xx_i2c_info = {
diff --git a/hw/pxa2xx_dma.c b/hw/pxa2xx_dma.c
index 0310154..aef039f 100644
--- a/hw/pxa2xx_dma.c
+++ b/hw/pxa2xx_dma.c
@@ -556,7 +556,7 @@ static void pxa2xx_dma_class_init(ObjectClass *klass, void *data)
     k->init = pxa2xx_dma_init;
     dc->desc = "PXA2xx DMA controller";
     dc->vmsd = &vmstate_pxa2xx_dma;
-    dc->props = pxa2xx_dma_properties;
+    klass->props = pxa2xx_dma_properties;
 }
 
 static TypeInfo pxa2xx_dma_info = {
diff --git a/hw/pxa2xx_gpio.c b/hw/pxa2xx_gpio.c
index 09a408b..c98454e 100644
--- a/hw/pxa2xx_gpio.c
+++ b/hw/pxa2xx_gpio.c
@@ -330,7 +330,7 @@ static void pxa2xx_gpio_class_init(ObjectClass *klass, void *data)
 
     k->init = pxa2xx_gpio_initfn;
     dc->desc = "PXA2xx GPIO controller";
-    dc->props = pxa2xx_gpio_properties;
+    klass->props = pxa2xx_gpio_properties;
 }
 
 static TypeInfo pxa2xx_gpio_info = {
diff --git a/hw/pxa2xx_timer.c b/hw/pxa2xx_timer.c
index 77b033b..db2ebe2 100644
--- a/hw/pxa2xx_timer.c
+++ b/hw/pxa2xx_timer.c
@@ -492,7 +492,7 @@ static void pxa25x_timer_dev_class_init(ObjectClass *klass, void *data)
     k->init = pxa2xx_timer_init;
     dc->desc = "PXA25x timer";
     dc->vmsd = &vmstate_pxa2xx_timer_regs;
-    dc->props = pxa25x_timer_dev_properties;
+    klass->props = pxa25x_timer_dev_properties;
 }
 
 static TypeInfo pxa25x_timer_dev_info = {
@@ -517,7 +517,7 @@ static void pxa27x_timer_dev_class_init(ObjectClass *klass, void *data)
     k->init = pxa2xx_timer_init;
     dc->desc = "PXA27x timer";
     dc->vmsd = &vmstate_pxa2xx_timer_regs;
-    dc->props = pxa27x_timer_dev_properties;
+    klass->props = pxa27x_timer_dev_properties;
 }
 
 static TypeInfo pxa27x_timer_dev_info = {
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 17452c8..c02517b 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -149,7 +149,7 @@ int qdev_device_help(QemuOpts *opts)
         return 0;
     }
     do {
-        for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) {
+        for (prop = OBJECT_CLASS(klass)->props; prop && prop->name; prop++) {
             /*
              * TODO Properties without a parser are just for dirty hacks.
              * qdev_prop_ptr is the only such PropertyInfo.  It's marked
@@ -527,7 +527,7 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
     }
     class = object_get_class(OBJECT(dev));
     do {
-        qdev_print_props(mon, dev, DEVICE_CLASS(class)->props, indent);
+        qdev_print_props(mon, dev, OBJECT_CLASS(class)->props, indent);
         class = object_class_get_parent(class);
     } while (class != object_class_by_name(TYPE_DEVICE));
     bus_print_dev(dev->parent_bus, mon, dev, indent + 2);
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 8651141..940bf39 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -522,7 +522,7 @@ static Property *qdev_prop_find(Object *obj, const char *name)
     /* device properties */
     class = object_get_class(obj);
     do {
-        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
+        prop = qdev_prop_walk(OBJECT_CLASS(class)->props, name);
         if (prop) {
             return prop;
         }
diff --git a/hw/qdev.c b/hw/qdev.c
index 9aaa60b..283eaab 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -630,9 +630,8 @@ static void device_initfn(Object *obj)
 
     class = object_get_class(OBJECT(dev));
     do {
-        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
+        for (prop = OBJECT_CLASS(class)->props; prop && prop->name; prop++) {
             qdev_property_add_legacy(dev, prop, NULL);
-            object_property_add_static(OBJECT(dev), prop, NULL);
         }
         class = object_class_get_parent(class);
     } while (class != object_class_by_name(TYPE_DEVICE));
@@ -669,16 +668,6 @@ static void device_finalize(Object *obj)
     }
 }
 
-static void device_class_base_init(ObjectClass *class, void *data)
-{
-    DeviceClass *klass = DEVICE_CLASS(class);
-
-    /* We explicitly look up properties in the superclasses,
-     * so do not propagate them to the subclasses.
-     */
-    klass->props = NULL;
-}
-
 void device_reset(DeviceState *dev)
 {
     DeviceClass *klass = DEVICE_GET_CLASS(dev);
@@ -705,7 +694,6 @@ static TypeInfo device_type_info = {
     .instance_size = sizeof(DeviceState),
     .instance_init = device_initfn,
     .instance_finalize = device_finalize,
-    .class_base_init = device_class_base_init,
     .abstract = true,
     .class_size = sizeof(DeviceClass),
 };
diff --git a/hw/qdev.h b/hw/qdev.h
index c810d43..168378c 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -33,7 +33,6 @@ typedef struct DeviceClass {
 
     const char *fw_name;
     const char *desc;
-    Property *props;
     int no_user;
 
     /* callbacks */
diff --git a/hw/qxl.c b/hw/qxl.c
index 3da3399..81b5093 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -2051,7 +2051,7 @@ static void qxl_primary_class_init(ObjectClass *klass, void *data)
     dc->desc = "Spice QXL GPU (primary, vga compatible)";
     dc->reset = qxl_reset_handler;
     dc->vmsd = &qxl_vmstate;
-    dc->props = qxl_properties;
+    klass->props = qxl_properties;
 }
 
 static TypeInfo qxl_primary_info = {
@@ -2073,7 +2073,7 @@ static void qxl_secondary_class_init(ObjectClass *klass, void *data)
     dc->desc = "Spice QXL GPU (secondary)";
     dc->reset = qxl_reset_handler;
     dc->vmsd = &qxl_vmstate;
-    dc->props = qxl_properties;
+    klass->props = qxl_properties;
 }
 
 static TypeInfo qxl_secondary_info = {
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index eb22d04..2ec1519 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3525,7 +3525,7 @@ static void rtl8139_class_init(ObjectClass *klass, void *data)
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
     dc->reset = rtl8139_reset;
     dc->vmsd = &vmstate_rtl8139;
-    dc->props = rtl8139_properties;
+    klass->props = rtl8139_properties;
 }
 
 static TypeInfo rtl8139_info = {
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index df8d052..fc57b56 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -384,11 +384,10 @@ static Property s390_virtio_net_properties[] = {
 
 static void s390_virtio_net_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
 
     k->init = s390_virtio_net_init;
-    dc->props = s390_virtio_net_properties;
+    klass->props = s390_virtio_net_properties;
 }
 
 static TypeInfo s390_virtio_net = {
@@ -409,11 +408,10 @@ static Property s390_virtio_blk_properties[] = {
 
 static void s390_virtio_blk_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
 
     k->init = s390_virtio_blk_init;
-    dc->props = s390_virtio_blk_properties;
+    klass->props = s390_virtio_blk_properties;
 }
 
 static TypeInfo s390_virtio_blk = {
@@ -431,11 +429,10 @@ static Property s390_virtio_serial_properties[] = {
 
 static void s390_virtio_serial_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
 
     k->init = s390_virtio_serial_init;
-    dc->props = s390_virtio_serial_properties;
+    klass->props = s390_virtio_serial_properties;
 }
 
 static TypeInfo s390_virtio_serial = {
@@ -478,11 +475,10 @@ static Property s390_virtio_scsi_properties[] = {
 
 static void s390_virtio_scsi_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
 
     k->init = s390_virtio_scsi_init;
-    dc->props = s390_virtio_scsi_properties;
+    klass->props = s390_virtio_scsi_properties;
 }
 
 static TypeInfo s390_virtio_scsi = {
diff --git a/hw/sb16.c b/hw/sb16.c
index c81455d..5e8ef6e 100644
--- a/hw/sb16.c
+++ b/hw/sb16.c
@@ -1407,7 +1407,7 @@ static void sb16_class_initfn (ObjectClass *klass, void *data)
     ic->init = sb16_initfn;
     dc->desc = "Creative Sound Blaster 16";
     dc->vmsd = &vmstate_sb16;
-    dc->props = sb16_properties;
+    klass->props = sb16_properties;
 }
 
 static TypeInfo sb16_info = {
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 7caf446..bd42e64 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -1609,7 +1609,7 @@ static void scsi_device_class_init(ObjectClass *klass, void *data)
     k->init     = scsi_qdev_init;
     k->unplug   = qdev_simple_unplug_cb;
     k->exit     = scsi_qdev_exit;
-    k->props    = scsi_props;
+    klass->props    = scsi_props;
 }
 
 static TypeInfo scsi_device_type_info = {
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 045c764..0a28d5a 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1945,7 +1945,7 @@ static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
     dc->fw_name = "disk";
     dc->desc = "virtual SCSI disk";
     dc->reset = scsi_disk_reset;
-    dc->props = scsi_hd_properties;
+    klass->props = scsi_hd_properties;
     dc->vmsd  = &vmstate_scsi_disk_state;
 }
 
@@ -1973,7 +1973,7 @@ static void scsi_cd_class_initfn(ObjectClass *klass, void *data)
     dc->fw_name = "disk";
     dc->desc = "virtual SCSI CD-ROM";
     dc->reset = scsi_disk_reset;
-    dc->props = scsi_cd_properties;
+    klass->props = scsi_cd_properties;
     dc->vmsd  = &vmstate_scsi_disk_state;
 }
 
@@ -2001,7 +2001,7 @@ static void scsi_block_class_initfn(ObjectClass *klass, void *data)
     dc->fw_name = "disk";
     dc->desc = "SCSI block device passthrough";
     dc->reset = scsi_disk_reset;
-    dc->props = scsi_block_properties;
+    klass->props = scsi_block_properties;
     dc->vmsd  = &vmstate_scsi_disk_state;
 }
 
@@ -2034,7 +2034,7 @@ static void scsi_disk_class_initfn(ObjectClass *klass, void *data)
     dc->fw_name = "disk";
     dc->desc = "virtual SCSI disk or CD-ROM (legacy)";
     dc->reset = scsi_disk_reset;
-    dc->props = scsi_disk_properties;
+    klass->props = scsi_disk_properties;
     dc->vmsd  = &vmstate_scsi_disk_state;
 }
 
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index d856d23..c3a50a3 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -497,7 +497,7 @@ static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
     dc->fw_name = "disk";
     dc->desc = "pass through generic scsi device (/dev/sg*)";
     dc->reset = scsi_generic_reset;
-    dc->props = scsi_generic_properties;
+    klass->props = scsi_generic_properties;
     dc->vmsd  = &vmstate_scsi_device;
 }
 
diff --git a/hw/serial.c b/hw/serial.c
index a421d1e..1a76e91 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -902,7 +902,7 @@ static void serial_isa_class_initfn(ObjectClass *klass, void *data)
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = serial_isa_initfn;
     dc->vmsd = &vmstate_isa_serial;
-    dc->props = serial_isa_properties;
+    klass->props = serial_isa_properties;
 }
 
 static TypeInfo serial_isa_info = {
diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c
index 97edebb..62ceece 100644
--- a/hw/slavio_timer.c
+++ b/hw/slavio_timer.c
@@ -417,7 +417,7 @@ static void slavio_timer_class_init(ObjectClass *klass, void *data)
     k->init = slavio_timer_init1;
     dc->reset = slavio_timer_reset;
     dc->vmsd = &vmstate_slavio_timer;
-    dc->props = slavio_timer_properties;
+    klass->props = slavio_timer_properties;
 }
 
 static TypeInfo slavio_timer_info = {
diff --git a/hw/smbus_eeprom.c b/hw/smbus_eeprom.c
index 11adab0..47e8a8a 100644
--- a/hw/smbus_eeprom.c
+++ b/hw/smbus_eeprom.c
@@ -111,7 +111,6 @@ static Property smbus_eeprom_properties[] = {
 
 static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(klass);
 
     sc->init = smbus_eeprom_initfn;
@@ -120,7 +119,7 @@ static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
     sc->receive_byte = eeprom_receive_byte;
     sc->write_data = eeprom_write_data;
     sc->read_data = eeprom_read_data;
-    dc->props = smbus_eeprom_properties;
+    klass->props = smbus_eeprom_properties;
 }
 
 static TypeInfo smbus_eeprom_info = {
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index 1a5213f..20a15ce 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -771,7 +771,7 @@ static void smc91c111_class_init(ObjectClass *klass, void *data)
     k->init = smc91c111_init1;
     dc->reset = smc91c111_reset;
     dc->vmsd = &vmstate_smc91c111;
-    dc->props = smc91c111_properties;
+    klass->props = smc91c111_properties;
 }
 
 static TypeInfo smc91c111_info = {
diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c
index 8313043..185fae5 100644
--- a/hw/spapr_llan.c
+++ b/hw/spapr_llan.c
@@ -486,7 +486,6 @@ static Property spapr_vlan_properties[] = {
 
 static void spapr_vlan_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
 
     k->init = spapr_vlan_init;
@@ -496,7 +495,7 @@ static void spapr_vlan_class_init(ObjectClass *klass, void *data)
     k->dt_type = "network";
     k->dt_compatible = "IBM,l-lan";
     k->signal_mask = 0x1;
-    dc->props = spapr_vlan_properties;
+    klass->props = spapr_vlan_properties;
 }
 
 static TypeInfo spapr_vlan_info = {
diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c
index 97d417a..9e6525e 100644
--- a/hw/spapr_pci.c
+++ b/hw/spapr_pci.c
@@ -344,10 +344,9 @@ static Property spapr_phb_properties[] = {
 static void spapr_phb_class_init(ObjectClass *klass, void *data)
 {
     SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
-    DeviceClass *dc = DEVICE_CLASS(klass);
 
     sdc->init = spapr_phb_init;
-    dc->props = spapr_phb_properties;
+    klass->props = spapr_phb_properties;
 
     spapr_rtas_register("read-pci-config", rtas_read_pci_config);
     spapr_rtas_register("write-pci-config", rtas_write_pci_config);
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index c8271c6..781f386 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -797,7 +797,7 @@ static void vio_spapr_device_class_init(ObjectClass *klass, void *data)
     k->init = spapr_vio_busdev_init;
     k->reset = spapr_vio_busdev_reset;
     k->bus_type = TYPE_SPAPR_VIO_BUS;
-    k->props = spapr_vio_props;
+    klass->props = spapr_vio_props;
 }
 
 static TypeInfo spapr_vio_type_info = {
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 037867a..a3adec7 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -951,7 +951,6 @@ static Property spapr_vscsi_properties[] = {
 
 static void spapr_vscsi_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
 
     k->init = spapr_vscsi_init;
@@ -961,7 +960,7 @@ static void spapr_vscsi_class_init(ObjectClass *klass, void *data)
     k->dt_type = "vscsi";
     k->dt_compatible = "IBM,v-scsi";
     k->signal_mask = 0x00000001;
-    dc->props = spapr_vscsi_properties;
+    klass->props = spapr_vscsi_properties;
 }
 
 static TypeInfo spapr_vscsi_info = {
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index f340b83..4d16622 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -140,14 +140,13 @@ static Property spapr_vty_properties[] = {
 
 static void spapr_vty_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
 
     k->init = spapr_vty_init;
     k->dt_name = "vty";
     k->dt_type = "serial";
     k->dt_compatible = "hvterm1";
-    dc->props = spapr_vty_properties;
+    klass->props = spapr_vty_properties;
 }
 
 static TypeInfo spapr_vty_info = {
diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index 1dbf69e..95b8a61 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -297,7 +297,7 @@ static void sparc32_dma_class_init(ObjectClass *klass, void *data)
     k->init = sparc32_dma_init1;
     dc->reset = dma_reset;
     dc->vmsd = &vmstate_dma;
-    dc->props = sparc32_dma_properties;
+    klass->props = sparc32_dma_properties;
 }
 
 static TypeInfo sparc32_dma_info = {
diff --git a/hw/spitz.c b/hw/spitz.c
index 9042d44..c22edfa 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -1036,7 +1036,7 @@ static void sl_nand_class_init(ObjectClass *klass, void *data)
 
     k->init = sl_nand_init;
     dc->vmsd = &vmstate_sl_nand_info;
-    dc->props = sl_nand_properties;
+    klass->props = sl_nand_properties;
 }
 
 static TypeInfo sl_nand_info = {
@@ -1071,7 +1071,7 @@ static void spitz_keyboard_class_init(ObjectClass *klass, void *data)
 
     k->init = spitz_keyboard_init;
     dc->vmsd = &vmstate_spitz_kbd;
-    dc->props = spitz_keyboard_properties;
+    klass->props = spitz_keyboard_properties;
 }
 
 static TypeInfo spitz_keyboard_info = {
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index fbe99cb..6ef99c0 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -427,11 +427,10 @@ static Property stellaris_enet_properties[] = {
 
 static void stellaris_enet_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = stellaris_enet_init;
-    dc->props = stellaris_enet_properties;
+    klass->props = stellaris_enet_properties;
 }
 
 static TypeInfo stellaris_enet_info = {
diff --git a/hw/strongarm.c b/hw/strongarm.c
index 1b15f39..8ce2f25 100644
--- a/hw/strongarm.c
+++ b/hw/strongarm.c
@@ -1295,7 +1295,7 @@ static void strongarm_uart_class_init(ObjectClass *klass, void *data)
     dc->desc = "StrongARM UART controller";
     dc->reset = strongarm_uart_reset;
     dc->vmsd = &vmstate_strongarm_uart_regs;
-    dc->props = strongarm_uart_properties;
+    klass->props = strongarm_uart_properties;
 }
 
 static TypeInfo strongarm_uart_info = {
diff --git a/hw/sun4m.c b/hw/sun4m.c
index a959261..11c43f3 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -730,11 +730,10 @@ static Property prom_properties[] = {
 
 static void prom_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = prom_init1;
-    dc->props = prom_properties;
+    klass->props = prom_properties;
 }
 
 static TypeInfo prom_info = {
@@ -794,11 +793,10 @@ static Property ram_properties[] = {
 
 static void ram_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = ram_init1;
-    dc->props = ram_properties;
+    klass->props = ram_properties;
 }
 
 static TypeInfo ram_info = {
diff --git a/hw/sun4m_iommu.c b/hw/sun4m_iommu.c
index ebefa91..485eee3 100644
--- a/hw/sun4m_iommu.c
+++ b/hw/sun4m_iommu.c
@@ -370,7 +370,7 @@ static void iommu_class_init(ObjectClass *klass, void *data)
     k->init = iommu_init1;
     dc->reset = iommu_reset;
     dc->vmsd = &vmstate_iommu;
-    dc->props = iommu_properties;
+    klass->props = iommu_properties;
 }
 
 static TypeInfo iommu_info = {
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 137a7c6..db3c9a4 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -681,11 +681,10 @@ static Property prom_properties[] = {
 
 static void prom_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = prom_init1;
-    dc->props = prom_properties;
+    klass->props = prom_properties;
 }
 
 static TypeInfo prom_info = {
@@ -738,11 +737,10 @@ static Property ram_properties[] = {
 
 static void ram_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = ram_init1;
-    dc->props = ram_properties;
+    klass->props = ram_properties;
 }
 
 static TypeInfo ram_info = {
diff --git a/hw/tcx.c b/hw/tcx.c
index ac7dcb4..5b64296 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -654,7 +654,7 @@ static void tcx_class_init(ObjectClass *klass, void *data)
     k->init = tcx_init1;
     dc->reset = tcx_reset;
     dc->vmsd = &vmstate_tcx;
-    dc->props = tcx_properties;
+    klass->props = tcx_properties;
 }
 
 static TypeInfo tcx_info = {
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index f87cc5f..8c51fc3 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -589,7 +589,7 @@ static void usb_device_class_init(ObjectClass *klass, void *data)
     k->init     = usb_qdev_init;
     k->unplug   = qdev_simple_unplug_cb;
     k->exit     = usb_qdev_exit;
-    k->props    = usb_props;
+    klass->props    = usb_props;
 }
 
 static TypeInfo usb_device_type_info = {
diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c
index 79b75fb..acafc4c 100644
--- a/hw/usb/dev-audio.c
+++ b/hw/usb/dev-audio.c
@@ -688,7 +688,7 @@ static void usb_audio_class_init(ObjectClass *klass, void *data)
     USBDeviceClass *k = USB_DEVICE_CLASS(klass);
 
     dc->vmsd          = &vmstate_usb_audio;
-    dc->props         = usb_audio_properties;
+    klass->props         = usb_audio_properties;
     k->product_desc   = "QEMU USB Audio Interface";
     k->usb_desc       = &desc_audio;
     k->init           = usb_audio_initfn;
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 5d2f098..e707b2b 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1408,7 +1408,7 @@ static void usb_net_class_initfn(ObjectClass *klass, void *data)
     uc->handle_destroy = usb_net_handle_destroy;
     dc->fw_name = "network";
     dc->vmsd = &vmstate_usb_net;
-    dc->props = net_properties;
+    klass->props = net_properties;
 }
 
 static TypeInfo net_info = {
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 56743ee..1f7d0a6 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -589,7 +589,7 @@ static void usb_serial_class_initfn(ObjectClass *klass, void *data)
     uc->handle_data    = usb_serial_handle_data;
     uc->handle_destroy = usb_serial_handle_destroy;
     dc->vmsd = &vmstate_usb_serial;
-    dc->props = serial_properties;
+    klass->props = serial_properties;
 }
 
 static TypeInfo serial_info = {
@@ -617,7 +617,7 @@ static void usb_braille_class_initfn(ObjectClass *klass, void *data)
     uc->handle_data    = usb_serial_handle_data;
     uc->handle_destroy = usb_serial_handle_destroy;
     dc->vmsd = &vmstate_usb_serial;
-    dc->props = braille_properties;
+    klass->props = braille_properties;
 }
 
 static TypeInfo braille_info = {
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 6cf4a1a..921ddd7 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -1334,7 +1334,7 @@ static void ccid_class_initfn(ObjectClass *klass, void *data)
     uc->handle_destroy = ccid_handle_destroy;
     dc->desc = "CCID Rev 1.1 smartcard reader";
     dc->vmsd = &ccid_vmstate;
-    dc->props = ccid_properties;
+    klass->props = ccid_properties;
 }
 
 static TypeInfo ccid_info = {
@@ -1350,7 +1350,7 @@ static void ccid_card_class_init(ObjectClass *klass, void *data)
     k->bus_type = TYPE_CCID_BUS;
     k->init = ccid_card_init;
     k->exit = ccid_card_exit;
-    k->props = ccid_props;
+    klass->props = ccid_props;
 }
 
 static TypeInfo ccid_card_type_info = {
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index a96c0b9..dc3aa74 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -662,7 +662,7 @@ static void usb_msd_class_initfn(ObjectClass *klass, void *data)
     uc->handle_data    = usb_msd_handle_data;
     dc->fw_name = "storage";
     dc->vmsd = &vmstate_usb_msd;
-    dc->props = msd_properties;
+    klass->props = msd_properties;
 }
 
 static TypeInfo msd_info = {
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index e759c99..6a22602 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2208,7 +2208,7 @@ static void ehci_class_init(ObjectClass *klass, void *data)
     k->revision = 0x10;
     k->class_id = PCI_CLASS_SERIAL_USB;
     dc->vmsd = &vmstate_ehci;
-    dc->props = ehci_properties;
+    klass->props = ehci_properties;
 }
 
 static TypeInfo ehci_info = {
@@ -2229,7 +2229,7 @@ static void ich9_ehci_class_init(ObjectClass *klass, void *data)
     k->revision = 0x03;
     k->class_id = PCI_CLASS_SERIAL_USB;
     dc->vmsd = &vmstate_ehci;
-    dc->props = ehci_properties;
+    klass->props = ehci_properties;
 }
 
 static TypeInfo ich9_ehci_info = {
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 1a1cc88..b547381 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1863,7 +1863,7 @@ static void ohci_pci_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_APPLE_IPID_USB;
     k->class_id = PCI_CLASS_SERIAL_USB;
     dc->desc = "Apple USB Controller";
-    dc->props = ohci_pci_properties;
+    klass->props = ohci_pci_properties;
 }
 
 static TypeInfo ohci_pci_info = {
@@ -1886,7 +1886,7 @@ static void ohci_sysbus_class_init(ObjectClass *klass, void *data)
 
     sbc->init = ohci_init_pxa;
     dc->desc = "OHCI USB Controller";
-    dc->props = ohci_sysbus_properties;
+    klass->props = ohci_sysbus_properties;
 }
 
 static TypeInfo ohci_sysbus_info = {
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 9e211a0..5b96645 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1259,7 +1259,7 @@ static void piix3_uhci_class_init(ObjectClass *klass, void *data)
     k->revision = 0x01;
     k->class_id = PCI_CLASS_SERIAL_USB;
     dc->vmsd = &vmstate_uhci;
-    dc->props = uhci_properties;
+    klass->props = uhci_properties;
 }
 
 static TypeInfo piix3_uhci_info = {
@@ -1281,7 +1281,7 @@ static void piix4_uhci_class_init(ObjectClass *klass, void *data)
     k->revision = 0x01;
     k->class_id = PCI_CLASS_SERIAL_USB;
     dc->vmsd = &vmstate_uhci;
-    dc->props = uhci_properties;
+    klass->props = uhci_properties;
 }
 
 static TypeInfo piix4_uhci_info = {
@@ -1303,7 +1303,7 @@ static void vt82c686b_uhci_class_init(ObjectClass *klass, void *data)
     k->revision = 0x01;
     k->class_id = PCI_CLASS_SERIAL_USB;
     dc->vmsd = &vmstate_uhci;
-    dc->props = uhci_properties;
+    klass->props = uhci_properties;
 }
 
 static TypeInfo vt82c686b_uhci_info = {
@@ -1324,7 +1324,7 @@ static void ich9_uhci1_class_init(ObjectClass *klass, void *data)
     k->revision = 0x03;
     k->class_id = PCI_CLASS_SERIAL_USB;
     dc->vmsd = &vmstate_uhci;
-    dc->props = uhci_properties;
+    klass->props = uhci_properties;
 }
 
 static TypeInfo ich9_uhci1_info = {
@@ -1345,7 +1345,7 @@ static void ich9_uhci2_class_init(ObjectClass *klass, void *data)
     k->revision = 0x03;
     k->class_id = PCI_CLASS_SERIAL_USB;
     dc->vmsd = &vmstate_uhci;
-    dc->props = uhci_properties;
+    klass->props = uhci_properties;
 }
 
 static TypeInfo ich9_uhci2_info = {
@@ -1366,7 +1366,7 @@ static void ich9_uhci3_class_init(ObjectClass *klass, void *data)
     k->revision = 0x03;
     k->class_id = PCI_CLASS_SERIAL_USB;
     dc->vmsd = &vmstate_uhci;
-    dc->props = uhci_properties;
+    klass->props = uhci_properties;
 }
 
 static TypeInfo ich9_uhci3_info = {
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 5cf1a64..67dcd53 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -2894,7 +2894,7 @@ static void xhci_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->vmsd    = &vmstate_xhci;
-    dc->props   = xhci_properties;
+    klass->props    = xhci_properties;
     k->init         = usb_xhci_initfn;
     k->vendor_id    = PCI_VENDOR_ID_NEC;
     k->device_id    = PCI_DEVICE_ID_NEC_UPD720200;
diff --git a/hw/usb/host-linux.c b/hw/usb/host-linux.c
index a95b0ed..548e207 100644
--- a/hw/usb/host-linux.c
+++ b/hw/usb/host-linux.c
@@ -1472,7 +1472,7 @@ static void usb_host_class_initfn(ObjectClass *klass, void *data)
     uc->handle_reset   = usb_host_handle_reset;
     uc->handle_destroy = usb_host_handle_destroy;
     dc->vmsd = &vmstate_usb_host;
-    dc->props = usb_host_dev_properties;
+    klass->props = usb_host_dev_properties;
 }
 
 static TypeInfo usb_host_dev_info = {
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 51c27b4..3cdd28a 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1479,7 +1479,7 @@ static void usbredir_class_initfn(ObjectClass *klass, void *data)
     uc->handle_reset   = usbredir_handle_reset;
     uc->handle_data    = usbredir_handle_data;
     uc->handle_control = usbredir_handle_control;
-    dc->props          = usbredir_properties;
+    klass->props          = usbredir_properties;
 }
 
 static TypeInfo usbredir_dev_info = {
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index cffee3d..212544a 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -131,7 +131,6 @@ static Property virtconsole_properties[] = {
 
 static void virtconsole_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
 
     k->is_console = true;
@@ -139,7 +138,7 @@ static void virtconsole_class_init(ObjectClass *klass, void *data)
     k->have_data = flush_buf;
     k->guest_open = guest_open;
     k->guest_close = guest_close;
-    dc->props = virtconsole_properties;
+    klass->props = virtconsole_properties;
 }
 
 static TypeInfo virtconsole_info = {
@@ -156,14 +155,13 @@ static Property virtserialport_properties[] = {
 
 static void virtserialport_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
 
     k->init = virtconsole_initfn;
     k->have_data = flush_buf;
     k->guest_open = guest_open;
     k->guest_close = guest_close;
-    dc->props = virtserialport_properties;
+    klass->props = virtserialport_properties;
 }
 
 static TypeInfo virtserialport_info = {
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index d08c159..871e756 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -961,7 +961,7 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data)
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = PCI_CLASS_STORAGE_SCSI;
     dc->reset = virtio_pci_reset;
-    dc->props = virtio_blk_properties;
+    klass->props = virtio_blk_properties;
 }
 
 static TypeInfo virtio_blk_info = {
@@ -995,7 +995,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data)
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
     dc->reset = virtio_pci_reset;
-    dc->props = virtio_net_properties;
+    klass->props = virtio_net_properties;
 }
 
 static TypeInfo virtio_net_info = {
@@ -1026,7 +1026,7 @@ static void virtio_serial_class_init(ObjectClass *klass, void *data)
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
     dc->reset = virtio_pci_reset;
-    dc->props = virtio_serial_properties;
+    klass->props = virtio_serial_properties;
 }
 
 static TypeInfo virtio_serial_info = {
@@ -1054,7 +1054,7 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data)
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = PCI_CLASS_OTHERS;
     dc->reset = virtio_pci_reset;
-    dc->props = virtio_balloon_properties;
+    klass->props = virtio_balloon_properties;
 }
 
 static TypeInfo virtio_balloon_info = {
@@ -1108,7 +1108,7 @@ static void virtio_scsi_class_init(ObjectClass *klass, void *data)
     k->revision = 0x00;
     k->class_id = PCI_CLASS_STORAGE_SCSI;
     dc->reset = virtio_pci_reset;
-    dc->props = virtio_scsi_properties;
+    klass->props = virtio_scsi_properties;
 }
 
 static TypeInfo virtio_scsi_info = {
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 96382a4..2636fdd 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -995,7 +995,7 @@ static void virtio_serial_port_class_init(ObjectClass *klass, void *data)
     k->bus_type = TYPE_VIRTIO_SERIAL_BUS;
     k->exit = virtser_port_qdev_exit;
     k->unplug = qdev_simple_unplug_cb;
-    k->props = virtser_props;
+    klass->props = virtser_props;
 }
 
 static TypeInfo virtio_serial_port_type_info = {
diff --git a/hw/vmmouse.c b/hw/vmmouse.c
index 6338efa..0fb7064 100644
--- a/hw/vmmouse.c
+++ b/hw/vmmouse.c
@@ -284,7 +284,7 @@ static void vmmouse_class_initfn(ObjectClass *klass, void *data)
     dc->no_user = 1;
     dc->reset = vmmouse_reset;
     dc->vmsd = &vmstate_vmmouse;
-    dc->props = vmmouse_properties;
+    klass->props = vmmouse_properties;
 }
 
 static TypeInfo vmmouse_info = {
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 6fb7950..59d1f0f 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -471,7 +471,7 @@ static void via_pm_class_init(ObjectClass *klass, void *data)
     k->revision = 0x40;
     dc->desc = "PM";
     dc->vmsd = &vmstate_acpi;
-    dc->props = via_pm_properties;
+    klass->props = via_pm_properties;
 }
 
 static TypeInfo via_pm_info = {
diff --git a/hw/xgmac.c b/hw/xgmac.c
index dd4bdc4..70ce403 100644
--- a/hw/xgmac.c
+++ b/hw/xgmac.c
@@ -415,7 +415,7 @@ static void xgmac_enet_class_init(ObjectClass *klass, void *data)
 
     sbc->init = xgmac_enet_init;
     dc->vmsd = &vmstate_xgmac;
-    dc->props = xgmac_properties;
+    klass->props = xgmac_properties;
 }
 
 static TypeInfo xgmac_enet_info = {
diff --git a/hw/xilinx_axidma.c b/hw/xilinx_axidma.c
index 85dfcbf..710c2ca 100644
--- a/hw/xilinx_axidma.c
+++ b/hw/xilinx_axidma.c
@@ -494,11 +494,10 @@ static Property axidma_properties[] = {
 
 static void axidma_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = xilinx_axidma_init;
-    dc->props = axidma_properties;
+    klass->props = axidma_properties;
 }
 
 static TypeInfo axidma_info = {
diff --git a/hw/xilinx_axienet.c b/hw/xilinx_axienet.c
index 7526273..326ce0c 100644
--- a/hw/xilinx_axienet.c
+++ b/hw/xilinx_axienet.c
@@ -881,11 +881,10 @@ static Property xilinx_enet_properties[] = {
 
 static void xilinx_enet_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = xilinx_enet_init;
-    dc->props = xilinx_enet_properties;
+    klass->props = xilinx_enet_properties;
 }
 
 static TypeInfo xilinx_enet_info = {
diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c
index 857b33d..7164891 100644
--- a/hw/xilinx_ethlite.c
+++ b/hw/xilinx_ethlite.c
@@ -235,11 +235,10 @@ static Property xilinx_ethlite_properties[] = {
 
 static void xilinx_ethlite_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = xilinx_ethlite_init;
-    dc->props = xilinx_ethlite_properties;
+    klass->props = xilinx_ethlite_properties;
 }
 
 static TypeInfo xilinx_ethlite_info = {
diff --git a/hw/xilinx_intc.c b/hw/xilinx_intc.c
index 553f848..8acda8f 100644
--- a/hw/xilinx_intc.c
+++ b/hw/xilinx_intc.c
@@ -168,11 +168,10 @@ static Property xilinx_intc_properties[] = {
 
 static void xilinx_intc_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = xilinx_intc_init;
-    dc->props = xilinx_intc_properties;
+    klass->props = xilinx_intc_properties;
 }
 
 static TypeInfo xilinx_intc_info = {
diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
index 3ab2f2b..2e441b4 100644
--- a/hw/xilinx_timer.c
+++ b/hw/xilinx_timer.c
@@ -227,11 +227,10 @@ static Property xilinx_timer_properties[] = {
 
 static void xilinx_timer_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = xilinx_timer_init;
-    dc->props = xilinx_timer_properties;
+    klass->props = xilinx_timer_properties;
 }
 
 static TypeInfo xilinx_timer_info = {
diff --git a/hw/xio3130_downstream.c b/hw/xio3130_downstream.c
index 319624f..6528af0 100644
--- a/hw/xio3130_downstream.c
+++ b/hw/xio3130_downstream.c
@@ -193,7 +193,7 @@ static void xio3130_downstream_class_init(ObjectClass *klass, void *data)
     dc->desc = "TI X3130 Downstream Port of PCI Express Switch";
     dc->reset = xio3130_downstream_reset;
     dc->vmsd = &vmstate_xio3130_downstream;
-    dc->props = xio3130_downstream_properties;
+    klass->props = xio3130_downstream_properties;
 }
 
 static TypeInfo xio3130_downstream_info = {
diff --git a/hw/xio3130_upstream.c b/hw/xio3130_upstream.c
index 34a99bb..4ff5e4c 100644
--- a/hw/xio3130_upstream.c
+++ b/hw/xio3130_upstream.c
@@ -167,7 +167,7 @@ static void xio3130_upstream_class_init(ObjectClass *klass, void *data)
     dc->desc = "TI X3130 Upstream Port of PCI Express Switch";
     dc->reset = xio3130_upstream_reset;
     dc->vmsd = &vmstate_xio3130_upstream;
-    dc->props = xio3130_upstream_properties;
+    klass->props = xio3130_upstream_properties;
 }
 
 static TypeInfo xio3130_upstream_info = {
diff --git a/hw/zaurus.c b/hw/zaurus.c
index 72838ec..4aca57c 100644
--- a/hw/zaurus.c
+++ b/hw/zaurus.c
@@ -233,7 +233,7 @@ static void scoop_sysbus_class_init(ObjectClass *klass, void *data)
     k->init = scoop_init;
     dc->desc = "Scoop2 Sharp custom ASIC";
     dc->vmsd = &vmstate_scoop_regs;
-    dc->props = scoop_sysbus_properties;
+    klass->props = scoop_sysbus_properties;
 }
 
 static TypeInfo scoop_sysbus_info = {
diff --git a/include/qemu/object.h b/include/qemu/object.h
index 048ac86..5736d1d 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -33,6 +33,9 @@ typedef struct TypeInfo TypeInfo;
 typedef struct InterfaceClass InterfaceClass;
 typedef struct InterfaceInfo InterfaceInfo;
 
+typedef struct Property Property;
+typedef struct PropertyInfo PropertyInfo;
+
 #define TYPE_OBJECT "object"
 
 /**
@@ -241,6 +244,7 @@ struct ObjectClass
     Type type;
 
     /*< public >*/
+    Property *props;
     void (*realize)(Object *obj, struct Error **errp);
     void (*realize_children)(Object *obj, struct Error **errp);
     void (*unrealize)(Object *obj);
@@ -989,9 +993,6 @@ int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
  */
 Object *container_get(Object *root, const char *path);
 
-typedef struct Property Property;
-typedef struct PropertyInfo PropertyInfo;
-
 struct Property {
     const char   *name;
     PropertyInfo *info;
diff --git a/qom/object.c b/qom/object.c
index c1f1bb4..212f163 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1323,12 +1323,31 @@ bool object_is_realized(Object *obj)
     return obj->realized;
 }
 
+static void object_class_base_init(ObjectClass *klass, void *data)
+{
+    /* We explicitly look up properties in the superclasses,
+     * so do not propagate them to the subclasses.
+     */
+    klass->props = NULL;
+}
+
 static void object_instance_init(Object *obj)
 {
+    ObjectClass *class;
+    Property *prop;
+
     object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
 
     object_property_add(obj, "realized", "bool", object_get_realized,
                         object_set_realized, NULL, NULL, NULL);
+
+    class = object_get_class(obj);
+    do {
+        for (prop = OBJECT_CLASS(class)->props; prop && prop->name; prop++) {
+            object_property_add_static(obj, prop, NULL);
+        }
+        class = object_class_get_parent(class);
+    } while (class != object_class_by_name(TYPE_OBJECT));
 }
 
 static void object_class_init(ObjectClass *klass, void *class_data)
@@ -1348,6 +1367,7 @@ static void register_types(void)
     static TypeInfo object_info = {
         .name = TYPE_OBJECT,
         .instance_size = sizeof(Object),
+        .class_base_init = object_class_base_init,
         .class_init = object_class_init,
         .instance_init = object_instance_init,
         .abstract = true,
-- 
1.7.7

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

* [Qemu-devel] [PATCH qom-next v2 7/7] qom: Add QERR_PROPERTY_SET_AFTER_REALIZE
  2012-06-10  1:09 [Qemu-devel] [PATCH qom-next v2 0/7] QOM realize, revised again Andreas Färber
                   ` (5 preceding siblings ...)
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 6/7] qom: Push static properties to Object Andreas Färber
@ 2012-06-10  1:09 ` Andreas Färber
  6 siblings, 0 replies; 9+ messages in thread
From: Andreas Färber @ 2012-06-10  1:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Andreas Färber, Anthony Liguori,
	Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

Add a new QError QERR_PROPERTY_SET_AFTER_REALIZE for attempts
to set a QOM or qdev property after the object/device has been
realized. This allows a slightly more informative diagnostic
than the previous "Insufficient permission" message.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[AF: Use object_get_typename() in place of object_get_id().]
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 hw/qdev-properties.c    |   15 ++++++++++-----
 qerror.c                |    4 ++++
 qerror.h                |    3 +++
 qom/object-properties.c |   24 ++++++++++++++++--------
 4 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 940bf39..c099bec 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -76,7 +76,8 @@ static void set_pointer(Object *obj, Visitor *v, Property *prop,
     int ret;
 
     if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
+        error_set(errp, QERR_PROPERTY_SET_AFTER_REALIZE,
+                  object_get_typename(obj), name);
         return;
     }
 
@@ -242,7 +243,8 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque,
     VLANState *vlan;
 
     if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
+        error_set(errp, QERR_PROPERTY_SET_AFTER_REALIZE,
+                  object_get_typename(obj), name);
         return;
     }
 
@@ -303,7 +305,8 @@ static void set_mac(Object *obj, Visitor *v, void *opaque,
     char *str, *p;
 
     if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
+        error_set(errp, QERR_PROPERTY_SET_AFTER_REALIZE,
+                  object_get_typename(obj), name);
         return;
     }
 
@@ -391,7 +394,8 @@ static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
     char *str;
 
     if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
+        error_set(errp, QERR_PROPERTY_SET_AFTER_REALIZE,
+                  object_get_typename(obj), name);
         return;
     }
 
@@ -469,7 +473,8 @@ static void set_blocksize(Object *obj, Visitor *v, void *opaque,
     const int64_t max = 32768;
 
     if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
+        error_set(errp, QERR_PROPERTY_SET_AFTER_REALIZE,
+                  object_get_typename(obj), name);
         return;
     }
 
diff --git a/qerror.c b/qerror.c
index 92c4eff..d3768cb 100644
--- a/qerror.c
+++ b/qerror.c
@@ -233,6 +233,10 @@ static const QErrorStringTable qerror_table[] = {
         .desc      = "Property '%(device).%(property)' not found",
     },
     {
+        .error_fmt = QERR_PROPERTY_SET_AFTER_REALIZE,
+        .desc      = "Property '%(device).%(property)' cannot be set after realize",
+    },
+    {
         .error_fmt = QERR_PROPERTY_VALUE_BAD,
         .desc      = "Property '%(device).%(property)' doesn't take value '%(value)'",
     },
diff --git a/qerror.h b/qerror.h
index b4c8758..b5cb730 100644
--- a/qerror.h
+++ b/qerror.h
@@ -196,6 +196,9 @@ QError *qobject_to_qerror(const QObject *obj);
 #define QERR_PROPERTY_NOT_FOUND \
     "{ 'class': 'PropertyNotFound', 'data': { 'device': %s, 'property': %s } }"
 
+#define QERR_PROPERTY_SET_AFTER_REALIZE \
+    "{ 'class': 'PropertySetAfterRealize', 'data': { 'device': %s, 'property': %s } }"
+
 #define QERR_PROPERTY_VALUE_BAD \
     "{ 'class': 'PropertyValueBad', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
 
diff --git a/qom/object-properties.c b/qom/object-properties.c
index 6765e90..e93c3db 100644
--- a/qom/object-properties.c
+++ b/qom/object-properties.c
@@ -50,7 +50,8 @@ static void set_bit(Object *obj, Visitor *v, void *opaque,
     bool value;
 
     if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
+        error_set(errp, QERR_PROPERTY_SET_AFTER_REALIZE,
+                  object_get_typename(obj), name);
         return;
     }
 
@@ -88,7 +89,8 @@ static void set_uint8(Object *obj, Visitor *v, void *opaque,
     uint8_t *ptr = object_get_prop_ptr(obj, prop);
 
     if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
+        error_set(errp, QERR_PROPERTY_SET_AFTER_REALIZE,
+                  object_get_typename(obj), name);
         return;
     }
 
@@ -153,7 +155,8 @@ static void set_uint16(Object *obj, Visitor *v, void *opaque,
     uint16_t *ptr = object_get_prop_ptr(obj, prop);
 
     if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
+        error_set(errp, QERR_PROPERTY_SET_AFTER_REALIZE,
+                  object_get_typename(obj), name);
         return;
     }
 
@@ -184,7 +187,8 @@ static void set_uint32(Object *obj, Visitor *v, void *opaque,
     uint32_t *ptr = object_get_prop_ptr(obj, prop);
 
     if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
+        error_set(errp, QERR_PROPERTY_SET_AFTER_REALIZE,
+                  object_get_typename(obj), name);
         return;
     }
 
@@ -207,7 +211,8 @@ static void set_int32(Object *obj, Visitor *v, void *opaque,
     int32_t *ptr = object_get_prop_ptr(obj, prop);
 
     if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
+        error_set(errp, QERR_PROPERTY_SET_AFTER_REALIZE,
+                  object_get_typename(obj), name);
         return;
     }
 
@@ -278,7 +283,8 @@ static void set_uint64(Object *obj, Visitor *v, void *opaque,
     uint64_t *ptr = object_get_prop_ptr(obj, prop);
 
     if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
+        error_set(errp, QERR_PROPERTY_SET_AFTER_REALIZE,
+                  object_get_typename(obj), name);
         return;
     }
 
@@ -364,7 +370,8 @@ static void set_string(Object *obj, Visitor *v, void *opaque,
     char *str;
 
     if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
+        error_set(errp, QERR_PROPERTY_SET_AFTER_REALIZE,
+                  object_get_typename(obj), name);
         return;
     }
 
@@ -407,7 +414,8 @@ void property_set_enum(Object *obj, Visitor *v, void *opaque,
     int *ptr = object_get_prop_ptr(obj, prop);
 
     if (object_is_realized(obj)) {
-        error_set(errp, QERR_PERMISSION_DENIED);
+        error_set(errp, QERR_PROPERTY_SET_AFTER_REALIZE,
+                  object_get_typename(obj), name);
         return;
     }
 
-- 
1.7.7

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

* Re: [Qemu-devel] [PATCH qom-next v2 1/7] make_device_config.sh: Fix target path in generated dependency file
  2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 1/7] make_device_config.sh: Fix target path in generated dependency file Andreas Färber
@ 2012-06-10  1:50   ` Andreas Färber
  0 siblings, 0 replies; 9+ messages in thread
From: Andreas Färber @ 2012-06-10  1:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Anthony Liguori

Am 10.06.2012 03:09, schrieb Andreas Färber:
> config-devices.mak.d is included from Makefile.target, i.e. from inside
> the *-softmmu/ directory. It included the directory path, so never
> applied to the actual config-devices.mak. Symptoms were spurious
> dependency issues with default-configs/pci.mak.
> 
> Fix by using `basename` to strip the directory path.
> 
> Reported-by: Gerhard Wiesinger <lists@wiesinger.com>
> Signed-off-by: Andreas Färber <afaerber@suse.de>

Sorry, this patch was not supposed to be in this series, it was
submitted already. (That comes from dropping one patch...)

/-F

> ---
>  scripts/make_device_config.sh |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/scripts/make_device_config.sh b/scripts/make_device_config.sh
> index 5d14885..0778fe2 100644
> --- a/scripts/make_device_config.sh
> +++ b/scripts/make_device_config.sh
> @@ -25,4 +25,4 @@ done
>  process_includes $src > $dest
>  
>  cat $src $all_includes | grep -v '^include' > $dest
> -echo "$1: $all_includes" > $dep
> +echo "`basename $1`: $all_includes" > $dep

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

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

end of thread, other threads:[~2012-06-10  1:51 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-10  1:09 [Qemu-devel] [PATCH qom-next v2 0/7] QOM realize, revised again Andreas Färber
2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 1/7] make_device_config.sh: Fix target path in generated dependency file Andreas Färber
2012-06-10  1:50   ` Andreas Färber
2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 2/7] qdev: Push state up to Object Andreas Färber
2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 3/7] qom: Add "realized" property Andreas Färber
2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 4/7] qdev: Generalize properties to Objects Andreas Färber
2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 5/7] qdev: Move bulk of qdev-properties.c to qom/object-properties.c Andreas Färber
2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 6/7] qom: Push static properties to Object Andreas Färber
2012-06-10  1:09 ` [Qemu-devel] [PATCH qom-next v2 7/7] qom: Add QERR_PROPERTY_SET_AFTER_REALIZE Andreas Färber

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).