118c86e2bSPeter Maydell #include "qemu/osdep.h"
2a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h"
3da34e65cSMarkus Armbruster #include "qapi/error.h"
42ae16a6aSMarkus Armbruster #include "qapi/qapi-types-misc.h"
532400a7eSKevin Wolf #include "qapi/qmp/qlist.h"
6856dfd8aSMarkus Armbruster #include "qemu/ctype.h"
7d49b6836SMarkus Armbruster #include "qemu/error-report.h"
849ab747fSPaolo Bonzini #include "qapi/visitor.h"
9645b55d1SRoman Kagan #include "qemu/units.h"
10f7806925SEric Auger #include "qemu/cutils.h"
11a2974439SPhilippe Mathieu-Daudé #include "qdev-prop-internal.h"
1232400a7eSKevin Wolf #include "qom/qom-qobject.h"
1349ab747fSPaolo Bonzini
qdev_prop_set_after_realize(DeviceState * dev,const char * name,Error ** errp)1449ab747fSPaolo Bonzini void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
1549ab747fSPaolo Bonzini Error **errp)
1649ab747fSPaolo Bonzini {
1749ab747fSPaolo Bonzini if (dev->id) {
1849ab747fSPaolo Bonzini error_setg(errp, "Attempt to set property '%s' on device '%s' "
1949ab747fSPaolo Bonzini "(type '%s') after it was realized", name, dev->id,
2049ab747fSPaolo Bonzini object_get_typename(OBJECT(dev)));
2149ab747fSPaolo Bonzini } else {
2249ab747fSPaolo Bonzini error_setg(errp, "Attempt to set property '%s' on anonymous device "
2349ab747fSPaolo Bonzini "(type '%s') after it was realized", name,
2449ab747fSPaolo Bonzini object_get_typename(OBJECT(dev)));
2549ab747fSPaolo Bonzini }
2649ab747fSPaolo Bonzini }
2749ab747fSPaolo Bonzini
28ea7c1e5cSEduardo Habkost /* returns: true if property is allowed to be set, false otherwise */
qdev_prop_allow_set(Object * obj,const char * name,const PropertyInfo * info,Error ** errp)29ea7c1e5cSEduardo Habkost static bool qdev_prop_allow_set(Object *obj, const char *name,
30deb2bb16SVladimir Sementsov-Ogievskiy const PropertyInfo *info, Error **errp)
31ea7c1e5cSEduardo Habkost {
32ea7c1e5cSEduardo Habkost DeviceState *dev = DEVICE(obj);
33ea7c1e5cSEduardo Habkost
34deb2bb16SVladimir Sementsov-Ogievskiy if (dev->realized && !info->realized_set_allowed) {
35ea7c1e5cSEduardo Habkost qdev_prop_set_after_realize(dev, name, errp);
36ea7c1e5cSEduardo Habkost return false;
37ea7c1e5cSEduardo Habkost }
38ea7c1e5cSEduardo Habkost return true;
39ea7c1e5cSEduardo Habkost }
40ea7c1e5cSEduardo Habkost
qdev_prop_allow_set_link_before_realize(const Object * obj,const char * name,Object * val,Error ** errp)418f5d58efSIgor Mammedov void qdev_prop_allow_set_link_before_realize(const Object *obj,
428f5d58efSIgor Mammedov const char *name,
4339f72ef9SStefan Hajnoczi Object *val, Error **errp)
4439f72ef9SStefan Hajnoczi {
4539f72ef9SStefan Hajnoczi DeviceState *dev = DEVICE(obj);
4639f72ef9SStefan Hajnoczi
4739f72ef9SStefan Hajnoczi if (dev->realized) {
4839f72ef9SStefan Hajnoczi error_setg(errp, "Attempt to set link property '%s' on device '%s' "
4939f72ef9SStefan Hajnoczi "(type '%s') after it was realized",
5039f72ef9SStefan Hajnoczi name, dev->id, object_get_typename(obj));
5139f72ef9SStefan Hajnoczi }
5239f72ef9SStefan Hajnoczi }
5339f72ef9SStefan Hajnoczi
object_field_prop_ptr(Object * obj,Property * prop)541e198715SEduardo Habkost void *object_field_prop_ptr(Object *obj, Property *prop)
5549ab747fSPaolo Bonzini {
56828ade86SEduardo Habkost void *ptr = obj;
5749ab747fSPaolo Bonzini ptr += prop->offset;
5849ab747fSPaolo Bonzini return ptr;
5949ab747fSPaolo Bonzini }
6049ab747fSPaolo Bonzini
field_prop_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)617ed854afSEduardo Habkost static void field_prop_get(Object *obj, Visitor *v, const char *name,
627ed854afSEduardo Habkost void *opaque, Error **errp)
637ed854afSEduardo Habkost {
647ed854afSEduardo Habkost Property *prop = opaque;
657ed854afSEduardo Habkost return prop->info->get(obj, v, name, opaque, errp);
667ed854afSEduardo Habkost }
677ed854afSEduardo Habkost
687ed854afSEduardo Habkost /**
697ed854afSEduardo Habkost * field_prop_getter: Return getter function to be used for property
707ed854afSEduardo Habkost *
717ed854afSEduardo Habkost * Return value can be NULL if @info has no getter function.
727ed854afSEduardo Habkost */
field_prop_getter(const PropertyInfo * info)737ed854afSEduardo Habkost static ObjectPropertyAccessor *field_prop_getter(const PropertyInfo *info)
747ed854afSEduardo Habkost {
757ed854afSEduardo Habkost return info->get ? field_prop_get : NULL;
767ed854afSEduardo Habkost }
777ed854afSEduardo Habkost
field_prop_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)787ed854afSEduardo Habkost static void field_prop_set(Object *obj, Visitor *v, const char *name,
797ed854afSEduardo Habkost void *opaque, Error **errp)
807ed854afSEduardo Habkost {
817ed854afSEduardo Habkost Property *prop = opaque;
82ea7c1e5cSEduardo Habkost
83deb2bb16SVladimir Sementsov-Ogievskiy if (!qdev_prop_allow_set(obj, name, prop->info, errp)) {
84ea7c1e5cSEduardo Habkost return;
85ea7c1e5cSEduardo Habkost }
86ea7c1e5cSEduardo Habkost
877ed854afSEduardo Habkost return prop->info->set(obj, v, name, opaque, errp);
887ed854afSEduardo Habkost }
897ed854afSEduardo Habkost
907ed854afSEduardo Habkost /**
917ed854afSEduardo Habkost * field_prop_setter: Return setter function to be used for property
927ed854afSEduardo Habkost *
937ed854afSEduardo Habkost * Return value can be NULL if @info has not setter function.
947ed854afSEduardo Habkost */
field_prop_setter(const PropertyInfo * info)957ed854afSEduardo Habkost static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
967ed854afSEduardo Habkost {
977ed854afSEduardo Habkost return info->set ? field_prop_set : NULL;
987ed854afSEduardo Habkost }
997ed854afSEduardo Habkost
qdev_propinfo_get_enum(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)100a2974439SPhilippe Mathieu-Daudé void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
101a2974439SPhilippe Mathieu-Daudé void *opaque, Error **errp)
10249ab747fSPaolo Bonzini {
10349ab747fSPaolo Bonzini Property *prop = opaque;
1041e198715SEduardo Habkost int *ptr = object_field_prop_ptr(obj, prop);
10549ab747fSPaolo Bonzini
106991f0ac9SEduardo Habkost visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
10749ab747fSPaolo Bonzini }
10849ab747fSPaolo Bonzini
qdev_propinfo_set_enum(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)109a2974439SPhilippe Mathieu-Daudé void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
110a2974439SPhilippe Mathieu-Daudé void *opaque, Error **errp)
11149ab747fSPaolo Bonzini {
11249ab747fSPaolo Bonzini Property *prop = opaque;
1131e198715SEduardo Habkost int *ptr = object_field_prop_ptr(obj, prop);
11449ab747fSPaolo Bonzini
115991f0ac9SEduardo Habkost visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
11649ab747fSPaolo Bonzini }
11749ab747fSPaolo Bonzini
qdev_propinfo_set_default_value_enum(ObjectProperty * op,const Property * prop)118a2974439SPhilippe Mathieu-Daudé void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
119a2974439SPhilippe Mathieu-Daudé const Property *prop)
120a2740ad5SMarc-André Lureau {
12177b06bbaSMarc-André Lureau object_property_set_default_str(op,
12277b06bbaSMarc-André Lureau qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
123a2740ad5SMarc-André Lureau }
124a2740ad5SMarc-André Lureau
12579bdf29cSPhilippe Mathieu-Daudé const PropertyInfo qdev_prop_enum = {
12679bdf29cSPhilippe Mathieu-Daudé .name = "enum",
12779bdf29cSPhilippe Mathieu-Daudé .get = qdev_propinfo_get_enum,
12879bdf29cSPhilippe Mathieu-Daudé .set = qdev_propinfo_set_enum,
12979bdf29cSPhilippe Mathieu-Daudé .set_default_value = qdev_propinfo_set_default_value_enum,
13079bdf29cSPhilippe Mathieu-Daudé };
13179bdf29cSPhilippe Mathieu-Daudé
13249ab747fSPaolo Bonzini /* Bit */
13349ab747fSPaolo Bonzini
qdev_get_prop_mask(Property * prop)13449ab747fSPaolo Bonzini static uint32_t qdev_get_prop_mask(Property *prop)
13549ab747fSPaolo Bonzini {
13649ab747fSPaolo Bonzini assert(prop->info == &qdev_prop_bit);
13749ab747fSPaolo Bonzini return 0x1 << prop->bitnr;
13849ab747fSPaolo Bonzini }
13949ab747fSPaolo Bonzini
bit_prop_set(Object * obj,Property * props,bool val)140605d9fc0SEduardo Habkost static void bit_prop_set(Object *obj, Property *props, bool val)
14149ab747fSPaolo Bonzini {
1421e198715SEduardo Habkost uint32_t *p = object_field_prop_ptr(obj, props);
14349ab747fSPaolo Bonzini uint32_t mask = qdev_get_prop_mask(props);
14449ab747fSPaolo Bonzini if (val) {
14549ab747fSPaolo Bonzini *p |= mask;
14649ab747fSPaolo Bonzini } else {
14749ab747fSPaolo Bonzini *p &= ~mask;
14849ab747fSPaolo Bonzini }
14949ab747fSPaolo Bonzini }
15049ab747fSPaolo Bonzini
prop_get_bit(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)151d7bce999SEric Blake static void prop_get_bit(Object *obj, Visitor *v, const char *name,
152d7bce999SEric Blake void *opaque, Error **errp)
15349ab747fSPaolo Bonzini {
15449ab747fSPaolo Bonzini Property *prop = opaque;
1551e198715SEduardo Habkost uint32_t *p = object_field_prop_ptr(obj, prop);
15649ab747fSPaolo Bonzini bool value = (*p & qdev_get_prop_mask(prop)) != 0;
15749ab747fSPaolo Bonzini
15851e72bc1SEric Blake visit_type_bool(v, name, &value, errp);
15949ab747fSPaolo Bonzini }
16049ab747fSPaolo Bonzini
prop_set_bit(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)161d7bce999SEric Blake static void prop_set_bit(Object *obj, Visitor *v, const char *name,
162d7bce999SEric Blake void *opaque, Error **errp)
16349ab747fSPaolo Bonzini {
16449ab747fSPaolo Bonzini Property *prop = opaque;
16549ab747fSPaolo Bonzini bool value;
16649ab747fSPaolo Bonzini
167668f62ecSMarkus Armbruster if (!visit_type_bool(v, name, &value, errp)) {
16849ab747fSPaolo Bonzini return;
16949ab747fSPaolo Bonzini }
170605d9fc0SEduardo Habkost bit_prop_set(obj, prop, value);
17149ab747fSPaolo Bonzini }
17249ab747fSPaolo Bonzini
set_default_value_bool(ObjectProperty * op,const Property * prop)17377b06bbaSMarc-André Lureau static void set_default_value_bool(ObjectProperty *op, const Property *prop)
174a2740ad5SMarc-André Lureau {
17577b06bbaSMarc-André Lureau object_property_set_default_bool(op, prop->defval.u);
176a2740ad5SMarc-André Lureau }
177a2740ad5SMarc-André Lureau
1781b6b7d10SFam Zheng const PropertyInfo qdev_prop_bit = {
17985ca1202SPaolo Bonzini .name = "bool",
18051b2e8c3SGonglei .description = "on/off",
181949fc823SMarcel Apfelbaum .get = prop_get_bit,
182949fc823SMarcel Apfelbaum .set = prop_set_bit,
183a2740ad5SMarc-André Lureau .set_default_value = set_default_value_bool,
18449ab747fSPaolo Bonzini };
18549ab747fSPaolo Bonzini
186fdba6d96SGerd Hoffmann /* Bit64 */
187fdba6d96SGerd Hoffmann
qdev_get_prop_mask64(Property * prop)188fdba6d96SGerd Hoffmann static uint64_t qdev_get_prop_mask64(Property *prop)
189fdba6d96SGerd Hoffmann {
1908aedc369SCornelia Huck assert(prop->info == &qdev_prop_bit64);
1911fa795a8SGonglei return 0x1ull << prop->bitnr;
192fdba6d96SGerd Hoffmann }
193fdba6d96SGerd Hoffmann
bit64_prop_set(Object * obj,Property * props,bool val)194605d9fc0SEduardo Habkost static void bit64_prop_set(Object *obj, Property *props, bool val)
195fdba6d96SGerd Hoffmann {
1961e198715SEduardo Habkost uint64_t *p = object_field_prop_ptr(obj, props);
197fdba6d96SGerd Hoffmann uint64_t mask = qdev_get_prop_mask64(props);
198fdba6d96SGerd Hoffmann if (val) {
199fdba6d96SGerd Hoffmann *p |= mask;
200fdba6d96SGerd Hoffmann } else {
201fdba6d96SGerd Hoffmann *p &= ~mask;
202fdba6d96SGerd Hoffmann }
203fdba6d96SGerd Hoffmann }
204fdba6d96SGerd Hoffmann
prop_get_bit64(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)205d7bce999SEric Blake static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
206d7bce999SEric Blake void *opaque, Error **errp)
207fdba6d96SGerd Hoffmann {
208fdba6d96SGerd Hoffmann Property *prop = opaque;
2091e198715SEduardo Habkost uint64_t *p = object_field_prop_ptr(obj, prop);
210fdba6d96SGerd Hoffmann bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
211fdba6d96SGerd Hoffmann
21251e72bc1SEric Blake visit_type_bool(v, name, &value, errp);
213fdba6d96SGerd Hoffmann }
214fdba6d96SGerd Hoffmann
prop_set_bit64(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)215d7bce999SEric Blake static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
216d7bce999SEric Blake void *opaque, Error **errp)
217fdba6d96SGerd Hoffmann {
218fdba6d96SGerd Hoffmann Property *prop = opaque;
219fdba6d96SGerd Hoffmann bool value;
220fdba6d96SGerd Hoffmann
221668f62ecSMarkus Armbruster if (!visit_type_bool(v, name, &value, errp)) {
222fdba6d96SGerd Hoffmann return;
223fdba6d96SGerd Hoffmann }
224605d9fc0SEduardo Habkost bit64_prop_set(obj, prop, value);
225fdba6d96SGerd Hoffmann }
226fdba6d96SGerd Hoffmann
2271b6b7d10SFam Zheng const PropertyInfo qdev_prop_bit64 = {
228fdba6d96SGerd Hoffmann .name = "bool",
229fdba6d96SGerd Hoffmann .description = "on/off",
230fdba6d96SGerd Hoffmann .get = prop_get_bit64,
231fdba6d96SGerd Hoffmann .set = prop_set_bit64,
232a2740ad5SMarc-André Lureau .set_default_value = set_default_value_bool,
233fdba6d96SGerd Hoffmann };
234fdba6d96SGerd Hoffmann
23572cc5137SIgor Mammedov /* --- bool --- */
23672cc5137SIgor Mammedov
get_bool(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)237d7bce999SEric Blake static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
238d7bce999SEric Blake Error **errp)
23972cc5137SIgor Mammedov {
24072cc5137SIgor Mammedov Property *prop = opaque;
2411e198715SEduardo Habkost bool *ptr = object_field_prop_ptr(obj, prop);
24272cc5137SIgor Mammedov
24351e72bc1SEric Blake visit_type_bool(v, name, ptr, errp);
24472cc5137SIgor Mammedov }
24572cc5137SIgor Mammedov
set_bool(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)246d7bce999SEric Blake static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
247d7bce999SEric Blake Error **errp)
24872cc5137SIgor Mammedov {
24972cc5137SIgor Mammedov Property *prop = opaque;
2501e198715SEduardo Habkost bool *ptr = object_field_prop_ptr(obj, prop);
25172cc5137SIgor Mammedov
25251e72bc1SEric Blake visit_type_bool(v, name, ptr, errp);
25372cc5137SIgor Mammedov }
25472cc5137SIgor Mammedov
2551b6b7d10SFam Zheng const PropertyInfo qdev_prop_bool = {
25685ca1202SPaolo Bonzini .name = "bool",
25772cc5137SIgor Mammedov .get = get_bool,
25872cc5137SIgor Mammedov .set = set_bool,
259a2740ad5SMarc-André Lureau .set_default_value = set_default_value_bool,
26072cc5137SIgor Mammedov };
26172cc5137SIgor Mammedov
26249ab747fSPaolo Bonzini /* --- 8bit integer --- */
26349ab747fSPaolo Bonzini
get_uint8(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)264d7bce999SEric Blake static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
265d7bce999SEric Blake Error **errp)
26649ab747fSPaolo Bonzini {
26749ab747fSPaolo Bonzini Property *prop = opaque;
2681e198715SEduardo Habkost uint8_t *ptr = object_field_prop_ptr(obj, prop);
26949ab747fSPaolo Bonzini
27051e72bc1SEric Blake visit_type_uint8(v, name, ptr, errp);
27149ab747fSPaolo Bonzini }
27249ab747fSPaolo Bonzini
set_uint8(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)273d7bce999SEric Blake static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
274d7bce999SEric Blake Error **errp)
27549ab747fSPaolo Bonzini {
27649ab747fSPaolo Bonzini Property *prop = opaque;
2771e198715SEduardo Habkost uint8_t *ptr = object_field_prop_ptr(obj, prop);
27849ab747fSPaolo Bonzini
27951e72bc1SEric Blake visit_type_uint8(v, name, ptr, errp);
28049ab747fSPaolo Bonzini }
28149ab747fSPaolo Bonzini
qdev_propinfo_set_default_value_int(ObjectProperty * op,const Property * prop)28293e163e4SPhilippe Mathieu-Daudé void qdev_propinfo_set_default_value_int(ObjectProperty *op,
28393e163e4SPhilippe Mathieu-Daudé const Property *prop)
284a2740ad5SMarc-André Lureau {
28577b06bbaSMarc-André Lureau object_property_set_default_int(op, prop->defval.i);
286a2740ad5SMarc-André Lureau }
287a2740ad5SMarc-André Lureau
qdev_propinfo_set_default_value_uint(ObjectProperty * op,const Property * prop)28893e163e4SPhilippe Mathieu-Daudé void qdev_propinfo_set_default_value_uint(ObjectProperty *op,
28993e163e4SPhilippe Mathieu-Daudé const Property *prop)
2903fb2111fSMarc-André Lureau {
29177b06bbaSMarc-André Lureau object_property_set_default_uint(op, prop->defval.u);
2923fb2111fSMarc-André Lureau }
2933fb2111fSMarc-André Lureau
2941b6b7d10SFam Zheng const PropertyInfo qdev_prop_uint8 = {
29549ab747fSPaolo Bonzini .name = "uint8",
29649ab747fSPaolo Bonzini .get = get_uint8,
29749ab747fSPaolo Bonzini .set = set_uint8,
29893e163e4SPhilippe Mathieu-Daudé .set_default_value = qdev_propinfo_set_default_value_uint,
29949ab747fSPaolo Bonzini };
30049ab747fSPaolo Bonzini
30149ab747fSPaolo Bonzini /* --- 16bit integer --- */
30249ab747fSPaolo Bonzini
get_uint16(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)303364f7e83SEduardo Habkost static void get_uint16(Object *obj, Visitor *v, const char *name,
304d7bce999SEric Blake void *opaque, Error **errp)
30549ab747fSPaolo Bonzini {
30649ab747fSPaolo Bonzini Property *prop = opaque;
3071e198715SEduardo Habkost uint16_t *ptr = object_field_prop_ptr(obj, prop);
30849ab747fSPaolo Bonzini
30951e72bc1SEric Blake visit_type_uint16(v, name, ptr, errp);
31049ab747fSPaolo Bonzini }
31149ab747fSPaolo Bonzini
set_uint16(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)312d7bce999SEric Blake static void set_uint16(Object *obj, Visitor *v, const char *name,
313d7bce999SEric Blake void *opaque, Error **errp)
31449ab747fSPaolo Bonzini {
31549ab747fSPaolo Bonzini Property *prop = opaque;
3161e198715SEduardo Habkost uint16_t *ptr = object_field_prop_ptr(obj, prop);
31749ab747fSPaolo Bonzini
31851e72bc1SEric Blake visit_type_uint16(v, name, ptr, errp);
31949ab747fSPaolo Bonzini }
32049ab747fSPaolo Bonzini
3211b6b7d10SFam Zheng const PropertyInfo qdev_prop_uint16 = {
32249ab747fSPaolo Bonzini .name = "uint16",
323364f7e83SEduardo Habkost .get = get_uint16,
32449ab747fSPaolo Bonzini .set = set_uint16,
32593e163e4SPhilippe Mathieu-Daudé .set_default_value = qdev_propinfo_set_default_value_uint,
32649ab747fSPaolo Bonzini };
32749ab747fSPaolo Bonzini
32849ab747fSPaolo Bonzini /* --- 32bit integer --- */
32949ab747fSPaolo Bonzini
get_uint32(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)330d7bce999SEric Blake static void get_uint32(Object *obj, Visitor *v, const char *name,
331d7bce999SEric Blake void *opaque, Error **errp)
33249ab747fSPaolo Bonzini {
33349ab747fSPaolo Bonzini Property *prop = opaque;
3341e198715SEduardo Habkost uint32_t *ptr = object_field_prop_ptr(obj, prop);
33549ab747fSPaolo Bonzini
33651e72bc1SEric Blake visit_type_uint32(v, name, ptr, errp);
33749ab747fSPaolo Bonzini }
33849ab747fSPaolo Bonzini
set_uint32(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)339d7bce999SEric Blake static void set_uint32(Object *obj, Visitor *v, const char *name,
340d7bce999SEric Blake void *opaque, Error **errp)
34149ab747fSPaolo Bonzini {
34249ab747fSPaolo Bonzini Property *prop = opaque;
3431e198715SEduardo Habkost uint32_t *ptr = object_field_prop_ptr(obj, prop);
34449ab747fSPaolo Bonzini
34551e72bc1SEric Blake visit_type_uint32(v, name, ptr, errp);
34649ab747fSPaolo Bonzini }
34749ab747fSPaolo Bonzini
qdev_propinfo_get_int32(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)34893e163e4SPhilippe Mathieu-Daudé void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
34993e163e4SPhilippe Mathieu-Daudé void *opaque, Error **errp)
35049ab747fSPaolo Bonzini {
35149ab747fSPaolo Bonzini Property *prop = opaque;
3521e198715SEduardo Habkost int32_t *ptr = object_field_prop_ptr(obj, prop);
35349ab747fSPaolo Bonzini
35451e72bc1SEric Blake visit_type_int32(v, name, ptr, errp);
35549ab747fSPaolo Bonzini }
35649ab747fSPaolo Bonzini
set_int32(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)357d7bce999SEric Blake static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
358d7bce999SEric Blake Error **errp)
35949ab747fSPaolo Bonzini {
36049ab747fSPaolo Bonzini Property *prop = opaque;
3611e198715SEduardo Habkost int32_t *ptr = object_field_prop_ptr(obj, prop);
36249ab747fSPaolo Bonzini
36351e72bc1SEric Blake visit_type_int32(v, name, ptr, errp);
36449ab747fSPaolo Bonzini }
36549ab747fSPaolo Bonzini
3661b6b7d10SFam Zheng const PropertyInfo qdev_prop_uint32 = {
36749ab747fSPaolo Bonzini .name = "uint32",
36849ab747fSPaolo Bonzini .get = get_uint32,
36949ab747fSPaolo Bonzini .set = set_uint32,
37093e163e4SPhilippe Mathieu-Daudé .set_default_value = qdev_propinfo_set_default_value_uint,
37149ab747fSPaolo Bonzini };
37249ab747fSPaolo Bonzini
3731b6b7d10SFam Zheng const PropertyInfo qdev_prop_int32 = {
37449ab747fSPaolo Bonzini .name = "int32",
37593e163e4SPhilippe Mathieu-Daudé .get = qdev_propinfo_get_int32,
37649ab747fSPaolo Bonzini .set = set_int32,
37793e163e4SPhilippe Mathieu-Daudé .set_default_value = qdev_propinfo_set_default_value_int,
37849ab747fSPaolo Bonzini };
37949ab747fSPaolo Bonzini
38049ab747fSPaolo Bonzini /* --- 64bit integer --- */
38149ab747fSPaolo Bonzini
get_uint64(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)382d7bce999SEric Blake static void get_uint64(Object *obj, Visitor *v, const char *name,
383d7bce999SEric Blake void *opaque, Error **errp)
38449ab747fSPaolo Bonzini {
38549ab747fSPaolo Bonzini Property *prop = opaque;
3861e198715SEduardo Habkost uint64_t *ptr = object_field_prop_ptr(obj, prop);
38749ab747fSPaolo Bonzini
38851e72bc1SEric Blake visit_type_uint64(v, name, ptr, errp);
38949ab747fSPaolo Bonzini }
39049ab747fSPaolo Bonzini
set_uint64(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)391d7bce999SEric Blake static void set_uint64(Object *obj, Visitor *v, const char *name,
392d7bce999SEric Blake void *opaque, Error **errp)
39349ab747fSPaolo Bonzini {
39449ab747fSPaolo Bonzini Property *prop = opaque;
3951e198715SEduardo Habkost uint64_t *ptr = object_field_prop_ptr(obj, prop);
39649ab747fSPaolo Bonzini
39751e72bc1SEric Blake visit_type_uint64(v, name, ptr, errp);
39849ab747fSPaolo Bonzini }
39949ab747fSPaolo Bonzini
get_int64(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)40007d1d063SPeter Xu static void get_int64(Object *obj, Visitor *v, const char *name,
40107d1d063SPeter Xu void *opaque, Error **errp)
40207d1d063SPeter Xu {
40307d1d063SPeter Xu Property *prop = opaque;
4041e198715SEduardo Habkost int64_t *ptr = object_field_prop_ptr(obj, prop);
40507d1d063SPeter Xu
40607d1d063SPeter Xu visit_type_int64(v, name, ptr, errp);
40707d1d063SPeter Xu }
40807d1d063SPeter Xu
set_int64(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)40907d1d063SPeter Xu static void set_int64(Object *obj, Visitor *v, const char *name,
41007d1d063SPeter Xu void *opaque, Error **errp)
41107d1d063SPeter Xu {
41207d1d063SPeter Xu Property *prop = opaque;
4131e198715SEduardo Habkost int64_t *ptr = object_field_prop_ptr(obj, prop);
41407d1d063SPeter Xu
41507d1d063SPeter Xu visit_type_int64(v, name, ptr, errp);
41607d1d063SPeter Xu }
41707d1d063SPeter Xu
4181b6b7d10SFam Zheng const PropertyInfo qdev_prop_uint64 = {
41949ab747fSPaolo Bonzini .name = "uint64",
42049ab747fSPaolo Bonzini .get = get_uint64,
42149ab747fSPaolo Bonzini .set = set_uint64,
42293e163e4SPhilippe Mathieu-Daudé .set_default_value = qdev_propinfo_set_default_value_uint,
42349ab747fSPaolo Bonzini };
42449ab747fSPaolo Bonzini
42507d1d063SPeter Xu const PropertyInfo qdev_prop_int64 = {
42607d1d063SPeter Xu .name = "int64",
42707d1d063SPeter Xu .get = get_int64,
42807d1d063SPeter Xu .set = set_int64,
42993e163e4SPhilippe Mathieu-Daudé .set_default_value = qdev_propinfo_set_default_value_int,
43007d1d063SPeter Xu };
43107d1d063SPeter Xu
set_uint64_checkmask(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)43218c22d71SYang Weijiang static void set_uint64_checkmask(Object *obj, Visitor *v, const char *name,
43318c22d71SYang Weijiang void *opaque, Error **errp)
43418c22d71SYang Weijiang {
43518c22d71SYang Weijiang Property *prop = opaque;
43618c22d71SYang Weijiang uint64_t *ptr = object_field_prop_ptr(obj, prop);
43718c22d71SYang Weijiang
43818c22d71SYang Weijiang visit_type_uint64(v, name, ptr, errp);
43918c22d71SYang Weijiang if (*ptr & ~prop->bitmask) {
44018c22d71SYang Weijiang error_setg(errp, "Property value for '%s' has bits outside mask '0x%" PRIx64 "'",
44118c22d71SYang Weijiang name, prop->bitmask);
44218c22d71SYang Weijiang }
44318c22d71SYang Weijiang }
44418c22d71SYang Weijiang
44518c22d71SYang Weijiang const PropertyInfo qdev_prop_uint64_checkmask = {
44618c22d71SYang Weijiang .name = "uint64",
44718c22d71SYang Weijiang .get = get_uint64,
44818c22d71SYang Weijiang .set = set_uint64_checkmask,
44918c22d71SYang Weijiang };
45018c22d71SYang Weijiang
45149ab747fSPaolo Bonzini /* --- string --- */
45249ab747fSPaolo Bonzini
release_string(Object * obj,const char * name,void * opaque)45349ab747fSPaolo Bonzini static void release_string(Object *obj, const char *name, void *opaque)
45449ab747fSPaolo Bonzini {
45549ab747fSPaolo Bonzini Property *prop = opaque;
4561e198715SEduardo Habkost g_free(*(char **)object_field_prop_ptr(obj, prop));
45749ab747fSPaolo Bonzini }
45849ab747fSPaolo Bonzini
get_string(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)459d7bce999SEric Blake static void get_string(Object *obj, Visitor *v, const char *name,
460d7bce999SEric Blake void *opaque, Error **errp)
46149ab747fSPaolo Bonzini {
46249ab747fSPaolo Bonzini Property *prop = opaque;
4631e198715SEduardo Habkost char **ptr = object_field_prop_ptr(obj, prop);
46449ab747fSPaolo Bonzini
46549ab747fSPaolo Bonzini if (!*ptr) {
46649ab747fSPaolo Bonzini char *str = (char *)"";
46751e72bc1SEric Blake visit_type_str(v, name, &str, errp);
46849ab747fSPaolo Bonzini } else {
46951e72bc1SEric Blake visit_type_str(v, name, ptr, errp);
47049ab747fSPaolo Bonzini }
47149ab747fSPaolo Bonzini }
47249ab747fSPaolo Bonzini
set_string(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)473d7bce999SEric Blake static void set_string(Object *obj, Visitor *v, const char *name,
474d7bce999SEric Blake void *opaque, Error **errp)
47549ab747fSPaolo Bonzini {
47649ab747fSPaolo Bonzini Property *prop = opaque;
4771e198715SEduardo Habkost char **ptr = object_field_prop_ptr(obj, prop);
47849ab747fSPaolo Bonzini char *str;
47949ab747fSPaolo Bonzini
480668f62ecSMarkus Armbruster if (!visit_type_str(v, name, &str, errp)) {
48149ab747fSPaolo Bonzini return;
48249ab747fSPaolo Bonzini }
48349ab747fSPaolo Bonzini g_free(*ptr);
48449ab747fSPaolo Bonzini *ptr = str;
48549ab747fSPaolo Bonzini }
48649ab747fSPaolo Bonzini
4871b6b7d10SFam Zheng const PropertyInfo qdev_prop_string = {
48885ca1202SPaolo Bonzini .name = "str",
48949ab747fSPaolo Bonzini .release = release_string,
49049ab747fSPaolo Bonzini .get = get_string,
49149ab747fSPaolo Bonzini .set = set_string,
49249ab747fSPaolo Bonzini };
49349ab747fSPaolo Bonzini
49455e8a154SMarkus Armbruster /* --- on/off/auto --- */
49555e8a154SMarkus Armbruster
4961b6b7d10SFam Zheng const PropertyInfo qdev_prop_on_off_auto = {
49755e8a154SMarkus Armbruster .name = "OnOffAuto",
49855e8a154SMarkus Armbruster .description = "on/off/auto",
499f7abe0ecSMarc-André Lureau .enum_table = &OnOffAuto_lookup,
500a2974439SPhilippe Mathieu-Daudé .get = qdev_propinfo_get_enum,
501a2974439SPhilippe Mathieu-Daudé .set = qdev_propinfo_set_enum,
502a2974439SPhilippe Mathieu-Daudé .set_default_value = qdev_propinfo_set_default_value_enum,
50355e8a154SMarkus Armbruster };
50455e8a154SMarkus Armbruster
505914e74cdSRoman Kagan /* --- 32bit unsigned int 'size' type --- */
506914e74cdSRoman Kagan
qdev_propinfo_get_size32(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)50793e163e4SPhilippe Mathieu-Daudé void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
50893e163e4SPhilippe Mathieu-Daudé void *opaque, Error **errp)
509031ffd9aSRoman Kagan {
510031ffd9aSRoman Kagan Property *prop = opaque;
5111e198715SEduardo Habkost uint32_t *ptr = object_field_prop_ptr(obj, prop);
512031ffd9aSRoman Kagan uint64_t value = *ptr;
513031ffd9aSRoman Kagan
514031ffd9aSRoman Kagan visit_type_size(v, name, &value, errp);
515031ffd9aSRoman Kagan }
516031ffd9aSRoman Kagan
set_size32(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)517914e74cdSRoman Kagan static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
518914e74cdSRoman Kagan Error **errp)
519914e74cdSRoman Kagan {
520914e74cdSRoman Kagan Property *prop = opaque;
5211e198715SEduardo Habkost uint32_t *ptr = object_field_prop_ptr(obj, prop);
522914e74cdSRoman Kagan uint64_t value;
523914e74cdSRoman Kagan
524668f62ecSMarkus Armbruster if (!visit_type_size(v, name, &value, errp)) {
525914e74cdSRoman Kagan return;
526914e74cdSRoman Kagan }
527914e74cdSRoman Kagan
528914e74cdSRoman Kagan if (value > UINT32_MAX) {
529914e74cdSRoman Kagan error_setg(errp,
530914e74cdSRoman Kagan "Property %s.%s doesn't take value %" PRIu64
531914e74cdSRoman Kagan " (maximum: %u)",
5325eb32b21SEduardo Habkost object_get_typename(obj), name, value, UINT32_MAX);
533914e74cdSRoman Kagan return;
534914e74cdSRoman Kagan }
535914e74cdSRoman Kagan
536914e74cdSRoman Kagan *ptr = value;
537914e74cdSRoman Kagan }
538914e74cdSRoman Kagan
539914e74cdSRoman Kagan const PropertyInfo qdev_prop_size32 = {
540914e74cdSRoman Kagan .name = "size",
54193e163e4SPhilippe Mathieu-Daudé .get = qdev_propinfo_get_size32,
542914e74cdSRoman Kagan .set = set_size32,
54393e163e4SPhilippe Mathieu-Daudé .set_default_value = qdev_propinfo_set_default_value_uint,
544914e74cdSRoman Kagan };
545914e74cdSRoman Kagan
54649ab747fSPaolo Bonzini /* --- support for array properties --- */
54749ab747fSPaolo Bonzini
548b06f8b50SKevin Wolf typedef struct ArrayElementList ArrayElementList;
54949ab747fSPaolo Bonzini
550b06f8b50SKevin Wolf struct ArrayElementList {
551b06f8b50SKevin Wolf ArrayElementList *next;
552b06f8b50SKevin Wolf void *value;
553b06f8b50SKevin Wolf };
554b06f8b50SKevin Wolf
555b06f8b50SKevin Wolf /*
556b06f8b50SKevin Wolf * Given an array property @parent_prop in @obj, return a Property for a
557b06f8b50SKevin Wolf * specific element of the array. Arrays are backed by an uint32_t length field
558b06f8b50SKevin Wolf * and an element array. @elem points at an element in this element array.
55949ab747fSPaolo Bonzini */
array_elem_prop(Object * obj,Property * parent_prop,const char * name,char * elem)560b06f8b50SKevin Wolf static Property array_elem_prop(Object *obj, Property *parent_prop,
561b06f8b50SKevin Wolf const char *name, char *elem)
56249ab747fSPaolo Bonzini {
563b06f8b50SKevin Wolf return (Property) {
564b06f8b50SKevin Wolf .info = parent_prop->arrayinfo,
565b06f8b50SKevin Wolf .name = name,
566b06f8b50SKevin Wolf /*
567b06f8b50SKevin Wolf * This ugly piece of pointer arithmetic sets up the offset so
568b06f8b50SKevin Wolf * that when the underlying release hook calls qdev_get_prop_ptr
569b06f8b50SKevin Wolf * they get the right answer despite the array element not actually
570b06f8b50SKevin Wolf * being inside the device struct.
571b06f8b50SKevin Wolf */
572b06f8b50SKevin Wolf .offset = (uintptr_t)elem - (uintptr_t)obj,
573b06f8b50SKevin Wolf };
57449ab747fSPaolo Bonzini }
57549ab747fSPaolo Bonzini
576b06f8b50SKevin Wolf /*
577b06f8b50SKevin Wolf * Object property release callback for array properties: We call the
578b06f8b50SKevin Wolf * underlying element's property release hook for each element.
579b06f8b50SKevin Wolf *
580b06f8b50SKevin Wolf * Note that it is the responsibility of the individual device's deinit
581b06f8b50SKevin Wolf * to free the array proper.
58249ab747fSPaolo Bonzini */
release_prop_array(Object * obj,const char * name,void * opaque)583b06f8b50SKevin Wolf static void release_prop_array(Object *obj, const char *name, void *opaque)
584b06f8b50SKevin Wolf {
58549ab747fSPaolo Bonzini Property *prop = opaque;
5861e198715SEduardo Habkost uint32_t *alenptr = object_field_prop_ptr(obj, prop);
587f405e3cdSEduardo Habkost void **arrayptr = (void *)obj + prop->arrayoffset;
588b06f8b50SKevin Wolf char *elem = *arrayptr;
58949ab747fSPaolo Bonzini int i;
59049ab747fSPaolo Bonzini
591b06f8b50SKevin Wolf if (!prop->arrayinfo->release) {
592b06f8b50SKevin Wolf return;
593b06f8b50SKevin Wolf }
594b06f8b50SKevin Wolf
595b06f8b50SKevin Wolf for (i = 0; i < *alenptr; i++) {
596b06f8b50SKevin Wolf Property elem_prop = array_elem_prop(obj, prop, name, elem);
597b06f8b50SKevin Wolf prop->arrayinfo->release(obj, NULL, &elem_prop);
598b06f8b50SKevin Wolf elem += prop->arrayfieldsize;
599b06f8b50SKevin Wolf }
600b06f8b50SKevin Wolf }
601b06f8b50SKevin Wolf
602b06f8b50SKevin Wolf /*
603b06f8b50SKevin Wolf * Setter for an array property. This sets both the array length (which
604b06f8b50SKevin Wolf * is technically the property field in the object) and the array itself
605b06f8b50SKevin Wolf * (a pointer to which is stored in the additional field described by
606b06f8b50SKevin Wolf * prop->arrayoffset).
607b06f8b50SKevin Wolf */
set_prop_array(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)608b06f8b50SKevin Wolf static void set_prop_array(Object *obj, Visitor *v, const char *name,
609b06f8b50SKevin Wolf void *opaque, Error **errp)
610b06f8b50SKevin Wolf {
611b06f8b50SKevin Wolf ERRP_GUARD();
612b06f8b50SKevin Wolf Property *prop = opaque;
613b06f8b50SKevin Wolf uint32_t *alenptr = object_field_prop_ptr(obj, prop);
614b06f8b50SKevin Wolf void **arrayptr = (void *)obj + prop->arrayoffset;
615b06f8b50SKevin Wolf ArrayElementList *list, *elem, *next;
616b06f8b50SKevin Wolf const size_t size = sizeof(*list);
617b06f8b50SKevin Wolf char *elemptr;
618b06f8b50SKevin Wolf bool ok = true;
619b06f8b50SKevin Wolf
62049ab747fSPaolo Bonzini if (*alenptr) {
62149ab747fSPaolo Bonzini error_setg(errp, "array size property %s may not be set more than once",
62249ab747fSPaolo Bonzini name);
62349ab747fSPaolo Bonzini return;
62449ab747fSPaolo Bonzini }
625b06f8b50SKevin Wolf
626b06f8b50SKevin Wolf if (!visit_start_list(v, name, (GenericList **) &list, size, errp)) {
62749ab747fSPaolo Bonzini return;
62849ab747fSPaolo Bonzini }
62949ab747fSPaolo Bonzini
630b06f8b50SKevin Wolf /* Read the whole input into a temporary list */
631b06f8b50SKevin Wolf elem = list;
632b06f8b50SKevin Wolf while (elem) {
633b06f8b50SKevin Wolf Property elem_prop;
63449ab747fSPaolo Bonzini
635b06f8b50SKevin Wolf elem->value = g_malloc0(prop->arrayfieldsize);
636b06f8b50SKevin Wolf elem_prop = array_elem_prop(obj, prop, name, elem->value);
637b06f8b50SKevin Wolf prop->arrayinfo->set(obj, v, NULL, &elem_prop, errp);
638b06f8b50SKevin Wolf if (*errp) {
639b06f8b50SKevin Wolf ok = false;
640b06f8b50SKevin Wolf goto out_obj;
641b06f8b50SKevin Wolf }
642b06f8b50SKevin Wolf if (*alenptr == INT_MAX) {
643b06f8b50SKevin Wolf error_setg(errp, "array is too big");
644b06f8b50SKevin Wolf return;
645b06f8b50SKevin Wolf }
646b06f8b50SKevin Wolf (*alenptr)++;
647b06f8b50SKevin Wolf elem = (ArrayElementList *) visit_next_list(v, (GenericList*) elem,
648b06f8b50SKevin Wolf size);
649b06f8b50SKevin Wolf }
650b06f8b50SKevin Wolf
651b06f8b50SKevin Wolf ok = visit_check_list(v, errp);
652b06f8b50SKevin Wolf out_obj:
653b06f8b50SKevin Wolf visit_end_list(v, (void**) &list);
654b06f8b50SKevin Wolf
655b06f8b50SKevin Wolf if (!ok) {
656b06f8b50SKevin Wolf for (elem = list; elem; elem = next) {
657b06f8b50SKevin Wolf Property elem_prop = array_elem_prop(obj, prop, name,
658b06f8b50SKevin Wolf elem->value);
659b06f8b50SKevin Wolf if (prop->arrayinfo->release) {
660b06f8b50SKevin Wolf prop->arrayinfo->release(obj, NULL, &elem_prop);
661b06f8b50SKevin Wolf }
662b06f8b50SKevin Wolf next = elem->next;
663b06f8b50SKevin Wolf g_free(elem->value);
664b06f8b50SKevin Wolf g_free(elem);
665b06f8b50SKevin Wolf }
666b06f8b50SKevin Wolf return;
667b06f8b50SKevin Wolf }
668b06f8b50SKevin Wolf
669b06f8b50SKevin Wolf /*
670b06f8b50SKevin Wolf * Now that we know how big the array has to be, move the data over to a
671b06f8b50SKevin Wolf * linear array and free the temporary list.
67249ab747fSPaolo Bonzini */
673b06f8b50SKevin Wolf *arrayptr = g_malloc_n(*alenptr, prop->arrayfieldsize);
674b06f8b50SKevin Wolf elemptr = *arrayptr;
675b06f8b50SKevin Wolf for (elem = list; elem; elem = next) {
676b06f8b50SKevin Wolf memcpy(elemptr, elem->value, prop->arrayfieldsize);
677b06f8b50SKevin Wolf elemptr += prop->arrayfieldsize;
678b06f8b50SKevin Wolf next = elem->next;
679b06f8b50SKevin Wolf g_free(elem->value);
680b06f8b50SKevin Wolf g_free(elem);
68149ab747fSPaolo Bonzini }
68249ab747fSPaolo Bonzini }
68349ab747fSPaolo Bonzini
get_prop_array(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)684b06f8b50SKevin Wolf static void get_prop_array(Object *obj, Visitor *v, const char *name,
685b06f8b50SKevin Wolf void *opaque, Error **errp)
686b06f8b50SKevin Wolf {
687b06f8b50SKevin Wolf ERRP_GUARD();
688b06f8b50SKevin Wolf Property *prop = opaque;
689b06f8b50SKevin Wolf uint32_t *alenptr = object_field_prop_ptr(obj, prop);
690b06f8b50SKevin Wolf void **arrayptr = (void *)obj + prop->arrayoffset;
69150571883SKevin Wolf char *elemptr = *arrayptr;
69250571883SKevin Wolf ArrayElementList *list = NULL, *elem;
69350571883SKevin Wolf ArrayElementList **tail = &list;
69450571883SKevin Wolf const size_t size = sizeof(*list);
695b06f8b50SKevin Wolf int i;
696b06f8b50SKevin Wolf bool ok;
697b06f8b50SKevin Wolf
69850571883SKevin Wolf /* At least the string output visitor needs a real list */
69950571883SKevin Wolf for (i = 0; i < *alenptr; i++) {
70050571883SKevin Wolf elem = g_new0(ArrayElementList, 1);
70150571883SKevin Wolf elem->value = elemptr;
70250571883SKevin Wolf elemptr += prop->arrayfieldsize;
70350571883SKevin Wolf
70450571883SKevin Wolf *tail = elem;
70550571883SKevin Wolf tail = &elem->next;
70650571883SKevin Wolf }
70750571883SKevin Wolf
70850571883SKevin Wolf if (!visit_start_list(v, name, (GenericList **) &list, size, errp)) {
709b06f8b50SKevin Wolf return;
710b06f8b50SKevin Wolf }
711b06f8b50SKevin Wolf
71250571883SKevin Wolf elem = list;
71350571883SKevin Wolf while (elem) {
71450571883SKevin Wolf Property elem_prop = array_elem_prop(obj, prop, name, elem->value);
715b06f8b50SKevin Wolf prop->arrayinfo->get(obj, v, NULL, &elem_prop, errp);
716b06f8b50SKevin Wolf if (*errp) {
717b06f8b50SKevin Wolf goto out_obj;
718b06f8b50SKevin Wolf }
71950571883SKevin Wolf elem = (ArrayElementList *) visit_next_list(v, (GenericList*) elem,
72050571883SKevin Wolf size);
721b06f8b50SKevin Wolf }
722b06f8b50SKevin Wolf
723b06f8b50SKevin Wolf /* visit_check_list() can only fail for input visitors */
724b06f8b50SKevin Wolf ok = visit_check_list(v, errp);
725b06f8b50SKevin Wolf assert(ok);
726b06f8b50SKevin Wolf
727b06f8b50SKevin Wolf out_obj:
728b06f8b50SKevin Wolf visit_end_list(v, (void**) &list);
72950571883SKevin Wolf
73050571883SKevin Wolf while (list) {
73150571883SKevin Wolf elem = list;
73250571883SKevin Wolf list = elem->next;
73350571883SKevin Wolf g_free(elem);
73450571883SKevin Wolf }
735b06f8b50SKevin Wolf }
736b06f8b50SKevin Wolf
default_prop_array(ObjectProperty * op,const Property * prop)737b06f8b50SKevin Wolf static void default_prop_array(ObjectProperty *op, const Property *prop)
738b06f8b50SKevin Wolf {
739b06f8b50SKevin Wolf object_property_set_default_list(op);
740b06f8b50SKevin Wolf }
741b06f8b50SKevin Wolf
742b06f8b50SKevin Wolf const PropertyInfo qdev_prop_array = {
743b06f8b50SKevin Wolf .name = "list",
744b06f8b50SKevin Wolf .get = get_prop_array,
745b06f8b50SKevin Wolf .set = set_prop_array,
746b06f8b50SKevin Wolf .release = release_prop_array,
747b06f8b50SKevin Wolf .set_default_value = default_prop_array,
74849ab747fSPaolo Bonzini };
74949ab747fSPaolo Bonzini
75049ab747fSPaolo Bonzini /* --- public helpers --- */
75149ab747fSPaolo Bonzini
qdev_prop_walk(const Property * props,const char * name)752*d36f165dSPaolo Bonzini static const Property *qdev_prop_walk(const Property *props, const char *name)
75349ab747fSPaolo Bonzini {
75449ab747fSPaolo Bonzini if (!props) {
75549ab747fSPaolo Bonzini return NULL;
75649ab747fSPaolo Bonzini }
75749ab747fSPaolo Bonzini while (props->name) {
75849ab747fSPaolo Bonzini if (strcmp(props->name, name) == 0) {
75949ab747fSPaolo Bonzini return props;
76049ab747fSPaolo Bonzini }
76149ab747fSPaolo Bonzini props++;
76249ab747fSPaolo Bonzini }
76349ab747fSPaolo Bonzini return NULL;
76449ab747fSPaolo Bonzini }
76549ab747fSPaolo Bonzini
qdev_prop_find(DeviceState * dev,const char * name)766*d36f165dSPaolo Bonzini static const Property *qdev_prop_find(DeviceState *dev, const char *name)
76749ab747fSPaolo Bonzini {
76849ab747fSPaolo Bonzini ObjectClass *class;
769*d36f165dSPaolo Bonzini const Property *prop;
77049ab747fSPaolo Bonzini
77149ab747fSPaolo Bonzini /* device properties */
77249ab747fSPaolo Bonzini class = object_get_class(OBJECT(dev));
77349ab747fSPaolo Bonzini do {
774385d8f22SPaolo Bonzini prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name);
77549ab747fSPaolo Bonzini if (prop) {
77649ab747fSPaolo Bonzini return prop;
77749ab747fSPaolo Bonzini }
77849ab747fSPaolo Bonzini class = object_class_get_parent(class);
77949ab747fSPaolo Bonzini } while (class != object_class_by_name(TYPE_DEVICE));
78049ab747fSPaolo Bonzini
78149ab747fSPaolo Bonzini return NULL;
78249ab747fSPaolo Bonzini }
78349ab747fSPaolo Bonzini
error_set_from_qdev_prop_error(Error ** errp,int ret,Object * obj,const char * name,const char * value)784c7525b18SEduardo Habkost void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj,
785e68c2cb7SEduardo Habkost const char *name, const char *value)
78649ab747fSPaolo Bonzini {
78749ab747fSPaolo Bonzini switch (ret) {
78849ab747fSPaolo Bonzini case -EEXIST:
789f231b88dSCole Robinson error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
790e68c2cb7SEduardo Habkost object_get_typename(obj), name, value);
79149ab747fSPaolo Bonzini break;
79249ab747fSPaolo Bonzini default:
79349ab747fSPaolo Bonzini case -EINVAL:
794be842efbSPhilippe Mathieu-Daudé error_setg(errp, "Property '%s.%s' doesn't take value '%s'",
795e68c2cb7SEduardo Habkost object_get_typename(obj), name, value);
79649ab747fSPaolo Bonzini break;
79749ab747fSPaolo Bonzini case -ENOENT:
798f231b88dSCole Robinson error_setg(errp, "Property '%s.%s' can't find value '%s'",
799e68c2cb7SEduardo Habkost object_get_typename(obj), name, value);
80049ab747fSPaolo Bonzini break;
80149ab747fSPaolo Bonzini case 0:
80249ab747fSPaolo Bonzini break;
80349ab747fSPaolo Bonzini }
80449ab747fSPaolo Bonzini }
80549ab747fSPaolo Bonzini
qdev_prop_set_bit(DeviceState * dev,const char * name,bool value)80649ab747fSPaolo Bonzini void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
80749ab747fSPaolo Bonzini {
8085325cc34SMarkus Armbruster object_property_set_bool(OBJECT(dev), name, value, &error_abort);
80949ab747fSPaolo Bonzini }
81049ab747fSPaolo Bonzini
qdev_prop_set_uint8(DeviceState * dev,const char * name,uint8_t value)81149ab747fSPaolo Bonzini void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
81249ab747fSPaolo Bonzini {
8135325cc34SMarkus Armbruster object_property_set_int(OBJECT(dev), name, value, &error_abort);
81449ab747fSPaolo Bonzini }
81549ab747fSPaolo Bonzini
qdev_prop_set_uint16(DeviceState * dev,const char * name,uint16_t value)81649ab747fSPaolo Bonzini void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
81749ab747fSPaolo Bonzini {
8185325cc34SMarkus Armbruster object_property_set_int(OBJECT(dev), name, value, &error_abort);
81949ab747fSPaolo Bonzini }
82049ab747fSPaolo Bonzini
qdev_prop_set_uint32(DeviceState * dev,const char * name,uint32_t value)82149ab747fSPaolo Bonzini void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
82249ab747fSPaolo Bonzini {
8235325cc34SMarkus Armbruster object_property_set_int(OBJECT(dev), name, value, &error_abort);
82449ab747fSPaolo Bonzini }
82549ab747fSPaolo Bonzini
qdev_prop_set_int32(DeviceState * dev,const char * name,int32_t value)82649ab747fSPaolo Bonzini void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
82749ab747fSPaolo Bonzini {
8285325cc34SMarkus Armbruster object_property_set_int(OBJECT(dev), name, value, &error_abort);
82949ab747fSPaolo Bonzini }
83049ab747fSPaolo Bonzini
qdev_prop_set_uint64(DeviceState * dev,const char * name,uint64_t value)83149ab747fSPaolo Bonzini void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
83249ab747fSPaolo Bonzini {
8335325cc34SMarkus Armbruster object_property_set_int(OBJECT(dev), name, value, &error_abort);
83449ab747fSPaolo Bonzini }
83549ab747fSPaolo Bonzini
qdev_prop_set_string(DeviceState * dev,const char * name,const char * value)83649ab747fSPaolo Bonzini void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
83749ab747fSPaolo Bonzini {
8385325cc34SMarkus Armbruster object_property_set_str(OBJECT(dev), name, value, &error_abort);
83949ab747fSPaolo Bonzini }
84049ab747fSPaolo Bonzini
qdev_prop_set_enum(DeviceState * dev,const char * name,int value)84149ab747fSPaolo Bonzini void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
84249ab747fSPaolo Bonzini {
843*d36f165dSPaolo Bonzini const Property *prop;
84449ab747fSPaolo Bonzini
84549ab747fSPaolo Bonzini prop = qdev_prop_find(dev, name);
8465325cc34SMarkus Armbruster object_property_set_str(OBJECT(dev), name,
847788b305cSMarkus Armbruster qapi_enum_lookup(prop->info->enum_table, value),
8485325cc34SMarkus Armbruster &error_abort);
84949ab747fSPaolo Bonzini }
85049ab747fSPaolo Bonzini
qdev_prop_set_array(DeviceState * dev,const char * name,QList * values)85132400a7eSKevin Wolf void qdev_prop_set_array(DeviceState *dev, const char *name, QList *values)
85232400a7eSKevin Wolf {
853b06f8b50SKevin Wolf object_property_set_qobject(OBJECT(dev), name, QOBJECT(values),
85432400a7eSKevin Wolf &error_abort);
85532400a7eSKevin Wolf qobject_unref(values);
85632400a7eSKevin Wolf }
85732400a7eSKevin Wolf
global_props(void)858e12ca3ceSMarc-André Lureau static GPtrArray *global_props(void)
859e12ca3ceSMarc-André Lureau {
860e12ca3ceSMarc-André Lureau static GPtrArray *gp;
861e12ca3ceSMarc-André Lureau
862e12ca3ceSMarc-André Lureau if (!gp) {
863e12ca3ceSMarc-André Lureau gp = g_ptr_array_new();
864e12ca3ceSMarc-André Lureau }
865e12ca3ceSMarc-André Lureau
866e12ca3ceSMarc-André Lureau return gp;
867e12ca3ceSMarc-André Lureau }
86849ab747fSPaolo Bonzini
qdev_prop_register_global(GlobalProperty * prop)86949ab747fSPaolo Bonzini void qdev_prop_register_global(GlobalProperty *prop)
87049ab747fSPaolo Bonzini {
871e12ca3ceSMarc-André Lureau g_ptr_array_add(global_props(), prop);
87249ab747fSPaolo Bonzini }
87349ab747fSPaolo Bonzini
qdev_find_global_prop(Object * obj,const char * name)87439501275SEduardo Habkost const GlobalProperty *qdev_find_global_prop(Object *obj,
8751bc13336SMarkus Armbruster const char *name)
8761bc13336SMarkus Armbruster {
8771bc13336SMarkus Armbruster GPtrArray *props = global_props();
8781bc13336SMarkus Armbruster const GlobalProperty *p;
8791bc13336SMarkus Armbruster int i;
8801bc13336SMarkus Armbruster
8811bc13336SMarkus Armbruster for (i = 0; i < props->len; i++) {
8821bc13336SMarkus Armbruster p = g_ptr_array_index(props, i);
88339501275SEduardo Habkost if (object_dynamic_cast(obj, p->driver)
8841bc13336SMarkus Armbruster && !strcmp(p->property, name)) {
8851bc13336SMarkus Armbruster return p;
8861bc13336SMarkus Armbruster }
8871bc13336SMarkus Armbruster }
8881bc13336SMarkus Armbruster return NULL;
8891bc13336SMarkus Armbruster }
8901bc13336SMarkus Armbruster
qdev_prop_check_globals(void)891d828c430SEduardo Habkost int qdev_prop_check_globals(void)
8929f9260a3SDon Slutz {
893e12ca3ceSMarc-André Lureau int i, ret = 0;
8949f9260a3SDon Slutz
895e12ca3ceSMarc-André Lureau for (i = 0; i < global_props()->len; i++) {
896e12ca3ceSMarc-André Lureau GlobalProperty *prop;
897b3ce84feSEduardo Habkost ObjectClass *oc;
898b3ce84feSEduardo Habkost DeviceClass *dc;
899e12ca3ceSMarc-André Lureau
900e12ca3ceSMarc-André Lureau prop = g_ptr_array_index(global_props(), i);
901b3ce84feSEduardo Habkost if (prop->used) {
9029f9260a3SDon Slutz continue;
9039f9260a3SDon Slutz }
904b3ce84feSEduardo Habkost oc = object_class_by_name(prop->driver);
905b3ce84feSEduardo Habkost oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
906b3ce84feSEduardo Habkost if (!oc) {
9073dc6f869SAlistair Francis warn_report("global %s.%s has invalid class name",
908b3ce84feSEduardo Habkost prop->driver, prop->property);
9099f9260a3SDon Slutz ret = 1;
910b3ce84feSEduardo Habkost continue;
911b3ce84feSEduardo Habkost }
912b3ce84feSEduardo Habkost dc = DEVICE_CLASS(oc);
913b3ce84feSEduardo Habkost if (!dc->hotpluggable && !prop->used) {
9143dc6f869SAlistair Francis warn_report("global %s.%s=%s not used",
9159f9260a3SDon Slutz prop->driver, prop->property, prop->value);
916b3ce84feSEduardo Habkost ret = 1;
917b3ce84feSEduardo Habkost continue;
918b3ce84feSEduardo Habkost }
9199f9260a3SDon Slutz }
9209f9260a3SDon Slutz return ret;
9219f9260a3SDon Slutz }
9229f9260a3SDon Slutz
qdev_prop_set_globals(DeviceState * dev)9235eb6a3c5SGreg Kurz void qdev_prop_set_globals(DeviceState *dev)
92449ab747fSPaolo Bonzini {
92550545b2cSMarc-André Lureau object_apply_global_props(OBJECT(dev), global_props(),
92650545b2cSMarc-André Lureau dev->hotplugged ? NULL : &error_fatal);
927868d378bSAndreas Färber }
928868d378bSAndreas Färber
929e8cd45c7SVasilis Liaskovitis /* --- 64bit unsigned int 'size' type --- */
930e8cd45c7SVasilis Liaskovitis
get_size(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)931d7bce999SEric Blake static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
932d7bce999SEric Blake Error **errp)
933e8cd45c7SVasilis Liaskovitis {
934e8cd45c7SVasilis Liaskovitis Property *prop = opaque;
9351e198715SEduardo Habkost uint64_t *ptr = object_field_prop_ptr(obj, prop);
936e8cd45c7SVasilis Liaskovitis
93751e72bc1SEric Blake visit_type_size(v, name, ptr, errp);
938e8cd45c7SVasilis Liaskovitis }
939e8cd45c7SVasilis Liaskovitis
set_size(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)940d7bce999SEric Blake static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
941d7bce999SEric Blake Error **errp)
942e8cd45c7SVasilis Liaskovitis {
943e8cd45c7SVasilis Liaskovitis Property *prop = opaque;
9441e198715SEduardo Habkost uint64_t *ptr = object_field_prop_ptr(obj, prop);
945e8cd45c7SVasilis Liaskovitis
94651e72bc1SEric Blake visit_type_size(v, name, ptr, errp);
947e8cd45c7SVasilis Liaskovitis }
948e8cd45c7SVasilis Liaskovitis
9491b6b7d10SFam Zheng const PropertyInfo qdev_prop_size = {
950e8cd45c7SVasilis Liaskovitis .name = "size",
951e8cd45c7SVasilis Liaskovitis .get = get_size,
952e8cd45c7SVasilis Liaskovitis .set = set_size,
95393e163e4SPhilippe Mathieu-Daudé .set_default_value = qdev_propinfo_set_default_value_uint,
954e8cd45c7SVasilis Liaskovitis };
9555b4ff3c6SFam Zheng
9565b4ff3c6SFam Zheng /* --- object link property --- */
9575b4ff3c6SFam Zheng
create_link_property(ObjectClass * oc,const char * name,const Property * prop)958f59c6d22SEduardo Habkost static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
959*d36f165dSPaolo Bonzini const Property *prop)
9605b4ff3c6SFam Zheng {
961f59c6d22SEduardo Habkost return object_class_property_add_link(oc, name, prop->link_type,
96277b06bbaSMarc-André Lureau prop->offset,
9635b4ff3c6SFam Zheng qdev_prop_allow_set_link_before_realize,
964d2623129SMarkus Armbruster OBJ_PROP_LINK_STRONG);
9655b4ff3c6SFam Zheng }
9665b4ff3c6SFam Zheng
9671b6b7d10SFam Zheng const PropertyInfo qdev_prop_link = {
9685b4ff3c6SFam Zheng .name = "link",
9695b4ff3c6SFam Zheng .create = create_link_property,
9705b4ff3c6SFam Zheng };
971d3fd6e73SEduardo Habkost
qdev_property_add_static(DeviceState * dev,const Property * prop)972*d36f165dSPaolo Bonzini void qdev_property_add_static(DeviceState *dev, const Property *prop)
973d3fd6e73SEduardo Habkost {
974d3fd6e73SEduardo Habkost Object *obj = OBJECT(dev);
975d3fd6e73SEduardo Habkost ObjectProperty *op;
976d3fd6e73SEduardo Habkost
977d3fd6e73SEduardo Habkost assert(!prop->info->create);
978d3fd6e73SEduardo Habkost
979d3fd6e73SEduardo Habkost op = object_property_add(obj, prop->name, prop->info->name,
9807ed854afSEduardo Habkost field_prop_getter(prop->info),
9817ed854afSEduardo Habkost field_prop_setter(prop->info),
982d3fd6e73SEduardo Habkost prop->info->release,
983*d36f165dSPaolo Bonzini (Property *)prop);
984d3fd6e73SEduardo Habkost
985d3fd6e73SEduardo Habkost object_property_set_description(obj, prop->name,
986d3fd6e73SEduardo Habkost prop->info->description);
987d3fd6e73SEduardo Habkost
988d3fd6e73SEduardo Habkost if (prop->set_default) {
989d3fd6e73SEduardo Habkost prop->info->set_default_value(op, prop);
990d3fd6e73SEduardo Habkost if (op->init) {
991d3fd6e73SEduardo Habkost op->init(obj, op);
992d3fd6e73SEduardo Habkost }
993d3fd6e73SEduardo Habkost }
994d3fd6e73SEduardo Habkost }
995d3fd6e73SEduardo Habkost
qdev_class_add_property(DeviceClass * klass,const char * name,const Property * prop)99623a1dae8SEduardo Habkost static void qdev_class_add_property(DeviceClass *klass, const char *name,
997*d36f165dSPaolo Bonzini const Property *prop)
998d3fd6e73SEduardo Habkost {
999d3fd6e73SEduardo Habkost ObjectClass *oc = OBJECT_CLASS(klass);
1000d3fd6e73SEduardo Habkost ObjectProperty *op;
1001d3fd6e73SEduardo Habkost
10020d5d5bc5SEduardo Habkost if (prop->info->create) {
10030d5d5bc5SEduardo Habkost op = prop->info->create(oc, name, prop);
10040d5d5bc5SEduardo Habkost } else {
1005d3fd6e73SEduardo Habkost op = object_class_property_add(oc,
100623a1dae8SEduardo Habkost name, prop->info->name,
10077ed854afSEduardo Habkost field_prop_getter(prop->info),
10087ed854afSEduardo Habkost field_prop_setter(prop->info),
1009d3fd6e73SEduardo Habkost prop->info->release,
1010*d36f165dSPaolo Bonzini (Property *)prop);
10110d5d5bc5SEduardo Habkost }
1012d3fd6e73SEduardo Habkost if (prop->set_default) {
1013d3fd6e73SEduardo Habkost prop->info->set_default_value(op, prop);
1014d3fd6e73SEduardo Habkost }
10150d5d5bc5SEduardo Habkost object_class_property_set_description(oc, name, prop->info->description);
1016d3fd6e73SEduardo Habkost }
1017d3fd6e73SEduardo Habkost
1018d3fd6e73SEduardo Habkost /**
1019d3fd6e73SEduardo Habkost * Legacy property handling
1020d3fd6e73SEduardo Habkost */
1021d3fd6e73SEduardo Habkost
qdev_get_legacy_property(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)1022d3fd6e73SEduardo Habkost static void qdev_get_legacy_property(Object *obj, Visitor *v,
1023d3fd6e73SEduardo Habkost const char *name, void *opaque,
1024d3fd6e73SEduardo Habkost Error **errp)
1025d3fd6e73SEduardo Habkost {
1026d3fd6e73SEduardo Habkost Property *prop = opaque;
1027d3fd6e73SEduardo Habkost
1028d3fd6e73SEduardo Habkost char buffer[1024];
1029d3fd6e73SEduardo Habkost char *ptr = buffer;
1030d3fd6e73SEduardo Habkost
103140ea00b0SEduardo Habkost prop->info->print(obj, prop, buffer, sizeof(buffer));
1032d3fd6e73SEduardo Habkost visit_type_str(v, name, &ptr, errp);
1033d3fd6e73SEduardo Habkost }
1034d3fd6e73SEduardo Habkost
1035d3fd6e73SEduardo Habkost /**
1036d3fd6e73SEduardo Habkost * qdev_class_add_legacy_property:
1037d3fd6e73SEduardo Habkost * @dev: Device to add the property to.
1038d3fd6e73SEduardo Habkost * @prop: The qdev property definition.
1039d3fd6e73SEduardo Habkost *
1040d3fd6e73SEduardo Habkost * Add a legacy QOM property to @dev for qdev property @prop.
1041d3fd6e73SEduardo Habkost *
1042d3fd6e73SEduardo Habkost * Legacy properties are string versions of QOM properties. The format of
1043d3fd6e73SEduardo Habkost * the string depends on the property type. Legacy properties are only
1044d3fd6e73SEduardo Habkost * needed for "info qtree".
1045d3fd6e73SEduardo Habkost *
1046d3fd6e73SEduardo Habkost * Do not use this in new code! QOM Properties added through this interface
1047d3fd6e73SEduardo Habkost * will be given names in the "legacy" namespace.
1048d3fd6e73SEduardo Habkost */
qdev_class_add_legacy_property(DeviceClass * dc,const Property * prop)1049*d36f165dSPaolo Bonzini static void qdev_class_add_legacy_property(DeviceClass *dc, const Property *prop)
1050d3fd6e73SEduardo Habkost {
1051d3fd6e73SEduardo Habkost g_autofree char *name = NULL;
1052d3fd6e73SEduardo Habkost
1053d3fd6e73SEduardo Habkost /* Register pointer properties as legacy properties */
1054d3fd6e73SEduardo Habkost if (!prop->info->print && prop->info->get) {
1055d3fd6e73SEduardo Habkost return;
1056d3fd6e73SEduardo Habkost }
1057d3fd6e73SEduardo Habkost
1058d3fd6e73SEduardo Habkost name = g_strdup_printf("legacy-%s", prop->name);
1059d3fd6e73SEduardo Habkost object_class_property_add(OBJECT_CLASS(dc), name, "str",
1060d3fd6e73SEduardo Habkost prop->info->print ? qdev_get_legacy_property : prop->info->get,
1061*d36f165dSPaolo Bonzini NULL, NULL, (Property *)prop);
1062d3fd6e73SEduardo Habkost }
1063d3fd6e73SEduardo Habkost
device_class_set_props(DeviceClass * dc,const Property * props)1064*d36f165dSPaolo Bonzini void device_class_set_props(DeviceClass *dc, const Property *props)
1065d3fd6e73SEduardo Habkost {
1066*d36f165dSPaolo Bonzini const Property *prop;
1067d3fd6e73SEduardo Habkost
1068d3fd6e73SEduardo Habkost dc->props_ = props;
1069d3fd6e73SEduardo Habkost for (prop = props; prop && prop->name; prop++) {
1070d3fd6e73SEduardo Habkost qdev_class_add_legacy_property(dc, prop);
107123a1dae8SEduardo Habkost qdev_class_add_property(dc, prop->name, prop);
1072d3fd6e73SEduardo Habkost }
1073d3fd6e73SEduardo Habkost }
1074d3fd6e73SEduardo Habkost
qdev_alias_all_properties(DeviceState * target,Object * source)1075d3fd6e73SEduardo Habkost void qdev_alias_all_properties(DeviceState *target, Object *source)
1076d3fd6e73SEduardo Habkost {
1077d3fd6e73SEduardo Habkost ObjectClass *class;
1078350147a8SStefan Hajnoczi ObjectPropertyIterator iter;
1079350147a8SStefan Hajnoczi ObjectProperty *prop;
1080d3fd6e73SEduardo Habkost
1081d3fd6e73SEduardo Habkost class = object_get_class(OBJECT(target));
1082d3fd6e73SEduardo Habkost
1083350147a8SStefan Hajnoczi object_class_property_iter_init(&iter, class);
1084350147a8SStefan Hajnoczi while ((prop = object_property_iter_next(&iter))) {
1085350147a8SStefan Hajnoczi if (object_property_find(source, prop->name)) {
1086350147a8SStefan Hajnoczi continue; /* skip duplicate properties */
1087350147a8SStefan Hajnoczi }
1088350147a8SStefan Hajnoczi
1089d3fd6e73SEduardo Habkost object_property_add_alias(source, prop->name,
1090d3fd6e73SEduardo Habkost OBJECT(target), prop->name);
1091d3fd6e73SEduardo Habkost }
1092d3fd6e73SEduardo Habkost }
1093