]> git.proxmox.com Git - qemu.git/blob - hw/qdev-properties.c
Merge remote-tracking branch 'kraxel/vnc.2' into staging
[qemu.git] / hw / qdev-properties.c
1 #include "net.h"
2 #include "qdev.h"
3 #include "qerror.h"
4 #include "blockdev.h"
5
6 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
7 {
8 void *ptr = dev;
9 ptr += prop->offset;
10 return ptr;
11 }
12
13 static uint32_t qdev_get_prop_mask(Property *prop)
14 {
15 assert(prop->info == &qdev_prop_bit);
16 return 0x1 << prop->bitnr;
17 }
18
19 static void bit_prop_set(DeviceState *dev, Property *props, bool val)
20 {
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;
27 }
28
29 /* Bit */
30 static int parse_bit(DeviceState *dev, Property *prop, const char *str)
31 {
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;
39 }
40
41 static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
42 {
43 uint32_t *p = qdev_get_prop_ptr(dev, prop);
44 return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
45 }
46
47 static void get_bit(Object *obj, Visitor *v, void *opaque,
48 const char *name, Error **errp)
49 {
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;
54
55 visit_type_bool(v, &value, name, errp);
56 }
57
58 static void set_bit(Object *obj, Visitor *v, void *opaque,
59 const char *name, Error **errp)
60 {
61 DeviceState *dev = DEVICE(obj);
62 Property *prop = opaque;
63 Error *local_err = NULL;
64 bool value;
65
66 if (dev->state != DEV_STATE_CREATED) {
67 error_set(errp, QERR_PERMISSION_DENIED);
68 return;
69 }
70
71 visit_type_bool(v, &value, name, &local_err);
72 if (local_err) {
73 error_propagate(errp, local_err);
74 return;
75 }
76 bit_prop_set(dev, prop, value);
77 }
78
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,
86 };
87
88 /* --- 8bit integer --- */
89
90 static int parse_uint8(DeviceState *dev, Property *prop, const char *str)
91 {
92 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
93 char *end;
94
95 /* accept both hex and decimal */
96 *ptr = strtoul(str, &end, 0);
97 if ((*end != '\0') || (end == str)) {
98 return -EINVAL;
99 }
100
101 return 0;
102 }
103
104 static int print_uint8(DeviceState *dev, Property *prop, char *dest, size_t len)
105 {
106 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
107 return snprintf(dest, len, "%" PRIu8, *ptr);
108 }
109
110 static void get_int8(Object *obj, Visitor *v, void *opaque,
111 const char *name, Error **errp)
112 {
113 DeviceState *dev = DEVICE(obj);
114 Property *prop = opaque;
115 int8_t *ptr = qdev_get_prop_ptr(dev, prop);
116 int64_t value;
117
118 value = *ptr;
119 visit_type_int(v, &value, name, errp);
120 }
121
122 static void set_int8(Object *obj, Visitor *v, void *opaque,
123 const char *name, Error **errp)
124 {
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;
130
131 if (dev->state != DEV_STATE_CREATED) {
132 error_set(errp, QERR_PERMISSION_DENIED);
133 return;
134 }
135
136 visit_type_int(v, &value, name, &local_err);
137 if (local_err) {
138 error_propagate(errp, local_err);
139 return;
140 }
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);
147 }
148 }
149
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,
158 };
159
160 /* --- 8bit hex value --- */
161
162 static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
163 {
164 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
165 char *end;
166
167 *ptr = strtoul(str, &end, 16);
168 if ((*end != '\0') || (end == str)) {
169 return -EINVAL;
170 }
171
172 return 0;
173 }
174
175 static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
176 {
177 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
178 return snprintf(dest, len, "0x%" PRIx8, *ptr);
179 }
180
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,
190 };
191
192 /* --- 16bit integer --- */
193
194 static int parse_uint16(DeviceState *dev, Property *prop, const char *str)
195 {
196 uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
197 char *end;
198
199 /* accept both hex and decimal */
200 *ptr = strtoul(str, &end, 0);
201 if ((*end != '\0') || (end == str)) {
202 return -EINVAL;
203 }
204
205 return 0;
206 }
207
208 static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len)
209 {
210 uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
211 return snprintf(dest, len, "%" PRIu16, *ptr);
212 }
213
214 static void get_int16(Object *obj, Visitor *v, void *opaque,
215 const char *name, Error **errp)
216 {
217 DeviceState *dev = DEVICE(obj);
218 Property *prop = opaque;
219 int16_t *ptr = qdev_get_prop_ptr(dev, prop);
220 int64_t value;
221
222 value = *ptr;
223 visit_type_int(v, &value, name, errp);
224 }
225
226 static void set_int16(Object *obj, Visitor *v, void *opaque,
227 const char *name, Error **errp)
228 {
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;
234
235 if (dev->state != DEV_STATE_CREATED) {
236 error_set(errp, QERR_PERMISSION_DENIED);
237 return;
238 }
239
240 visit_type_int(v, &value, name, &local_err);
241 if (local_err) {
242 error_propagate(errp, local_err);
243 return;
244 }
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);
251 }
252 }
253
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,
262 };
263
264 /* --- 32bit integer --- */
265
266 static int parse_uint32(DeviceState *dev, Property *prop, const char *str)
267 {
268 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
269 char *end;
270
271 /* accept both hex and decimal */
272 *ptr = strtoul(str, &end, 0);
273 if ((*end != '\0') || (end == str)) {
274 return -EINVAL;
275 }
276
277 return 0;
278 }
279
280 static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len)
281 {
282 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
283 return snprintf(dest, len, "%" PRIu32, *ptr);
284 }
285
286 static void get_int32(Object *obj, Visitor *v, void *opaque,
287 const char *name, Error **errp)
288 {
289 DeviceState *dev = DEVICE(obj);
290 Property *prop = opaque;
291 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
292 int64_t value;
293
294 value = *ptr;
295 visit_type_int(v, &value, name, errp);
296 }
297
298 static void set_int32(Object *obj, Visitor *v, void *opaque,
299 const char *name, Error **errp)
300 {
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;
306
307 if (dev->state != DEV_STATE_CREATED) {
308 error_set(errp, QERR_PERMISSION_DENIED);
309 return;
310 }
311
312 visit_type_int(v, &value, name, &local_err);
313 if (local_err) {
314 error_propagate(errp, local_err);
315 return;
316 }
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);
323 }
324 }
325
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,
334 };
335
336 static int parse_int32(DeviceState *dev, Property *prop, const char *str)
337 {
338 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
339 char *end;
340
341 *ptr = strtol(str, &end, 10);
342 if ((*end != '\0') || (end == str)) {
343 return -EINVAL;
344 }
345
346 return 0;
347 }
348
349 static int print_int32(DeviceState *dev, Property *prop, char *dest, size_t len)
350 {
351 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
352 return snprintf(dest, len, "%" PRId32, *ptr);
353 }
354
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,
363 };
364
365 /* --- 32bit hex value --- */
366
367 static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
368 {
369 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
370 char *end;
371
372 *ptr = strtoul(str, &end, 16);
373 if ((*end != '\0') || (end == str)) {
374 return -EINVAL;
375 }
376
377 return 0;
378 }
379
380 static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
381 {
382 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
383 return snprintf(dest, len, "0x%" PRIx32, *ptr);
384 }
385
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,
395 };
396
397 /* --- 64bit integer --- */
398
399 static int parse_uint64(DeviceState *dev, Property *prop, const char *str)
400 {
401 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
402 char *end;
403
404 /* accept both hex and decimal */
405 *ptr = strtoull(str, &end, 0);
406 if ((*end != '\0') || (end == str)) {
407 return -EINVAL;
408 }
409
410 return 0;
411 }
412
413 static int print_uint64(DeviceState *dev, Property *prop, char *dest, size_t len)
414 {
415 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
416 return snprintf(dest, len, "%" PRIu64, *ptr);
417 }
418
419 static void get_int64(Object *obj, Visitor *v, void *opaque,
420 const char *name, Error **errp)
421 {
422 DeviceState *dev = DEVICE(obj);
423 Property *prop = opaque;
424 int64_t *ptr = qdev_get_prop_ptr(dev, prop);
425
426 visit_type_int(v, ptr, name, errp);
427 }
428
429 static void set_int64(Object *obj, Visitor *v, void *opaque,
430 const char *name, Error **errp)
431 {
432 DeviceState *dev = DEVICE(obj);
433 Property *prop = opaque;
434 int64_t *ptr = qdev_get_prop_ptr(dev, prop);
435
436 if (dev->state != DEV_STATE_CREATED) {
437 error_set(errp, QERR_PERMISSION_DENIED);
438 return;
439 }
440
441 visit_type_int(v, ptr, name, errp);
442 }
443
444 PropertyInfo qdev_prop_uint64 = {
445 .name = "uint64",
446 .parse = parse_uint64,
447 .print = print_uint64,
448 .get = get_int64,
449 .set = set_int64,
450 };
451
452 /* --- 64bit hex value --- */
453
454 static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
455 {
456 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
457 char *end;
458
459 *ptr = strtoull(str, &end, 16);
460 if ((*end != '\0') || (end == str)) {
461 return -EINVAL;
462 }
463
464 return 0;
465 }
466
467 static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
468 {
469 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
470 return snprintf(dest, len, "0x%" PRIx64, *ptr);
471 }
472
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,
480 };
481
482 /* --- string --- */
483
484 static void release_string(Object *obj, const char *name, void *opaque)
485 {
486 Property *prop = opaque;
487 g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
488 }
489
490 static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
491 {
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);
496 }
497
498 static void get_string(Object *obj, Visitor *v, void *opaque,
499 const char *name, Error **errp)
500 {
501 DeviceState *dev = DEVICE(obj);
502 Property *prop = opaque;
503 char **ptr = qdev_get_prop_ptr(dev, prop);
504
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);
510 }
511 }
512
513 static void set_string(Object *obj, Visitor *v, void *opaque,
514 const char *name, Error **errp)
515 {
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;
521
522 if (dev->state != DEV_STATE_CREATED) {
523 error_set(errp, QERR_PERMISSION_DENIED);
524 return;
525 }
526
527 visit_type_str(v, &str, name, &local_err);
528 if (local_err) {
529 error_propagate(errp, local_err);
530 return;
531 }
532 if (!*str) {
533 g_free(str);
534 str = NULL;
535 }
536 if (*ptr) {
537 g_free(*ptr);
538 }
539 *ptr = str;
540 }
541
542 PropertyInfo qdev_prop_string = {
543 .name = "string",
544 .print = print_string,
545 .release = release_string,
546 .get = get_string,
547 .set = set_string,
548 };
549
550 /* --- drive --- */
551
552 static int parse_drive(DeviceState *dev, const char *str, void **ptr)
553 {
554 BlockDriverState *bs;
555
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;
563 }
564
565 static void release_drive(Object *obj, const char *name, void *opaque)
566 {
567 DeviceState *dev = DEVICE(obj);
568 Property *prop = opaque;
569 BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
570
571 if (*ptr) {
572 bdrv_detach_dev(*ptr, dev);
573 blockdev_auto_del(*ptr);
574 }
575 }
576
577 static const char *print_drive(void *ptr)
578 {
579 return bdrv_get_device_name(ptr);
580 }
581
582 static void get_pointer(Object *obj, Visitor *v, Property *prop,
583 const char *(*print)(void *ptr),
584 const char *name, Error **errp)
585 {
586 DeviceState *dev = DEVICE(obj);
587 void **ptr = qdev_get_prop_ptr(dev, prop);
588 char *p;
589
590 p = (char *) (*ptr ? print(*ptr) : "");
591 visit_type_str(v, &p, name, errp);
592 }
593
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)
597 {
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;
603
604 if (dev->state != DEV_STATE_CREATED) {
605 error_set(errp, QERR_PERMISSION_DENIED);
606 return;
607 }
608
609 visit_type_str(v, &str, name, &local_err);
610 if (local_err) {
611 error_propagate(errp, local_err);
612 return;
613 }
614 if (!*str) {
615 g_free(str);
616 *ptr = NULL;
617 return;
618 }
619 ret = parse(dev, str, ptr);
620 error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
621 g_free(str);
622 }
623
624 static void get_drive(Object *obj, Visitor *v, void *opaque,
625 const char *name, Error **errp)
626 {
627 get_pointer(obj, v, opaque, print_drive, name, errp);
628 }
629
630 static void set_drive(Object *obj, Visitor *v, void *opaque,
631 const char *name, Error **errp)
632 {
633 set_pointer(obj, v, opaque, parse_drive, name, errp);
634 }
635
636 PropertyInfo qdev_prop_drive = {
637 .name = "drive",
638 .get = get_drive,
639 .set = set_drive,
640 .release = release_drive,
641 };
642
643 /* --- character device --- */
644
645 static int parse_chr(DeviceState *dev, const char *str, void **ptr)
646 {
647 CharDriverState *chr = qemu_chr_find(str);
648 if (chr == NULL) {
649 return -ENOENT;
650 }
651 if (chr->avail_connections < 1) {
652 return -EEXIST;
653 }
654 *ptr = chr;
655 --chr->avail_connections;
656 return 0;
657 }
658
659 static void release_chr(Object *obj, const char *name, void *opaque)
660 {
661 DeviceState *dev = DEVICE(obj);
662 Property *prop = opaque;
663 CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
664
665 if (*ptr) {
666 qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL);
667 }
668 }
669
670
671 static const char *print_chr(void *ptr)
672 {
673 CharDriverState *chr = ptr;
674
675 return chr->label ? chr->label : "";
676 }
677
678 static void get_chr(Object *obj, Visitor *v, void *opaque,
679 const char *name, Error **errp)
680 {
681 get_pointer(obj, v, opaque, print_chr, name, errp);
682 }
683
684 static void set_chr(Object *obj, Visitor *v, void *opaque,
685 const char *name, Error **errp)
686 {
687 set_pointer(obj, v, opaque, parse_chr, name, errp);
688 }
689
690 PropertyInfo qdev_prop_chr = {
691 .name = "chr",
692 .get = get_chr,
693 .set = set_chr,
694 .release = release_chr,
695 };
696
697 /* --- netdev device --- */
698
699 static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
700 {
701 VLANClientState *netdev = qemu_find_netdev(str);
702
703 if (netdev == NULL) {
704 return -ENOENT;
705 }
706 if (netdev->peer) {
707 return -EEXIST;
708 }
709 *ptr = netdev;
710 return 0;
711 }
712
713 static const char *print_netdev(void *ptr)
714 {
715 VLANClientState *netdev = ptr;
716
717 return netdev->name ? netdev->name : "";
718 }
719
720 static void get_netdev(Object *obj, Visitor *v, void *opaque,
721 const char *name, Error **errp)
722 {
723 get_pointer(obj, v, opaque, print_netdev, name, errp);
724 }
725
726 static void set_netdev(Object *obj, Visitor *v, void *opaque,
727 const char *name, Error **errp)
728 {
729 set_pointer(obj, v, opaque, parse_netdev, name, errp);
730 }
731
732 PropertyInfo qdev_prop_netdev = {
733 .name = "netdev",
734 .get = get_netdev,
735 .set = set_netdev,
736 };
737
738 /* --- vlan --- */
739
740 static int parse_vlan(DeviceState *dev, Property *prop, const char *str)
741 {
742 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
743 int id;
744
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;
751 }
752
753 static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
754 {
755 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
756
757 if (*ptr) {
758 return snprintf(dest, len, "%d", (*ptr)->id);
759 } else {
760 return snprintf(dest, len, "<null>");
761 }
762 }
763
764 static void get_vlan(Object *obj, Visitor *v, void *opaque,
765 const char *name, Error **errp)
766 {
767 DeviceState *dev = DEVICE(obj);
768 Property *prop = opaque;
769 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
770 int64_t id;
771
772 id = *ptr ? (*ptr)->id : -1;
773 visit_type_int(v, &id, name, errp);
774 }
775
776 static void set_vlan(Object *obj, Visitor *v, void *opaque,
777 const char *name, Error **errp)
778 {
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;
785
786 if (dev->state != DEV_STATE_CREATED) {
787 error_set(errp, QERR_PERMISSION_DENIED);
788 return;
789 }
790
791 visit_type_int(v, &id, name, &local_err);
792 if (local_err) {
793 error_propagate(errp, local_err);
794 return;
795 }
796 if (id == -1) {
797 *ptr = NULL;
798 return;
799 }
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;
805 }
806 *ptr = vlan;
807 }
808
809 PropertyInfo qdev_prop_vlan = {
810 .name = "vlan",
811 .parse = parse_vlan,
812 .print = print_vlan,
813 .get = get_vlan,
814 .set = set_vlan,
815 };
816
817 /* --- pointer --- */
818
819 /* Not a proper property, just for dirty hacks. TODO Remove it! */
820 PropertyInfo qdev_prop_ptr = {
821 .name = "ptr",
822 };
823
824 /* --- mac address --- */
825
826 /*
827 * accepted syntax versions:
828 * 01:02:03:04:05:06
829 * 01-02-03-04-05-06
830 */
831 static void get_mac(Object *obj, Visitor *v, void *opaque,
832 const char *name, Error **errp)
833 {
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;
839
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]);
843
844 visit_type_str(v, &p, name, errp);
845 }
846
847 static void set_mac(Object *obj, Visitor *v, void *opaque,
848 const char *name, Error **errp)
849 {
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;
856
857 if (dev->state != DEV_STATE_CREATED) {
858 error_set(errp, QERR_PERMISSION_DENIED);
859 return;
860 }
861
862 visit_type_str(v, &str, name, &local_err);
863 if (local_err) {
864 error_propagate(errp, local_err);
865 return;
866 }
867
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;
879 }
880 mac->a[i] = strtol(str+pos, &p, 16);
881 }
882 return;
883
884 inval:
885 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
886 }
887
888 PropertyInfo qdev_prop_macaddr = {
889 .name = "macaddr",
890 .get = get_mac,
891 .set = set_mac,
892 };
893
894
895 /* --- lost tick policy --- */
896
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,
903 };
904
905 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
906
907 static void get_enum(Object *obj, Visitor *v, void *opaque,
908 const char *name, Error **errp)
909 {
910 DeviceState *dev = DEVICE(obj);
911 Property *prop = opaque;
912 int *ptr = qdev_get_prop_ptr(dev, prop);
913
914 visit_type_enum(v, ptr, prop->info->enum_table,
915 prop->info->name, prop->name, errp);
916 }
917
918 static void set_enum(Object *obj, Visitor *v, void *opaque,
919 const char *name, Error **errp)
920 {
921 DeviceState *dev = DEVICE(obj);
922 Property *prop = opaque;
923 int *ptr = qdev_get_prop_ptr(dev, prop);
924
925 if (dev->state != DEV_STATE_CREATED) {
926 error_set(errp, QERR_PERMISSION_DENIED);
927 return;
928 }
929
930 visit_type_enum(v, ptr, prop->info->enum_table,
931 prop->info->name, prop->name, errp);
932 }
933
934 PropertyInfo qdev_prop_losttickpolicy = {
935 .name = "LostTickPolicy",
936 .enum_table = lost_tick_policy_table,
937 .get = get_enum,
938 .set = set_enum,
939 };
940
941 /* --- pci address --- */
942
943 /*
944 * bus-local address, i.e. "$slot" or "$slot.$fn"
945 */
946 static int parse_pci_devfn(DeviceState *dev, Property *prop, const char *str)
947 {
948 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
949 unsigned int slot, fn, n;
950
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;
955 }
956 }
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;
965 }
966
967 static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
968 {
969 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
970
971 if (*ptr == -1) {
972 return snprintf(dest, len, "<unset>");
973 } else {
974 return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
975 }
976 }
977
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.
987 */
988 .min = 0,
989 .max = 0xFFFFFFFFULL,
990 };
991
992 /* --- public helpers --- */
993
994 static Property *qdev_prop_walk(Property *props, const char *name)
995 {
996 if (!props)
997 return NULL;
998 while (props->name) {
999 if (strcmp(props->name, name) == 0)
1000 return props;
1001 props++;
1002 }
1003 return NULL;
1004 }
1005
1006 static Property *qdev_prop_find(DeviceState *dev, const char *name)
1007 {
1008 Property *prop;
1009
1010 /* device properties */
1011 prop = qdev_prop_walk(qdev_get_props(dev), name);
1012 if (prop)
1013 return prop;
1014
1015 /* bus properties */
1016 prop = qdev_prop_walk(dev->parent_bus->info->props, name);
1017 if (prop)
1018 return prop;
1019
1020 return NULL;
1021 }
1022
1023 int qdev_prop_exists(DeviceState *dev, const char *name)
1024 {
1025 return qdev_prop_find(dev, name) ? true : false;
1026 }
1027
1028 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
1029 Property *prop, const char *value)
1030 {
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;
1047 }
1048 }
1049
1050 int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
1051 {
1052 char *legacy_name;
1053 Error *err = NULL;
1054
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);
1060 }
1061 g_free(legacy_name);
1062
1063 if (err) {
1064 qerror_report_err(err);
1065 error_free(err);
1066 return -1;
1067 }
1068 return 0;
1069 }
1070
1071 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1072 {
1073 Error *errp = NULL;
1074 object_property_set_bool(OBJECT(dev), value, name, &errp);
1075 assert_no_error(errp);
1076 }
1077
1078 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1079 {
1080 Error *errp = NULL;
1081 object_property_set_int(OBJECT(dev), value, name, &errp);
1082 assert_no_error(errp);
1083 }
1084
1085 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1086 {
1087 Error *errp = NULL;
1088 object_property_set_int(OBJECT(dev), value, name, &errp);
1089 assert_no_error(errp);
1090 }
1091
1092 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1093 {
1094 Error *errp = NULL;
1095 object_property_set_int(OBJECT(dev), value, name, &errp);
1096 assert_no_error(errp);
1097 }
1098
1099 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1100 {
1101 Error *errp = NULL;
1102 object_property_set_int(OBJECT(dev), value, name, &errp);
1103 assert_no_error(errp);
1104 }
1105
1106 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1107 {
1108 Error *errp = NULL;
1109 object_property_set_int(OBJECT(dev), value, name, &errp);
1110 assert_no_error(errp);
1111 }
1112
1113 void qdev_prop_set_string(DeviceState *dev, const char *name, char *value)
1114 {
1115 Error *errp = NULL;
1116 object_property_set_str(OBJECT(dev), value, name, &errp);
1117 assert_no_error(errp);
1118 }
1119
1120 int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
1121 {
1122 Error *errp = NULL;
1123 const char *bdrv_name = value ? bdrv_get_device_name(value) : "";
1124 object_property_set_str(OBJECT(dev), bdrv_name,
1125 name, &errp);
1126 if (errp) {
1127 qerror_report_err(errp);
1128 error_free(errp);
1129 return -1;
1130 }
1131 return 0;
1132 }
1133
1134 void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value)
1135 {
1136 if (qdev_prop_set_drive(dev, name, value) < 0) {
1137 exit(1);
1138 }
1139 }
1140 void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
1141 {
1142 Error *errp = NULL;
1143 assert(!value || value->label);
1144 object_property_set_str(OBJECT(dev),
1145 value ? value->label : "", name, &errp);
1146 assert_no_error(errp);
1147 }
1148
1149 void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value)
1150 {
1151 Error *errp = NULL;
1152 assert(!value || value->name);
1153 object_property_set_str(OBJECT(dev),
1154 value ? value->name : "", name, &errp);
1155 assert_no_error(errp);
1156 }
1157
1158 void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
1159 {
1160 Error *errp = NULL;
1161 object_property_set_int(OBJECT(dev), value ? value->id : -1, name, &errp);
1162 assert_no_error(errp);
1163 }
1164
1165 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
1166 {
1167 Error *errp = NULL;
1168 char str[2 * 6 + 5 + 1];
1169 snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1170 value[0], value[1], value[2], value[3], value[4], value[5]);
1171
1172 object_property_set_str(OBJECT(dev), str, name, &errp);
1173 assert_no_error(errp);
1174 }
1175
1176 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1177 {
1178 Property *prop;
1179 Error *errp = NULL;
1180
1181 prop = qdev_prop_find(dev, name);
1182 object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
1183 name, &errp);
1184 assert_no_error(errp);
1185 }
1186
1187 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1188 {
1189 Property *prop;
1190 void **ptr;
1191
1192 prop = qdev_prop_find(dev, name);
1193 assert(prop && prop->info == &qdev_prop_ptr);
1194 ptr = qdev_get_prop_ptr(dev, prop);
1195 *ptr = value;
1196 }
1197
1198 void qdev_prop_set_defaults(DeviceState *dev, Property *props)
1199 {
1200 Object *obj = OBJECT(dev);
1201 if (!props)
1202 return;
1203 for (; props->name; props++) {
1204 Error *errp = NULL;
1205 if (props->qtype == QTYPE_NONE) {
1206 continue;
1207 }
1208 if (props->qtype == QTYPE_QBOOL) {
1209 object_property_set_bool(obj, props->defval, props->name, &errp);
1210 } else if (props->info->enum_table) {
1211 object_property_set_str(obj, props->info->enum_table[props->defval],
1212 props->name, &errp);
1213 } else if (props->qtype == QTYPE_QINT) {
1214 object_property_set_int(obj, props->defval, props->name, &errp);
1215 }
1216 assert_no_error(errp);
1217 }
1218 }
1219
1220 static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
1221
1222 static void qdev_prop_register_global(GlobalProperty *prop)
1223 {
1224 QTAILQ_INSERT_TAIL(&global_props, prop, next);
1225 }
1226
1227 void qdev_prop_register_global_list(GlobalProperty *props)
1228 {
1229 int i;
1230
1231 for (i = 0; props[i].driver != NULL; i++) {
1232 qdev_prop_register_global(props+i);
1233 }
1234 }
1235
1236 void qdev_prop_set_globals(DeviceState *dev)
1237 {
1238 GlobalProperty *prop;
1239
1240 QTAILQ_FOREACH(prop, &global_props, next) {
1241 if (strcmp(object_get_typename(OBJECT(dev)), prop->driver) != 0 &&
1242 strcmp(qdev_get_bus_info(dev)->name, prop->driver) != 0) {
1243 continue;
1244 }
1245 if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
1246 exit(1);
1247 }
1248 }
1249 }
1250
1251 static int qdev_add_one_global(QemuOpts *opts, void *opaque)
1252 {
1253 GlobalProperty *g;
1254
1255 g = g_malloc0(sizeof(*g));
1256 g->driver = qemu_opt_get(opts, "driver");
1257 g->property = qemu_opt_get(opts, "property");
1258 g->value = qemu_opt_get(opts, "value");
1259 qdev_prop_register_global(g);
1260 return 0;
1261 }
1262
1263 void qemu_add_globals(void)
1264 {
1265 qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0);
1266 }