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/qerror.h"
6 #include "qapi/qmp/qlist.h"
7 #include "qemu/ctype.h"
8 #include "qemu/error-report.h"
9 #include "qapi/visitor.h"
10 #include "qemu/units.h"
11 #include "qemu/cutils.h"
12 #include "qdev-prop-internal.h"
13 #include "qom/qom-qobject.h"
15 void qdev_prop_set_after_realize(DeviceState
*dev
, const char *name
,
19 error_setg(errp
, "Attempt to set property '%s' on device '%s' "
20 "(type '%s') after it was realized", name
, dev
->id
,
21 object_get_typename(OBJECT(dev
)));
23 error_setg(errp
, "Attempt to set property '%s' on anonymous device "
24 "(type '%s') after it was realized", name
,
25 object_get_typename(OBJECT(dev
)));
29 /* returns: true if property is allowed to be set, false otherwise */
30 static bool qdev_prop_allow_set(Object
*obj
, const char *name
,
31 const PropertyInfo
*info
, Error
**errp
)
33 DeviceState
*dev
= DEVICE(obj
);
35 if (dev
->realized
&& !info
->realized_set_allowed
) {
36 qdev_prop_set_after_realize(dev
, name
, errp
);
42 void qdev_prop_allow_set_link_before_realize(const Object
*obj
,
44 Object
*val
, Error
**errp
)
46 DeviceState
*dev
= DEVICE(obj
);
49 error_setg(errp
, "Attempt to set link property '%s' on device '%s' "
50 "(type '%s') after it was realized",
51 name
, dev
->id
, object_get_typename(obj
));
55 void *object_field_prop_ptr(Object
*obj
, Property
*prop
)
62 static void field_prop_get(Object
*obj
, Visitor
*v
, const char *name
,
63 void *opaque
, Error
**errp
)
65 Property
*prop
= opaque
;
66 return prop
->info
->get(obj
, v
, name
, opaque
, errp
);
70 * field_prop_getter: Return getter function to be used for property
72 * Return value can be NULL if @info has no getter function.
74 static ObjectPropertyAccessor
*field_prop_getter(const PropertyInfo
*info
)
76 return info
->get
? field_prop_get
: NULL
;
79 static void field_prop_set(Object
*obj
, Visitor
*v
, const char *name
,
80 void *opaque
, Error
**errp
)
82 Property
*prop
= opaque
;
84 if (!qdev_prop_allow_set(obj
, name
, prop
->info
, errp
)) {
88 return prop
->info
->set(obj
, v
, name
, opaque
, errp
);
92 * field_prop_setter: Return setter function to be used for property
94 * Return value can be NULL if @info has not setter function.
96 static ObjectPropertyAccessor
*field_prop_setter(const PropertyInfo
*info
)
98 return info
->set
? field_prop_set
: NULL
;
101 void qdev_propinfo_get_enum(Object
*obj
, Visitor
*v
, const char *name
,
102 void *opaque
, Error
**errp
)
104 Property
*prop
= opaque
;
105 int *ptr
= object_field_prop_ptr(obj
, prop
);
107 visit_type_enum(v
, name
, ptr
, prop
->info
->enum_table
, errp
);
110 void qdev_propinfo_set_enum(Object
*obj
, Visitor
*v
, const char *name
,
111 void *opaque
, Error
**errp
)
113 Property
*prop
= opaque
;
114 int *ptr
= object_field_prop_ptr(obj
, prop
);
116 visit_type_enum(v
, name
, ptr
, prop
->info
->enum_table
, errp
);
119 void qdev_propinfo_set_default_value_enum(ObjectProperty
*op
,
120 const Property
*prop
)
122 object_property_set_default_str(op
,
123 qapi_enum_lookup(prop
->info
->enum_table
, prop
->defval
.i
));
126 const PropertyInfo qdev_prop_enum
= {
128 .get
= qdev_propinfo_get_enum
,
129 .set
= qdev_propinfo_set_enum
,
130 .set_default_value
= qdev_propinfo_set_default_value_enum
,
135 static uint32_t qdev_get_prop_mask(Property
*prop
)
137 assert(prop
->info
== &qdev_prop_bit
);
138 return 0x1 << prop
->bitnr
;
141 static void bit_prop_set(Object
*obj
, Property
*props
, bool val
)
143 uint32_t *p
= object_field_prop_ptr(obj
, props
);
144 uint32_t mask
= qdev_get_prop_mask(props
);
152 static void prop_get_bit(Object
*obj
, Visitor
*v
, const char *name
,
153 void *opaque
, Error
**errp
)
155 Property
*prop
= opaque
;
156 uint32_t *p
= object_field_prop_ptr(obj
, prop
);
157 bool value
= (*p
& qdev_get_prop_mask(prop
)) != 0;
159 visit_type_bool(v
, name
, &value
, errp
);
162 static void prop_set_bit(Object
*obj
, Visitor
*v
, const char *name
,
163 void *opaque
, Error
**errp
)
165 Property
*prop
= opaque
;
168 if (!visit_type_bool(v
, name
, &value
, errp
)) {
171 bit_prop_set(obj
, prop
, value
);
174 static void set_default_value_bool(ObjectProperty
*op
, const Property
*prop
)
176 object_property_set_default_bool(op
, prop
->defval
.u
);
179 const PropertyInfo qdev_prop_bit
= {
181 .description
= "on/off",
184 .set_default_value
= set_default_value_bool
,
189 static uint64_t qdev_get_prop_mask64(Property
*prop
)
191 assert(prop
->info
== &qdev_prop_bit64
);
192 return 0x1ull
<< prop
->bitnr
;
195 static void bit64_prop_set(Object
*obj
, Property
*props
, bool val
)
197 uint64_t *p
= object_field_prop_ptr(obj
, props
);
198 uint64_t mask
= qdev_get_prop_mask64(props
);
206 static void prop_get_bit64(Object
*obj
, Visitor
*v
, const char *name
,
207 void *opaque
, Error
**errp
)
209 Property
*prop
= opaque
;
210 uint64_t *p
= object_field_prop_ptr(obj
, prop
);
211 bool value
= (*p
& qdev_get_prop_mask64(prop
)) != 0;
213 visit_type_bool(v
, name
, &value
, errp
);
216 static void prop_set_bit64(Object
*obj
, Visitor
*v
, const char *name
,
217 void *opaque
, Error
**errp
)
219 Property
*prop
= opaque
;
222 if (!visit_type_bool(v
, name
, &value
, errp
)) {
225 bit64_prop_set(obj
, prop
, value
);
228 const PropertyInfo qdev_prop_bit64
= {
230 .description
= "on/off",
231 .get
= prop_get_bit64
,
232 .set
= prop_set_bit64
,
233 .set_default_value
= set_default_value_bool
,
238 static void get_bool(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
241 Property
*prop
= opaque
;
242 bool *ptr
= object_field_prop_ptr(obj
, prop
);
244 visit_type_bool(v
, name
, ptr
, errp
);
247 static void set_bool(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
250 Property
*prop
= opaque
;
251 bool *ptr
= object_field_prop_ptr(obj
, prop
);
253 visit_type_bool(v
, name
, ptr
, errp
);
256 const PropertyInfo qdev_prop_bool
= {
260 .set_default_value
= set_default_value_bool
,
263 /* --- 8bit integer --- */
265 static void get_uint8(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
268 Property
*prop
= opaque
;
269 uint8_t *ptr
= object_field_prop_ptr(obj
, prop
);
271 visit_type_uint8(v
, name
, ptr
, errp
);
274 static void set_uint8(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
277 Property
*prop
= opaque
;
278 uint8_t *ptr
= object_field_prop_ptr(obj
, prop
);
280 visit_type_uint8(v
, name
, ptr
, errp
);
283 void qdev_propinfo_set_default_value_int(ObjectProperty
*op
,
284 const Property
*prop
)
286 object_property_set_default_int(op
, prop
->defval
.i
);
289 void qdev_propinfo_set_default_value_uint(ObjectProperty
*op
,
290 const Property
*prop
)
292 object_property_set_default_uint(op
, prop
->defval
.u
);
295 const PropertyInfo qdev_prop_uint8
= {
299 .set_default_value
= qdev_propinfo_set_default_value_uint
,
302 /* --- 16bit integer --- */
304 static void get_uint16(Object
*obj
, Visitor
*v
, const char *name
,
305 void *opaque
, Error
**errp
)
307 Property
*prop
= opaque
;
308 uint16_t *ptr
= object_field_prop_ptr(obj
, prop
);
310 visit_type_uint16(v
, name
, ptr
, errp
);
313 static void set_uint16(Object
*obj
, Visitor
*v
, const char *name
,
314 void *opaque
, Error
**errp
)
316 Property
*prop
= opaque
;
317 uint16_t *ptr
= object_field_prop_ptr(obj
, prop
);
319 visit_type_uint16(v
, name
, ptr
, errp
);
322 const PropertyInfo qdev_prop_uint16
= {
326 .set_default_value
= qdev_propinfo_set_default_value_uint
,
329 /* --- 32bit integer --- */
331 static void get_uint32(Object
*obj
, Visitor
*v
, const char *name
,
332 void *opaque
, Error
**errp
)
334 Property
*prop
= opaque
;
335 uint32_t *ptr
= object_field_prop_ptr(obj
, prop
);
337 visit_type_uint32(v
, name
, ptr
, errp
);
340 static void set_uint32(Object
*obj
, Visitor
*v
, const char *name
,
341 void *opaque
, Error
**errp
)
343 Property
*prop
= opaque
;
344 uint32_t *ptr
= object_field_prop_ptr(obj
, prop
);
346 visit_type_uint32(v
, name
, ptr
, errp
);
349 void qdev_propinfo_get_int32(Object
*obj
, Visitor
*v
, const char *name
,
350 void *opaque
, Error
**errp
)
352 Property
*prop
= opaque
;
353 int32_t *ptr
= object_field_prop_ptr(obj
, prop
);
355 visit_type_int32(v
, name
, ptr
, errp
);
358 static void set_int32(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
361 Property
*prop
= opaque
;
362 int32_t *ptr
= object_field_prop_ptr(obj
, prop
);
364 visit_type_int32(v
, name
, ptr
, errp
);
367 const PropertyInfo qdev_prop_uint32
= {
371 .set_default_value
= qdev_propinfo_set_default_value_uint
,
374 const PropertyInfo qdev_prop_int32
= {
376 .get
= qdev_propinfo_get_int32
,
378 .set_default_value
= qdev_propinfo_set_default_value_int
,
381 /* --- 64bit integer --- */
383 static void get_uint64(Object
*obj
, Visitor
*v
, const char *name
,
384 void *opaque
, Error
**errp
)
386 Property
*prop
= opaque
;
387 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
389 visit_type_uint64(v
, name
, ptr
, errp
);
392 static void set_uint64(Object
*obj
, Visitor
*v
, const char *name
,
393 void *opaque
, Error
**errp
)
395 Property
*prop
= opaque
;
396 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
398 visit_type_uint64(v
, name
, ptr
, errp
);
401 static void get_int64(Object
*obj
, Visitor
*v
, const char *name
,
402 void *opaque
, Error
**errp
)
404 Property
*prop
= opaque
;
405 int64_t *ptr
= object_field_prop_ptr(obj
, prop
);
407 visit_type_int64(v
, name
, ptr
, errp
);
410 static void set_int64(Object
*obj
, Visitor
*v
, const char *name
,
411 void *opaque
, Error
**errp
)
413 Property
*prop
= opaque
;
414 int64_t *ptr
= object_field_prop_ptr(obj
, prop
);
416 visit_type_int64(v
, name
, ptr
, errp
);
419 const PropertyInfo qdev_prop_uint64
= {
423 .set_default_value
= qdev_propinfo_set_default_value_uint
,
426 const PropertyInfo qdev_prop_int64
= {
430 .set_default_value
= qdev_propinfo_set_default_value_int
,
433 static void set_uint64_checkmask(Object
*obj
, Visitor
*v
, const char *name
,
434 void *opaque
, Error
**errp
)
436 Property
*prop
= opaque
;
437 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
439 visit_type_uint64(v
, name
, ptr
, errp
);
440 if (*ptr
& ~prop
->bitmask
) {
441 error_setg(errp
, "Property value for '%s' has bits outside mask '0x%" PRIx64
"'",
442 name
, prop
->bitmask
);
446 const PropertyInfo qdev_prop_uint64_checkmask
= {
449 .set
= set_uint64_checkmask
,
454 static void release_string(Object
*obj
, const char *name
, void *opaque
)
456 Property
*prop
= opaque
;
457 g_free(*(char **)object_field_prop_ptr(obj
, prop
));
460 static void get_string(Object
*obj
, Visitor
*v
, const char *name
,
461 void *opaque
, Error
**errp
)
463 Property
*prop
= opaque
;
464 char **ptr
= object_field_prop_ptr(obj
, prop
);
467 char *str
= (char *)"";
468 visit_type_str(v
, name
, &str
, errp
);
470 visit_type_str(v
, name
, ptr
, errp
);
474 static void set_string(Object
*obj
, Visitor
*v
, const char *name
,
475 void *opaque
, Error
**errp
)
477 Property
*prop
= opaque
;
478 char **ptr
= object_field_prop_ptr(obj
, prop
);
481 if (!visit_type_str(v
, name
, &str
, errp
)) {
488 const PropertyInfo qdev_prop_string
= {
490 .release
= release_string
,
495 /* --- on/off/auto --- */
497 const PropertyInfo qdev_prop_on_off_auto
= {
499 .description
= "on/off/auto",
500 .enum_table
= &OnOffAuto_lookup
,
501 .get
= qdev_propinfo_get_enum
,
502 .set
= qdev_propinfo_set_enum
,
503 .set_default_value
= qdev_propinfo_set_default_value_enum
,
506 /* --- 32bit unsigned int 'size' type --- */
508 void qdev_propinfo_get_size32(Object
*obj
, Visitor
*v
, const char *name
,
509 void *opaque
, Error
**errp
)
511 Property
*prop
= opaque
;
512 uint32_t *ptr
= object_field_prop_ptr(obj
, prop
);
513 uint64_t value
= *ptr
;
515 visit_type_size(v
, name
, &value
, errp
);
518 static void set_size32(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
521 Property
*prop
= opaque
;
522 uint32_t *ptr
= object_field_prop_ptr(obj
, prop
);
525 if (!visit_type_size(v
, name
, &value
, errp
)) {
529 if (value
> UINT32_MAX
) {
531 "Property %s.%s doesn't take value %" PRIu64
533 object_get_typename(obj
), name
, value
, UINT32_MAX
);
540 const PropertyInfo qdev_prop_size32
= {
542 .get
= qdev_propinfo_get_size32
,
544 .set_default_value
= qdev_propinfo_set_default_value_uint
,
547 /* --- support for array properties --- */
549 typedef struct ArrayElementList ArrayElementList
;
551 struct ArrayElementList
{
552 ArrayElementList
*next
;
557 * Given an array property @parent_prop in @obj, return a Property for a
558 * specific element of the array. Arrays are backed by an uint32_t length field
559 * and an element array. @elem points at an element in this element array.
561 static Property
array_elem_prop(Object
*obj
, Property
*parent_prop
,
562 const char *name
, char *elem
)
565 .info
= parent_prop
->arrayinfo
,
568 * This ugly piece of pointer arithmetic sets up the offset so
569 * that when the underlying release hook calls qdev_get_prop_ptr
570 * they get the right answer despite the array element not actually
571 * being inside the device struct.
573 .offset
= (uintptr_t)elem
- (uintptr_t)obj
,
578 * Object property release callback for array properties: We call the
579 * underlying element's property release hook for each element.
581 * Note that it is the responsibility of the individual device's deinit
582 * to free the array proper.
584 static void release_prop_array(Object
*obj
, const char *name
, void *opaque
)
586 Property
*prop
= opaque
;
587 uint32_t *alenptr
= object_field_prop_ptr(obj
, prop
);
588 void **arrayptr
= (void *)obj
+ prop
->arrayoffset
;
589 char *elem
= *arrayptr
;
592 if (!prop
->arrayinfo
->release
) {
596 for (i
= 0; i
< *alenptr
; i
++) {
597 Property elem_prop
= array_elem_prop(obj
, prop
, name
, elem
);
598 prop
->arrayinfo
->release(obj
, NULL
, &elem_prop
);
599 elem
+= prop
->arrayfieldsize
;
604 * Setter for an array property. This sets both the array length (which
605 * is technically the property field in the object) and the array itself
606 * (a pointer to which is stored in the additional field described by
607 * prop->arrayoffset).
609 static void set_prop_array(Object
*obj
, Visitor
*v
, const char *name
,
610 void *opaque
, Error
**errp
)
613 Property
*prop
= opaque
;
614 uint32_t *alenptr
= object_field_prop_ptr(obj
, prop
);
615 void **arrayptr
= (void *)obj
+ prop
->arrayoffset
;
616 ArrayElementList
*list
, *elem
, *next
;
617 const size_t size
= sizeof(*list
);
622 error_setg(errp
, "array size property %s may not be set more than once",
627 if (!visit_start_list(v
, name
, (GenericList
**) &list
, size
, errp
)) {
631 /* Read the whole input into a temporary list */
636 elem
->value
= g_malloc0(prop
->arrayfieldsize
);
637 elem_prop
= array_elem_prop(obj
, prop
, name
, elem
->value
);
638 prop
->arrayinfo
->set(obj
, v
, NULL
, &elem_prop
, errp
);
643 if (*alenptr
== INT_MAX
) {
644 error_setg(errp
, "array is too big");
648 elem
= (ArrayElementList
*) visit_next_list(v
, (GenericList
*) elem
,
652 ok
= visit_check_list(v
, errp
);
654 visit_end_list(v
, (void**) &list
);
657 for (elem
= list
; elem
; elem
= next
) {
658 Property elem_prop
= array_elem_prop(obj
, prop
, name
,
660 if (prop
->arrayinfo
->release
) {
661 prop
->arrayinfo
->release(obj
, NULL
, &elem_prop
);
671 * Now that we know how big the array has to be, move the data over to a
672 * linear array and free the temporary list.
674 *arrayptr
= g_malloc_n(*alenptr
, prop
->arrayfieldsize
);
676 for (elem
= list
; elem
; elem
= next
) {
677 memcpy(elemptr
, elem
->value
, prop
->arrayfieldsize
);
678 elemptr
+= prop
->arrayfieldsize
;
685 static void get_prop_array(Object
*obj
, Visitor
*v
, const char *name
,
686 void *opaque
, Error
**errp
)
689 Property
*prop
= opaque
;
690 uint32_t *alenptr
= object_field_prop_ptr(obj
, prop
);
691 void **arrayptr
= (void *)obj
+ prop
->arrayoffset
;
692 char *elemptr
= *arrayptr
;
693 ArrayElementList
*list
= NULL
, *elem
;
694 ArrayElementList
**tail
= &list
;
695 const size_t size
= sizeof(*list
);
699 /* At least the string output visitor needs a real list */
700 for (i
= 0; i
< *alenptr
; i
++) {
701 elem
= g_new0(ArrayElementList
, 1);
702 elem
->value
= elemptr
;
703 elemptr
+= prop
->arrayfieldsize
;
709 if (!visit_start_list(v
, name
, (GenericList
**) &list
, size
, errp
)) {
715 Property elem_prop
= array_elem_prop(obj
, prop
, name
, elem
->value
);
716 prop
->arrayinfo
->get(obj
, v
, NULL
, &elem_prop
, errp
);
720 elem
= (ArrayElementList
*) visit_next_list(v
, (GenericList
*) elem
,
724 /* visit_check_list() can only fail for input visitors */
725 ok
= visit_check_list(v
, errp
);
729 visit_end_list(v
, (void**) &list
);
738 static void default_prop_array(ObjectProperty
*op
, const Property
*prop
)
740 object_property_set_default_list(op
);
743 const PropertyInfo qdev_prop_array
= {
745 .get
= get_prop_array
,
746 .set
= set_prop_array
,
747 .release
= release_prop_array
,
748 .set_default_value
= default_prop_array
,
751 /* --- public helpers --- */
753 static Property
*qdev_prop_walk(Property
*props
, const char *name
)
758 while (props
->name
) {
759 if (strcmp(props
->name
, name
) == 0) {
767 static Property
*qdev_prop_find(DeviceState
*dev
, const char *name
)
772 /* device properties */
773 class = object_get_class(OBJECT(dev
));
775 prop
= qdev_prop_walk(DEVICE_CLASS(class)->props_
, name
);
779 class = object_class_get_parent(class);
780 } while (class != object_class_by_name(TYPE_DEVICE
));
785 void error_set_from_qdev_prop_error(Error
**errp
, int ret
, Object
*obj
,
786 const char *name
, const char *value
)
790 error_setg(errp
, "Property '%s.%s' can't take value '%s', it's in use",
791 object_get_typename(obj
), name
, value
);
795 error_setg(errp
, QERR_PROPERTY_VALUE_BAD
,
796 object_get_typename(obj
), name
, value
);
799 error_setg(errp
, "Property '%s.%s' can't find value '%s'",
800 object_get_typename(obj
), name
, value
);
807 void qdev_prop_set_bit(DeviceState
*dev
, const char *name
, bool value
)
809 object_property_set_bool(OBJECT(dev
), name
, value
, &error_abort
);
812 void qdev_prop_set_uint8(DeviceState
*dev
, const char *name
, uint8_t value
)
814 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
817 void qdev_prop_set_uint16(DeviceState
*dev
, const char *name
, uint16_t value
)
819 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
822 void qdev_prop_set_uint32(DeviceState
*dev
, const char *name
, uint32_t value
)
824 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
827 void qdev_prop_set_int32(DeviceState
*dev
, const char *name
, int32_t value
)
829 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
832 void qdev_prop_set_uint64(DeviceState
*dev
, const char *name
, uint64_t value
)
834 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
837 void qdev_prop_set_string(DeviceState
*dev
, const char *name
, const char *value
)
839 object_property_set_str(OBJECT(dev
), name
, value
, &error_abort
);
842 void qdev_prop_set_enum(DeviceState
*dev
, const char *name
, int value
)
846 prop
= qdev_prop_find(dev
, name
);
847 object_property_set_str(OBJECT(dev
), name
,
848 qapi_enum_lookup(prop
->info
->enum_table
, value
),
852 void qdev_prop_set_array(DeviceState
*dev
, const char *name
, QList
*values
)
854 object_property_set_qobject(OBJECT(dev
), name
, QOBJECT(values
),
856 qobject_unref(values
);
859 static GPtrArray
*global_props(void)
861 static GPtrArray
*gp
;
864 gp
= g_ptr_array_new();
870 void qdev_prop_register_global(GlobalProperty
*prop
)
872 g_ptr_array_add(global_props(), prop
);
875 const GlobalProperty
*qdev_find_global_prop(Object
*obj
,
878 GPtrArray
*props
= global_props();
879 const GlobalProperty
*p
;
882 for (i
= 0; i
< props
->len
; i
++) {
883 p
= g_ptr_array_index(props
, i
);
884 if (object_dynamic_cast(obj
, p
->driver
)
885 && !strcmp(p
->property
, name
)) {
892 int qdev_prop_check_globals(void)
896 for (i
= 0; i
< global_props()->len
; i
++) {
897 GlobalProperty
*prop
;
901 prop
= g_ptr_array_index(global_props(), i
);
905 oc
= object_class_by_name(prop
->driver
);
906 oc
= object_class_dynamic_cast(oc
, TYPE_DEVICE
);
908 warn_report("global %s.%s has invalid class name",
909 prop
->driver
, prop
->property
);
913 dc
= DEVICE_CLASS(oc
);
914 if (!dc
->hotpluggable
&& !prop
->used
) {
915 warn_report("global %s.%s=%s not used",
916 prop
->driver
, prop
->property
, prop
->value
);
924 void qdev_prop_set_globals(DeviceState
*dev
)
926 object_apply_global_props(OBJECT(dev
), global_props(),
927 dev
->hotplugged
? NULL
: &error_fatal
);
930 /* --- 64bit unsigned int 'size' type --- */
932 static void get_size(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
935 Property
*prop
= opaque
;
936 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
938 visit_type_size(v
, name
, ptr
, errp
);
941 static void set_size(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
944 Property
*prop
= opaque
;
945 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
947 visit_type_size(v
, name
, ptr
, errp
);
950 const PropertyInfo qdev_prop_size
= {
954 .set_default_value
= qdev_propinfo_set_default_value_uint
,
957 /* --- object link property --- */
959 static ObjectProperty
*create_link_property(ObjectClass
*oc
, const char *name
,
962 return object_class_property_add_link(oc
, name
, prop
->link_type
,
964 qdev_prop_allow_set_link_before_realize
,
965 OBJ_PROP_LINK_STRONG
);
968 const PropertyInfo qdev_prop_link
= {
970 .create
= create_link_property
,
973 void qdev_property_add_static(DeviceState
*dev
, Property
*prop
)
975 Object
*obj
= OBJECT(dev
);
978 assert(!prop
->info
->create
);
980 op
= object_property_add(obj
, prop
->name
, prop
->info
->name
,
981 field_prop_getter(prop
->info
),
982 field_prop_setter(prop
->info
),
986 object_property_set_description(obj
, prop
->name
,
987 prop
->info
->description
);
989 if (prop
->set_default
) {
990 prop
->info
->set_default_value(op
, prop
);
997 static void qdev_class_add_property(DeviceClass
*klass
, const char *name
,
1000 ObjectClass
*oc
= OBJECT_CLASS(klass
);
1003 if (prop
->info
->create
) {
1004 op
= prop
->info
->create(oc
, name
, prop
);
1006 op
= object_class_property_add(oc
,
1007 name
, prop
->info
->name
,
1008 field_prop_getter(prop
->info
),
1009 field_prop_setter(prop
->info
),
1010 prop
->info
->release
,
1013 if (prop
->set_default
) {
1014 prop
->info
->set_default_value(op
, prop
);
1016 object_class_property_set_description(oc
, name
, prop
->info
->description
);
1020 * Legacy property handling
1023 static void qdev_get_legacy_property(Object
*obj
, Visitor
*v
,
1024 const char *name
, void *opaque
,
1027 Property
*prop
= opaque
;
1032 prop
->info
->print(obj
, prop
, buffer
, sizeof(buffer
));
1033 visit_type_str(v
, name
, &ptr
, errp
);
1037 * qdev_class_add_legacy_property:
1038 * @dev: Device to add the property to.
1039 * @prop: The qdev property definition.
1041 * Add a legacy QOM property to @dev for qdev property @prop.
1043 * Legacy properties are string versions of QOM properties. The format of
1044 * the string depends on the property type. Legacy properties are only
1045 * needed for "info qtree".
1047 * Do not use this in new code! QOM Properties added through this interface
1048 * will be given names in the "legacy" namespace.
1050 static void qdev_class_add_legacy_property(DeviceClass
*dc
, Property
*prop
)
1052 g_autofree
char *name
= NULL
;
1054 /* Register pointer properties as legacy properties */
1055 if (!prop
->info
->print
&& prop
->info
->get
) {
1059 name
= g_strdup_printf("legacy-%s", prop
->name
);
1060 object_class_property_add(OBJECT_CLASS(dc
), name
, "str",
1061 prop
->info
->print
? qdev_get_legacy_property
: prop
->info
->get
,
1065 void device_class_set_props(DeviceClass
*dc
, Property
*props
)
1070 for (prop
= props
; prop
&& prop
->name
; prop
++) {
1071 qdev_class_add_legacy_property(dc
, prop
);
1072 qdev_class_add_property(dc
, prop
->name
, prop
);
1076 void qdev_alias_all_properties(DeviceState
*target
, Object
*source
)
1079 ObjectPropertyIterator iter
;
1080 ObjectProperty
*prop
;
1082 class = object_get_class(OBJECT(target
));
1084 object_class_property_iter_init(&iter
, class);
1085 while ((prop
= object_property_iter_next(&iter
))) {
1086 if (object_property_find(source
, prop
->name
)) {
1087 continue; /* skip duplicate properties */
1090 object_property_add_alias(source
, prop
->name
,
1091 OBJECT(target
), prop
->name
);