usb-musb: switch to usb_find_device()
[qemu/kevin.git] / hw / qdev-properties.c
blobb6d6fcff011431180664a6dc7b761111427639a4
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 == &qdev_prop_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 /* Bit */
30 static int parse_bit(DeviceState *dev, Property *prop, const char *str)
32 if (!strcasecmp(str, "on"))
33 bit_prop_set(dev, prop, true);
34 else if (!strcasecmp(str, "off"))
35 bit_prop_set(dev, prop, false);
36 else
37 return -EINVAL;
38 return 0;
41 static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
43 uint32_t *p = qdev_get_prop_ptr(dev, prop);
44 return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
47 static void get_bit(Object *obj, Visitor *v, void *opaque,
48 const char *name, Error **errp)
50 DeviceState *dev = DEVICE(obj);
51 Property *prop = opaque;
52 uint32_t *p = qdev_get_prop_ptr(dev, prop);
53 bool value = (*p & qdev_get_prop_mask(prop)) != 0;
55 visit_type_bool(v, &value, name, errp);
58 static void set_bit(Object *obj, Visitor *v, void *opaque,
59 const char *name, Error **errp)
61 DeviceState *dev = DEVICE(obj);
62 Property *prop = opaque;
63 Error *local_err = NULL;
64 bool value;
66 if (dev->state != DEV_STATE_CREATED) {
67 error_set(errp, QERR_PERMISSION_DENIED);
68 return;
71 visit_type_bool(v, &value, name, &local_err);
72 if (local_err) {
73 error_propagate(errp, local_err);
74 return;
76 bit_prop_set(dev, prop, value);
79 PropertyInfo qdev_prop_bit = {
80 .name = "boolean",
81 .legacy_name = "on/off",
82 .parse = parse_bit,
83 .print = print_bit,
84 .get = get_bit,
85 .set = set_bit,
88 /* --- 8bit integer --- */
90 static int parse_uint8(DeviceState *dev, Property *prop, const char *str)
92 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
93 char *end;
95 /* accept both hex and decimal */
96 *ptr = strtoul(str, &end, 0);
97 if ((*end != '\0') || (end == str)) {
98 return -EINVAL;
101 return 0;
104 static int print_uint8(DeviceState *dev, Property *prop, char *dest, size_t len)
106 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
107 return snprintf(dest, len, "%" PRIu8, *ptr);
110 static void get_int8(Object *obj, Visitor *v, void *opaque,
111 const char *name, Error **errp)
113 DeviceState *dev = DEVICE(obj);
114 Property *prop = opaque;
115 int8_t *ptr = qdev_get_prop_ptr(dev, prop);
116 int64_t value;
118 value = *ptr;
119 visit_type_int(v, &value, name, errp);
122 static void set_int8(Object *obj, Visitor *v, void *opaque,
123 const char *name, Error **errp)
125 DeviceState *dev = DEVICE(obj);
126 Property *prop = opaque;
127 int8_t *ptr = qdev_get_prop_ptr(dev, prop);
128 Error *local_err = NULL;
129 int64_t value;
131 if (dev->state != DEV_STATE_CREATED) {
132 error_set(errp, QERR_PERMISSION_DENIED);
133 return;
136 visit_type_int(v, &value, name, &local_err);
137 if (local_err) {
138 error_propagate(errp, local_err);
139 return;
141 if (value >= prop->info->min && value <= prop->info->max) {
142 *ptr = value;
143 } else {
144 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
145 dev->id?:"", name, value, prop->info->min,
146 prop->info->max);
150 PropertyInfo qdev_prop_uint8 = {
151 .name = "uint8",
152 .parse = parse_uint8,
153 .print = print_uint8,
154 .get = get_int8,
155 .set = set_int8,
156 .min = 0,
157 .max = 255,
160 /* --- 8bit hex value --- */
162 static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
164 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
165 char *end;
167 *ptr = strtoul(str, &end, 16);
168 if ((*end != '\0') || (end == str)) {
169 return -EINVAL;
172 return 0;
175 static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
177 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
178 return snprintf(dest, len, "0x%" PRIx8, *ptr);
181 PropertyInfo qdev_prop_hex8 = {
182 .name = "uint8",
183 .legacy_name = "hex8",
184 .parse = parse_hex8,
185 .print = print_hex8,
186 .get = get_int8,
187 .set = set_int8,
188 .min = 0,
189 .max = 255,
192 /* --- 16bit integer --- */
194 static int parse_uint16(DeviceState *dev, Property *prop, const char *str)
196 uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
197 char *end;
199 /* accept both hex and decimal */
200 *ptr = strtoul(str, &end, 0);
201 if ((*end != '\0') || (end == str)) {
202 return -EINVAL;
205 return 0;
208 static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len)
210 uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
211 return snprintf(dest, len, "%" PRIu16, *ptr);
214 static void get_int16(Object *obj, Visitor *v, void *opaque,
215 const char *name, Error **errp)
217 DeviceState *dev = DEVICE(obj);
218 Property *prop = opaque;
219 int16_t *ptr = qdev_get_prop_ptr(dev, prop);
220 int64_t value;
222 value = *ptr;
223 visit_type_int(v, &value, name, errp);
226 static void set_int16(Object *obj, Visitor *v, void *opaque,
227 const char *name, Error **errp)
229 DeviceState *dev = DEVICE(obj);
230 Property *prop = opaque;
231 int16_t *ptr = qdev_get_prop_ptr(dev, prop);
232 Error *local_err = NULL;
233 int64_t value;
235 if (dev->state != DEV_STATE_CREATED) {
236 error_set(errp, QERR_PERMISSION_DENIED);
237 return;
240 visit_type_int(v, &value, name, &local_err);
241 if (local_err) {
242 error_propagate(errp, local_err);
243 return;
245 if (value >= prop->info->min && value <= prop->info->max) {
246 *ptr = value;
247 } else {
248 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
249 dev->id?:"", name, value, prop->info->min,
250 prop->info->max);
254 PropertyInfo qdev_prop_uint16 = {
255 .name = "uint16",
256 .parse = parse_uint16,
257 .print = print_uint16,
258 .get = get_int16,
259 .set = set_int16,
260 .min = 0,
261 .max = 65535,
264 /* --- 32bit integer --- */
266 static int parse_uint32(DeviceState *dev, Property *prop, const char *str)
268 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
269 char *end;
271 /* accept both hex and decimal */
272 *ptr = strtoul(str, &end, 0);
273 if ((*end != '\0') || (end == str)) {
274 return -EINVAL;
277 return 0;
280 static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len)
282 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
283 return snprintf(dest, len, "%" PRIu32, *ptr);
286 static void get_int32(Object *obj, Visitor *v, void *opaque,
287 const char *name, Error **errp)
289 DeviceState *dev = DEVICE(obj);
290 Property *prop = opaque;
291 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
292 int64_t value;
294 value = *ptr;
295 visit_type_int(v, &value, name, errp);
298 static void set_int32(Object *obj, Visitor *v, void *opaque,
299 const char *name, Error **errp)
301 DeviceState *dev = DEVICE(obj);
302 Property *prop = opaque;
303 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
304 Error *local_err = NULL;
305 int64_t value;
307 if (dev->state != DEV_STATE_CREATED) {
308 error_set(errp, QERR_PERMISSION_DENIED);
309 return;
312 visit_type_int(v, &value, name, &local_err);
313 if (local_err) {
314 error_propagate(errp, local_err);
315 return;
317 if (value >= prop->info->min && value <= prop->info->max) {
318 *ptr = value;
319 } else {
320 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
321 dev->id?:"", name, value, prop->info->min,
322 prop->info->max);
326 PropertyInfo qdev_prop_uint32 = {
327 .name = "uint32",
328 .parse = parse_uint32,
329 .print = print_uint32,
330 .get = get_int32,
331 .set = set_int32,
332 .min = 0,
333 .max = 0xFFFFFFFFULL,
336 static int parse_int32(DeviceState *dev, Property *prop, const char *str)
338 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
339 char *end;
341 *ptr = strtol(str, &end, 10);
342 if ((*end != '\0') || (end == str)) {
343 return -EINVAL;
346 return 0;
349 static int print_int32(DeviceState *dev, Property *prop, char *dest, size_t len)
351 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
352 return snprintf(dest, len, "%" PRId32, *ptr);
355 PropertyInfo qdev_prop_int32 = {
356 .name = "int32",
357 .parse = parse_int32,
358 .print = print_int32,
359 .get = get_int32,
360 .set = set_int32,
361 .min = -0x80000000LL,
362 .max = 0x7FFFFFFFLL,
365 /* --- 32bit hex value --- */
367 static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
369 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
370 char *end;
372 *ptr = strtoul(str, &end, 16);
373 if ((*end != '\0') || (end == str)) {
374 return -EINVAL;
377 return 0;
380 static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
382 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
383 return snprintf(dest, len, "0x%" PRIx32, *ptr);
386 PropertyInfo qdev_prop_hex32 = {
387 .name = "uint32",
388 .legacy_name = "hex32",
389 .parse = parse_hex32,
390 .print = print_hex32,
391 .get = get_int32,
392 .set = set_int32,
393 .min = 0,
394 .max = 0xFFFFFFFFULL,
397 /* --- 64bit integer --- */
399 static int parse_uint64(DeviceState *dev, Property *prop, const char *str)
401 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
402 char *end;
404 /* accept both hex and decimal */
405 *ptr = strtoull(str, &end, 0);
406 if ((*end != '\0') || (end == str)) {
407 return -EINVAL;
410 return 0;
413 static int print_uint64(DeviceState *dev, Property *prop, char *dest, size_t len)
415 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
416 return snprintf(dest, len, "%" PRIu64, *ptr);
419 static void get_int64(Object *obj, Visitor *v, void *opaque,
420 const char *name, Error **errp)
422 DeviceState *dev = DEVICE(obj);
423 Property *prop = opaque;
424 int64_t *ptr = qdev_get_prop_ptr(dev, prop);
426 visit_type_int(v, ptr, name, errp);
429 static void set_int64(Object *obj, Visitor *v, void *opaque,
430 const char *name, Error **errp)
432 DeviceState *dev = DEVICE(obj);
433 Property *prop = opaque;
434 int64_t *ptr = qdev_get_prop_ptr(dev, prop);
436 if (dev->state != DEV_STATE_CREATED) {
437 error_set(errp, QERR_PERMISSION_DENIED);
438 return;
441 visit_type_int(v, ptr, name, errp);
444 PropertyInfo qdev_prop_uint64 = {
445 .name = "uint64",
446 .parse = parse_uint64,
447 .print = print_uint64,
448 .get = get_int64,
449 .set = set_int64,
452 /* --- 64bit hex value --- */
454 static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
456 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
457 char *end;
459 *ptr = strtoull(str, &end, 16);
460 if ((*end != '\0') || (end == str)) {
461 return -EINVAL;
464 return 0;
467 static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
469 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
470 return snprintf(dest, len, "0x%" PRIx64, *ptr);
473 PropertyInfo qdev_prop_hex64 = {
474 .name = "uint64",
475 .legacy_name = "hex64",
476 .parse = parse_hex64,
477 .print = print_hex64,
478 .get = get_int64,
479 .set = set_int64,
482 /* --- string --- */
484 static void release_string(Object *obj, const char *name, void *opaque)
486 Property *prop = opaque;
487 g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
490 static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
492 char **ptr = qdev_get_prop_ptr(dev, prop);
493 if (!*ptr)
494 return snprintf(dest, len, "<null>");
495 return snprintf(dest, len, "\"%s\"", *ptr);
498 static void get_string(Object *obj, Visitor *v, void *opaque,
499 const char *name, Error **errp)
501 DeviceState *dev = DEVICE(obj);
502 Property *prop = opaque;
503 char **ptr = qdev_get_prop_ptr(dev, prop);
505 if (!*ptr) {
506 char *str = (char *)"";
507 visit_type_str(v, &str, name, errp);
508 } else {
509 visit_type_str(v, ptr, name, errp);
513 static void set_string(Object *obj, Visitor *v, void *opaque,
514 const char *name, Error **errp)
516 DeviceState *dev = DEVICE(obj);
517 Property *prop = opaque;
518 char **ptr = qdev_get_prop_ptr(dev, prop);
519 Error *local_err = NULL;
520 char *str;
522 if (dev->state != DEV_STATE_CREATED) {
523 error_set(errp, QERR_PERMISSION_DENIED);
524 return;
527 visit_type_str(v, &str, name, &local_err);
528 if (local_err) {
529 error_propagate(errp, local_err);
530 return;
532 if (!*str) {
533 g_free(str);
534 str = NULL;
536 if (*ptr) {
537 g_free(*ptr);
539 *ptr = str;
542 PropertyInfo qdev_prop_string = {
543 .name = "string",
544 .print = print_string,
545 .release = release_string,
546 .get = get_string,
547 .set = set_string,
550 /* --- drive --- */
552 static int parse_drive(DeviceState *dev, const char *str, void **ptr)
554 BlockDriverState *bs;
556 bs = bdrv_find(str);
557 if (bs == NULL)
558 return -ENOENT;
559 if (bdrv_attach_dev(bs, dev) < 0)
560 return -EEXIST;
561 *ptr = bs;
562 return 0;
565 static void release_drive(Object *obj, const char *name, void *opaque)
567 DeviceState *dev = DEVICE(obj);
568 Property *prop = opaque;
569 BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
571 if (*ptr) {
572 bdrv_detach_dev(*ptr, dev);
573 blockdev_auto_del(*ptr);
577 static const char *print_drive(void *ptr)
579 return bdrv_get_device_name(ptr);
582 static void get_pointer(Object *obj, Visitor *v, Property *prop,
583 const char *(*print)(void *ptr),
584 const char *name, Error **errp)
586 DeviceState *dev = DEVICE(obj);
587 void **ptr = qdev_get_prop_ptr(dev, prop);
588 char *p;
590 p = (char *) (*ptr ? print(*ptr) : "");
591 visit_type_str(v, &p, name, errp);
594 static void set_pointer(Object *obj, Visitor *v, Property *prop,
595 int (*parse)(DeviceState *dev, const char *str, void **ptr),
596 const char *name, Error **errp)
598 DeviceState *dev = DEVICE(obj);
599 Error *local_err = NULL;
600 void **ptr = qdev_get_prop_ptr(dev, prop);
601 char *str;
602 int ret;
604 if (dev->state != DEV_STATE_CREATED) {
605 error_set(errp, QERR_PERMISSION_DENIED);
606 return;
609 visit_type_str(v, &str, name, &local_err);
610 if (local_err) {
611 error_propagate(errp, local_err);
612 return;
614 if (!*str) {
615 g_free(str);
616 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
617 return;
619 ret = parse(dev, str, ptr);
620 error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
621 g_free(str);
624 static void get_drive(Object *obj, Visitor *v, void *opaque,
625 const char *name, Error **errp)
627 get_pointer(obj, v, opaque, print_drive, name, errp);
630 static void set_drive(Object *obj, Visitor *v, void *opaque,
631 const char *name, Error **errp)
633 set_pointer(obj, v, opaque, parse_drive, name, errp);
636 PropertyInfo qdev_prop_drive = {
637 .name = "drive",
638 .get = get_drive,
639 .set = set_drive,
640 .release = release_drive,
643 /* --- character device --- */
645 static int parse_chr(DeviceState *dev, const char *str, void **ptr)
647 CharDriverState *chr = qemu_chr_find(str);
648 if (chr == NULL) {
649 return -ENOENT;
651 if (chr->avail_connections < 1) {
652 return -EEXIST;
654 *ptr = chr;
655 --chr->avail_connections;
656 return 0;
659 static void release_chr(Object *obj, const char *name, void *opaque)
661 DeviceState *dev = DEVICE(obj);
662 Property *prop = opaque;
663 CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
665 if (*ptr) {
666 qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL);
671 static const char *print_chr(void *ptr)
673 CharDriverState *chr = ptr;
675 return chr->label ? chr->label : "";
678 static void get_chr(Object *obj, Visitor *v, void *opaque,
679 const char *name, Error **errp)
681 get_pointer(obj, v, opaque, print_chr, name, errp);
684 static void set_chr(Object *obj, Visitor *v, void *opaque,
685 const char *name, Error **errp)
687 set_pointer(obj, v, opaque, parse_chr, name, errp);
690 PropertyInfo qdev_prop_chr = {
691 .name = "chr",
692 .get = get_chr,
693 .set = set_chr,
694 .release = release_chr,
697 /* --- netdev device --- */
699 static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
701 VLANClientState *netdev = qemu_find_netdev(str);
703 if (netdev == NULL) {
704 return -ENOENT;
706 if (netdev->peer) {
707 return -EEXIST;
709 *ptr = netdev;
710 return 0;
713 static const char *print_netdev(void *ptr)
715 VLANClientState *netdev = ptr;
717 return netdev->name ? netdev->name : "";
720 static void get_netdev(Object *obj, Visitor *v, void *opaque,
721 const char *name, Error **errp)
723 get_pointer(obj, v, opaque, print_netdev, name, errp);
726 static void set_netdev(Object *obj, Visitor *v, void *opaque,
727 const char *name, Error **errp)
729 set_pointer(obj, v, opaque, parse_netdev, name, errp);
732 PropertyInfo qdev_prop_netdev = {
733 .name = "netdev",
734 .get = get_netdev,
735 .set = set_netdev,
738 /* --- vlan --- */
740 static int parse_vlan(DeviceState *dev, Property *prop, const char *str)
742 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
743 int id;
745 if (sscanf(str, "%d", &id) != 1)
746 return -EINVAL;
747 *ptr = qemu_find_vlan(id, 1);
748 if (*ptr == NULL)
749 return -ENOENT;
750 return 0;
753 static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
755 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
757 if (*ptr) {
758 return snprintf(dest, len, "%d", (*ptr)->id);
759 } else {
760 return snprintf(dest, len, "<null>");
764 static void get_vlan(Object *obj, Visitor *v, void *opaque,
765 const char *name, Error **errp)
767 DeviceState *dev = DEVICE(obj);
768 Property *prop = opaque;
769 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
770 int64_t id;
772 id = *ptr ? (*ptr)->id : -1;
773 visit_type_int(v, &id, name, errp);
776 static void set_vlan(Object *obj, Visitor *v, void *opaque,
777 const char *name, Error **errp)
779 DeviceState *dev = DEVICE(obj);
780 Property *prop = opaque;
781 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
782 Error *local_err = NULL;
783 int64_t id;
784 VLANState *vlan;
786 if (dev->state != DEV_STATE_CREATED) {
787 error_set(errp, QERR_PERMISSION_DENIED);
788 return;
791 visit_type_int(v, &id, name, &local_err);
792 if (local_err) {
793 error_propagate(errp, local_err);
794 return;
796 if (id == -1) {
797 *ptr = NULL;
798 return;
800 vlan = qemu_find_vlan(id, 1);
801 if (!vlan) {
802 error_set(errp, QERR_INVALID_PARAMETER_VALUE,
803 name, prop->info->name);
804 return;
806 *ptr = vlan;
809 PropertyInfo qdev_prop_vlan = {
810 .name = "vlan",
811 .parse = parse_vlan,
812 .print = print_vlan,
813 .get = get_vlan,
814 .set = set_vlan,
817 /* --- pointer --- */
819 /* Not a proper property, just for dirty hacks. TODO Remove it! */
820 PropertyInfo qdev_prop_ptr = {
821 .name = "ptr",
824 /* --- mac address --- */
827 * accepted syntax versions:
828 * 01:02:03:04:05:06
829 * 01-02-03-04-05-06
831 static void get_mac(Object *obj, Visitor *v, void *opaque,
832 const char *name, Error **errp)
834 DeviceState *dev = DEVICE(obj);
835 Property *prop = opaque;
836 MACAddr *mac = qdev_get_prop_ptr(dev, prop);
837 char buffer[2 * 6 + 5 + 1];
838 char *p = buffer;
840 snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
841 mac->a[0], mac->a[1], mac->a[2],
842 mac->a[3], mac->a[4], mac->a[5]);
844 visit_type_str(v, &p, name, errp);
847 static void set_mac(Object *obj, Visitor *v, void *opaque,
848 const char *name, Error **errp)
850 DeviceState *dev = DEVICE(obj);
851 Property *prop = opaque;
852 MACAddr *mac = qdev_get_prop_ptr(dev, prop);
853 Error *local_err = NULL;
854 int i, pos;
855 char *str, *p;
857 if (dev->state != DEV_STATE_CREATED) {
858 error_set(errp, QERR_PERMISSION_DENIED);
859 return;
862 visit_type_str(v, &str, name, &local_err);
863 if (local_err) {
864 error_propagate(errp, local_err);
865 return;
868 for (i = 0, pos = 0; i < 6; i++, pos += 3) {
869 if (!qemu_isxdigit(str[pos]))
870 goto inval;
871 if (!qemu_isxdigit(str[pos+1]))
872 goto inval;
873 if (i == 5) {
874 if (str[pos+2] != '\0')
875 goto inval;
876 } else {
877 if (str[pos+2] != ':' && str[pos+2] != '-')
878 goto inval;
880 mac->a[i] = strtol(str+pos, &p, 16);
882 return;
884 inval:
885 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
888 PropertyInfo qdev_prop_macaddr = {
889 .name = "macaddr",
890 .get = get_mac,
891 .set = set_mac,
895 /* --- lost tick policy --- */
897 static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
898 [LOST_TICK_DISCARD] = "discard",
899 [LOST_TICK_DELAY] = "delay",
900 [LOST_TICK_MERGE] = "merge",
901 [LOST_TICK_SLEW] = "slew",
902 [LOST_TICK_MAX] = NULL,
905 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
907 static void get_enum(Object *obj, Visitor *v, void *opaque,
908 const char *name, Error **errp)
910 DeviceState *dev = DEVICE(obj);
911 Property *prop = opaque;
912 int *ptr = qdev_get_prop_ptr(dev, prop);
914 visit_type_enum(v, ptr, prop->info->enum_table,
915 prop->info->name, prop->name, errp);
918 static void set_enum(Object *obj, Visitor *v, void *opaque,
919 const char *name, Error **errp)
921 DeviceState *dev = DEVICE(obj);
922 Property *prop = opaque;
923 int *ptr = qdev_get_prop_ptr(dev, prop);
925 if (dev->state != DEV_STATE_CREATED) {
926 error_set(errp, QERR_PERMISSION_DENIED);
927 return;
930 visit_type_enum(v, ptr, prop->info->enum_table,
931 prop->info->name, prop->name, errp);
934 PropertyInfo qdev_prop_losttickpolicy = {
935 .name = "LostTickPolicy",
936 .enum_table = lost_tick_policy_table,
937 .get = get_enum,
938 .set = set_enum,
941 /* --- pci address --- */
944 * bus-local address, i.e. "$slot" or "$slot.$fn"
946 static int parse_pci_devfn(DeviceState *dev, Property *prop, const char *str)
948 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
949 unsigned int slot, fn, n;
951 if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
952 fn = 0;
953 if (sscanf(str, "%x%n", &slot, &n) != 1) {
954 return -EINVAL;
957 if (str[n] != '\0')
958 return -EINVAL;
959 if (fn > 7)
960 return -EINVAL;
961 if (slot > 31)
962 return -EINVAL;
963 *ptr = slot << 3 | fn;
964 return 0;
967 static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
969 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
971 if (*ptr == -1) {
972 return snprintf(dest, len, "<unset>");
973 } else {
974 return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
978 PropertyInfo qdev_prop_pci_devfn = {
979 .name = "int32",
980 .legacy_name = "pci-devfn",
981 .parse = parse_pci_devfn,
982 .print = print_pci_devfn,
983 .get = get_int32,
984 .set = set_int32,
985 /* FIXME: this should be -1...255, but the address is stored
986 * into an uint32_t rather than int32_t.
988 .min = 0,
989 .max = 0xFFFFFFFFULL,
992 /* --- public helpers --- */
994 static Property *qdev_prop_walk(Property *props, const char *name)
996 if (!props)
997 return NULL;
998 while (props->name) {
999 if (strcmp(props->name, name) == 0)
1000 return props;
1001 props++;
1003 return NULL;
1006 static Property *qdev_prop_find(DeviceState *dev, const char *name)
1008 Property *prop;
1010 /* device properties */
1011 prop = qdev_prop_walk(qdev_get_props(dev), name);
1012 if (prop)
1013 return prop;
1015 /* bus properties */
1016 prop = qdev_prop_walk(dev->parent_bus->info->props, name);
1017 if (prop)
1018 return prop;
1020 return NULL;
1023 int qdev_prop_exists(DeviceState *dev, const char *name)
1025 return qdev_prop_find(dev, name) ? true : false;
1028 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
1029 Property *prop, const char *value)
1031 switch (ret) {
1032 case -EEXIST:
1033 error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
1034 object_get_typename(OBJECT(dev)), prop->name, value);
1035 break;
1036 default:
1037 case -EINVAL:
1038 error_set(errp, QERR_PROPERTY_VALUE_BAD,
1039 object_get_typename(OBJECT(dev)), prop->name, value);
1040 break;
1041 case -ENOENT:
1042 error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
1043 object_get_typename(OBJECT(dev)), prop->name, value);
1044 break;
1045 case 0:
1046 break;
1050 int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
1052 char *legacy_name;
1053 Error *err = NULL;
1055 legacy_name = g_strdup_printf("legacy-%s", name);
1056 if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
1057 object_property_set_str(OBJECT(dev), value, legacy_name, &err);
1058 } else {
1059 object_property_set_str(OBJECT(dev), value, name, &err);
1061 g_free(legacy_name);
1063 if (err) {
1064 qerror_report_err(err);
1065 error_free(err);
1066 return -1;
1068 return 0;
1071 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1073 Error *errp = NULL;
1074 object_property_set_bool(OBJECT(dev), value, name, &errp);
1075 assert(!errp);
1078 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1080 Error *errp = NULL;
1081 object_property_set_int(OBJECT(dev), value, name, &errp);
1082 assert(!errp);
1085 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1087 Error *errp = NULL;
1088 object_property_set_int(OBJECT(dev), value, name, &errp);
1089 assert(!errp);
1092 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1094 Error *errp = NULL;
1095 object_property_set_int(OBJECT(dev), value, name, &errp);
1096 assert(!errp);
1099 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1101 Error *errp = NULL;
1102 object_property_set_int(OBJECT(dev), value, name, &errp);
1103 assert(!errp);
1106 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1108 Error *errp = NULL;
1109 object_property_set_int(OBJECT(dev), value, name, &errp);
1110 assert(!errp);
1113 void qdev_prop_set_string(DeviceState *dev, const char *name, char *value)
1115 Error *errp = NULL;
1116 object_property_set_str(OBJECT(dev), value, name, &errp);
1117 assert(!errp);
1120 int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
1122 Error *errp = NULL;
1123 object_property_set_str(OBJECT(dev), bdrv_get_device_name(value),
1124 name, &errp);
1125 if (errp) {
1126 qerror_report_err(errp);
1127 error_free(errp);
1128 return -1;
1130 return 0;
1133 void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value)
1135 if (qdev_prop_set_drive(dev, name, value) < 0) {
1136 exit(1);
1139 void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
1141 Error *errp = NULL;
1142 assert(value->label);
1143 object_property_set_str(OBJECT(dev), value->label, name, &errp);
1144 assert(!errp);
1147 void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value)
1149 Error *errp = NULL;
1150 assert(value->name);
1151 object_property_set_str(OBJECT(dev), value->name, name, &errp);
1152 assert(!errp);
1155 void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
1157 Error *errp = NULL;
1158 object_property_set_int(OBJECT(dev), value ? value->id : -1, name, &errp);
1159 assert(!errp);
1162 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
1164 Error *errp = NULL;
1165 char str[2 * 6 + 5 + 1];
1166 snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1167 value[0], value[1], value[2], value[3], value[4], value[5]);
1169 object_property_set_str(OBJECT(dev), str, name, &errp);
1170 assert(!errp);
1173 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1175 Property *prop;
1176 Error *errp = NULL;
1178 prop = qdev_prop_find(dev, name);
1179 object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
1180 name, &errp);
1181 assert(!errp);
1184 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1186 Property *prop;
1187 void **ptr;
1189 prop = qdev_prop_find(dev, name);
1190 assert(prop && prop->info == &qdev_prop_ptr);
1191 ptr = qdev_get_prop_ptr(dev, prop);
1192 *ptr = value;
1195 void qdev_prop_set_defaults(DeviceState *dev, Property *props)
1197 Object *obj = OBJECT(dev);
1198 if (!props)
1199 return;
1200 for (; props->name; props++) {
1201 Error *errp = NULL;
1202 if (props->qtype == QTYPE_NONE) {
1203 continue;
1205 if (props->qtype == QTYPE_QBOOL) {
1206 object_property_set_bool(obj, props->defval, props->name, &errp);
1207 } else if (props->info->enum_table) {
1208 object_property_set_str(obj, props->info->enum_table[props->defval],
1209 props->name, &errp);
1210 } else if (props->qtype == QTYPE_QINT) {
1211 object_property_set_int(obj, props->defval, props->name, &errp);
1213 assert(!errp);
1217 static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
1219 static void qdev_prop_register_global(GlobalProperty *prop)
1221 QTAILQ_INSERT_TAIL(&global_props, prop, next);
1224 void qdev_prop_register_global_list(GlobalProperty *props)
1226 int i;
1228 for (i = 0; props[i].driver != NULL; i++) {
1229 qdev_prop_register_global(props+i);
1233 void qdev_prop_set_globals(DeviceState *dev)
1235 GlobalProperty *prop;
1237 QTAILQ_FOREACH(prop, &global_props, next) {
1238 if (strcmp(object_get_typename(OBJECT(dev)), prop->driver) != 0 &&
1239 strcmp(qdev_get_bus_info(dev)->name, prop->driver) != 0) {
1240 continue;
1242 if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
1243 exit(1);
1248 static int qdev_add_one_global(QemuOpts *opts, void *opaque)
1250 GlobalProperty *g;
1252 g = g_malloc0(sizeof(*g));
1253 g->driver = qemu_opt_get(opts, "driver");
1254 g->property = qemu_opt_get(opts, "property");
1255 g->value = qemu_opt_get(opts, "value");
1256 qdev_prop_register_global(g);
1257 return 0;
1260 void qemu_add_globals(void)
1262 qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0);