xref: /openbmc/qemu/hw/core/qdev-properties.c (revision fc58891d)
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"
14 
15 void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
16                                   Error **errp)
17 {
18     if (dev->id) {
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)));
22     } else {
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)));
26     }
27 }
28 
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)
32 {
33     DeviceState *dev = DEVICE(obj);
34 
35     if (dev->realized && !info->realized_set_allowed) {
36         qdev_prop_set_after_realize(dev, name, errp);
37         return false;
38     }
39     return true;
40 }
41 
42 void qdev_prop_allow_set_link_before_realize(const Object *obj,
43                                              const char *name,
44                                              Object *val, Error **errp)
45 {
46     DeviceState *dev = DEVICE(obj);
47 
48     if (dev->realized) {
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));
52     }
53 }
54 
55 void *object_field_prop_ptr(Object *obj, Property *prop)
56 {
57     void *ptr = obj;
58     ptr += prop->offset;
59     return ptr;
60 }
61 
62 static void field_prop_get(Object *obj, Visitor *v, const char *name,
63                            void *opaque, Error **errp)
64 {
65     Property *prop = opaque;
66     return prop->info->get(obj, v, name, opaque, errp);
67 }
68 
69 /**
70  * field_prop_getter: Return getter function to be used for property
71  *
72  * Return value can be NULL if @info has no getter function.
73  */
74 static ObjectPropertyAccessor *field_prop_getter(const PropertyInfo *info)
75 {
76     return info->get ? field_prop_get : NULL;
77 }
78 
79 static void field_prop_set(Object *obj, Visitor *v, const char *name,
80                            void *opaque, Error **errp)
81 {
82     Property *prop = opaque;
83 
84     if (!qdev_prop_allow_set(obj, name, prop->info, errp)) {
85         return;
86     }
87 
88     return prop->info->set(obj, v, name, opaque, errp);
89 }
90 
91 /**
92  * field_prop_setter: Return setter function to be used for property
93  *
94  * Return value can be NULL if @info has not setter function.
95  */
96 static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
97 {
98     return info->set ? field_prop_set : NULL;
99 }
100 
101 void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
102                             void *opaque, Error **errp)
103 {
104     Property *prop = opaque;
105     int *ptr = object_field_prop_ptr(obj, prop);
106 
107     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
108 }
109 
110 void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
111                             void *opaque, Error **errp)
112 {
113     Property *prop = opaque;
114     int *ptr = object_field_prop_ptr(obj, prop);
115 
116     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
117 }
118 
119 void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
120                                           const Property *prop)
121 {
122     object_property_set_default_str(op,
123         qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
124 }
125 
126 const PropertyInfo qdev_prop_enum = {
127     .name  = "enum",
128     .get   = qdev_propinfo_get_enum,
129     .set   = qdev_propinfo_set_enum,
130     .set_default_value = qdev_propinfo_set_default_value_enum,
131 };
132 
133 /* Bit */
134 
135 static uint32_t qdev_get_prop_mask(Property *prop)
136 {
137     assert(prop->info == &qdev_prop_bit);
138     return 0x1 << prop->bitnr;
139 }
140 
141 static void bit_prop_set(Object *obj, Property *props, bool val)
142 {
143     uint32_t *p = object_field_prop_ptr(obj, props);
144     uint32_t mask = qdev_get_prop_mask(props);
145     if (val) {
146         *p |= mask;
147     } else {
148         *p &= ~mask;
149     }
150 }
151 
152 static void prop_get_bit(Object *obj, Visitor *v, const char *name,
153                          void *opaque, Error **errp)
154 {
155     Property *prop = opaque;
156     uint32_t *p = object_field_prop_ptr(obj, prop);
157     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
158 
159     visit_type_bool(v, name, &value, errp);
160 }
161 
162 static void prop_set_bit(Object *obj, Visitor *v, const char *name,
163                          void *opaque, Error **errp)
164 {
165     Property *prop = opaque;
166     bool value;
167 
168     if (!visit_type_bool(v, name, &value, errp)) {
169         return;
170     }
171     bit_prop_set(obj, prop, value);
172 }
173 
174 static void set_default_value_bool(ObjectProperty *op, const Property *prop)
175 {
176     object_property_set_default_bool(op, prop->defval.u);
177 }
178 
179 const PropertyInfo qdev_prop_bit = {
180     .name  = "bool",
181     .description = "on/off",
182     .get   = prop_get_bit,
183     .set   = prop_set_bit,
184     .set_default_value = set_default_value_bool,
185 };
186 
187 /* Bit64 */
188 
189 static uint64_t qdev_get_prop_mask64(Property *prop)
190 {
191     assert(prop->info == &qdev_prop_bit64);
192     return 0x1ull << prop->bitnr;
193 }
194 
195 static void bit64_prop_set(Object *obj, Property *props, bool val)
196 {
197     uint64_t *p = object_field_prop_ptr(obj, props);
198     uint64_t mask = qdev_get_prop_mask64(props);
199     if (val) {
200         *p |= mask;
201     } else {
202         *p &= ~mask;
203     }
204 }
205 
206 static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
207                            void *opaque, Error **errp)
208 {
209     Property *prop = opaque;
210     uint64_t *p = object_field_prop_ptr(obj, prop);
211     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
212 
213     visit_type_bool(v, name, &value, errp);
214 }
215 
216 static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
217                            void *opaque, Error **errp)
218 {
219     Property *prop = opaque;
220     bool value;
221 
222     if (!visit_type_bool(v, name, &value, errp)) {
223         return;
224     }
225     bit64_prop_set(obj, prop, value);
226 }
227 
228 const PropertyInfo qdev_prop_bit64 = {
229     .name  = "bool",
230     .description = "on/off",
231     .get   = prop_get_bit64,
232     .set   = prop_set_bit64,
233     .set_default_value = set_default_value_bool,
234 };
235 
236 /* --- bool --- */
237 
238 static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
239                      Error **errp)
240 {
241     Property *prop = opaque;
242     bool *ptr = object_field_prop_ptr(obj, prop);
243 
244     visit_type_bool(v, name, ptr, errp);
245 }
246 
247 static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
248                      Error **errp)
249 {
250     Property *prop = opaque;
251     bool *ptr = object_field_prop_ptr(obj, prop);
252 
253     visit_type_bool(v, name, ptr, errp);
254 }
255 
256 const PropertyInfo qdev_prop_bool = {
257     .name  = "bool",
258     .get   = get_bool,
259     .set   = set_bool,
260     .set_default_value = set_default_value_bool,
261 };
262 
263 /* --- 8bit integer --- */
264 
265 static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
266                       Error **errp)
267 {
268     Property *prop = opaque;
269     uint8_t *ptr = object_field_prop_ptr(obj, prop);
270 
271     visit_type_uint8(v, name, ptr, errp);
272 }
273 
274 static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
275                       Error **errp)
276 {
277     Property *prop = opaque;
278     uint8_t *ptr = object_field_prop_ptr(obj, prop);
279 
280     visit_type_uint8(v, name, ptr, errp);
281 }
282 
283 void qdev_propinfo_set_default_value_int(ObjectProperty *op,
284                                          const Property *prop)
285 {
286     object_property_set_default_int(op, prop->defval.i);
287 }
288 
289 void qdev_propinfo_set_default_value_uint(ObjectProperty *op,
290                                           const Property *prop)
291 {
292     object_property_set_default_uint(op, prop->defval.u);
293 }
294 
295 const PropertyInfo qdev_prop_uint8 = {
296     .name  = "uint8",
297     .get   = get_uint8,
298     .set   = set_uint8,
299     .set_default_value = qdev_propinfo_set_default_value_uint,
300 };
301 
302 /* --- 16bit integer --- */
303 
304 static void get_uint16(Object *obj, Visitor *v, const char *name,
305                        void *opaque, Error **errp)
306 {
307     Property *prop = opaque;
308     uint16_t *ptr = object_field_prop_ptr(obj, prop);
309 
310     visit_type_uint16(v, name, ptr, errp);
311 }
312 
313 static void set_uint16(Object *obj, Visitor *v, const char *name,
314                        void *opaque, Error **errp)
315 {
316     Property *prop = opaque;
317     uint16_t *ptr = object_field_prop_ptr(obj, prop);
318 
319     visit_type_uint16(v, name, ptr, errp);
320 }
321 
322 const PropertyInfo qdev_prop_uint16 = {
323     .name  = "uint16",
324     .get   = get_uint16,
325     .set   = set_uint16,
326     .set_default_value = qdev_propinfo_set_default_value_uint,
327 };
328 
329 /* --- 32bit integer --- */
330 
331 static void get_uint32(Object *obj, Visitor *v, const char *name,
332                        void *opaque, Error **errp)
333 {
334     Property *prop = opaque;
335     uint32_t *ptr = object_field_prop_ptr(obj, prop);
336 
337     visit_type_uint32(v, name, ptr, errp);
338 }
339 
340 static void set_uint32(Object *obj, Visitor *v, const char *name,
341                        void *opaque, Error **errp)
342 {
343     Property *prop = opaque;
344     uint32_t *ptr = object_field_prop_ptr(obj, prop);
345 
346     visit_type_uint32(v, name, ptr, errp);
347 }
348 
349 void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
350                              void *opaque, Error **errp)
351 {
352     Property *prop = opaque;
353     int32_t *ptr = object_field_prop_ptr(obj, prop);
354 
355     visit_type_int32(v, name, ptr, errp);
356 }
357 
358 static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
359                       Error **errp)
360 {
361     Property *prop = opaque;
362     int32_t *ptr = object_field_prop_ptr(obj, prop);
363 
364     visit_type_int32(v, name, ptr, errp);
365 }
366 
367 const PropertyInfo qdev_prop_uint32 = {
368     .name  = "uint32",
369     .get   = get_uint32,
370     .set   = set_uint32,
371     .set_default_value = qdev_propinfo_set_default_value_uint,
372 };
373 
374 const PropertyInfo qdev_prop_int32 = {
375     .name  = "int32",
376     .get   = qdev_propinfo_get_int32,
377     .set   = set_int32,
378     .set_default_value = qdev_propinfo_set_default_value_int,
379 };
380 
381 /* --- 64bit integer --- */
382 
383 static void get_uint64(Object *obj, Visitor *v, const char *name,
384                        void *opaque, Error **errp)
385 {
386     Property *prop = opaque;
387     uint64_t *ptr = object_field_prop_ptr(obj, prop);
388 
389     visit_type_uint64(v, name, ptr, errp);
390 }
391 
392 static void set_uint64(Object *obj, Visitor *v, const char *name,
393                        void *opaque, Error **errp)
394 {
395     Property *prop = opaque;
396     uint64_t *ptr = object_field_prop_ptr(obj, prop);
397 
398     visit_type_uint64(v, name, ptr, errp);
399 }
400 
401 static void get_int64(Object *obj, Visitor *v, const char *name,
402                       void *opaque, Error **errp)
403 {
404     Property *prop = opaque;
405     int64_t *ptr = object_field_prop_ptr(obj, prop);
406 
407     visit_type_int64(v, name, ptr, errp);
408 }
409 
410 static void set_int64(Object *obj, Visitor *v, const char *name,
411                       void *opaque, Error **errp)
412 {
413     Property *prop = opaque;
414     int64_t *ptr = object_field_prop_ptr(obj, prop);
415 
416     visit_type_int64(v, name, ptr, errp);
417 }
418 
419 const PropertyInfo qdev_prop_uint64 = {
420     .name  = "uint64",
421     .get   = get_uint64,
422     .set   = set_uint64,
423     .set_default_value = qdev_propinfo_set_default_value_uint,
424 };
425 
426 const PropertyInfo qdev_prop_int64 = {
427     .name  = "int64",
428     .get   = get_int64,
429     .set   = set_int64,
430     .set_default_value = qdev_propinfo_set_default_value_int,
431 };
432 
433 static void set_uint64_checkmask(Object *obj, Visitor *v, const char *name,
434                       void *opaque, Error **errp)
435 {
436     Property *prop = opaque;
437     uint64_t *ptr = object_field_prop_ptr(obj, prop);
438 
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);
443     }
444 }
445 
446 const PropertyInfo qdev_prop_uint64_checkmask = {
447     .name  = "uint64",
448     .get   = get_uint64,
449     .set   = set_uint64_checkmask,
450 };
451 
452 /* --- string --- */
453 
454 static void release_string(Object *obj, const char *name, void *opaque)
455 {
456     Property *prop = opaque;
457     g_free(*(char **)object_field_prop_ptr(obj, prop));
458 }
459 
460 static void get_string(Object *obj, Visitor *v, const char *name,
461                        void *opaque, Error **errp)
462 {
463     Property *prop = opaque;
464     char **ptr = object_field_prop_ptr(obj, prop);
465 
466     if (!*ptr) {
467         char *str = (char *)"";
468         visit_type_str(v, name, &str, errp);
469     } else {
470         visit_type_str(v, name, ptr, errp);
471     }
472 }
473 
474 static void set_string(Object *obj, Visitor *v, const char *name,
475                        void *opaque, Error **errp)
476 {
477     Property *prop = opaque;
478     char **ptr = object_field_prop_ptr(obj, prop);
479     char *str;
480 
481     if (!visit_type_str(v, name, &str, errp)) {
482         return;
483     }
484     g_free(*ptr);
485     *ptr = str;
486 }
487 
488 const PropertyInfo qdev_prop_string = {
489     .name  = "str",
490     .release = release_string,
491     .get   = get_string,
492     .set   = set_string,
493 };
494 
495 /* --- on/off/auto --- */
496 
497 const PropertyInfo qdev_prop_on_off_auto = {
498     .name = "OnOffAuto",
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,
504 };
505 
506 /* --- 32bit unsigned int 'size' type --- */
507 
508 void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
509                               void *opaque, Error **errp)
510 {
511     Property *prop = opaque;
512     uint32_t *ptr = object_field_prop_ptr(obj, prop);
513     uint64_t value = *ptr;
514 
515     visit_type_size(v, name, &value, errp);
516 }
517 
518 static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
519                        Error **errp)
520 {
521     Property *prop = opaque;
522     uint32_t *ptr = object_field_prop_ptr(obj, prop);
523     uint64_t value;
524 
525     if (!visit_type_size(v, name, &value, errp)) {
526         return;
527     }
528 
529     if (value > UINT32_MAX) {
530         error_setg(errp,
531                    "Property %s.%s doesn't take value %" PRIu64
532                    " (maximum: %u)",
533                    object_get_typename(obj), name, value, UINT32_MAX);
534         return;
535     }
536 
537     *ptr = value;
538 }
539 
540 const PropertyInfo qdev_prop_size32 = {
541     .name  = "size",
542     .get = qdev_propinfo_get_size32,
543     .set = set_size32,
544     .set_default_value = qdev_propinfo_set_default_value_uint,
545 };
546 
547 /* --- support for array properties --- */
548 
549 typedef struct ArrayElementList ArrayElementList;
550 
551 struct ArrayElementList {
552     ArrayElementList *next;
553     void *value;
554 };
555 
556 /*
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.
560  */
561 static Property array_elem_prop(Object *obj, Property *parent_prop,
562                                 const char *name, char *elem)
563 {
564     return (Property) {
565         .info = parent_prop->arrayinfo,
566         .name = name,
567         /*
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.
572          */
573         .offset = (uintptr_t)elem - (uintptr_t)obj,
574     };
575 }
576 
577 /*
578  * Object property release callback for array properties: We call the
579  * underlying element's property release hook for each element.
580  *
581  * Note that it is the responsibility of the individual device's deinit
582  * to free the array proper.
583  */
584 static void release_prop_array(Object *obj, const char *name, void *opaque)
585 {
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;
590     int i;
591 
592     if (!prop->arrayinfo->release) {
593         return;
594     }
595 
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;
600     }
601 }
602 
603 /*
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).
608  */
609 static void set_prop_array(Object *obj, Visitor *v, const char *name,
610                            void *opaque, Error **errp)
611 {
612     ERRP_GUARD();
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);
618     char *elemptr;
619     bool ok = true;
620 
621     if (*alenptr) {
622         error_setg(errp, "array size property %s may not be set more than once",
623                    name);
624         return;
625     }
626 
627     if (!visit_start_list(v, name, (GenericList **) &list, size, errp)) {
628         return;
629     }
630 
631     /* Read the whole input into a temporary list */
632     elem = list;
633     while (elem) {
634         Property elem_prop;
635 
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);
639         if (*errp) {
640             ok = false;
641             goto out_obj;
642         }
643         if (*alenptr == INT_MAX) {
644             error_setg(errp, "array is too big");
645             return;
646         }
647         (*alenptr)++;
648         elem = (ArrayElementList *) visit_next_list(v, (GenericList*) elem,
649                                                     size);
650     }
651 
652     ok = visit_check_list(v, errp);
653 out_obj:
654     visit_end_list(v, (void**) &list);
655 
656     if (!ok) {
657         for (elem = list; elem; elem = next) {
658             Property elem_prop = array_elem_prop(obj, prop, name,
659                                                  elem->value);
660             if (prop->arrayinfo->release) {
661                 prop->arrayinfo->release(obj, NULL, &elem_prop);
662             }
663             next = elem->next;
664             g_free(elem->value);
665             g_free(elem);
666         }
667         return;
668     }
669 
670     /*
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.
673      */
674     *arrayptr = g_malloc_n(*alenptr, prop->arrayfieldsize);
675     elemptr = *arrayptr;
676     for (elem = list; elem; elem = next) {
677         memcpy(elemptr, elem->value, prop->arrayfieldsize);
678         elemptr += prop->arrayfieldsize;
679         next = elem->next;
680         g_free(elem->value);
681         g_free(elem);
682     }
683 }
684 
685 static void get_prop_array(Object *obj, Visitor *v, const char *name,
686                            void *opaque, Error **errp)
687 {
688     ERRP_GUARD();
689     Property *prop = opaque;
690     uint32_t *alenptr = object_field_prop_ptr(obj, prop);
691     void **arrayptr = (void *)obj + prop->arrayoffset;
692     char *elem = *arrayptr;
693     GenericList *list;
694     const size_t list_elem_size = sizeof(*list) + prop->arrayfieldsize;
695     int i;
696     bool ok;
697 
698     if (!visit_start_list(v, name, &list, list_elem_size, errp)) {
699         return;
700     }
701 
702     for (i = 0; i < *alenptr; i++) {
703         Property elem_prop = array_elem_prop(obj, prop, name, elem);
704         prop->arrayinfo->get(obj, v, NULL, &elem_prop, errp);
705         if (*errp) {
706             goto out_obj;
707         }
708         elem += prop->arrayfieldsize;
709     }
710 
711     /* visit_check_list() can only fail for input visitors */
712     ok = visit_check_list(v, errp);
713     assert(ok);
714 
715 out_obj:
716     visit_end_list(v, (void**) &list);
717 }
718 
719 static void default_prop_array(ObjectProperty *op, const Property *prop)
720 {
721     object_property_set_default_list(op);
722 }
723 
724 const PropertyInfo qdev_prop_array = {
725     .name = "list",
726     .get = get_prop_array,
727     .set = set_prop_array,
728     .release = release_prop_array,
729     .set_default_value = default_prop_array,
730 };
731 
732 /* --- public helpers --- */
733 
734 static Property *qdev_prop_walk(Property *props, const char *name)
735 {
736     if (!props) {
737         return NULL;
738     }
739     while (props->name) {
740         if (strcmp(props->name, name) == 0) {
741             return props;
742         }
743         props++;
744     }
745     return NULL;
746 }
747 
748 static Property *qdev_prop_find(DeviceState *dev, const char *name)
749 {
750     ObjectClass *class;
751     Property *prop;
752 
753     /* device properties */
754     class = object_get_class(OBJECT(dev));
755     do {
756         prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name);
757         if (prop) {
758             return prop;
759         }
760         class = object_class_get_parent(class);
761     } while (class != object_class_by_name(TYPE_DEVICE));
762 
763     return NULL;
764 }
765 
766 void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj,
767                                     const char *name, const char *value)
768 {
769     switch (ret) {
770     case -EEXIST:
771         error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
772                   object_get_typename(obj), name, value);
773         break;
774     default:
775     case -EINVAL:
776         error_setg(errp, QERR_PROPERTY_VALUE_BAD,
777                    object_get_typename(obj), name, value);
778         break;
779     case -ENOENT:
780         error_setg(errp, "Property '%s.%s' can't find value '%s'",
781                   object_get_typename(obj), name, value);
782         break;
783     case 0:
784         break;
785     }
786 }
787 
788 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
789 {
790     object_property_set_bool(OBJECT(dev), name, value, &error_abort);
791 }
792 
793 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
794 {
795     object_property_set_int(OBJECT(dev), name, value, &error_abort);
796 }
797 
798 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
799 {
800     object_property_set_int(OBJECT(dev), name, value, &error_abort);
801 }
802 
803 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
804 {
805     object_property_set_int(OBJECT(dev), name, value, &error_abort);
806 }
807 
808 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
809 {
810     object_property_set_int(OBJECT(dev), name, value, &error_abort);
811 }
812 
813 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
814 {
815     object_property_set_int(OBJECT(dev), name, value, &error_abort);
816 }
817 
818 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
819 {
820     object_property_set_str(OBJECT(dev), name, value, &error_abort);
821 }
822 
823 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
824 {
825     Property *prop;
826 
827     prop = qdev_prop_find(dev, name);
828     object_property_set_str(OBJECT(dev), name,
829                             qapi_enum_lookup(prop->info->enum_table, value),
830                             &error_abort);
831 }
832 
833 void qdev_prop_set_array(DeviceState *dev, const char *name, QList *values)
834 {
835     object_property_set_qobject(OBJECT(dev), name, QOBJECT(values),
836                                 &error_abort);
837     qobject_unref(values);
838 }
839 
840 static GPtrArray *global_props(void)
841 {
842     static GPtrArray *gp;
843 
844     if (!gp) {
845         gp = g_ptr_array_new();
846     }
847 
848     return gp;
849 }
850 
851 void qdev_prop_register_global(GlobalProperty *prop)
852 {
853     g_ptr_array_add(global_props(), prop);
854 }
855 
856 const GlobalProperty *qdev_find_global_prop(Object *obj,
857                                             const char *name)
858 {
859     GPtrArray *props = global_props();
860     const GlobalProperty *p;
861     int i;
862 
863     for (i = 0; i < props->len; i++) {
864         p = g_ptr_array_index(props, i);
865         if (object_dynamic_cast(obj, p->driver)
866             && !strcmp(p->property, name)) {
867             return p;
868         }
869     }
870     return NULL;
871 }
872 
873 int qdev_prop_check_globals(void)
874 {
875     int i, ret = 0;
876 
877     for (i = 0; i < global_props()->len; i++) {
878         GlobalProperty *prop;
879         ObjectClass *oc;
880         DeviceClass *dc;
881 
882         prop = g_ptr_array_index(global_props(), i);
883         if (prop->used) {
884             continue;
885         }
886         oc = object_class_by_name(prop->driver);
887         oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
888         if (!oc) {
889             warn_report("global %s.%s has invalid class name",
890                         prop->driver, prop->property);
891             ret = 1;
892             continue;
893         }
894         dc = DEVICE_CLASS(oc);
895         if (!dc->hotpluggable && !prop->used) {
896             warn_report("global %s.%s=%s not used",
897                         prop->driver, prop->property, prop->value);
898             ret = 1;
899             continue;
900         }
901     }
902     return ret;
903 }
904 
905 void qdev_prop_set_globals(DeviceState *dev)
906 {
907     object_apply_global_props(OBJECT(dev), global_props(),
908                               dev->hotplugged ? NULL : &error_fatal);
909 }
910 
911 /* --- 64bit unsigned int 'size' type --- */
912 
913 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
914                      Error **errp)
915 {
916     Property *prop = opaque;
917     uint64_t *ptr = object_field_prop_ptr(obj, prop);
918 
919     visit_type_size(v, name, ptr, errp);
920 }
921 
922 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
923                      Error **errp)
924 {
925     Property *prop = opaque;
926     uint64_t *ptr = object_field_prop_ptr(obj, prop);
927 
928     visit_type_size(v, name, ptr, errp);
929 }
930 
931 const PropertyInfo qdev_prop_size = {
932     .name  = "size",
933     .get = get_size,
934     .set = set_size,
935     .set_default_value = qdev_propinfo_set_default_value_uint,
936 };
937 
938 /* --- object link property --- */
939 
940 static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
941                                             Property *prop)
942 {
943     return object_class_property_add_link(oc, name, prop->link_type,
944                                           prop->offset,
945                                           qdev_prop_allow_set_link_before_realize,
946                                           OBJ_PROP_LINK_STRONG);
947 }
948 
949 const PropertyInfo qdev_prop_link = {
950     .name = "link",
951     .create = create_link_property,
952 };
953 
954 void qdev_property_add_static(DeviceState *dev, Property *prop)
955 {
956     Object *obj = OBJECT(dev);
957     ObjectProperty *op;
958 
959     assert(!prop->info->create);
960 
961     op = object_property_add(obj, prop->name, prop->info->name,
962                              field_prop_getter(prop->info),
963                              field_prop_setter(prop->info),
964                              prop->info->release,
965                              prop);
966 
967     object_property_set_description(obj, prop->name,
968                                     prop->info->description);
969 
970     if (prop->set_default) {
971         prop->info->set_default_value(op, prop);
972         if (op->init) {
973             op->init(obj, op);
974         }
975     }
976 }
977 
978 static void qdev_class_add_property(DeviceClass *klass, const char *name,
979                                     Property *prop)
980 {
981     ObjectClass *oc = OBJECT_CLASS(klass);
982     ObjectProperty *op;
983 
984     if (prop->info->create) {
985         op = prop->info->create(oc, name, prop);
986     } else {
987         op = object_class_property_add(oc,
988                                        name, prop->info->name,
989                                        field_prop_getter(prop->info),
990                                        field_prop_setter(prop->info),
991                                        prop->info->release,
992                                        prop);
993     }
994     if (prop->set_default) {
995         prop->info->set_default_value(op, prop);
996     }
997     object_class_property_set_description(oc, name, prop->info->description);
998 }
999 
1000 /**
1001  * Legacy property handling
1002  */
1003 
1004 static void qdev_get_legacy_property(Object *obj, Visitor *v,
1005                                      const char *name, void *opaque,
1006                                      Error **errp)
1007 {
1008     Property *prop = opaque;
1009 
1010     char buffer[1024];
1011     char *ptr = buffer;
1012 
1013     prop->info->print(obj, prop, buffer, sizeof(buffer));
1014     visit_type_str(v, name, &ptr, errp);
1015 }
1016 
1017 /**
1018  * qdev_class_add_legacy_property:
1019  * @dev: Device to add the property to.
1020  * @prop: The qdev property definition.
1021  *
1022  * Add a legacy QOM property to @dev for qdev property @prop.
1023  *
1024  * Legacy properties are string versions of QOM properties.  The format of
1025  * the string depends on the property type.  Legacy properties are only
1026  * needed for "info qtree".
1027  *
1028  * Do not use this in new code!  QOM Properties added through this interface
1029  * will be given names in the "legacy" namespace.
1030  */
1031 static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop)
1032 {
1033     g_autofree char *name = NULL;
1034 
1035     /* Register pointer properties as legacy properties */
1036     if (!prop->info->print && prop->info->get) {
1037         return;
1038     }
1039 
1040     name = g_strdup_printf("legacy-%s", prop->name);
1041     object_class_property_add(OBJECT_CLASS(dc), name, "str",
1042         prop->info->print ? qdev_get_legacy_property : prop->info->get,
1043         NULL, NULL, prop);
1044 }
1045 
1046 void device_class_set_props(DeviceClass *dc, Property *props)
1047 {
1048     Property *prop;
1049 
1050     dc->props_ = props;
1051     for (prop = props; prop && prop->name; prop++) {
1052         qdev_class_add_legacy_property(dc, prop);
1053         qdev_class_add_property(dc, prop->name, prop);
1054     }
1055 }
1056 
1057 void qdev_alias_all_properties(DeviceState *target, Object *source)
1058 {
1059     ObjectClass *class;
1060     Property *prop;
1061 
1062     class = object_get_class(OBJECT(target));
1063     do {
1064         DeviceClass *dc = DEVICE_CLASS(class);
1065 
1066         for (prop = dc->props_; prop && prop->name; prop++) {
1067             object_property_add_alias(source, prop->name,
1068                                       OBJECT(target), prop->name);
1069         }
1070         class = object_class_get_parent(class);
1071     } while (class != object_class_by_name(TYPE_DEVICE));
1072 }
1073