xref: /openbmc/qemu/hw/core/qdev-properties.c (revision a1dacb66915eb7d08a0596cc97068a37c39930d3)
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