aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2012-02-08 07:24:37 -0600
committerAnthony Liguori <aliguori@us.ibm.com>2012-02-08 07:24:37 -0600
commita642153013b2d0af106c0d4b9a637677d1e2c010 (patch)
tree5a242376c84726634ae3fdf88ba36dd22824c75e /hw
parentdc717bfd057ac3d6b75c633d57e501d5e6d5ef50 (diff)
parenta3d4a1b0479414fc4d59368a0635640979a9e4d2 (diff)
Merge remote-tracking branch 'bonzini/qdev-props-for-anthony' into staging
* bonzini/qdev-props-for-anthony: (25 commits) qdev: remove unused fields from PropertyInfo qdev: initialize properties via QOM qdev: inline qdev_prop_set into qdev_prop_set_ptr qdev: access properties via QOM qdev: fix off-by-one qdev: let QOM free properties qdev: remove parse/print methods for pointer properties qdev: make the non-legacy pci address property accept an integer qdev: remove parse/print methods for mac properties qdev: remove print/parse methods from LostTickPolicy properties qdev: remove parse method for string properties qdev: allow reusing get/set for legacy property qdev: remove direct calls to print/parse qom: add property get/set wrappers for links qom: fix canonical paths vs. interfaces qom: use object_resolve_path_type for links qom: add object_resolve_path_type qom: fix off-by-one qom: add property get/set wrappers for C types qom: add QObject-based property get/set wrappers ...
Diffstat (limited to 'hw')
-rw-r--r--hw/qdev-addr.c7
-rw-r--r--hw/qdev-monitor.c30
-rw-r--r--hw/qdev-properties.c510
-rw-r--r--hw/qdev.c32
-rw-r--r--hw/qdev.h39
5 files changed, 304 insertions, 314 deletions
diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
index 5976dcdf47..0bb16c7eb3 100644
--- a/hw/qdev-addr.c
+++ b/hw/qdev-addr.c
@@ -61,8 +61,6 @@ static void set_taddr(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_taddr = {
.name = "taddr",
- .type = PROP_TYPE_TADDR,
- .size = sizeof(target_phys_addr_t),
.parse = parse_taddr,
.print = print_taddr,
.get = get_taddr,
@@ -71,5 +69,8 @@ PropertyInfo qdev_prop_taddr = {
void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_TADDR);
+ Error *errp = NULL;
+ object_property_set_int(OBJECT(dev), value, name, &errp);
+ assert(!errp);
+
}
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 135c2bf237..49f13ca087 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -485,22 +485,26 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent);
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
const char *prefix, int indent)
{
- char buf[64];
-
if (!props)
return;
- while (props->name) {
- /*
- * TODO Properties without a print method are just for dirty
- * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
- * marked for removal. The test props->info->print should be
- * removed along with it.
- */
- if (props->info->print) {
- props->info->print(dev, props, buf, sizeof(buf));
- qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
+ for (; props->name; props++) {
+ Error *err = NULL;
+ char *value;
+ char *legacy_name = g_strdup_printf("legacy-%s", props->name);
+ if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
+ value = object_property_get_str(OBJECT(dev), legacy_name, &err);
+ } else {
+ value = object_property_get_str(OBJECT(dev), props->name, &err);
+ }
+ g_free(legacy_name);
+
+ if (err) {
+ error_free(err);
+ continue;
}
- props++;
+ qdev_printf("%s-prop: %s = %s\n", prefix, props->name,
+ value && *value ? value : "<null>");
+ g_free(value);
}
}
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index c4583a14d7..b6d6fcff01 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -12,7 +12,7 @@ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
static uint32_t qdev_get_prop_mask(Property *prop)
{
- assert(prop->info->type == PROP_TYPE_BIT);
+ assert(prop->info == &qdev_prop_bit);
return 0x1 << prop->bitnr;
}
@@ -26,17 +26,6 @@ static void bit_prop_set(DeviceState *dev, Property *props, bool val)
*p &= ~mask;
}
-static void qdev_prop_cpy(DeviceState *dev, Property *props, void *src)
-{
- if (props->info->type == PROP_TYPE_BIT) {
- bool *defval = src;
- bit_prop_set(dev, props, *defval);
- } else {
- char *dst = qdev_get_prop_ptr(dev, props);
- memcpy(dst, src, props->info->size);
- }
-}
-
/* Bit */
static int parse_bit(DeviceState *dev, Property *prop, const char *str)
{
@@ -90,8 +79,6 @@ static void set_bit(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_bit = {
.name = "boolean",
.legacy_name = "on/off",
- .type = PROP_TYPE_BIT,
- .size = sizeof(uint32_t),
.parse = parse_bit,
.print = print_bit,
.get = get_bit,
@@ -151,7 +138,7 @@ static void set_int8(Object *obj, Visitor *v, void *opaque,
error_propagate(errp, local_err);
return;
}
- if (value > prop->info->min && value <= prop->info->max) {
+ if (value >= prop->info->min && value <= prop->info->max) {
*ptr = value;
} else {
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
@@ -162,8 +149,6 @@ static void set_int8(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_uint8 = {
.name = "uint8",
- .type = PROP_TYPE_UINT8,
- .size = sizeof(uint8_t),
.parse = parse_uint8,
.print = print_uint8,
.get = get_int8,
@@ -196,8 +181,6 @@ static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
PropertyInfo qdev_prop_hex8 = {
.name = "uint8",
.legacy_name = "hex8",
- .type = PROP_TYPE_UINT8,
- .size = sizeof(uint8_t),
.parse = parse_hex8,
.print = print_hex8,
.get = get_int8,
@@ -259,7 +242,7 @@ static void set_int16(Object *obj, Visitor *v, void *opaque,
error_propagate(errp, local_err);
return;
}
- if (value > prop->info->min && value <= prop->info->max) {
+ if (value >= prop->info->min && value <= prop->info->max) {
*ptr = value;
} else {
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
@@ -270,8 +253,6 @@ static void set_int16(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_uint16 = {
.name = "uint16",
- .type = PROP_TYPE_UINT16,
- .size = sizeof(uint16_t),
.parse = parse_uint16,
.print = print_uint16,
.get = get_int16,
@@ -333,7 +314,7 @@ static void set_int32(Object *obj, Visitor *v, void *opaque,
error_propagate(errp, local_err);
return;
}
- if (value > prop->info->min && value <= prop->info->max) {
+ if (value >= prop->info->min && value <= prop->info->max) {
*ptr = value;
} else {
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
@@ -344,8 +325,6 @@ static void set_int32(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_uint32 = {
.name = "uint32",
- .type = PROP_TYPE_UINT32,
- .size = sizeof(uint32_t),
.parse = parse_uint32,
.print = print_uint32,
.get = get_int32,
@@ -375,8 +354,6 @@ static int print_int32(DeviceState *dev, Property *prop, char *dest, size_t len)
PropertyInfo qdev_prop_int32 = {
.name = "int32",
- .type = PROP_TYPE_INT32,
- .size = sizeof(int32_t),
.parse = parse_int32,
.print = print_int32,
.get = get_int32,
@@ -409,8 +386,6 @@ static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
PropertyInfo qdev_prop_hex32 = {
.name = "uint32",
.legacy_name = "hex32",
- .type = PROP_TYPE_UINT32,
- .size = sizeof(uint32_t),
.parse = parse_hex32,
.print = print_hex32,
.get = get_int32,
@@ -468,8 +443,6 @@ static void set_int64(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_uint64 = {
.name = "uint64",
- .type = PROP_TYPE_UINT64,
- .size = sizeof(uint64_t),
.parse = parse_uint64,
.print = print_uint64,
.get = get_int64,
@@ -500,8 +473,6 @@ static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
PropertyInfo qdev_prop_hex64 = {
.name = "uint64",
.legacy_name = "hex64",
- .type = PROP_TYPE_UINT64,
- .size = sizeof(uint64_t),
.parse = parse_hex64,
.print = print_hex64,
.get = get_int64,
@@ -510,19 +481,10 @@ PropertyInfo qdev_prop_hex64 = {
/* --- string --- */
-static int parse_string(DeviceState *dev, Property *prop, const char *str)
-{
- char **ptr = qdev_get_prop_ptr(dev, prop);
-
- if (*ptr)
- g_free(*ptr);
- *ptr = g_strdup(str);
- return 0;
-}
-
-static void free_string(DeviceState *dev, Property *prop)
+static void release_string(Object *obj, const char *name, void *opaque)
{
- g_free(*(char **)qdev_get_prop_ptr(dev, prop));
+ Property *prop = opaque;
+ g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
}
static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
@@ -579,20 +541,16 @@ static void set_string(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_string = {
.name = "string",
- .type = PROP_TYPE_STRING,
- .size = sizeof(char*),
- .parse = parse_string,
.print = print_string,
- .free = free_string,
+ .release = release_string,
.get = get_string,
.set = set_string,
};
/* --- drive --- */
-static int parse_drive(DeviceState *dev, Property *prop, const char *str)
+static int parse_drive(DeviceState *dev, const char *str, void **ptr)
{
- BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
BlockDriverState *bs;
bs = bdrv_find(str);
@@ -604,8 +562,10 @@ static int parse_drive(DeviceState *dev, Property *prop, const char *str)
return 0;
}
-static void free_drive(DeviceState *dev, Property *prop)
+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);
if (*ptr) {
@@ -614,35 +574,30 @@ static void free_drive(DeviceState *dev, Property *prop)
}
}
-static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len)
+static const char *print_drive(void *ptr)
{
- BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
- return snprintf(dest, len, "%s",
- *ptr ? bdrv_get_device_name(*ptr) : "<null>");
+ return bdrv_get_device_name(ptr);
}
-static void get_generic(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
+static void get_pointer(Object *obj, Visitor *v, Property *prop,
+ const char *(*print)(void *ptr),
+ const char *name, Error **errp)
{
DeviceState *dev = DEVICE(obj);
- Property *prop = opaque;
void **ptr = qdev_get_prop_ptr(dev, prop);
- char buffer[1024];
- char *p = buffer;
+ char *p;
- buffer[0] = 0;
- if (*ptr) {
- prop->info->print(dev, prop, buffer, sizeof(buffer));
- }
+ p = (char *) (*ptr ? print(*ptr) : "");
visit_type_str(v, &p, name, errp);
}
-static void set_generic(Object *obj, Visitor *v, void *opaque,
+static void set_pointer(Object *obj, Visitor *v, Property *prop,
+ int (*parse)(DeviceState *dev, const char *str, void **ptr),
const char *name, Error **errp)
{
DeviceState *dev = DEVICE(obj);
- Property *prop = opaque;
Error *local_err = NULL;
+ void **ptr = qdev_get_prop_ptr(dev, prop);
char *str;
int ret;
@@ -661,41 +616,50 @@ static void set_generic(Object *obj, Visitor *v, void *opaque,
error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
return;
}
- ret = prop->info->parse(dev, prop, str);
+ ret = parse(dev, str, ptr);
error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
g_free(str);
}
+static void get_drive(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ get_pointer(obj, v, opaque, print_drive, name, errp);
+}
+
+static void set_drive(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ set_pointer(obj, v, opaque, parse_drive, name, errp);
+}
+
PropertyInfo qdev_prop_drive = {
.name = "drive",
- .type = PROP_TYPE_DRIVE,
- .size = sizeof(BlockDriverState *),
- .parse = parse_drive,
- .print = print_drive,
- .get = get_generic,
- .set = set_generic,
- .free = free_drive,
+ .get = get_drive,
+ .set = set_drive,
+ .release = release_drive,
};
/* --- character device --- */
-static int parse_chr(DeviceState *dev, Property *prop, const char *str)
+static int parse_chr(DeviceState *dev, const char *str, void **ptr)
{
- CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
-
- *ptr = qemu_chr_find(str);
- if (*ptr == NULL) {
+ CharDriverState *chr = qemu_chr_find(str);
+ if (chr == NULL) {
return -ENOENT;
}
- if ((*ptr)->avail_connections < 1) {
+ if (chr->avail_connections < 1) {
return -EEXIST;
}
- --(*ptr)->avail_connections;
+ *ptr = chr;
+ --chr->avail_connections;
return 0;
}
-static void free_chr(DeviceState *dev, Property *prop)
+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);
if (*ptr) {
@@ -704,62 +668,71 @@ static void free_chr(DeviceState *dev, Property *prop)
}
-static int print_chr(DeviceState *dev, Property *prop, char *dest, size_t len)
+static const char *print_chr(void *ptr)
{
- CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
+ CharDriverState *chr = ptr;
- if (*ptr && (*ptr)->label) {
- return snprintf(dest, len, "%s", (*ptr)->label);
- } else {
- return snprintf(dest, len, "<null>");
- }
+ return chr->label ? chr->label : "";
+}
+
+static void get_chr(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ get_pointer(obj, v, opaque, print_chr, name, errp);
+}
+
+static void set_chr(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ set_pointer(obj, v, opaque, parse_chr, name, errp);
}
PropertyInfo qdev_prop_chr = {
.name = "chr",
- .type = PROP_TYPE_CHR,
- .size = sizeof(CharDriverState*),
- .parse = parse_chr,
- .print = print_chr,
- .get = get_generic,
- .set = set_generic,
- .free = free_chr,
+ .get = get_chr,
+ .set = set_chr,
+ .release = release_chr,
};
/* --- netdev device --- */
-static int parse_netdev(DeviceState *dev, Property *prop, const char *str)
+static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
{
- VLANClientState **ptr = qdev_get_prop_ptr(dev, prop);
+ VLANClientState *netdev = qemu_find_netdev(str);
- *ptr = qemu_find_netdev(str);
- if (*ptr == NULL)
+ if (netdev == NULL) {
return -ENOENT;
- if ((*ptr)->peer) {
+ }
+ if (netdev->peer) {
return -EEXIST;
}
+ *ptr = netdev;
return 0;
}
-static int print_netdev(DeviceState *dev, Property *prop, char *dest, size_t len)
+static const char *print_netdev(void *ptr)
{
- VLANClientState **ptr = qdev_get_prop_ptr(dev, prop);
+ VLANClientState *netdev = ptr;
- if (*ptr && (*ptr)->name) {
- return snprintf(dest, len, "%s", (*ptr)->name);
- } else {
- return snprintf(dest, len, "<null>");
- }
+ return netdev->name ? netdev->name : "";
+}
+
+static void get_netdev(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ get_pointer(obj, v, opaque, print_netdev, name, errp);
+}
+
+static void set_netdev(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ set_pointer(obj, v, opaque, parse_netdev, name, errp);
}
PropertyInfo qdev_prop_netdev = {
.name = "netdev",
- .type = PROP_TYPE_NETDEV,
- .size = sizeof(VLANClientState*),
- .parse = parse_netdev,
- .print = print_netdev,
- .get = get_generic,
- .set = set_generic,
+ .get = get_netdev,
+ .set = set_netdev,
};
/* --- vlan --- */
@@ -835,8 +808,6 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_vlan = {
.name = "vlan",
- .type = PROP_TYPE_VLAN,
- .size = sizeof(VLANClientState*),
.parse = parse_vlan,
.print = print_vlan,
.get = get_vlan,
@@ -848,8 +819,6 @@ PropertyInfo qdev_prop_vlan = {
/* Not a proper property, just for dirty hacks. TODO Remove it! */
PropertyInfo qdev_prop_ptr = {
.name = "ptr",
- .type = PROP_TYPE_PTR,
- .size = sizeof(void*),
};
/* --- mac address --- */
@@ -859,95 +828,114 @@ PropertyInfo qdev_prop_ptr = {
* 01:02:03:04:05:06
* 01-02-03-04-05-06
*/
-static int parse_mac(DeviceState *dev, Property *prop, const char *str)
+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);
+ char buffer[2 * 6 + 5 + 1];
+ char *p = buffer;
+
+ snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac->a[0], mac->a[1], mac->a[2],
+ mac->a[3], mac->a[4], mac->a[5]);
+
+ visit_type_str(v, &p, name, errp);
+}
+
+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);
+ Error *local_err = NULL;
int i, pos;
- char *p;
+ char *str, *p;
+
+ if (dev->state != DEV_STATE_CREATED) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
+
+ visit_type_str(v, &str, name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
for (i = 0, pos = 0; i < 6; i++, pos += 3) {
if (!qemu_isxdigit(str[pos]))
- return -EINVAL;
+ goto inval;
if (!qemu_isxdigit(str[pos+1]))
- return -EINVAL;
+ goto inval;
if (i == 5) {
if (str[pos+2] != '\0')
- return -EINVAL;
+ goto inval;
} else {
if (str[pos+2] != ':' && str[pos+2] != '-')
- return -EINVAL;
+ goto inval;
}
mac->a[i] = strtol(str+pos, &p, 16);
}
- return 0;
-}
+ return;
-static int print_mac(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
- MACAddr *mac = qdev_get_prop_ptr(dev, prop);
-
- return snprintf(dest, len, "%02x:%02x:%02x:%02x:%02x:%02x",
- mac->a[0], mac->a[1], mac->a[2],
- mac->a[3], mac->a[4], mac->a[5]);
+inval:
+ error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
}
PropertyInfo qdev_prop_macaddr = {
.name = "macaddr",
- .type = PROP_TYPE_MACADDR,
- .size = sizeof(MACAddr),
- .parse = parse_mac,
- .print = print_mac,
- .get = get_generic,
- .set = set_generic,
+ .get = get_mac,
+ .set = set_mac,
};
/* --- lost tick policy --- */
-static const struct {
- const char *name;
- LostTickPolicy code;
-} lost_tick_policy_table[] = {
- { .name = "discard", .code = LOST_TICK_DISCARD },
- { .name = "delay", .code = LOST_TICK_DELAY },
- { .name = "merge", .code = LOST_TICK_MERGE },
- { .name = "slew", .code = LOST_TICK_SLEW },
+static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
+ [LOST_TICK_DISCARD] = "discard",
+ [LOST_TICK_DELAY] = "delay",
+ [LOST_TICK_MERGE] = "merge",
+ [LOST_TICK_SLEW] = "slew",
+ [LOST_TICK_MAX] = NULL,
};
-static int parse_lost_tick_policy(DeviceState *dev, Property *prop,
- const char *str)
+QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
+
+static void get_enum(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
- LostTickPolicy *ptr = qdev_get_prop_ptr(dev, prop);
- int i;
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ int *ptr = qdev_get_prop_ptr(dev, prop);
- for (i = 0; i < ARRAY_SIZE(lost_tick_policy_table); i++) {
- if (!strcasecmp(str, lost_tick_policy_table[i].name)) {
- *ptr = lost_tick_policy_table[i].code;
- break;
- }
- }
- if (i == ARRAY_SIZE(lost_tick_policy_table)) {
- return -EINVAL;
- }
- return 0;
+ visit_type_enum(v, ptr, prop->info->enum_table,
+ prop->info->name, prop->name, errp);
}
-static int print_lost_tick_policy(DeviceState *dev, Property *prop, char *dest,
- size_t len)
+static void set_enum(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
- LostTickPolicy *ptr = qdev_get_prop_ptr(dev, prop);
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ int *ptr = qdev_get_prop_ptr(dev, prop);
+
+ if (dev->state != DEV_STATE_CREATED) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
- return snprintf(dest, len, "%s", lost_tick_policy_table[*ptr].name);
+ visit_type_enum(v, ptr, prop->info->enum_table,
+ prop->info->name, prop->name, errp);
}
PropertyInfo qdev_prop_losttickpolicy = {
- .name = "lost_tick_policy",
- .type = PROP_TYPE_LOSTTICKPOLICY,
- .size = sizeof(LostTickPolicy),
- .parse = parse_lost_tick_policy,
- .print = print_lost_tick_policy,
- .get = get_generic,
- .set = set_generic,
+ .name = "LostTickPolicy",
+ .enum_table = lost_tick_policy_table,
+ .get = get_enum,
+ .set = set_enum,
};
/* --- pci address --- */
@@ -987,30 +975,18 @@ static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t
}
}
-static void get_pci_devfn(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
-{
- DeviceState *dev = DEVICE(obj);
- Property *prop = opaque;
- uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
- char buffer[32];
- char *p = buffer;
-
- buffer[0] = 0;
- if (*ptr != -1) {
- snprintf(buffer, sizeof(buffer), "%02x.%x", *ptr >> 3, *ptr & 7);
- }
- visit_type_str(v, &p, name, errp);
-}
-
PropertyInfo qdev_prop_pci_devfn = {
- .name = "pci-devfn",
- .type = PROP_TYPE_UINT32,
- .size = sizeof(uint32_t),
+ .name = "int32",
+ .legacy_name = "pci-devfn",
.parse = parse_pci_devfn,
.print = print_pci_devfn,
- .get = get_pci_devfn,
- .set = set_generic,
+ .get = get_int32,
+ .set = set_int32,
+ /* FIXME: this should be -1...255, but the address is stored
+ * into an uint32_t rather than int32_t.
+ */
+ .min = 0,
+ .max = 0xFFFFFFFFULL,
};
/* --- public helpers --- */
@@ -1073,24 +1049,18 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
{
- Property *prop;
- int ret;
+ char *legacy_name;
+ Error *err = NULL;
- prop = qdev_prop_find(dev, name);
- /*
- * TODO Properties without a parse method are just for dirty
- * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
- * marked for removal. The test !prop->info->parse should be
- * removed along with it.
- */
- if (!prop || !prop->info->parse) {
- qerror_report(QERR_PROPERTY_NOT_FOUND, object_get_typename(OBJECT(dev)), name);
- return -1;
+ legacy_name = g_strdup_printf("legacy-%s", name);
+ if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
+ object_property_set_str(OBJECT(dev), value, legacy_name, &err);
+ } else {
+ object_property_set_str(OBJECT(dev), value, name, &err);
}
- ret = prop->info->parse(dev, prop, value);
- if (ret < 0) {
- Error *err;
- error_set_from_qdev_prop_error(&err, ret, dev, prop, value);
+ g_free(legacy_name);
+
+ if (err) {
qerror_report_err(err);
error_free(err);
return -1;
@@ -1098,72 +1068,65 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
return 0;
}
-void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
-{
- Property *prop;
-
- prop = qdev_prop_find(dev, name);
- if (!prop) {
- fprintf(stderr, "%s: property \"%s.%s\" not found\n",
- __FUNCTION__, object_get_typename(OBJECT(dev)), name);
- abort();
- }
- if (prop->info->type != type) {
- fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n",
- __FUNCTION__, object_get_typename(OBJECT(dev)), name);
- abort();
- }
- qdev_prop_cpy(dev, prop, src);
-}
-
void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_BIT);
+ Error *errp = NULL;
+ object_property_set_bool(OBJECT(dev), value, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_UINT8);
+ Error *errp = NULL;
+ object_property_set_int(OBJECT(dev), value, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_UINT16);
+ Error *errp = NULL;
+ object_property_set_int(OBJECT(dev), value, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_UINT32);
+ Error *errp = NULL;
+ object_property_set_int(OBJECT(dev), value, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_INT32);
+ Error *errp = NULL;
+ object_property_set_int(OBJECT(dev), value, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_UINT64);
+ Error *errp = NULL;
+ object_property_set_int(OBJECT(dev), value, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_string(DeviceState *dev, const char *name, char *value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_STRING);
+ Error *errp = NULL;
+ object_property_set_str(OBJECT(dev), value, name, &errp);
+ assert(!errp);
}
int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
{
- int res;
-
- res = bdrv_attach_dev(value, dev);
- if (res < 0) {
- error_report("Can't attach drive %s to %s.%s: %s",
- bdrv_get_device_name(value),
- dev->id ? dev->id : object_get_typename(OBJECT(dev)),
- name, strerror(-res));
+ Error *errp = NULL;
+ object_property_set_str(OBJECT(dev), bdrv_get_device_name(value),
+ name, &errp);
+ if (errp) {
+ qerror_report_err(errp);
+ error_free(errp);
return -1;
}
- qdev_prop_set(dev, name, &value, PROP_TYPE_DRIVE);
return 0;
}
@@ -1175,44 +1138,79 @@ void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverS
}
void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_CHR);
+ Error *errp = NULL;
+ assert(value->label);
+ object_property_set_str(OBJECT(dev), value->label, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_NETDEV);
+ Error *errp = NULL;
+ assert(value->name);
+ object_property_set_str(OBJECT(dev), value->name, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_VLAN);
+ Error *errp = NULL;
+ object_property_set_int(OBJECT(dev), value ? value->id : -1, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
{
- qdev_prop_set(dev, name, value, PROP_TYPE_MACADDR);
+ Error *errp = NULL;
+ char str[2 * 6 + 5 + 1];
+ snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
+ value[0], value[1], value[2], value[3], value[4], value[5]);
+
+ object_property_set_str(OBJECT(dev), str, name, &errp);
+ assert(!errp);
}
-void qdev_prop_set_losttickpolicy(DeviceState *dev, const char *name,
- LostTickPolicy *value)
+void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
{
- qdev_prop_set(dev, name, value, PROP_TYPE_LOSTTICKPOLICY);
+ Property *prop;
+ Error *errp = NULL;
+
+ prop = qdev_prop_find(dev, name);
+ object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
+ name, &errp);
+ assert(!errp);
}
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_PTR);
+ Property *prop;
+ void **ptr;
+
+ prop = qdev_prop_find(dev, name);
+ assert(prop && prop->info == &qdev_prop_ptr);
+ ptr = qdev_get_prop_ptr(dev, prop);
+ *ptr = value;
}
void qdev_prop_set_defaults(DeviceState *dev, Property *props)
{
+ Object *obj = OBJECT(dev);
if (!props)
return;
- while (props->name) {
- if (props->defval) {
- qdev_prop_cpy(dev, props, props->defval);
+ for (; props->name; props++) {
+ Error *errp = NULL;
+ if (props->qtype == QTYPE_NONE) {
+ continue;
}
- props++;
+ if (props->qtype == QTYPE_QBOOL) {
+ object_property_set_bool(obj, props->defval, props->name, &errp);
+ } else if (props->info->enum_table) {
+ object_property_set_str(obj, props->info->enum_table[props->defval],
+ props->name, &errp);
+ } else if (props->qtype == QTYPE_QINT) {
+ object_property_set_int(obj, props->defval, props->name, &errp);
+ }
+ assert(!errp);
}
}
diff --git a/hw/qdev.c b/hw/qdev.c
index e3b53b7f62..8a413ef0ed 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -86,11 +86,11 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
dev->parent_bus = bus;
QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
- qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
for (prop = qdev_get_bus_info(dev)->props; prop && prop->name; prop++) {
qdev_property_add_legacy(dev, prop, NULL);
qdev_property_add_static(dev, prop, NULL);
}
+ qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
}
/* Create a new device. This only initializes the device state structure
@@ -550,21 +550,24 @@ static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
* Do not use this is new code! Properties added through this interface will
* be given names and types in the "legacy" namespace.
*
- * Legacy properties are always processed as strings. The format of the string
- * depends on the property type.
+ * Legacy properties are string versions of other OOM properties. The format
+ * of the string depends on the property type.
*/
void qdev_property_add_legacy(DeviceState *dev, Property *prop,
Error **errp)
{
gchar *name, *type;
+ if (!prop->info->print && !prop->info->parse) {
+ return;
+ }
name = g_strdup_printf("legacy-%s", prop->name);
type = g_strdup_printf("legacy<%s>",
prop->info->legacy_name ?: prop->info->name);
object_property_add(OBJECT(dev), name, type,
- prop->info->print ? qdev_get_legacy_property : NULL,
- prop->info->parse ? qdev_set_legacy_property : NULL,
+ prop->info->print ? qdev_get_legacy_property : prop->info->get,
+ prop->info->parse ? qdev_set_legacy_property : prop->info->set,
NULL,
prop, errp);
@@ -581,9 +584,18 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
void qdev_property_add_static(DeviceState *dev, Property *prop,
Error **errp)
{
+ /*
+ * 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(OBJECT(dev), prop->name, prop->info->name,
prop->info->get, prop->info->set,
- NULL,
+ prop->info->release,
prop, errp);
}
@@ -600,13 +612,13 @@ static void device_initfn(Object *obj)
dev->instance_id_alias = -1;
dev->state = DEV_STATE_CREATED;
- qdev_prop_set_defaults(dev, qdev_get_props(dev));
for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
qdev_property_add_legacy(dev, prop, NULL);
qdev_property_add_static(dev, prop, NULL);
}
object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL);
+ qdev_prop_set_defaults(dev, qdev_get_props(dev));
}
/* Unlink device from bus and free the structure. */
@@ -614,7 +626,6 @@ static void device_finalize(Object *obj)
{
DeviceState *dev = DEVICE(obj);
BusState *bus;
- Property *prop;
DeviceClass *dc = DEVICE_GET_CLASS(dev);
if (dev->state == DEV_STATE_INITIALIZED) {
@@ -633,11 +644,6 @@ static void device_finalize(Object *obj)
}
}
QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
- for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
- if (prop->info->free) {
- prop->info->free(dev, prop);
- }
- }
}
void device_reset(DeviceState *dev)
diff --git a/hw/qdev.h b/hw/qdev.h
index ab53273632..9cc3f984b2 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -112,41 +112,22 @@ struct Property {
const char *name;
PropertyInfo *info;
int offset;
- int bitnr;
- void *defval;
-};
-
-enum PropertyType {
- PROP_TYPE_UNSPEC = 0,
- PROP_TYPE_UINT8,
- PROP_TYPE_UINT16,
- PROP_TYPE_UINT32,
- PROP_TYPE_INT32,
- PROP_TYPE_UINT64,
- PROP_TYPE_TADDR,
- PROP_TYPE_MACADDR,
- PROP_TYPE_LOSTTICKPOLICY,
- PROP_TYPE_DRIVE,
- PROP_TYPE_CHR,
- PROP_TYPE_STRING,
- PROP_TYPE_NETDEV,
- PROP_TYPE_VLAN,
- PROP_TYPE_PTR,
- PROP_TYPE_BIT,
+ uint8_t bitnr;
+ uint8_t qtype;
+ int64_t defval;
};
struct PropertyInfo {
const char *name;
const char *legacy_name;
- size_t size;
- enum PropertyType type;
+ const char **enum_table;
int64_t min;
int64_t max;
int (*parse)(DeviceState *dev, Property *prop, const char *str);
int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
- void (*free)(DeviceState *dev, Property *prop);
ObjectPropertyAccessor *get;
ObjectPropertyAccessor *set;
+ ObjectPropertyRelease *release;
};
typedef struct GlobalProperty {
@@ -254,7 +235,8 @@ extern PropertyInfo qdev_prop_pci_devfn;
.info = &(_prop), \
.offset = offsetof(_state, _field) \
+ type_check(_type,typeof_field(_state, _field)), \
- .defval = (_type[]) { _defval }, \
+ .qtype = QTYPE_QINT, \
+ .defval = (_type)_defval, \
}
#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) { \
.name = (_name), \
@@ -262,7 +244,8 @@ extern PropertyInfo qdev_prop_pci_devfn;
.bitnr = (_bit), \
.offset = offsetof(_state, _field) \
+ type_check(uint32_t,typeof_field(_state, _field)), \
- .defval = (bool[]) { (_defval) }, \
+ .qtype = QTYPE_QBOOL, \
+ .defval = (bool)_defval, \
}
#define DEFINE_PROP_UINT8(_n, _s, _f, _d) \
@@ -309,7 +292,6 @@ extern PropertyInfo qdev_prop_pci_devfn;
void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
int qdev_prop_exists(DeviceState *dev, const char *name);
int qdev_prop_parse(DeviceState *dev, const char *name, const char *value);
-void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type);
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);
void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value);
@@ -323,8 +305,7 @@ void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value);
int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) QEMU_WARN_UNUSED_RESULT;
void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value);
void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
-void qdev_prop_set_losttickpolicy(DeviceState *dev, const char *name,
- LostTickPolicy *value);
+void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
/* FIXME: Remove opaque pointer properties. */
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
void qdev_prop_set_defaults(DeviceState *dev, Property *props);