1 #include "qemu/osdep.h"
2 #include "hw/qdev-properties.h"
3 #include "qapi/error.h"
4 #include "qapi/qapi-types-misc.h"
5 #include "qapi/qmp/qlist.h"
6 #include "qemu/ctype.h"
7 #include "qemu/error-report.h"
8 #include "qapi/visitor.h"
9 #include "qemu/units.h"
10 #include "qemu/cutils.h"
11 #include "qdev-prop-internal.h"
12 #include "qom/qom-qobject.h"
14 void qdev_prop_set_after_realize(DeviceState
*dev
, const char *name
,
18 error_setg(errp
, "Attempt to set property '%s' on device '%s' "
19 "(type '%s') after it was realized", name
, dev
->id
,
20 object_get_typename(OBJECT(dev
)));
22 error_setg(errp
, "Attempt to set property '%s' on anonymous device "
23 "(type '%s') after it was realized", name
,
24 object_get_typename(OBJECT(dev
)));
28 /* returns: true if property is allowed to be set, false otherwise */
29 static bool qdev_prop_allow_set(Object
*obj
, const char *name
,
30 const PropertyInfo
*info
, Error
**errp
)
32 DeviceState
*dev
= DEVICE(obj
);
34 if (dev
->realized
&& !info
->realized_set_allowed
) {
35 qdev_prop_set_after_realize(dev
, name
, errp
);
41 void qdev_prop_allow_set_link_before_realize(const Object
*obj
,
43 Object
*val
, Error
**errp
)
45 DeviceState
*dev
= DEVICE(obj
);
48 error_setg(errp
, "Attempt to set link property '%s' on device '%s' "
49 "(type '%s') after it was realized",
50 name
, dev
->id
, object_get_typename(obj
));
54 void *object_field_prop_ptr(Object
*obj
, Property
*prop
)
61 static void field_prop_get(Object
*obj
, Visitor
*v
, const char *name
,
62 void *opaque
, Error
**errp
)
64 Property
*prop
= opaque
;
65 return prop
->info
->get(obj
, v
, name
, opaque
, errp
);
69 * field_prop_getter: Return getter function to be used for property
71 * Return value can be NULL if @info has no getter function.
73 static ObjectPropertyAccessor
*field_prop_getter(const PropertyInfo
*info
)
75 return info
->get
? field_prop_get
: NULL
;
78 static void field_prop_set(Object
*obj
, Visitor
*v
, const char *name
,
79 void *opaque
, Error
**errp
)
81 Property
*prop
= opaque
;
83 if (!qdev_prop_allow_set(obj
, name
, prop
->info
, errp
)) {
87 return prop
->info
->set(obj
, v
, name
, opaque
, errp
);
91 * field_prop_setter: Return setter function to be used for property
93 * Return value can be NULL if @info has not setter function.
95 static ObjectPropertyAccessor
*field_prop_setter(const PropertyInfo
*info
)
97 return info
->set
? field_prop_set
: NULL
;
100 void qdev_propinfo_get_enum(Object
*obj
, Visitor
*v
, const char *name
,
101 void *opaque
, Error
**errp
)
103 Property
*prop
= opaque
;
104 int *ptr
= object_field_prop_ptr(obj
, prop
);
106 visit_type_enum(v
, name
, ptr
, prop
->info
->enum_table
, errp
);
109 void qdev_propinfo_set_enum(Object
*obj
, Visitor
*v
, const char *name
,
110 void *opaque
, Error
**errp
)
112 Property
*prop
= opaque
;
113 int *ptr
= object_field_prop_ptr(obj
, prop
);
115 visit_type_enum(v
, name
, ptr
, prop
->info
->enum_table
, errp
);
118 void qdev_propinfo_set_default_value_enum(ObjectProperty
*op
,
119 const Property
*prop
)
121 object_property_set_default_str(op
,
122 qapi_enum_lookup(prop
->info
->enum_table
, prop
->defval
.i
));
125 const PropertyInfo qdev_prop_enum
= {
127 .get
= qdev_propinfo_get_enum
,
128 .set
= qdev_propinfo_set_enum
,
129 .set_default_value
= qdev_propinfo_set_default_value_enum
,
134 static uint32_t qdev_get_prop_mask(Property
*prop
)
136 assert(prop
->info
== &qdev_prop_bit
);
137 return 0x1 << prop
->bitnr
;
140 static void bit_prop_set(Object
*obj
, Property
*props
, bool val
)
142 uint32_t *p
= object_field_prop_ptr(obj
, props
);
143 uint32_t mask
= qdev_get_prop_mask(props
);
151 static void prop_get_bit(Object
*obj
, Visitor
*v
, const char *name
,
152 void *opaque
, Error
**errp
)
154 Property
*prop
= opaque
;
155 uint32_t *p
= object_field_prop_ptr(obj
, prop
);
156 bool value
= (*p
& qdev_get_prop_mask(prop
)) != 0;
158 visit_type_bool(v
, name
, &value
, errp
);
161 static void prop_set_bit(Object
*obj
, Visitor
*v
, const char *name
,
162 void *opaque
, Error
**errp
)
164 Property
*prop
= opaque
;
167 if (!visit_type_bool(v
, name
, &value
, errp
)) {
170 bit_prop_set(obj
, prop
, value
);
173 static void set_default_value_bool(ObjectProperty
*op
, const Property
*prop
)
175 object_property_set_default_bool(op
, prop
->defval
.u
);
178 const PropertyInfo qdev_prop_bit
= {
180 .description
= "on/off",
183 .set_default_value
= set_default_value_bool
,
188 static uint64_t qdev_get_prop_mask64(Property
*prop
)
190 assert(prop
->info
== &qdev_prop_bit64
);
191 return 0x1ull
<< prop
->bitnr
;
194 static void bit64_prop_set(Object
*obj
, Property
*props
, bool val
)
196 uint64_t *p
= object_field_prop_ptr(obj
, props
);
197 uint64_t mask
= qdev_get_prop_mask64(props
);
205 static void prop_get_bit64(Object
*obj
, Visitor
*v
, const char *name
,
206 void *opaque
, Error
**errp
)
208 Property
*prop
= opaque
;
209 uint64_t *p
= object_field_prop_ptr(obj
, prop
);
210 bool value
= (*p
& qdev_get_prop_mask64(prop
)) != 0;
212 visit_type_bool(v
, name
, &value
, errp
);
215 static void prop_set_bit64(Object
*obj
, Visitor
*v
, const char *name
,
216 void *opaque
, Error
**errp
)
218 Property
*prop
= opaque
;
221 if (!visit_type_bool(v
, name
, &value
, errp
)) {
224 bit64_prop_set(obj
, prop
, value
);
227 const PropertyInfo qdev_prop_bit64
= {
229 .description
= "on/off",
230 .get
= prop_get_bit64
,
231 .set
= prop_set_bit64
,
232 .set_default_value
= set_default_value_bool
,
237 static void get_bool(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
240 Property
*prop
= opaque
;
241 bool *ptr
= object_field_prop_ptr(obj
, prop
);
243 visit_type_bool(v
, name
, ptr
, errp
);
246 static void set_bool(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
249 Property
*prop
= opaque
;
250 bool *ptr
= object_field_prop_ptr(obj
, prop
);
252 visit_type_bool(v
, name
, ptr
, errp
);
255 const PropertyInfo qdev_prop_bool
= {
259 .set_default_value
= set_default_value_bool
,
262 /* --- 8bit integer --- */
264 static void get_uint8(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
267 Property
*prop
= opaque
;
268 uint8_t *ptr
= object_field_prop_ptr(obj
, prop
);
270 visit_type_uint8(v
, name
, ptr
, errp
);
273 static void set_uint8(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
276 Property
*prop
= opaque
;
277 uint8_t *ptr
= object_field_prop_ptr(obj
, prop
);
279 visit_type_uint8(v
, name
, ptr
, errp
);
282 void qdev_propinfo_set_default_value_int(ObjectProperty
*op
,
283 const Property
*prop
)
285 object_property_set_default_int(op
, prop
->defval
.i
);
288 void qdev_propinfo_set_default_value_uint(ObjectProperty
*op
,
289 const Property
*prop
)
291 object_property_set_default_uint(op
, prop
->defval
.u
);
294 const PropertyInfo qdev_prop_uint8
= {
298 .set_default_value
= qdev_propinfo_set_default_value_uint
,
301 /* --- 16bit integer --- */
303 static void get_uint16(Object
*obj
, Visitor
*v
, const char *name
,
304 void *opaque
, Error
**errp
)
306 Property
*prop
= opaque
;
307 uint16_t *ptr
= object_field_prop_ptr(obj
, prop
);
309 visit_type_uint16(v
, name
, ptr
, errp
);
312 static void set_uint16(Object
*obj
, Visitor
*v
, const char *name
,
313 void *opaque
, Error
**errp
)
315 Property
*prop
= opaque
;
316 uint16_t *ptr
= object_field_prop_ptr(obj
, prop
);
318 visit_type_uint16(v
, name
, ptr
, errp
);
321 const PropertyInfo qdev_prop_uint16
= {
325 .set_default_value
= qdev_propinfo_set_default_value_uint
,
328 /* --- 32bit integer --- */
330 static void get_uint32(Object
*obj
, Visitor
*v
, const char *name
,
331 void *opaque
, Error
**errp
)
333 Property
*prop
= opaque
;
334 uint32_t *ptr
= object_field_prop_ptr(obj
, prop
);
336 visit_type_uint32(v
, name
, ptr
, errp
);
339 static void set_uint32(Object
*obj
, Visitor
*v
, const char *name
,
340 void *opaque
, Error
**errp
)
342 Property
*prop
= opaque
;
343 uint32_t *ptr
= object_field_prop_ptr(obj
, prop
);
345 visit_type_uint32(v
, name
, ptr
, errp
);
348 void qdev_propinfo_get_int32(Object
*obj
, Visitor
*v
, const char *name
,
349 void *opaque
, Error
**errp
)
351 Property
*prop
= opaque
;
352 int32_t *ptr
= object_field_prop_ptr(obj
, prop
);
354 visit_type_int32(v
, name
, ptr
, errp
);
357 static void set_int32(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
360 Property
*prop
= opaque
;
361 int32_t *ptr
= object_field_prop_ptr(obj
, prop
);
363 visit_type_int32(v
, name
, ptr
, errp
);
366 const PropertyInfo qdev_prop_uint32
= {
370 .set_default_value
= qdev_propinfo_set_default_value_uint
,
373 const PropertyInfo qdev_prop_int32
= {
375 .get
= qdev_propinfo_get_int32
,
377 .set_default_value
= qdev_propinfo_set_default_value_int
,
380 /* --- 64bit integer --- */
382 static void get_uint64(Object
*obj
, Visitor
*v
, const char *name
,
383 void *opaque
, Error
**errp
)
385 Property
*prop
= opaque
;
386 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
388 visit_type_uint64(v
, name
, ptr
, errp
);
391 static void set_uint64(Object
*obj
, Visitor
*v
, const char *name
,
392 void *opaque
, Error
**errp
)
394 Property
*prop
= opaque
;
395 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
397 visit_type_uint64(v
, name
, ptr
, errp
);
400 static void get_int64(Object
*obj
, Visitor
*v
, const char *name
,
401 void *opaque
, Error
**errp
)
403 Property
*prop
= opaque
;
404 int64_t *ptr
= object_field_prop_ptr(obj
, prop
);
406 visit_type_int64(v
, name
, ptr
, errp
);
409 static void set_int64(Object
*obj
, Visitor
*v
, const char *name
,
410 void *opaque
, Error
**errp
)
412 Property
*prop
= opaque
;
413 int64_t *ptr
= object_field_prop_ptr(obj
, prop
);
415 visit_type_int64(v
, name
, ptr
, errp
);
418 const PropertyInfo qdev_prop_uint64
= {
422 .set_default_value
= qdev_propinfo_set_default_value_uint
,
425 const PropertyInfo qdev_prop_int64
= {
429 .set_default_value
= qdev_propinfo_set_default_value_int
,
432 static void set_uint64_checkmask(Object
*obj
, Visitor
*v
, const char *name
,
433 void *opaque
, Error
**errp
)
435 Property
*prop
= opaque
;
436 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
438 visit_type_uint64(v
, name
, ptr
, errp
);
439 if (*ptr
& ~prop
->bitmask
) {
440 error_setg(errp
, "Property value for '%s' has bits outside mask '0x%" PRIx64
"'",
441 name
, prop
->bitmask
);
445 const PropertyInfo qdev_prop_uint64_checkmask
= {
448 .set
= set_uint64_checkmask
,
453 static void release_string(Object
*obj
, const char *name
, void *opaque
)
455 Property
*prop
= opaque
;
456 g_free(*(char **)object_field_prop_ptr(obj
, prop
));
459 static void get_string(Object
*obj
, Visitor
*v
, const char *name
,
460 void *opaque
, Error
**errp
)
462 Property
*prop
= opaque
;
463 char **ptr
= object_field_prop_ptr(obj
, prop
);
466 char *str
= (char *)"";
467 visit_type_str(v
, name
, &str
, errp
);
469 visit_type_str(v
, name
, ptr
, errp
);
473 static void set_string(Object
*obj
, Visitor
*v
, const char *name
,
474 void *opaque
, Error
**errp
)
476 Property
*prop
= opaque
;
477 char **ptr
= object_field_prop_ptr(obj
, prop
);
480 if (!visit_type_str(v
, name
, &str
, errp
)) {
487 const PropertyInfo qdev_prop_string
= {
489 .release
= release_string
,
494 /* --- on/off/auto --- */
496 const PropertyInfo qdev_prop_on_off_auto
= {
498 .description
= "on/off/auto",
499 .enum_table
= &OnOffAuto_lookup
,
500 .get
= qdev_propinfo_get_enum
,
501 .set
= qdev_propinfo_set_enum
,
502 .set_default_value
= qdev_propinfo_set_default_value_enum
,
505 /* --- 32bit unsigned int 'size' type --- */
507 void qdev_propinfo_get_size32(Object
*obj
, Visitor
*v
, const char *name
,
508 void *opaque
, Error
**errp
)
510 Property
*prop
= opaque
;
511 uint32_t *ptr
= object_field_prop_ptr(obj
, prop
);
512 uint64_t value
= *ptr
;
514 visit_type_size(v
, name
, &value
, errp
);
517 static void set_size32(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
520 Property
*prop
= opaque
;
521 uint32_t *ptr
= object_field_prop_ptr(obj
, prop
);
524 if (!visit_type_size(v
, name
, &value
, errp
)) {
528 if (value
> UINT32_MAX
) {
530 "Property %s.%s doesn't take value %" PRIu64
532 object_get_typename(obj
), name
, value
, UINT32_MAX
);
539 const PropertyInfo qdev_prop_size32
= {
541 .get
= qdev_propinfo_get_size32
,
543 .set_default_value
= qdev_propinfo_set_default_value_uint
,
546 /* --- support for array properties --- */
548 typedef struct ArrayElementList ArrayElementList
;
550 struct ArrayElementList
{
551 ArrayElementList
*next
;
556 * Given an array property @parent_prop in @obj, return a Property for a
557 * specific element of the array. Arrays are backed by an uint32_t length field
558 * and an element array. @elem points at an element in this element array.
560 static Property
array_elem_prop(Object
*obj
, Property
*parent_prop
,
561 const char *name
, char *elem
)
564 .info
= parent_prop
->arrayinfo
,
567 * This ugly piece of pointer arithmetic sets up the offset so
568 * that when the underlying release hook calls qdev_get_prop_ptr
569 * they get the right answer despite the array element not actually
570 * being inside the device struct.
572 .offset
= (uintptr_t)elem
- (uintptr_t)obj
,
577 * Object property release callback for array properties: We call the
578 * underlying element's property release hook for each element.
580 * Note that it is the responsibility of the individual device's deinit
581 * to free the array proper.
583 static void release_prop_array(Object
*obj
, const char *name
, void *opaque
)
585 Property
*prop
= opaque
;
586 uint32_t *alenptr
= object_field_prop_ptr(obj
, prop
);
587 void **arrayptr
= (void *)obj
+ prop
->arrayoffset
;
588 char *elem
= *arrayptr
;
591 if (!prop
->arrayinfo
->release
) {
595 for (i
= 0; i
< *alenptr
; i
++) {
596 Property elem_prop
= array_elem_prop(obj
, prop
, name
, elem
);
597 prop
->arrayinfo
->release(obj
, NULL
, &elem_prop
);
598 elem
+= prop
->arrayfieldsize
;
603 * Setter for an array property. This sets both the array length (which
604 * is technically the property field in the object) and the array itself
605 * (a pointer to which is stored in the additional field described by
606 * prop->arrayoffset).
608 static void set_prop_array(Object
*obj
, Visitor
*v
, const char *name
,
609 void *opaque
, Error
**errp
)
612 Property
*prop
= opaque
;
613 uint32_t *alenptr
= object_field_prop_ptr(obj
, prop
);
614 void **arrayptr
= (void *)obj
+ prop
->arrayoffset
;
615 ArrayElementList
*list
, *elem
, *next
;
616 const size_t size
= sizeof(*list
);
621 error_setg(errp
, "array size property %s may not be set more than once",
626 if (!visit_start_list(v
, name
, (GenericList
**) &list
, size
, errp
)) {
630 /* Read the whole input into a temporary list */
635 elem
->value
= g_malloc0(prop
->arrayfieldsize
);
636 elem_prop
= array_elem_prop(obj
, prop
, name
, elem
->value
);
637 prop
->arrayinfo
->set(obj
, v
, NULL
, &elem_prop
, errp
);
642 if (*alenptr
== INT_MAX
) {
643 error_setg(errp
, "array is too big");
647 elem
= (ArrayElementList
*) visit_next_list(v
, (GenericList
*) elem
,
651 ok
= visit_check_list(v
, errp
);
653 visit_end_list(v
, (void**) &list
);
656 for (elem
= list
; elem
; elem
= next
) {
657 Property elem_prop
= array_elem_prop(obj
, prop
, name
,
659 if (prop
->arrayinfo
->release
) {
660 prop
->arrayinfo
->release(obj
, NULL
, &elem_prop
);
670 * Now that we know how big the array has to be, move the data over to a
671 * linear array and free the temporary list.
673 *arrayptr
= g_malloc_n(*alenptr
, prop
->arrayfieldsize
);
675 for (elem
= list
; elem
; elem
= next
) {
676 memcpy(elemptr
, elem
->value
, prop
->arrayfieldsize
);
677 elemptr
+= prop
->arrayfieldsize
;
684 static void get_prop_array(Object
*obj
, Visitor
*v
, const char *name
,
685 void *opaque
, Error
**errp
)
688 Property
*prop
= opaque
;
689 uint32_t *alenptr
= object_field_prop_ptr(obj
, prop
);
690 void **arrayptr
= (void *)obj
+ prop
->arrayoffset
;
691 char *elemptr
= *arrayptr
;
692 ArrayElementList
*list
= NULL
, *elem
;
693 ArrayElementList
**tail
= &list
;
694 const size_t size
= sizeof(*list
);
698 /* At least the string output visitor needs a real list */
699 for (i
= 0; i
< *alenptr
; i
++) {
700 elem
= g_new0(ArrayElementList
, 1);
701 elem
->value
= elemptr
;
702 elemptr
+= prop
->arrayfieldsize
;
708 if (!visit_start_list(v
, name
, (GenericList
**) &list
, size
, errp
)) {
714 Property elem_prop
= array_elem_prop(obj
, prop
, name
, elem
->value
);
715 prop
->arrayinfo
->get(obj
, v
, NULL
, &elem_prop
, errp
);
719 elem
= (ArrayElementList
*) visit_next_list(v
, (GenericList
*) elem
,
723 /* visit_check_list() can only fail for input visitors */
724 ok
= visit_check_list(v
, errp
);
728 visit_end_list(v
, (void**) &list
);
737 static void default_prop_array(ObjectProperty
*op
, const Property
*prop
)
739 object_property_set_default_list(op
);
742 const PropertyInfo qdev_prop_array
= {
744 .get
= get_prop_array
,
745 .set
= set_prop_array
,
746 .release
= release_prop_array
,
747 .set_default_value
= default_prop_array
,
750 /* --- public helpers --- */
752 static Property
*qdev_prop_walk(Property
*props
, const char *name
)
757 while (props
->name
) {
758 if (strcmp(props
->name
, name
) == 0) {
766 static Property
*qdev_prop_find(DeviceState
*dev
, const char *name
)
771 /* device properties */
772 class = object_get_class(OBJECT(dev
));
774 prop
= qdev_prop_walk(DEVICE_CLASS(class)->props_
, name
);
778 class = object_class_get_parent(class);
779 } while (class != object_class_by_name(TYPE_DEVICE
));
784 void error_set_from_qdev_prop_error(Error
**errp
, int ret
, Object
*obj
,
785 const char *name
, const char *value
)
789 error_setg(errp
, "Property '%s.%s' can't take value '%s', it's in use",
790 object_get_typename(obj
), name
, value
);
794 error_setg(errp
, "Property '%s.%s' doesn't take value '%s'",
795 object_get_typename(obj
), name
, value
);
798 error_setg(errp
, "Property '%s.%s' can't find value '%s'",
799 object_get_typename(obj
), name
, value
);
806 void qdev_prop_set_bit(DeviceState
*dev
, const char *name
, bool value
)
808 object_property_set_bool(OBJECT(dev
), name
, value
, &error_abort
);
811 void qdev_prop_set_uint8(DeviceState
*dev
, const char *name
, uint8_t value
)
813 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
816 void qdev_prop_set_uint16(DeviceState
*dev
, const char *name
, uint16_t value
)
818 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
821 void qdev_prop_set_uint32(DeviceState
*dev
, const char *name
, uint32_t value
)
823 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
826 void qdev_prop_set_int32(DeviceState
*dev
, const char *name
, int32_t value
)
828 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
831 void qdev_prop_set_uint64(DeviceState
*dev
, const char *name
, uint64_t value
)
833 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
836 void qdev_prop_set_string(DeviceState
*dev
, const char *name
, const char *value
)
838 object_property_set_str(OBJECT(dev
), name
, value
, &error_abort
);
841 void qdev_prop_set_enum(DeviceState
*dev
, const char *name
, int value
)
845 prop
= qdev_prop_find(dev
, name
);
846 object_property_set_str(OBJECT(dev
), name
,
847 qapi_enum_lookup(prop
->info
->enum_table
, value
),
851 void qdev_prop_set_array(DeviceState
*dev
, const char *name
, QList
*values
)
853 object_property_set_qobject(OBJECT(dev
), name
, QOBJECT(values
),
855 qobject_unref(values
);
858 static GPtrArray
*global_props(void)
860 static GPtrArray
*gp
;
863 gp
= g_ptr_array_new();
869 void qdev_prop_register_global(GlobalProperty
*prop
)
871 g_ptr_array_add(global_props(), prop
);
874 const GlobalProperty
*qdev_find_global_prop(Object
*obj
,
877 GPtrArray
*props
= global_props();
878 const GlobalProperty
*p
;
881 for (i
= 0; i
< props
->len
; i
++) {
882 p
= g_ptr_array_index(props
, i
);
883 if (object_dynamic_cast(obj
, p
->driver
)
884 && !strcmp(p
->property
, name
)) {
891 int qdev_prop_check_globals(void)
895 for (i
= 0; i
< global_props()->len
; i
++) {
896 GlobalProperty
*prop
;
900 prop
= g_ptr_array_index(global_props(), i
);
904 oc
= object_class_by_name(prop
->driver
);
905 oc
= object_class_dynamic_cast(oc
, TYPE_DEVICE
);
907 warn_report("global %s.%s has invalid class name",
908 prop
->driver
, prop
->property
);
912 dc
= DEVICE_CLASS(oc
);
913 if (!dc
->hotpluggable
&& !prop
->used
) {
914 warn_report("global %s.%s=%s not used",
915 prop
->driver
, prop
->property
, prop
->value
);
923 void qdev_prop_set_globals(DeviceState
*dev
)
925 object_apply_global_props(OBJECT(dev
), global_props(),
926 dev
->hotplugged
? NULL
: &error_fatal
);
929 /* --- 64bit unsigned int 'size' type --- */
931 static void get_size(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
934 Property
*prop
= opaque
;
935 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
937 visit_type_size(v
, name
, ptr
, errp
);
940 static void set_size(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
943 Property
*prop
= opaque
;
944 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
946 visit_type_size(v
, name
, ptr
, errp
);
949 const PropertyInfo qdev_prop_size
= {
953 .set_default_value
= qdev_propinfo_set_default_value_uint
,
956 /* --- object link property --- */
958 static ObjectProperty
*create_link_property(ObjectClass
*oc
, const char *name
,
961 return object_class_property_add_link(oc
, name
, prop
->link_type
,
963 qdev_prop_allow_set_link_before_realize
,
964 OBJ_PROP_LINK_STRONG
);
967 const PropertyInfo qdev_prop_link
= {
969 .create
= create_link_property
,
972 void qdev_property_add_static(DeviceState
*dev
, Property
*prop
)
974 Object
*obj
= OBJECT(dev
);
977 assert(!prop
->info
->create
);
979 op
= object_property_add(obj
, prop
->name
, prop
->info
->name
,
980 field_prop_getter(prop
->info
),
981 field_prop_setter(prop
->info
),
985 object_property_set_description(obj
, prop
->name
,
986 prop
->info
->description
);
988 if (prop
->set_default
) {
989 prop
->info
->set_default_value(op
, prop
);
996 static void qdev_class_add_property(DeviceClass
*klass
, const char *name
,
999 ObjectClass
*oc
= OBJECT_CLASS(klass
);
1002 if (prop
->info
->create
) {
1003 op
= prop
->info
->create(oc
, name
, prop
);
1005 op
= object_class_property_add(oc
,
1006 name
, prop
->info
->name
,
1007 field_prop_getter(prop
->info
),
1008 field_prop_setter(prop
->info
),
1009 prop
->info
->release
,
1012 if (prop
->set_default
) {
1013 prop
->info
->set_default_value(op
, prop
);
1015 object_class_property_set_description(oc
, name
, prop
->info
->description
);
1019 * Legacy property handling
1022 static void qdev_get_legacy_property(Object
*obj
, Visitor
*v
,
1023 const char *name
, void *opaque
,
1026 Property
*prop
= opaque
;
1031 prop
->info
->print(obj
, prop
, buffer
, sizeof(buffer
));
1032 visit_type_str(v
, name
, &ptr
, errp
);
1036 * qdev_class_add_legacy_property:
1037 * @dev: Device to add the property to.
1038 * @prop: The qdev property definition.
1040 * Add a legacy QOM property to @dev for qdev property @prop.
1042 * Legacy properties are string versions of QOM properties. The format of
1043 * the string depends on the property type. Legacy properties are only
1044 * needed for "info qtree".
1046 * Do not use this in new code! QOM Properties added through this interface
1047 * will be given names in the "legacy" namespace.
1049 static void qdev_class_add_legacy_property(DeviceClass
*dc
, Property
*prop
)
1051 g_autofree
char *name
= NULL
;
1053 /* Register pointer properties as legacy properties */
1054 if (!prop
->info
->print
&& prop
->info
->get
) {
1058 name
= g_strdup_printf("legacy-%s", prop
->name
);
1059 object_class_property_add(OBJECT_CLASS(dc
), name
, "str",
1060 prop
->info
->print
? qdev_get_legacy_property
: prop
->info
->get
,
1064 void device_class_set_props(DeviceClass
*dc
, Property
*props
)
1069 for (prop
= props
; prop
&& prop
->name
; prop
++) {
1070 qdev_class_add_legacy_property(dc
, prop
);
1071 qdev_class_add_property(dc
, prop
->name
, prop
);
1075 void qdev_alias_all_properties(DeviceState
*target
, Object
*source
)
1078 ObjectPropertyIterator iter
;
1079 ObjectProperty
*prop
;
1081 class = object_get_class(OBJECT(target
));
1083 object_class_property_iter_init(&iter
, class);
1084 while ((prop
= object_property_iter_next(&iter
))) {
1085 if (object_property_find(source
, prop
->name
)) {
1086 continue; /* skip duplicate properties */
1089 object_property_add_alias(source
, prop
->name
,
1090 OBJECT(target
), prop
->name
);