xref: /openbmc/qemu/hw/core/qdev-properties.c (revision e6b5a071)
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 "qemu/ctype.h"
7 #include "qemu/error-report.h"
8 #include "qapi/visitor.h"
9 #include "qemu/uuid.h"
10 #include "qemu/units.h"
11 #include "qemu/cutils.h"
12 #include "qdev-prop-internal.h"
13 
14 void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
15                                   Error **errp)
16 {
17     if (dev->id) {
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)));
21     } else {
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)));
25     }
26 }
27 
28 void qdev_prop_allow_set_link_before_realize(const Object *obj,
29                                              const char *name,
30                                              Object *val, Error **errp)
31 {
32     DeviceState *dev = DEVICE(obj);
33 
34     if (dev->realized) {
35         error_setg(errp, "Attempt to set link property '%s' on device '%s' "
36                    "(type '%s') after it was realized",
37                    name, dev->id, object_get_typename(obj));
38     }
39 }
40 
41 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
42 {
43     void *ptr = dev;
44     ptr += prop->offset;
45     return ptr;
46 }
47 
48 void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
49                             void *opaque, Error **errp)
50 {
51     DeviceState *dev = DEVICE(obj);
52     Property *prop = opaque;
53     int *ptr = qdev_get_prop_ptr(dev, prop);
54 
55     visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
56 }
57 
58 void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
59                             void *opaque, Error **errp)
60 {
61     DeviceState *dev = DEVICE(obj);
62     Property *prop = opaque;
63     int *ptr = qdev_get_prop_ptr(dev, prop);
64 
65     if (dev->realized) {
66         qdev_prop_set_after_realize(dev, name, errp);
67         return;
68     }
69 
70     visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
71 }
72 
73 void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
74                                           const Property *prop)
75 {
76     object_property_set_default_str(op,
77         qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
78 }
79 
80 const PropertyInfo qdev_prop_enum = {
81     .name  = "enum",
82     .get   = qdev_propinfo_get_enum,
83     .set   = qdev_propinfo_set_enum,
84     .set_default_value = qdev_propinfo_set_default_value_enum,
85 };
86 
87 /* Bit */
88 
89 static uint32_t qdev_get_prop_mask(Property *prop)
90 {
91     assert(prop->info == &qdev_prop_bit);
92     return 0x1 << prop->bitnr;
93 }
94 
95 static void bit_prop_set(DeviceState *dev, Property *props, bool val)
96 {
97     uint32_t *p = qdev_get_prop_ptr(dev, props);
98     uint32_t mask = qdev_get_prop_mask(props);
99     if (val) {
100         *p |= mask;
101     } else {
102         *p &= ~mask;
103     }
104 }
105 
106 static void prop_get_bit(Object *obj, Visitor *v, const char *name,
107                          void *opaque, Error **errp)
108 {
109     DeviceState *dev = DEVICE(obj);
110     Property *prop = opaque;
111     uint32_t *p = qdev_get_prop_ptr(dev, prop);
112     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
113 
114     visit_type_bool(v, name, &value, errp);
115 }
116 
117 static void prop_set_bit(Object *obj, Visitor *v, const char *name,
118                          void *opaque, Error **errp)
119 {
120     DeviceState *dev = DEVICE(obj);
121     Property *prop = opaque;
122     bool value;
123 
124     if (dev->realized) {
125         qdev_prop_set_after_realize(dev, name, errp);
126         return;
127     }
128 
129     if (!visit_type_bool(v, name, &value, errp)) {
130         return;
131     }
132     bit_prop_set(dev, prop, value);
133 }
134 
135 static void set_default_value_bool(ObjectProperty *op, const Property *prop)
136 {
137     object_property_set_default_bool(op, prop->defval.u);
138 }
139 
140 const PropertyInfo qdev_prop_bit = {
141     .name  = "bool",
142     .description = "on/off",
143     .get   = prop_get_bit,
144     .set   = prop_set_bit,
145     .set_default_value = set_default_value_bool,
146 };
147 
148 /* Bit64 */
149 
150 static uint64_t qdev_get_prop_mask64(Property *prop)
151 {
152     assert(prop->info == &qdev_prop_bit64);
153     return 0x1ull << prop->bitnr;
154 }
155 
156 static void bit64_prop_set(DeviceState *dev, Property *props, bool val)
157 {
158     uint64_t *p = qdev_get_prop_ptr(dev, props);
159     uint64_t mask = qdev_get_prop_mask64(props);
160     if (val) {
161         *p |= mask;
162     } else {
163         *p &= ~mask;
164     }
165 }
166 
167 static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
168                            void *opaque, Error **errp)
169 {
170     DeviceState *dev = DEVICE(obj);
171     Property *prop = opaque;
172     uint64_t *p = qdev_get_prop_ptr(dev, prop);
173     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
174 
175     visit_type_bool(v, name, &value, errp);
176 }
177 
178 static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
179                            void *opaque, Error **errp)
180 {
181     DeviceState *dev = DEVICE(obj);
182     Property *prop = opaque;
183     bool value;
184 
185     if (dev->realized) {
186         qdev_prop_set_after_realize(dev, name, errp);
187         return;
188     }
189 
190     if (!visit_type_bool(v, name, &value, errp)) {
191         return;
192     }
193     bit64_prop_set(dev, prop, value);
194 }
195 
196 const PropertyInfo qdev_prop_bit64 = {
197     .name  = "bool",
198     .description = "on/off",
199     .get   = prop_get_bit64,
200     .set   = prop_set_bit64,
201     .set_default_value = set_default_value_bool,
202 };
203 
204 /* --- bool --- */
205 
206 static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
207                      Error **errp)
208 {
209     DeviceState *dev = DEVICE(obj);
210     Property *prop = opaque;
211     bool *ptr = qdev_get_prop_ptr(dev, prop);
212 
213     visit_type_bool(v, name, ptr, errp);
214 }
215 
216 static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
217                      Error **errp)
218 {
219     DeviceState *dev = DEVICE(obj);
220     Property *prop = opaque;
221     bool *ptr = qdev_get_prop_ptr(dev, prop);
222 
223     if (dev->realized) {
224         qdev_prop_set_after_realize(dev, name, errp);
225         return;
226     }
227 
228     visit_type_bool(v, name, ptr, errp);
229 }
230 
231 const PropertyInfo qdev_prop_bool = {
232     .name  = "bool",
233     .get   = get_bool,
234     .set   = set_bool,
235     .set_default_value = set_default_value_bool,
236 };
237 
238 /* --- 8bit integer --- */
239 
240 static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
241                       Error **errp)
242 {
243     DeviceState *dev = DEVICE(obj);
244     Property *prop = opaque;
245     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
246 
247     visit_type_uint8(v, name, ptr, errp);
248 }
249 
250 static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
251                       Error **errp)
252 {
253     DeviceState *dev = DEVICE(obj);
254     Property *prop = opaque;
255     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
256 
257     if (dev->realized) {
258         qdev_prop_set_after_realize(dev, name, errp);
259         return;
260     }
261 
262     visit_type_uint8(v, name, ptr, errp);
263 }
264 
265 void qdev_propinfo_set_default_value_int(ObjectProperty *op,
266                                          const Property *prop)
267 {
268     object_property_set_default_int(op, prop->defval.i);
269 }
270 
271 void qdev_propinfo_set_default_value_uint(ObjectProperty *op,
272                                           const Property *prop)
273 {
274     object_property_set_default_uint(op, prop->defval.u);
275 }
276 
277 const PropertyInfo qdev_prop_uint8 = {
278     .name  = "uint8",
279     .get   = get_uint8,
280     .set   = set_uint8,
281     .set_default_value = qdev_propinfo_set_default_value_uint,
282 };
283 
284 /* --- 16bit integer --- */
285 
286 void qdev_propinfo_get_uint16(Object *obj, Visitor *v, const char *name,
287                               void *opaque, Error **errp)
288 {
289     DeviceState *dev = DEVICE(obj);
290     Property *prop = opaque;
291     uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
292 
293     visit_type_uint16(v, name, ptr, errp);
294 }
295 
296 static void set_uint16(Object *obj, Visitor *v, const char *name,
297                        void *opaque, Error **errp)
298 {
299     DeviceState *dev = DEVICE(obj);
300     Property *prop = opaque;
301     uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
302 
303     if (dev->realized) {
304         qdev_prop_set_after_realize(dev, name, errp);
305         return;
306     }
307 
308     visit_type_uint16(v, name, ptr, errp);
309 }
310 
311 const PropertyInfo qdev_prop_uint16 = {
312     .name  = "uint16",
313     .get   = qdev_propinfo_get_uint16,
314     .set   = set_uint16,
315     .set_default_value = qdev_propinfo_set_default_value_uint,
316 };
317 
318 /* --- 32bit integer --- */
319 
320 static void get_uint32(Object *obj, Visitor *v, const char *name,
321                        void *opaque, Error **errp)
322 {
323     DeviceState *dev = DEVICE(obj);
324     Property *prop = opaque;
325     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
326 
327     visit_type_uint32(v, name, ptr, errp);
328 }
329 
330 static void set_uint32(Object *obj, Visitor *v, const char *name,
331                        void *opaque, Error **errp)
332 {
333     DeviceState *dev = DEVICE(obj);
334     Property *prop = opaque;
335     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
336 
337     if (dev->realized) {
338         qdev_prop_set_after_realize(dev, name, errp);
339         return;
340     }
341 
342     visit_type_uint32(v, name, ptr, errp);
343 }
344 
345 void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
346                              void *opaque, Error **errp)
347 {
348     DeviceState *dev = DEVICE(obj);
349     Property *prop = opaque;
350     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
351 
352     visit_type_int32(v, name, ptr, errp);
353 }
354 
355 static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
356                       Error **errp)
357 {
358     DeviceState *dev = DEVICE(obj);
359     Property *prop = opaque;
360     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
361 
362     if (dev->realized) {
363         qdev_prop_set_after_realize(dev, name, errp);
364         return;
365     }
366 
367     visit_type_int32(v, name, ptr, errp);
368 }
369 
370 const PropertyInfo qdev_prop_uint32 = {
371     .name  = "uint32",
372     .get   = get_uint32,
373     .set   = set_uint32,
374     .set_default_value = qdev_propinfo_set_default_value_uint,
375 };
376 
377 const PropertyInfo qdev_prop_int32 = {
378     .name  = "int32",
379     .get   = qdev_propinfo_get_int32,
380     .set   = set_int32,
381     .set_default_value = qdev_propinfo_set_default_value_int,
382 };
383 
384 /* --- 64bit integer --- */
385 
386 static void get_uint64(Object *obj, Visitor *v, const char *name,
387                        void *opaque, Error **errp)
388 {
389     DeviceState *dev = DEVICE(obj);
390     Property *prop = opaque;
391     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
392 
393     visit_type_uint64(v, name, ptr, errp);
394 }
395 
396 static void set_uint64(Object *obj, Visitor *v, const char *name,
397                        void *opaque, Error **errp)
398 {
399     DeviceState *dev = DEVICE(obj);
400     Property *prop = opaque;
401     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
402 
403     if (dev->realized) {
404         qdev_prop_set_after_realize(dev, name, errp);
405         return;
406     }
407 
408     visit_type_uint64(v, name, ptr, errp);
409 }
410 
411 static void get_int64(Object *obj, Visitor *v, const char *name,
412                       void *opaque, Error **errp)
413 {
414     DeviceState *dev = DEVICE(obj);
415     Property *prop = opaque;
416     int64_t *ptr = qdev_get_prop_ptr(dev, prop);
417 
418     visit_type_int64(v, name, ptr, errp);
419 }
420 
421 static void set_int64(Object *obj, Visitor *v, const char *name,
422                       void *opaque, Error **errp)
423 {
424     DeviceState *dev = DEVICE(obj);
425     Property *prop = opaque;
426     int64_t *ptr = qdev_get_prop_ptr(dev, prop);
427 
428     if (dev->realized) {
429         qdev_prop_set_after_realize(dev, name, errp);
430         return;
431     }
432 
433     visit_type_int64(v, name, ptr, errp);
434 }
435 
436 const PropertyInfo qdev_prop_uint64 = {
437     .name  = "uint64",
438     .get   = get_uint64,
439     .set   = set_uint64,
440     .set_default_value = qdev_propinfo_set_default_value_uint,
441 };
442 
443 const PropertyInfo qdev_prop_int64 = {
444     .name  = "int64",
445     .get   = get_int64,
446     .set   = set_int64,
447     .set_default_value = qdev_propinfo_set_default_value_int,
448 };
449 
450 /* --- string --- */
451 
452 static void release_string(Object *obj, const char *name, void *opaque)
453 {
454     Property *prop = opaque;
455     g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
456 }
457 
458 static void get_string(Object *obj, Visitor *v, const char *name,
459                        void *opaque, Error **errp)
460 {
461     DeviceState *dev = DEVICE(obj);
462     Property *prop = opaque;
463     char **ptr = qdev_get_prop_ptr(dev, prop);
464 
465     if (!*ptr) {
466         char *str = (char *)"";
467         visit_type_str(v, name, &str, errp);
468     } else {
469         visit_type_str(v, name, ptr, errp);
470     }
471 }
472 
473 static void set_string(Object *obj, Visitor *v, const char *name,
474                        void *opaque, Error **errp)
475 {
476     DeviceState *dev = DEVICE(obj);
477     Property *prop = opaque;
478     char **ptr = qdev_get_prop_ptr(dev, prop);
479     char *str;
480 
481     if (dev->realized) {
482         qdev_prop_set_after_realize(dev, name, errp);
483         return;
484     }
485 
486     if (!visit_type_str(v, name, &str, errp)) {
487         return;
488     }
489     g_free(*ptr);
490     *ptr = str;
491 }
492 
493 const PropertyInfo qdev_prop_string = {
494     .name  = "str",
495     .release = release_string,
496     .get   = get_string,
497     .set   = set_string,
498 };
499 
500 /* --- on/off/auto --- */
501 
502 const PropertyInfo qdev_prop_on_off_auto = {
503     .name = "OnOffAuto",
504     .description = "on/off/auto",
505     .enum_table = &OnOffAuto_lookup,
506     .get = qdev_propinfo_get_enum,
507     .set = qdev_propinfo_set_enum,
508     .set_default_value = qdev_propinfo_set_default_value_enum,
509 };
510 
511 /* --- 32bit unsigned int 'size' type --- */
512 
513 void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
514                               void *opaque, Error **errp)
515 {
516     DeviceState *dev = DEVICE(obj);
517     Property *prop = opaque;
518     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
519     uint64_t value = *ptr;
520 
521     visit_type_size(v, name, &value, errp);
522 }
523 
524 static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
525                        Error **errp)
526 {
527     DeviceState *dev = DEVICE(obj);
528     Property *prop = opaque;
529     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
530     uint64_t value;
531 
532     if (dev->realized) {
533         qdev_prop_set_after_realize(dev, name, errp);
534         return;
535     }
536 
537     if (!visit_type_size(v, name, &value, errp)) {
538         return;
539     }
540 
541     if (value > UINT32_MAX) {
542         error_setg(errp,
543                    "Property %s.%s doesn't take value %" PRIu64
544                    " (maximum: %u)",
545                    dev->id ? : "", name, value, UINT32_MAX);
546         return;
547     }
548 
549     *ptr = value;
550 }
551 
552 const PropertyInfo qdev_prop_size32 = {
553     .name  = "size",
554     .get = qdev_propinfo_get_size32,
555     .set = set_size32,
556     .set_default_value = qdev_propinfo_set_default_value_uint,
557 };
558 
559 /* --- UUID --- */
560 
561 static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
562                      Error **errp)
563 {
564     DeviceState *dev = DEVICE(obj);
565     Property *prop = opaque;
566     QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
567     char buffer[UUID_FMT_LEN + 1];
568     char *p = buffer;
569 
570     qemu_uuid_unparse(uuid, buffer);
571 
572     visit_type_str(v, name, &p, errp);
573 }
574 
575 #define UUID_VALUE_AUTO        "auto"
576 
577 static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
578                     Error **errp)
579 {
580     DeviceState *dev = DEVICE(obj);
581     Property *prop = opaque;
582     QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
583     char *str;
584 
585     if (dev->realized) {
586         qdev_prop_set_after_realize(dev, name, errp);
587         return;
588     }
589 
590     if (!visit_type_str(v, name, &str, errp)) {
591         return;
592     }
593 
594     if (!strcmp(str, UUID_VALUE_AUTO)) {
595         qemu_uuid_generate(uuid);
596     } else if (qemu_uuid_parse(str, uuid) < 0) {
597         error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
598     }
599     g_free(str);
600 }
601 
602 static void set_default_uuid_auto(ObjectProperty *op, const Property *prop)
603 {
604     object_property_set_default_str(op, UUID_VALUE_AUTO);
605 }
606 
607 const PropertyInfo qdev_prop_uuid = {
608     .name  = "str",
609     .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
610         "\" for random value (default)",
611     .get   = get_uuid,
612     .set   = set_uuid,
613     .set_default_value = set_default_uuid_auto,
614 };
615 
616 /* --- support for array properties --- */
617 
618 /* Used as an opaque for the object properties we add for each
619  * array element. Note that the struct Property must be first
620  * in the struct so that a pointer to this works as the opaque
621  * for the underlying element's property hooks as well as for
622  * our own release callback.
623  */
624 typedef struct {
625     struct Property prop;
626     char *propname;
627     ObjectPropertyRelease *release;
628 } ArrayElementProperty;
629 
630 /* object property release callback for array element properties:
631  * we call the underlying element's property release hook, and
632  * then free the memory we allocated when we added the property.
633  */
634 static void array_element_release(Object *obj, const char *name, void *opaque)
635 {
636     ArrayElementProperty *p = opaque;
637     if (p->release) {
638         p->release(obj, name, opaque);
639     }
640     g_free(p->propname);
641     g_free(p);
642 }
643 
644 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
645                               void *opaque, Error **errp)
646 {
647     /* Setter for the property which defines the length of a
648      * variable-sized property array. As well as actually setting the
649      * array-length field in the device struct, we have to create the
650      * array itself and dynamically add the corresponding properties.
651      */
652     DeviceState *dev = DEVICE(obj);
653     Property *prop = opaque;
654     uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
655     void **arrayptr = (void *)dev + prop->arrayoffset;
656     void *eltptr;
657     const char *arrayname;
658     int i;
659 
660     if (dev->realized) {
661         qdev_prop_set_after_realize(dev, name, errp);
662         return;
663     }
664     if (*alenptr) {
665         error_setg(errp, "array size property %s may not be set more than once",
666                    name);
667         return;
668     }
669     if (!visit_type_uint32(v, name, alenptr, errp)) {
670         return;
671     }
672     if (!*alenptr) {
673         return;
674     }
675 
676     /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
677      * strip it off so we can get the name of the array itself.
678      */
679     assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
680                    strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
681     arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
682 
683     /* Note that it is the responsibility of the individual device's deinit
684      * to free the array proper.
685      */
686     *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
687     for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
688         char *propname = g_strdup_printf("%s[%d]", arrayname, i);
689         ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
690         arrayprop->release = prop->arrayinfo->release;
691         arrayprop->propname = propname;
692         arrayprop->prop.info = prop->arrayinfo;
693         arrayprop->prop.name = propname;
694         /* This ugly piece of pointer arithmetic sets up the offset so
695          * that when the underlying get/set hooks call qdev_get_prop_ptr
696          * they get the right answer despite the array element not actually
697          * being inside the device struct.
698          */
699         arrayprop->prop.offset = eltptr - (void *)dev;
700         assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
701         object_property_add(obj, propname,
702                             arrayprop->prop.info->name,
703                             arrayprop->prop.info->get,
704                             arrayprop->prop.info->set,
705                             array_element_release,
706                             arrayprop);
707     }
708 }
709 
710 const PropertyInfo qdev_prop_arraylen = {
711     .name = "uint32",
712     .get = get_uint32,
713     .set = set_prop_arraylen,
714     .set_default_value = qdev_propinfo_set_default_value_uint,
715 };
716 
717 /* --- public helpers --- */
718 
719 static Property *qdev_prop_walk(Property *props, const char *name)
720 {
721     if (!props) {
722         return NULL;
723     }
724     while (props->name) {
725         if (strcmp(props->name, name) == 0) {
726             return props;
727         }
728         props++;
729     }
730     return NULL;
731 }
732 
733 static Property *qdev_prop_find(DeviceState *dev, const char *name)
734 {
735     ObjectClass *class;
736     Property *prop;
737 
738     /* device properties */
739     class = object_get_class(OBJECT(dev));
740     do {
741         prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name);
742         if (prop) {
743             return prop;
744         }
745         class = object_class_get_parent(class);
746     } while (class != object_class_by_name(TYPE_DEVICE));
747 
748     return NULL;
749 }
750 
751 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
752                                     Property *prop, const char *value)
753 {
754     switch (ret) {
755     case -EEXIST:
756         error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
757                   object_get_typename(OBJECT(dev)), prop->name, value);
758         break;
759     default:
760     case -EINVAL:
761         error_setg(errp, QERR_PROPERTY_VALUE_BAD,
762                    object_get_typename(OBJECT(dev)), prop->name, value);
763         break;
764     case -ENOENT:
765         error_setg(errp, "Property '%s.%s' can't find value '%s'",
766                   object_get_typename(OBJECT(dev)), prop->name, value);
767         break;
768     case 0:
769         break;
770     }
771 }
772 
773 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
774 {
775     object_property_set_bool(OBJECT(dev), name, value, &error_abort);
776 }
777 
778 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
779 {
780     object_property_set_int(OBJECT(dev), name, value, &error_abort);
781 }
782 
783 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
784 {
785     object_property_set_int(OBJECT(dev), name, value, &error_abort);
786 }
787 
788 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
789 {
790     object_property_set_int(OBJECT(dev), name, value, &error_abort);
791 }
792 
793 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
794 {
795     object_property_set_int(OBJECT(dev), name, value, &error_abort);
796 }
797 
798 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
799 {
800     object_property_set_int(OBJECT(dev), name, value, &error_abort);
801 }
802 
803 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
804 {
805     object_property_set_str(OBJECT(dev), name, value, &error_abort);
806 }
807 
808 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
809 {
810     Property *prop;
811 
812     prop = qdev_prop_find(dev, name);
813     object_property_set_str(OBJECT(dev), name,
814                             qapi_enum_lookup(prop->info->enum_table, value),
815                             &error_abort);
816 }
817 
818 static GPtrArray *global_props(void)
819 {
820     static GPtrArray *gp;
821 
822     if (!gp) {
823         gp = g_ptr_array_new();
824     }
825 
826     return gp;
827 }
828 
829 void qdev_prop_register_global(GlobalProperty *prop)
830 {
831     g_ptr_array_add(global_props(), prop);
832 }
833 
834 const GlobalProperty *qdev_find_global_prop(DeviceState *dev,
835                                             const char *name)
836 {
837     GPtrArray *props = global_props();
838     const GlobalProperty *p;
839     int i;
840 
841     for (i = 0; i < props->len; i++) {
842         p = g_ptr_array_index(props, i);
843         if (object_dynamic_cast(OBJECT(dev), p->driver)
844             && !strcmp(p->property, name)) {
845             return p;
846         }
847     }
848     return NULL;
849 }
850 
851 int qdev_prop_check_globals(void)
852 {
853     int i, ret = 0;
854 
855     for (i = 0; i < global_props()->len; i++) {
856         GlobalProperty *prop;
857         ObjectClass *oc;
858         DeviceClass *dc;
859 
860         prop = g_ptr_array_index(global_props(), i);
861         if (prop->used) {
862             continue;
863         }
864         oc = object_class_by_name(prop->driver);
865         oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
866         if (!oc) {
867             warn_report("global %s.%s has invalid class name",
868                         prop->driver, prop->property);
869             ret = 1;
870             continue;
871         }
872         dc = DEVICE_CLASS(oc);
873         if (!dc->hotpluggable && !prop->used) {
874             warn_report("global %s.%s=%s not used",
875                         prop->driver, prop->property, prop->value);
876             ret = 1;
877             continue;
878         }
879     }
880     return ret;
881 }
882 
883 void qdev_prop_set_globals(DeviceState *dev)
884 {
885     object_apply_global_props(OBJECT(dev), global_props(),
886                               dev->hotplugged ? NULL : &error_fatal);
887 }
888 
889 /* --- 64bit unsigned int 'size' type --- */
890 
891 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
892                      Error **errp)
893 {
894     DeviceState *dev = DEVICE(obj);
895     Property *prop = opaque;
896     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
897 
898     visit_type_size(v, name, ptr, errp);
899 }
900 
901 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
902                      Error **errp)
903 {
904     DeviceState *dev = DEVICE(obj);
905     Property *prop = opaque;
906     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
907 
908     visit_type_size(v, name, ptr, errp);
909 }
910 
911 const PropertyInfo qdev_prop_size = {
912     .name  = "size",
913     .get = get_size,
914     .set = set_size,
915     .set_default_value = qdev_propinfo_set_default_value_uint,
916 };
917 
918 /* --- object link property --- */
919 
920 static void create_link_property(ObjectClass *oc, Property *prop)
921 {
922     object_class_property_add_link(oc, prop->name, prop->link_type,
923                                    prop->offset,
924                                    qdev_prop_allow_set_link_before_realize,
925                                    OBJ_PROP_LINK_STRONG);
926 }
927 
928 const PropertyInfo qdev_prop_link = {
929     .name = "link",
930     .create = create_link_property,
931 };
932