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