qom: move properties from qdev to object
[qemu/ar7.git] / hw / qdev-properties.c
blobc4583a14d75bec32f00f6a05c7d71fa5854bd724
1 #include "net.h"
2 #include "qdev.h"
3 #include "qerror.h"
4 #include "blockdev.h"
6 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
8 void *ptr = dev;
9 ptr += prop->offset;
10 return ptr;
13 static uint32_t qdev_get_prop_mask(Property *prop)
15 assert(prop->info->type == PROP_TYPE_BIT);
16 return 0x1 << prop->bitnr;
19 static void bit_prop_set(DeviceState *dev, Property *props, bool val)
21 uint32_t *p = qdev_get_prop_ptr(dev, props);
22 uint32_t mask = qdev_get_prop_mask(props);
23 if (val)
24 *p |= mask;
25 else
26 *p &= ~mask;
29 static void qdev_prop_cpy(DeviceState *dev, Property *props, void *src)
31 if (props->info->type == PROP_TYPE_BIT) {
32 bool *defval = src;
33 bit_prop_set(dev, props, *defval);
34 } else {
35 char *dst = qdev_get_prop_ptr(dev, props);
36 memcpy(dst, src, props->info->size);
40 /* Bit */
41 static int parse_bit(DeviceState *dev, Property *prop, const char *str)
43 if (!strcasecmp(str, "on"))
44 bit_prop_set(dev, prop, true);
45 else if (!strcasecmp(str, "off"))
46 bit_prop_set(dev, prop, false);
47 else
48 return -EINVAL;
49 return 0;
52 static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
54 uint32_t *p = qdev_get_prop_ptr(dev, prop);
55 return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
58 static void get_bit(Object *obj, Visitor *v, void *opaque,
59 const char *name, Error **errp)
61 DeviceState *dev = DEVICE(obj);
62 Property *prop = opaque;
63 uint32_t *p = qdev_get_prop_ptr(dev, prop);
64 bool value = (*p & qdev_get_prop_mask(prop)) != 0;
66 visit_type_bool(v, &value, name, errp);
69 static void set_bit(Object *obj, Visitor *v, void *opaque,
70 const char *name, Error **errp)
72 DeviceState *dev = DEVICE(obj);
73 Property *prop = opaque;
74 Error *local_err = NULL;
75 bool value;
77 if (dev->state != DEV_STATE_CREATED) {
78 error_set(errp, QERR_PERMISSION_DENIED);
79 return;
82 visit_type_bool(v, &value, name, &local_err);
83 if (local_err) {
84 error_propagate(errp, local_err);
85 return;
87 bit_prop_set(dev, prop, value);
90 PropertyInfo qdev_prop_bit = {
91 .name = "boolean",
92 .legacy_name = "on/off",
93 .type = PROP_TYPE_BIT,
94 .size = sizeof(uint32_t),
95 .parse = parse_bit,
96 .print = print_bit,
97 .get = get_bit,
98 .set = set_bit,
101 /* --- 8bit integer --- */
103 static int parse_uint8(DeviceState *dev, Property *prop, const char *str)
105 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
106 char *end;
108 /* accept both hex and decimal */
109 *ptr = strtoul(str, &end, 0);
110 if ((*end != '\0') || (end == str)) {
111 return -EINVAL;
114 return 0;
117 static int print_uint8(DeviceState *dev, Property *prop, char *dest, size_t len)
119 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
120 return snprintf(dest, len, "%" PRIu8, *ptr);
123 static void get_int8(Object *obj, Visitor *v, void *opaque,
124 const char *name, Error **errp)
126 DeviceState *dev = DEVICE(obj);
127 Property *prop = opaque;
128 int8_t *ptr = qdev_get_prop_ptr(dev, prop);
129 int64_t value;
131 value = *ptr;
132 visit_type_int(v, &value, name, errp);
135 static void set_int8(Object *obj, Visitor *v, void *opaque,
136 const char *name, Error **errp)
138 DeviceState *dev = DEVICE(obj);
139 Property *prop = opaque;
140 int8_t *ptr = qdev_get_prop_ptr(dev, prop);
141 Error *local_err = NULL;
142 int64_t value;
144 if (dev->state != DEV_STATE_CREATED) {
145 error_set(errp, QERR_PERMISSION_DENIED);
146 return;
149 visit_type_int(v, &value, name, &local_err);
150 if (local_err) {
151 error_propagate(errp, local_err);
152 return;
154 if (value > prop->info->min && value <= prop->info->max) {
155 *ptr = value;
156 } else {
157 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
158 dev->id?:"", name, value, prop->info->min,
159 prop->info->max);
163 PropertyInfo qdev_prop_uint8 = {
164 .name = "uint8",
165 .type = PROP_TYPE_UINT8,
166 .size = sizeof(uint8_t),
167 .parse = parse_uint8,
168 .print = print_uint8,
169 .get = get_int8,
170 .set = set_int8,
171 .min = 0,
172 .max = 255,
175 /* --- 8bit hex value --- */
177 static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
179 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
180 char *end;
182 *ptr = strtoul(str, &end, 16);
183 if ((*end != '\0') || (end == str)) {
184 return -EINVAL;
187 return 0;
190 static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
192 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
193 return snprintf(dest, len, "0x%" PRIx8, *ptr);
196 PropertyInfo qdev_prop_hex8 = {
197 .name = "uint8",
198 .legacy_name = "hex8",
199 .type = PROP_TYPE_UINT8,
200 .size = sizeof(uint8_t),
201 .parse = parse_hex8,
202 .print = print_hex8,
203 .get = get_int8,
204 .set = set_int8,
205 .min = 0,
206 .max = 255,
209 /* --- 16bit integer --- */
211 static int parse_uint16(DeviceState *dev, Property *prop, const char *str)
213 uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
214 char *end;
216 /* accept both hex and decimal */
217 *ptr = strtoul(str, &end, 0);
218 if ((*end != '\0') || (end == str)) {
219 return -EINVAL;
222 return 0;
225 static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len)
227 uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
228 return snprintf(dest, len, "%" PRIu16, *ptr);
231 static void get_int16(Object *obj, Visitor *v, void *opaque,
232 const char *name, Error **errp)
234 DeviceState *dev = DEVICE(obj);
235 Property *prop = opaque;
236 int16_t *ptr = qdev_get_prop_ptr(dev, prop);
237 int64_t value;
239 value = *ptr;
240 visit_type_int(v, &value, name, errp);
243 static void set_int16(Object *obj, Visitor *v, void *opaque,
244 const char *name, Error **errp)
246 DeviceState *dev = DEVICE(obj);
247 Property *prop = opaque;
248 int16_t *ptr = qdev_get_prop_ptr(dev, prop);
249 Error *local_err = NULL;
250 int64_t value;
252 if (dev->state != DEV_STATE_CREATED) {
253 error_set(errp, QERR_PERMISSION_DENIED);
254 return;
257 visit_type_int(v, &value, name, &local_err);
258 if (local_err) {
259 error_propagate(errp, local_err);
260 return;
262 if (value > prop->info->min && value <= prop->info->max) {
263 *ptr = value;
264 } else {
265 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
266 dev->id?:"", name, value, prop->info->min,
267 prop->info->max);
271 PropertyInfo qdev_prop_uint16 = {
272 .name = "uint16",
273 .type = PROP_TYPE_UINT16,
274 .size = sizeof(uint16_t),
275 .parse = parse_uint16,
276 .print = print_uint16,
277 .get = get_int16,
278 .set = set_int16,
279 .min = 0,
280 .max = 65535,
283 /* --- 32bit integer --- */
285 static int parse_uint32(DeviceState *dev, Property *prop, const char *str)
287 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
288 char *end;
290 /* accept both hex and decimal */
291 *ptr = strtoul(str, &end, 0);
292 if ((*end != '\0') || (end == str)) {
293 return -EINVAL;
296 return 0;
299 static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len)
301 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
302 return snprintf(dest, len, "%" PRIu32, *ptr);
305 static void get_int32(Object *obj, Visitor *v, void *opaque,
306 const char *name, Error **errp)
308 DeviceState *dev = DEVICE(obj);
309 Property *prop = opaque;
310 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
311 int64_t value;
313 value = *ptr;
314 visit_type_int(v, &value, name, errp);
317 static void set_int32(Object *obj, Visitor *v, void *opaque,
318 const char *name, Error **errp)
320 DeviceState *dev = DEVICE(obj);
321 Property *prop = opaque;
322 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
323 Error *local_err = NULL;
324 int64_t value;
326 if (dev->state != DEV_STATE_CREATED) {
327 error_set(errp, QERR_PERMISSION_DENIED);
328 return;
331 visit_type_int(v, &value, name, &local_err);
332 if (local_err) {
333 error_propagate(errp, local_err);
334 return;
336 if (value > prop->info->min && value <= prop->info->max) {
337 *ptr = value;
338 } else {
339 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
340 dev->id?:"", name, value, prop->info->min,
341 prop->info->max);
345 PropertyInfo qdev_prop_uint32 = {
346 .name = "uint32",
347 .type = PROP_TYPE_UINT32,
348 .size = sizeof(uint32_t),
349 .parse = parse_uint32,
350 .print = print_uint32,
351 .get = get_int32,
352 .set = set_int32,
353 .min = 0,
354 .max = 0xFFFFFFFFULL,
357 static int parse_int32(DeviceState *dev, Property *prop, const char *str)
359 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
360 char *end;
362 *ptr = strtol(str, &end, 10);
363 if ((*end != '\0') || (end == str)) {
364 return -EINVAL;
367 return 0;
370 static int print_int32(DeviceState *dev, Property *prop, char *dest, size_t len)
372 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
373 return snprintf(dest, len, "%" PRId32, *ptr);
376 PropertyInfo qdev_prop_int32 = {
377 .name = "int32",
378 .type = PROP_TYPE_INT32,
379 .size = sizeof(int32_t),
380 .parse = parse_int32,
381 .print = print_int32,
382 .get = get_int32,
383 .set = set_int32,
384 .min = -0x80000000LL,
385 .max = 0x7FFFFFFFLL,
388 /* --- 32bit hex value --- */
390 static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
392 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
393 char *end;
395 *ptr = strtoul(str, &end, 16);
396 if ((*end != '\0') || (end == str)) {
397 return -EINVAL;
400 return 0;
403 static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
405 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
406 return snprintf(dest, len, "0x%" PRIx32, *ptr);
409 PropertyInfo qdev_prop_hex32 = {
410 .name = "uint32",
411 .legacy_name = "hex32",
412 .type = PROP_TYPE_UINT32,
413 .size = sizeof(uint32_t),
414 .parse = parse_hex32,
415 .print = print_hex32,
416 .get = get_int32,
417 .set = set_int32,
418 .min = 0,
419 .max = 0xFFFFFFFFULL,
422 /* --- 64bit integer --- */
424 static int parse_uint64(DeviceState *dev, Property *prop, const char *str)
426 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
427 char *end;
429 /* accept both hex and decimal */
430 *ptr = strtoull(str, &end, 0);
431 if ((*end != '\0') || (end == str)) {
432 return -EINVAL;
435 return 0;
438 static int print_uint64(DeviceState *dev, Property *prop, char *dest, size_t len)
440 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
441 return snprintf(dest, len, "%" PRIu64, *ptr);
444 static void get_int64(Object *obj, Visitor *v, void *opaque,
445 const char *name, Error **errp)
447 DeviceState *dev = DEVICE(obj);
448 Property *prop = opaque;
449 int64_t *ptr = qdev_get_prop_ptr(dev, prop);
451 visit_type_int(v, ptr, name, errp);
454 static void set_int64(Object *obj, Visitor *v, void *opaque,
455 const char *name, Error **errp)
457 DeviceState *dev = DEVICE(obj);
458 Property *prop = opaque;
459 int64_t *ptr = qdev_get_prop_ptr(dev, prop);
461 if (dev->state != DEV_STATE_CREATED) {
462 error_set(errp, QERR_PERMISSION_DENIED);
463 return;
466 visit_type_int(v, ptr, name, errp);
469 PropertyInfo qdev_prop_uint64 = {
470 .name = "uint64",
471 .type = PROP_TYPE_UINT64,
472 .size = sizeof(uint64_t),
473 .parse = parse_uint64,
474 .print = print_uint64,
475 .get = get_int64,
476 .set = set_int64,
479 /* --- 64bit hex value --- */
481 static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
483 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
484 char *end;
486 *ptr = strtoull(str, &end, 16);
487 if ((*end != '\0') || (end == str)) {
488 return -EINVAL;
491 return 0;
494 static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
496 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
497 return snprintf(dest, len, "0x%" PRIx64, *ptr);
500 PropertyInfo qdev_prop_hex64 = {
501 .name = "uint64",
502 .legacy_name = "hex64",
503 .type = PROP_TYPE_UINT64,
504 .size = sizeof(uint64_t),
505 .parse = parse_hex64,
506 .print = print_hex64,
507 .get = get_int64,
508 .set = set_int64,
511 /* --- string --- */
513 static int parse_string(DeviceState *dev, Property *prop, const char *str)
515 char **ptr = qdev_get_prop_ptr(dev, prop);
517 if (*ptr)
518 g_free(*ptr);
519 *ptr = g_strdup(str);
520 return 0;
523 static void free_string(DeviceState *dev, Property *prop)
525 g_free(*(char **)qdev_get_prop_ptr(dev, prop));
528 static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
530 char **ptr = qdev_get_prop_ptr(dev, prop);
531 if (!*ptr)
532 return snprintf(dest, len, "<null>");
533 return snprintf(dest, len, "\"%s\"", *ptr);
536 static void get_string(Object *obj, Visitor *v, void *opaque,
537 const char *name, Error **errp)
539 DeviceState *dev = DEVICE(obj);
540 Property *prop = opaque;
541 char **ptr = qdev_get_prop_ptr(dev, prop);
543 if (!*ptr) {
544 char *str = (char *)"";
545 visit_type_str(v, &str, name, errp);
546 } else {
547 visit_type_str(v, ptr, name, errp);
551 static void set_string(Object *obj, Visitor *v, void *opaque,
552 const char *name, Error **errp)
554 DeviceState *dev = DEVICE(obj);
555 Property *prop = opaque;
556 char **ptr = qdev_get_prop_ptr(dev, prop);
557 Error *local_err = NULL;
558 char *str;
560 if (dev->state != DEV_STATE_CREATED) {
561 error_set(errp, QERR_PERMISSION_DENIED);
562 return;
565 visit_type_str(v, &str, name, &local_err);
566 if (local_err) {
567 error_propagate(errp, local_err);
568 return;
570 if (!*str) {
571 g_free(str);
572 str = NULL;
574 if (*ptr) {
575 g_free(*ptr);
577 *ptr = str;
580 PropertyInfo qdev_prop_string = {
581 .name = "string",
582 .type = PROP_TYPE_STRING,
583 .size = sizeof(char*),
584 .parse = parse_string,
585 .print = print_string,
586 .free = free_string,
587 .get = get_string,
588 .set = set_string,
591 /* --- drive --- */
593 static int parse_drive(DeviceState *dev, Property *prop, const char *str)
595 BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
596 BlockDriverState *bs;
598 bs = bdrv_find(str);
599 if (bs == NULL)
600 return -ENOENT;
601 if (bdrv_attach_dev(bs, dev) < 0)
602 return -EEXIST;
603 *ptr = bs;
604 return 0;
607 static void free_drive(DeviceState *dev, Property *prop)
609 BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
611 if (*ptr) {
612 bdrv_detach_dev(*ptr, dev);
613 blockdev_auto_del(*ptr);
617 static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len)
619 BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
620 return snprintf(dest, len, "%s",
621 *ptr ? bdrv_get_device_name(*ptr) : "<null>");
624 static void get_generic(Object *obj, Visitor *v, void *opaque,
625 const char *name, Error **errp)
627 DeviceState *dev = DEVICE(obj);
628 Property *prop = opaque;
629 void **ptr = qdev_get_prop_ptr(dev, prop);
630 char buffer[1024];
631 char *p = buffer;
633 buffer[0] = 0;
634 if (*ptr) {
635 prop->info->print(dev, prop, buffer, sizeof(buffer));
637 visit_type_str(v, &p, name, errp);
640 static void set_generic(Object *obj, Visitor *v, void *opaque,
641 const char *name, Error **errp)
643 DeviceState *dev = DEVICE(obj);
644 Property *prop = opaque;
645 Error *local_err = NULL;
646 char *str;
647 int ret;
649 if (dev->state != DEV_STATE_CREATED) {
650 error_set(errp, QERR_PERMISSION_DENIED);
651 return;
654 visit_type_str(v, &str, name, &local_err);
655 if (local_err) {
656 error_propagate(errp, local_err);
657 return;
659 if (!*str) {
660 g_free(str);
661 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
662 return;
664 ret = prop->info->parse(dev, prop, str);
665 error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
666 g_free(str);
669 PropertyInfo qdev_prop_drive = {
670 .name = "drive",
671 .type = PROP_TYPE_DRIVE,
672 .size = sizeof(BlockDriverState *),
673 .parse = parse_drive,
674 .print = print_drive,
675 .get = get_generic,
676 .set = set_generic,
677 .free = free_drive,
680 /* --- character device --- */
682 static int parse_chr(DeviceState *dev, Property *prop, const char *str)
684 CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
686 *ptr = qemu_chr_find(str);
687 if (*ptr == NULL) {
688 return -ENOENT;
690 if ((*ptr)->avail_connections < 1) {
691 return -EEXIST;
693 --(*ptr)->avail_connections;
694 return 0;
697 static void free_chr(DeviceState *dev, Property *prop)
699 CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
701 if (*ptr) {
702 qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL);
707 static int print_chr(DeviceState *dev, Property *prop, char *dest, size_t len)
709 CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
711 if (*ptr && (*ptr)->label) {
712 return snprintf(dest, len, "%s", (*ptr)->label);
713 } else {
714 return snprintf(dest, len, "<null>");
718 PropertyInfo qdev_prop_chr = {
719 .name = "chr",
720 .type = PROP_TYPE_CHR,
721 .size = sizeof(CharDriverState*),
722 .parse = parse_chr,
723 .print = print_chr,
724 .get = get_generic,
725 .set = set_generic,
726 .free = free_chr,
729 /* --- netdev device --- */
731 static int parse_netdev(DeviceState *dev, Property *prop, const char *str)
733 VLANClientState **ptr = qdev_get_prop_ptr(dev, prop);
735 *ptr = qemu_find_netdev(str);
736 if (*ptr == NULL)
737 return -ENOENT;
738 if ((*ptr)->peer) {
739 return -EEXIST;
741 return 0;
744 static int print_netdev(DeviceState *dev, Property *prop, char *dest, size_t len)
746 VLANClientState **ptr = qdev_get_prop_ptr(dev, prop);
748 if (*ptr && (*ptr)->name) {
749 return snprintf(dest, len, "%s", (*ptr)->name);
750 } else {
751 return snprintf(dest, len, "<null>");
755 PropertyInfo qdev_prop_netdev = {
756 .name = "netdev",
757 .type = PROP_TYPE_NETDEV,
758 .size = sizeof(VLANClientState*),
759 .parse = parse_netdev,
760 .print = print_netdev,
761 .get = get_generic,
762 .set = set_generic,
765 /* --- vlan --- */
767 static int parse_vlan(DeviceState *dev, Property *prop, const char *str)
769 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
770 int id;
772 if (sscanf(str, "%d", &id) != 1)
773 return -EINVAL;
774 *ptr = qemu_find_vlan(id, 1);
775 if (*ptr == NULL)
776 return -ENOENT;
777 return 0;
780 static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
782 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
784 if (*ptr) {
785 return snprintf(dest, len, "%d", (*ptr)->id);
786 } else {
787 return snprintf(dest, len, "<null>");
791 static void get_vlan(Object *obj, Visitor *v, void *opaque,
792 const char *name, Error **errp)
794 DeviceState *dev = DEVICE(obj);
795 Property *prop = opaque;
796 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
797 int64_t id;
799 id = *ptr ? (*ptr)->id : -1;
800 visit_type_int(v, &id, name, errp);
803 static void set_vlan(Object *obj, Visitor *v, void *opaque,
804 const char *name, Error **errp)
806 DeviceState *dev = DEVICE(obj);
807 Property *prop = opaque;
808 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
809 Error *local_err = NULL;
810 int64_t id;
811 VLANState *vlan;
813 if (dev->state != DEV_STATE_CREATED) {
814 error_set(errp, QERR_PERMISSION_DENIED);
815 return;
818 visit_type_int(v, &id, name, &local_err);
819 if (local_err) {
820 error_propagate(errp, local_err);
821 return;
823 if (id == -1) {
824 *ptr = NULL;
825 return;
827 vlan = qemu_find_vlan(id, 1);
828 if (!vlan) {
829 error_set(errp, QERR_INVALID_PARAMETER_VALUE,
830 name, prop->info->name);
831 return;
833 *ptr = vlan;
836 PropertyInfo qdev_prop_vlan = {
837 .name = "vlan",
838 .type = PROP_TYPE_VLAN,
839 .size = sizeof(VLANClientState*),
840 .parse = parse_vlan,
841 .print = print_vlan,
842 .get = get_vlan,
843 .set = set_vlan,
846 /* --- pointer --- */
848 /* Not a proper property, just for dirty hacks. TODO Remove it! */
849 PropertyInfo qdev_prop_ptr = {
850 .name = "ptr",
851 .type = PROP_TYPE_PTR,
852 .size = sizeof(void*),
855 /* --- mac address --- */
858 * accepted syntax versions:
859 * 01:02:03:04:05:06
860 * 01-02-03-04-05-06
862 static int parse_mac(DeviceState *dev, Property *prop, const char *str)
864 MACAddr *mac = qdev_get_prop_ptr(dev, prop);
865 int i, pos;
866 char *p;
868 for (i = 0, pos = 0; i < 6; i++, pos += 3) {
869 if (!qemu_isxdigit(str[pos]))
870 return -EINVAL;
871 if (!qemu_isxdigit(str[pos+1]))
872 return -EINVAL;
873 if (i == 5) {
874 if (str[pos+2] != '\0')
875 return -EINVAL;
876 } else {
877 if (str[pos+2] != ':' && str[pos+2] != '-')
878 return -EINVAL;
880 mac->a[i] = strtol(str+pos, &p, 16);
882 return 0;
885 static int print_mac(DeviceState *dev, Property *prop, char *dest, size_t len)
887 MACAddr *mac = qdev_get_prop_ptr(dev, prop);
889 return snprintf(dest, len, "%02x:%02x:%02x:%02x:%02x:%02x",
890 mac->a[0], mac->a[1], mac->a[2],
891 mac->a[3], mac->a[4], mac->a[5]);
894 PropertyInfo qdev_prop_macaddr = {
895 .name = "macaddr",
896 .type = PROP_TYPE_MACADDR,
897 .size = sizeof(MACAddr),
898 .parse = parse_mac,
899 .print = print_mac,
900 .get = get_generic,
901 .set = set_generic,
905 /* --- lost tick policy --- */
907 static const struct {
908 const char *name;
909 LostTickPolicy code;
910 } lost_tick_policy_table[] = {
911 { .name = "discard", .code = LOST_TICK_DISCARD },
912 { .name = "delay", .code = LOST_TICK_DELAY },
913 { .name = "merge", .code = LOST_TICK_MERGE },
914 { .name = "slew", .code = LOST_TICK_SLEW },
917 static int parse_lost_tick_policy(DeviceState *dev, Property *prop,
918 const char *str)
920 LostTickPolicy *ptr = qdev_get_prop_ptr(dev, prop);
921 int i;
923 for (i = 0; i < ARRAY_SIZE(lost_tick_policy_table); i++) {
924 if (!strcasecmp(str, lost_tick_policy_table[i].name)) {
925 *ptr = lost_tick_policy_table[i].code;
926 break;
929 if (i == ARRAY_SIZE(lost_tick_policy_table)) {
930 return -EINVAL;
932 return 0;
935 static int print_lost_tick_policy(DeviceState *dev, Property *prop, char *dest,
936 size_t len)
938 LostTickPolicy *ptr = qdev_get_prop_ptr(dev, prop);
940 return snprintf(dest, len, "%s", lost_tick_policy_table[*ptr].name);
943 PropertyInfo qdev_prop_losttickpolicy = {
944 .name = "lost_tick_policy",
945 .type = PROP_TYPE_LOSTTICKPOLICY,
946 .size = sizeof(LostTickPolicy),
947 .parse = parse_lost_tick_policy,
948 .print = print_lost_tick_policy,
949 .get = get_generic,
950 .set = set_generic,
953 /* --- pci address --- */
956 * bus-local address, i.e. "$slot" or "$slot.$fn"
958 static int parse_pci_devfn(DeviceState *dev, Property *prop, const char *str)
960 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
961 unsigned int slot, fn, n;
963 if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
964 fn = 0;
965 if (sscanf(str, "%x%n", &slot, &n) != 1) {
966 return -EINVAL;
969 if (str[n] != '\0')
970 return -EINVAL;
971 if (fn > 7)
972 return -EINVAL;
973 if (slot > 31)
974 return -EINVAL;
975 *ptr = slot << 3 | fn;
976 return 0;
979 static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
981 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
983 if (*ptr == -1) {
984 return snprintf(dest, len, "<unset>");
985 } else {
986 return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
990 static void get_pci_devfn(Object *obj, Visitor *v, void *opaque,
991 const char *name, Error **errp)
993 DeviceState *dev = DEVICE(obj);
994 Property *prop = opaque;
995 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
996 char buffer[32];
997 char *p = buffer;
999 buffer[0] = 0;
1000 if (*ptr != -1) {
1001 snprintf(buffer, sizeof(buffer), "%02x.%x", *ptr >> 3, *ptr & 7);
1003 visit_type_str(v, &p, name, errp);
1006 PropertyInfo qdev_prop_pci_devfn = {
1007 .name = "pci-devfn",
1008 .type = PROP_TYPE_UINT32,
1009 .size = sizeof(uint32_t),
1010 .parse = parse_pci_devfn,
1011 .print = print_pci_devfn,
1012 .get = get_pci_devfn,
1013 .set = set_generic,
1016 /* --- public helpers --- */
1018 static Property *qdev_prop_walk(Property *props, const char *name)
1020 if (!props)
1021 return NULL;
1022 while (props->name) {
1023 if (strcmp(props->name, name) == 0)
1024 return props;
1025 props++;
1027 return NULL;
1030 static Property *qdev_prop_find(DeviceState *dev, const char *name)
1032 Property *prop;
1034 /* device properties */
1035 prop = qdev_prop_walk(qdev_get_props(dev), name);
1036 if (prop)
1037 return prop;
1039 /* bus properties */
1040 prop = qdev_prop_walk(dev->parent_bus->info->props, name);
1041 if (prop)
1042 return prop;
1044 return NULL;
1047 int qdev_prop_exists(DeviceState *dev, const char *name)
1049 return qdev_prop_find(dev, name) ? true : false;
1052 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
1053 Property *prop, const char *value)
1055 switch (ret) {
1056 case -EEXIST:
1057 error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
1058 object_get_typename(OBJECT(dev)), prop->name, value);
1059 break;
1060 default:
1061 case -EINVAL:
1062 error_set(errp, QERR_PROPERTY_VALUE_BAD,
1063 object_get_typename(OBJECT(dev)), prop->name, value);
1064 break;
1065 case -ENOENT:
1066 error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
1067 object_get_typename(OBJECT(dev)), prop->name, value);
1068 break;
1069 case 0:
1070 break;
1074 int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
1076 Property *prop;
1077 int ret;
1079 prop = qdev_prop_find(dev, name);
1081 * TODO Properties without a parse method are just for dirty
1082 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
1083 * marked for removal. The test !prop->info->parse should be
1084 * removed along with it.
1086 if (!prop || !prop->info->parse) {
1087 qerror_report(QERR_PROPERTY_NOT_FOUND, object_get_typename(OBJECT(dev)), name);
1088 return -1;
1090 ret = prop->info->parse(dev, prop, value);
1091 if (ret < 0) {
1092 Error *err;
1093 error_set_from_qdev_prop_error(&err, ret, dev, prop, value);
1094 qerror_report_err(err);
1095 error_free(err);
1096 return -1;
1098 return 0;
1101 void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
1103 Property *prop;
1105 prop = qdev_prop_find(dev, name);
1106 if (!prop) {
1107 fprintf(stderr, "%s: property \"%s.%s\" not found\n",
1108 __FUNCTION__, object_get_typename(OBJECT(dev)), name);
1109 abort();
1111 if (prop->info->type != type) {
1112 fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n",
1113 __FUNCTION__, object_get_typename(OBJECT(dev)), name);
1114 abort();
1116 qdev_prop_cpy(dev, prop, src);
1119 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1121 qdev_prop_set(dev, name, &value, PROP_TYPE_BIT);
1124 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1126 qdev_prop_set(dev, name, &value, PROP_TYPE_UINT8);
1129 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1131 qdev_prop_set(dev, name, &value, PROP_TYPE_UINT16);
1134 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1136 qdev_prop_set(dev, name, &value, PROP_TYPE_UINT32);
1139 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1141 qdev_prop_set(dev, name, &value, PROP_TYPE_INT32);
1144 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1146 qdev_prop_set(dev, name, &value, PROP_TYPE_UINT64);
1149 void qdev_prop_set_string(DeviceState *dev, const char *name, char *value)
1151 qdev_prop_set(dev, name, &value, PROP_TYPE_STRING);
1154 int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
1156 int res;
1158 res = bdrv_attach_dev(value, dev);
1159 if (res < 0) {
1160 error_report("Can't attach drive %s to %s.%s: %s",
1161 bdrv_get_device_name(value),
1162 dev->id ? dev->id : object_get_typename(OBJECT(dev)),
1163 name, strerror(-res));
1164 return -1;
1166 qdev_prop_set(dev, name, &value, PROP_TYPE_DRIVE);
1167 return 0;
1170 void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value)
1172 if (qdev_prop_set_drive(dev, name, value) < 0) {
1173 exit(1);
1176 void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
1178 qdev_prop_set(dev, name, &value, PROP_TYPE_CHR);
1181 void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value)
1183 qdev_prop_set(dev, name, &value, PROP_TYPE_NETDEV);
1186 void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
1188 qdev_prop_set(dev, name, &value, PROP_TYPE_VLAN);
1191 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
1193 qdev_prop_set(dev, name, value, PROP_TYPE_MACADDR);
1196 void qdev_prop_set_losttickpolicy(DeviceState *dev, const char *name,
1197 LostTickPolicy *value)
1199 qdev_prop_set(dev, name, value, PROP_TYPE_LOSTTICKPOLICY);
1202 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1204 qdev_prop_set(dev, name, &value, PROP_TYPE_PTR);
1207 void qdev_prop_set_defaults(DeviceState *dev, Property *props)
1209 if (!props)
1210 return;
1211 while (props->name) {
1212 if (props->defval) {
1213 qdev_prop_cpy(dev, props, props->defval);
1215 props++;
1219 static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
1221 static void qdev_prop_register_global(GlobalProperty *prop)
1223 QTAILQ_INSERT_TAIL(&global_props, prop, next);
1226 void qdev_prop_register_global_list(GlobalProperty *props)
1228 int i;
1230 for (i = 0; props[i].driver != NULL; i++) {
1231 qdev_prop_register_global(props+i);
1235 void qdev_prop_set_globals(DeviceState *dev)
1237 GlobalProperty *prop;
1239 QTAILQ_FOREACH(prop, &global_props, next) {
1240 if (strcmp(object_get_typename(OBJECT(dev)), prop->driver) != 0 &&
1241 strcmp(qdev_get_bus_info(dev)->name, prop->driver) != 0) {
1242 continue;
1244 if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
1245 exit(1);
1250 static int qdev_add_one_global(QemuOpts *opts, void *opaque)
1252 GlobalProperty *g;
1254 g = g_malloc0(sizeof(*g));
1255 g->driver = qemu_opt_get(opts, "driver");
1256 g->property = qemu_opt_get(opts, "property");
1257 g->value = qemu_opt_get(opts, "value");
1258 qdev_prop_register_global(g);
1259 return 0;
1262 void qemu_add_globals(void)
1264 qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0);