]> git.proxmox.com Git - qemu.git/blob - hw/qdev-properties.c
Merge branch pci into master
[qemu.git] / hw / qdev-properties.c
1 #include "net.h"
2 #include "qdev.h"
3 #include "qerror.h"
4 #include "blockdev.h"
5 #include "hw/block-common.h"
6
7 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
8 {
9 void *ptr = dev;
10 ptr += prop->offset;
11 return ptr;
12 }
13
14 static void get_pointer(Object *obj, Visitor *v, Property *prop,
15 const char *(*print)(void *ptr),
16 const char *name, Error **errp)
17 {
18 DeviceState *dev = DEVICE(obj);
19 void **ptr = qdev_get_prop_ptr(dev, prop);
20 char *p;
21
22 p = (char *) (*ptr ? print(*ptr) : "");
23 visit_type_str(v, &p, name, errp);
24 }
25
26 static void set_pointer(Object *obj, Visitor *v, Property *prop,
27 int (*parse)(DeviceState *dev, const char *str,
28 void **ptr),
29 const char *name, Error **errp)
30 {
31 DeviceState *dev = DEVICE(obj);
32 Error *local_err = NULL;
33 void **ptr = qdev_get_prop_ptr(dev, prop);
34 char *str;
35 int ret;
36
37 if (dev->state != DEV_STATE_CREATED) {
38 error_set(errp, QERR_PERMISSION_DENIED);
39 return;
40 }
41
42 visit_type_str(v, &str, name, &local_err);
43 if (local_err) {
44 error_propagate(errp, local_err);
45 return;
46 }
47 if (!*str) {
48 g_free(str);
49 *ptr = NULL;
50 return;
51 }
52 ret = parse(dev, str, ptr);
53 error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
54 g_free(str);
55 }
56
57 static void get_enum(Object *obj, Visitor *v, void *opaque,
58 const char *name, Error **errp)
59 {
60 DeviceState *dev = DEVICE(obj);
61 Property *prop = opaque;
62 int *ptr = qdev_get_prop_ptr(dev, prop);
63
64 visit_type_enum(v, ptr, prop->info->enum_table,
65 prop->info->name, prop->name, errp);
66 }
67
68 static void set_enum(Object *obj, Visitor *v, void *opaque,
69 const char *name, Error **errp)
70 {
71 DeviceState *dev = DEVICE(obj);
72 Property *prop = opaque;
73 int *ptr = qdev_get_prop_ptr(dev, prop);
74
75 if (dev->state != DEV_STATE_CREATED) {
76 error_set(errp, QERR_PERMISSION_DENIED);
77 return;
78 }
79
80 visit_type_enum(v, ptr, prop->info->enum_table,
81 prop->info->name, prop->name, errp);
82 }
83
84 /* Bit */
85
86 static uint32_t qdev_get_prop_mask(Property *prop)
87 {
88 assert(prop->info == &qdev_prop_bit);
89 return 0x1 << prop->bitnr;
90 }
91
92 static void bit_prop_set(DeviceState *dev, Property *props, bool val)
93 {
94 uint32_t *p = qdev_get_prop_ptr(dev, props);
95 uint32_t mask = qdev_get_prop_mask(props);
96 if (val)
97 *p |= mask;
98 else
99 *p &= ~mask;
100 }
101
102 static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
103 {
104 uint32_t *p = qdev_get_prop_ptr(dev, prop);
105 return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
106 }
107
108 static void get_bit(Object *obj, Visitor *v, void *opaque,
109 const char *name, Error **errp)
110 {
111 DeviceState *dev = DEVICE(obj);
112 Property *prop = opaque;
113 uint32_t *p = qdev_get_prop_ptr(dev, prop);
114 bool value = (*p & qdev_get_prop_mask(prop)) != 0;
115
116 visit_type_bool(v, &value, name, errp);
117 }
118
119 static void set_bit(Object *obj, Visitor *v, void *opaque,
120 const char *name, Error **errp)
121 {
122 DeviceState *dev = DEVICE(obj);
123 Property *prop = opaque;
124 Error *local_err = NULL;
125 bool value;
126
127 if (dev->state != DEV_STATE_CREATED) {
128 error_set(errp, QERR_PERMISSION_DENIED);
129 return;
130 }
131
132 visit_type_bool(v, &value, name, &local_err);
133 if (local_err) {
134 error_propagate(errp, local_err);
135 return;
136 }
137 bit_prop_set(dev, prop, value);
138 }
139
140 PropertyInfo qdev_prop_bit = {
141 .name = "boolean",
142 .legacy_name = "on/off",
143 .print = print_bit,
144 .get = get_bit,
145 .set = set_bit,
146 };
147
148 /* --- 8bit integer --- */
149
150 static void get_uint8(Object *obj, Visitor *v, void *opaque,
151 const char *name, Error **errp)
152 {
153 DeviceState *dev = DEVICE(obj);
154 Property *prop = opaque;
155 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
156
157 visit_type_uint8(v, ptr, name, errp);
158 }
159
160 static void set_uint8(Object *obj, Visitor *v, void *opaque,
161 const char *name, Error **errp)
162 {
163 DeviceState *dev = DEVICE(obj);
164 Property *prop = opaque;
165 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
166
167 if (dev->state != DEV_STATE_CREATED) {
168 error_set(errp, QERR_PERMISSION_DENIED);
169 return;
170 }
171
172 visit_type_uint8(v, ptr, name, errp);
173 }
174
175 PropertyInfo qdev_prop_uint8 = {
176 .name = "uint8",
177 .get = get_uint8,
178 .set = set_uint8,
179 };
180
181 /* --- 8bit hex value --- */
182
183 static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
184 {
185 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
186 char *end;
187
188 if (str[0] != '0' || str[1] != 'x') {
189 return -EINVAL;
190 }
191
192 *ptr = strtoul(str, &end, 16);
193 if ((*end != '\0') || (end == str)) {
194 return -EINVAL;
195 }
196
197 return 0;
198 }
199
200 static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
201 {
202 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
203 return snprintf(dest, len, "0x%" PRIx8, *ptr);
204 }
205
206 PropertyInfo qdev_prop_hex8 = {
207 .name = "uint8",
208 .legacy_name = "hex8",
209 .parse = parse_hex8,
210 .print = print_hex8,
211 .get = get_uint8,
212 .set = set_uint8,
213 };
214
215 /* --- 16bit integer --- */
216
217 static void get_uint16(Object *obj, Visitor *v, void *opaque,
218 const char *name, Error **errp)
219 {
220 DeviceState *dev = DEVICE(obj);
221 Property *prop = opaque;
222 uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
223
224 visit_type_uint16(v, ptr, name, errp);
225 }
226
227 static void set_uint16(Object *obj, Visitor *v, void *opaque,
228 const char *name, Error **errp)
229 {
230 DeviceState *dev = DEVICE(obj);
231 Property *prop = opaque;
232 uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
233
234 if (dev->state != DEV_STATE_CREATED) {
235 error_set(errp, QERR_PERMISSION_DENIED);
236 return;
237 }
238
239 visit_type_uint16(v, ptr, name, errp);
240 }
241
242 PropertyInfo qdev_prop_uint16 = {
243 .name = "uint16",
244 .get = get_uint16,
245 .set = set_uint16,
246 };
247
248 /* --- 32bit integer --- */
249
250 static void get_uint32(Object *obj, Visitor *v, void *opaque,
251 const char *name, Error **errp)
252 {
253 DeviceState *dev = DEVICE(obj);
254 Property *prop = opaque;
255 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
256
257 visit_type_uint32(v, ptr, name, errp);
258 }
259
260 static void set_uint32(Object *obj, Visitor *v, void *opaque,
261 const char *name, Error **errp)
262 {
263 DeviceState *dev = DEVICE(obj);
264 Property *prop = opaque;
265 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
266
267 if (dev->state != DEV_STATE_CREATED) {
268 error_set(errp, QERR_PERMISSION_DENIED);
269 return;
270 }
271
272 visit_type_uint32(v, ptr, name, errp);
273 }
274
275 static void get_int32(Object *obj, Visitor *v, void *opaque,
276 const char *name, Error **errp)
277 {
278 DeviceState *dev = DEVICE(obj);
279 Property *prop = opaque;
280 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
281
282 visit_type_int32(v, ptr, name, errp);
283 }
284
285 static void set_int32(Object *obj, Visitor *v, void *opaque,
286 const char *name, Error **errp)
287 {
288 DeviceState *dev = DEVICE(obj);
289 Property *prop = opaque;
290 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
291
292 if (dev->state != DEV_STATE_CREATED) {
293 error_set(errp, QERR_PERMISSION_DENIED);
294 return;
295 }
296
297 visit_type_int32(v, ptr, name, errp);
298 }
299
300 PropertyInfo qdev_prop_uint32 = {
301 .name = "uint32",
302 .get = get_uint32,
303 .set = set_uint32,
304 };
305
306 PropertyInfo qdev_prop_int32 = {
307 .name = "int32",
308 .get = get_int32,
309 .set = set_int32,
310 };
311
312 /* --- 32bit hex value --- */
313
314 static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
315 {
316 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
317 char *end;
318
319 if (str[0] != '0' || str[1] != 'x') {
320 return -EINVAL;
321 }
322
323 *ptr = strtoul(str, &end, 16);
324 if ((*end != '\0') || (end == str)) {
325 return -EINVAL;
326 }
327
328 return 0;
329 }
330
331 static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
332 {
333 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
334 return snprintf(dest, len, "0x%" PRIx32, *ptr);
335 }
336
337 PropertyInfo qdev_prop_hex32 = {
338 .name = "uint32",
339 .legacy_name = "hex32",
340 .parse = parse_hex32,
341 .print = print_hex32,
342 .get = get_uint32,
343 .set = set_uint32,
344 };
345
346 /* --- 64bit integer --- */
347
348 static void get_uint64(Object *obj, Visitor *v, void *opaque,
349 const char *name, Error **errp)
350 {
351 DeviceState *dev = DEVICE(obj);
352 Property *prop = opaque;
353 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
354
355 visit_type_uint64(v, ptr, name, errp);
356 }
357
358 static void set_uint64(Object *obj, Visitor *v, void *opaque,
359 const char *name, Error **errp)
360 {
361 DeviceState *dev = DEVICE(obj);
362 Property *prop = opaque;
363 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
364
365 if (dev->state != DEV_STATE_CREATED) {
366 error_set(errp, QERR_PERMISSION_DENIED);
367 return;
368 }
369
370 visit_type_uint64(v, ptr, name, errp);
371 }
372
373 PropertyInfo qdev_prop_uint64 = {
374 .name = "uint64",
375 .get = get_uint64,
376 .set = set_uint64,
377 };
378
379 /* --- 64bit hex value --- */
380
381 static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
382 {
383 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
384 char *end;
385
386 if (str[0] != '0' || str[1] != 'x') {
387 return -EINVAL;
388 }
389
390 *ptr = strtoull(str, &end, 16);
391 if ((*end != '\0') || (end == str)) {
392 return -EINVAL;
393 }
394
395 return 0;
396 }
397
398 static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
399 {
400 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
401 return snprintf(dest, len, "0x%" PRIx64, *ptr);
402 }
403
404 PropertyInfo qdev_prop_hex64 = {
405 .name = "uint64",
406 .legacy_name = "hex64",
407 .parse = parse_hex64,
408 .print = print_hex64,
409 .get = get_uint64,
410 .set = set_uint64,
411 };
412
413 /* --- string --- */
414
415 static void release_string(Object *obj, const char *name, void *opaque)
416 {
417 Property *prop = opaque;
418 g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
419 }
420
421 static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
422 {
423 char **ptr = qdev_get_prop_ptr(dev, prop);
424 if (!*ptr)
425 return snprintf(dest, len, "<null>");
426 return snprintf(dest, len, "\"%s\"", *ptr);
427 }
428
429 static void get_string(Object *obj, Visitor *v, void *opaque,
430 const char *name, Error **errp)
431 {
432 DeviceState *dev = DEVICE(obj);
433 Property *prop = opaque;
434 char **ptr = qdev_get_prop_ptr(dev, prop);
435
436 if (!*ptr) {
437 char *str = (char *)"";
438 visit_type_str(v, &str, name, errp);
439 } else {
440 visit_type_str(v, ptr, name, errp);
441 }
442 }
443
444 static void set_string(Object *obj, Visitor *v, void *opaque,
445 const char *name, Error **errp)
446 {
447 DeviceState *dev = DEVICE(obj);
448 Property *prop = opaque;
449 char **ptr = qdev_get_prop_ptr(dev, prop);
450 Error *local_err = NULL;
451 char *str;
452
453 if (dev->state != DEV_STATE_CREATED) {
454 error_set(errp, QERR_PERMISSION_DENIED);
455 return;
456 }
457
458 visit_type_str(v, &str, name, &local_err);
459 if (local_err) {
460 error_propagate(errp, local_err);
461 return;
462 }
463 if (*ptr) {
464 g_free(*ptr);
465 }
466 *ptr = str;
467 }
468
469 PropertyInfo qdev_prop_string = {
470 .name = "string",
471 .print = print_string,
472 .release = release_string,
473 .get = get_string,
474 .set = set_string,
475 };
476
477 /* --- drive --- */
478
479 static int parse_drive(DeviceState *dev, const char *str, void **ptr)
480 {
481 BlockDriverState *bs;
482
483 bs = bdrv_find(str);
484 if (bs == NULL)
485 return -ENOENT;
486 if (bdrv_attach_dev(bs, dev) < 0)
487 return -EEXIST;
488 *ptr = bs;
489 return 0;
490 }
491
492 static void release_drive(Object *obj, const char *name, void *opaque)
493 {
494 DeviceState *dev = DEVICE(obj);
495 Property *prop = opaque;
496 BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
497
498 if (*ptr) {
499 bdrv_detach_dev(*ptr, dev);
500 blockdev_auto_del(*ptr);
501 }
502 }
503
504 static const char *print_drive(void *ptr)
505 {
506 return bdrv_get_device_name(ptr);
507 }
508
509 static void get_drive(Object *obj, Visitor *v, void *opaque,
510 const char *name, Error **errp)
511 {
512 get_pointer(obj, v, opaque, print_drive, name, errp);
513 }
514
515 static void set_drive(Object *obj, Visitor *v, void *opaque,
516 const char *name, Error **errp)
517 {
518 set_pointer(obj, v, opaque, parse_drive, name, errp);
519 }
520
521 PropertyInfo qdev_prop_drive = {
522 .name = "drive",
523 .get = get_drive,
524 .set = set_drive,
525 .release = release_drive,
526 };
527
528 /* --- character device --- */
529
530 static int parse_chr(DeviceState *dev, const char *str, void **ptr)
531 {
532 CharDriverState *chr = qemu_chr_find(str);
533 if (chr == NULL) {
534 return -ENOENT;
535 }
536 if (chr->avail_connections < 1) {
537 return -EEXIST;
538 }
539 *ptr = chr;
540 --chr->avail_connections;
541 return 0;
542 }
543
544 static void release_chr(Object *obj, const char *name, void *opaque)
545 {
546 DeviceState *dev = DEVICE(obj);
547 Property *prop = opaque;
548 CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
549
550 if (*ptr) {
551 qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL);
552 }
553 }
554
555
556 static const char *print_chr(void *ptr)
557 {
558 CharDriverState *chr = ptr;
559
560 return chr->label ? chr->label : "";
561 }
562
563 static void get_chr(Object *obj, Visitor *v, void *opaque,
564 const char *name, Error **errp)
565 {
566 get_pointer(obj, v, opaque, print_chr, name, errp);
567 }
568
569 static void set_chr(Object *obj, Visitor *v, void *opaque,
570 const char *name, Error **errp)
571 {
572 set_pointer(obj, v, opaque, parse_chr, name, errp);
573 }
574
575 PropertyInfo qdev_prop_chr = {
576 .name = "chr",
577 .get = get_chr,
578 .set = set_chr,
579 .release = release_chr,
580 };
581
582 /* --- netdev device --- */
583
584 static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
585 {
586 VLANClientState *netdev = qemu_find_netdev(str);
587
588 if (netdev == NULL) {
589 return -ENOENT;
590 }
591 if (netdev->peer) {
592 return -EEXIST;
593 }
594 *ptr = netdev;
595 return 0;
596 }
597
598 static const char *print_netdev(void *ptr)
599 {
600 VLANClientState *netdev = ptr;
601
602 return netdev->name ? netdev->name : "";
603 }
604
605 static void get_netdev(Object *obj, Visitor *v, void *opaque,
606 const char *name, Error **errp)
607 {
608 get_pointer(obj, v, opaque, print_netdev, name, errp);
609 }
610
611 static void set_netdev(Object *obj, Visitor *v, void *opaque,
612 const char *name, Error **errp)
613 {
614 set_pointer(obj, v, opaque, parse_netdev, name, errp);
615 }
616
617 PropertyInfo qdev_prop_netdev = {
618 .name = "netdev",
619 .get = get_netdev,
620 .set = set_netdev,
621 };
622
623 /* --- vlan --- */
624
625 static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
626 {
627 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
628
629 if (*ptr) {
630 return snprintf(dest, len, "%d", (*ptr)->id);
631 } else {
632 return snprintf(dest, len, "<null>");
633 }
634 }
635
636 static void get_vlan(Object *obj, Visitor *v, void *opaque,
637 const char *name, Error **errp)
638 {
639 DeviceState *dev = DEVICE(obj);
640 Property *prop = opaque;
641 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
642 int64_t id;
643
644 id = *ptr ? (*ptr)->id : -1;
645 visit_type_int64(v, &id, name, errp);
646 }
647
648 static void set_vlan(Object *obj, Visitor *v, void *opaque,
649 const char *name, Error **errp)
650 {
651 DeviceState *dev = DEVICE(obj);
652 Property *prop = opaque;
653 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
654 Error *local_err = NULL;
655 int64_t id;
656 VLANState *vlan;
657
658 if (dev->state != DEV_STATE_CREATED) {
659 error_set(errp, QERR_PERMISSION_DENIED);
660 return;
661 }
662
663 visit_type_int64(v, &id, name, &local_err);
664 if (local_err) {
665 error_propagate(errp, local_err);
666 return;
667 }
668 if (id == -1) {
669 *ptr = NULL;
670 return;
671 }
672 vlan = qemu_find_vlan(id, 1);
673 if (!vlan) {
674 error_set(errp, QERR_INVALID_PARAMETER_VALUE,
675 name, prop->info->name);
676 return;
677 }
678 *ptr = vlan;
679 }
680
681 PropertyInfo qdev_prop_vlan = {
682 .name = "vlan",
683 .print = print_vlan,
684 .get = get_vlan,
685 .set = set_vlan,
686 };
687
688 /* --- pointer --- */
689
690 /* Not a proper property, just for dirty hacks. TODO Remove it! */
691 PropertyInfo qdev_prop_ptr = {
692 .name = "ptr",
693 };
694
695 /* --- mac address --- */
696
697 /*
698 * accepted syntax versions:
699 * 01:02:03:04:05:06
700 * 01-02-03-04-05-06
701 */
702 static void get_mac(Object *obj, Visitor *v, void *opaque,
703 const char *name, Error **errp)
704 {
705 DeviceState *dev = DEVICE(obj);
706 Property *prop = opaque;
707 MACAddr *mac = qdev_get_prop_ptr(dev, prop);
708 char buffer[2 * 6 + 5 + 1];
709 char *p = buffer;
710
711 snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
712 mac->a[0], mac->a[1], mac->a[2],
713 mac->a[3], mac->a[4], mac->a[5]);
714
715 visit_type_str(v, &p, name, errp);
716 }
717
718 static void set_mac(Object *obj, Visitor *v, void *opaque,
719 const char *name, Error **errp)
720 {
721 DeviceState *dev = DEVICE(obj);
722 Property *prop = opaque;
723 MACAddr *mac = qdev_get_prop_ptr(dev, prop);
724 Error *local_err = NULL;
725 int i, pos;
726 char *str, *p;
727
728 if (dev->state != DEV_STATE_CREATED) {
729 error_set(errp, QERR_PERMISSION_DENIED);
730 return;
731 }
732
733 visit_type_str(v, &str, name, &local_err);
734 if (local_err) {
735 error_propagate(errp, local_err);
736 return;
737 }
738
739 for (i = 0, pos = 0; i < 6; i++, pos += 3) {
740 if (!qemu_isxdigit(str[pos]))
741 goto inval;
742 if (!qemu_isxdigit(str[pos+1]))
743 goto inval;
744 if (i == 5) {
745 if (str[pos+2] != '\0')
746 goto inval;
747 } else {
748 if (str[pos+2] != ':' && str[pos+2] != '-')
749 goto inval;
750 }
751 mac->a[i] = strtol(str+pos, &p, 16);
752 }
753 g_free(str);
754 return;
755
756 inval:
757 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
758 g_free(str);
759 }
760
761 PropertyInfo qdev_prop_macaddr = {
762 .name = "macaddr",
763 .get = get_mac,
764 .set = set_mac,
765 };
766
767 /* --- lost tick policy --- */
768
769 static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
770 [LOST_TICK_DISCARD] = "discard",
771 [LOST_TICK_DELAY] = "delay",
772 [LOST_TICK_MERGE] = "merge",
773 [LOST_TICK_SLEW] = "slew",
774 [LOST_TICK_MAX] = NULL,
775 };
776
777 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
778
779 PropertyInfo qdev_prop_losttickpolicy = {
780 .name = "LostTickPolicy",
781 .enum_table = lost_tick_policy_table,
782 .get = get_enum,
783 .set = set_enum,
784 };
785
786 /* --- BIOS CHS translation */
787
788 static const char *bios_chs_trans_table[] = {
789 [BIOS_ATA_TRANSLATION_AUTO] = "auto",
790 [BIOS_ATA_TRANSLATION_NONE] = "none",
791 [BIOS_ATA_TRANSLATION_LBA] = "lba",
792 };
793
794 PropertyInfo qdev_prop_bios_chs_trans = {
795 .name = "bios-chs-trans",
796 .enum_table = bios_chs_trans_table,
797 .get = get_enum,
798 .set = set_enum,
799 };
800
801 /* --- pci address --- */
802
803 /*
804 * bus-local address, i.e. "$slot" or "$slot.$fn"
805 */
806 static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
807 const char *name, Error **errp)
808 {
809 DeviceState *dev = DEVICE(obj);
810 Property *prop = opaque;
811 int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
812 unsigned int slot, fn, n;
813 Error *local_err = NULL;
814 char *str;
815
816 if (dev->state != DEV_STATE_CREATED) {
817 error_set(errp, QERR_PERMISSION_DENIED);
818 return;
819 }
820
821 visit_type_str(v, &str, name, &local_err);
822 if (local_err) {
823 error_free(local_err);
824 local_err = NULL;
825 visit_type_int32(v, &value, name, &local_err);
826 if (local_err) {
827 error_propagate(errp, local_err);
828 } else if (value < -1 || value > 255) {
829 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
830 "pci_devfn");
831 } else {
832 *ptr = value;
833 }
834 return;
835 }
836
837 if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
838 fn = 0;
839 if (sscanf(str, "%x%n", &slot, &n) != 1) {
840 goto invalid;
841 }
842 }
843 if (str[n] != '\0' || fn > 7 || slot > 31) {
844 goto invalid;
845 }
846 *ptr = slot << 3 | fn;
847 g_free(str);
848 return;
849
850 invalid:
851 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
852 g_free(str);
853 }
854
855 static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
856 {
857 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
858
859 if (*ptr == -1) {
860 return snprintf(dest, len, "<unset>");
861 } else {
862 return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
863 }
864 }
865
866 PropertyInfo qdev_prop_pci_devfn = {
867 .name = "int32",
868 .legacy_name = "pci-devfn",
869 .print = print_pci_devfn,
870 .get = get_int32,
871 .set = set_pci_devfn,
872 };
873
874 /* --- blocksize --- */
875
876 static void set_blocksize(Object *obj, Visitor *v, void *opaque,
877 const char *name, Error **errp)
878 {
879 DeviceState *dev = DEVICE(obj);
880 Property *prop = opaque;
881 uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
882 Error *local_err = NULL;
883 const int64_t min = 512;
884 const int64_t max = 32768;
885
886 if (dev->state != DEV_STATE_CREATED) {
887 error_set(errp, QERR_PERMISSION_DENIED);
888 return;
889 }
890
891 visit_type_uint16(v, &value, name, &local_err);
892 if (local_err) {
893 error_propagate(errp, local_err);
894 return;
895 }
896 if (value < min || value > max) {
897 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
898 dev->id?:"", name, (int64_t)value, min, max);
899 return;
900 }
901
902 /* We rely on power-of-2 blocksizes for bitmasks */
903 if ((value & (value - 1)) != 0) {
904 error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
905 dev->id?:"", name, (int64_t)value);
906 return;
907 }
908
909 *ptr = value;
910 }
911
912 PropertyInfo qdev_prop_blocksize = {
913 .name = "blocksize",
914 .get = get_uint16,
915 .set = set_blocksize,
916 };
917
918 /* --- pci host address --- */
919
920 static void get_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
921 const char *name, Error **errp)
922 {
923 DeviceState *dev = DEVICE(obj);
924 Property *prop = opaque;
925 PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
926 char buffer[] = "xxxx:xx:xx.x";
927 char *p = buffer;
928 int rc = 0;
929
930 rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d",
931 addr->domain, addr->bus, addr->slot, addr->function);
932 assert(rc == sizeof(buffer) - 1);
933
934 visit_type_str(v, &p, name, errp);
935 }
936
937 /*
938 * Parse [<domain>:]<bus>:<slot>.<func>
939 * if <domain> is not supplied, it's assumed to be 0.
940 */
941 static void set_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
942 const char *name, Error **errp)
943 {
944 DeviceState *dev = DEVICE(obj);
945 Property *prop = opaque;
946 PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
947 Error *local_err = NULL;
948 char *str, *p;
949 char *e;
950 unsigned long val;
951 unsigned long dom = 0, bus = 0;
952 unsigned int slot = 0, func = 0;
953
954 if (dev->state != DEV_STATE_CREATED) {
955 error_set(errp, QERR_PERMISSION_DENIED);
956 return;
957 }
958
959 visit_type_str(v, &str, name, &local_err);
960 if (local_err) {
961 error_propagate(errp, local_err);
962 return;
963 }
964
965 p = str;
966 val = strtoul(p, &e, 16);
967 if (e == p || *e != ':') {
968 goto inval;
969 }
970 bus = val;
971
972 p = e + 1;
973 val = strtoul(p, &e, 16);
974 if (e == p) {
975 goto inval;
976 }
977 if (*e == ':') {
978 dom = bus;
979 bus = val;
980 p = e + 1;
981 val = strtoul(p, &e, 16);
982 if (e == p) {
983 goto inval;
984 }
985 }
986 slot = val;
987
988 if (*e != '.') {
989 goto inval;
990 }
991 p = e + 1;
992 val = strtoul(p, &e, 10);
993 if (e == p) {
994 goto inval;
995 }
996 func = val;
997
998 if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
999 goto inval;
1000 }
1001
1002 if (*e) {
1003 goto inval;
1004 }
1005
1006 addr->domain = dom;
1007 addr->bus = bus;
1008 addr->slot = slot;
1009 addr->function = func;
1010
1011 g_free(str);
1012 return;
1013
1014 inval:
1015 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
1016 g_free(str);
1017 }
1018
1019 PropertyInfo qdev_prop_pci_host_devaddr = {
1020 .name = "pci-host-devaddr",
1021 .get = get_pci_host_devaddr,
1022 .set = set_pci_host_devaddr,
1023 };
1024
1025 /* --- public helpers --- */
1026
1027 static Property *qdev_prop_walk(Property *props, const char *name)
1028 {
1029 if (!props)
1030 return NULL;
1031 while (props->name) {
1032 if (strcmp(props->name, name) == 0)
1033 return props;
1034 props++;
1035 }
1036 return NULL;
1037 }
1038
1039 static Property *qdev_prop_find(DeviceState *dev, const char *name)
1040 {
1041 ObjectClass *class;
1042 Property *prop;
1043
1044 /* device properties */
1045 class = object_get_class(OBJECT(dev));
1046 do {
1047 prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
1048 if (prop) {
1049 return prop;
1050 }
1051 class = object_class_get_parent(class);
1052 } while (class != object_class_by_name(TYPE_DEVICE));
1053
1054 return NULL;
1055 }
1056
1057 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
1058 Property *prop, const char *value)
1059 {
1060 switch (ret) {
1061 case -EEXIST:
1062 error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
1063 object_get_typename(OBJECT(dev)), prop->name, value);
1064 break;
1065 default:
1066 case -EINVAL:
1067 error_set(errp, QERR_PROPERTY_VALUE_BAD,
1068 object_get_typename(OBJECT(dev)), prop->name, value);
1069 break;
1070 case -ENOENT:
1071 error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
1072 object_get_typename(OBJECT(dev)), prop->name, value);
1073 break;
1074 case 0:
1075 break;
1076 }
1077 }
1078
1079 int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
1080 {
1081 char *legacy_name;
1082 Error *err = NULL;
1083
1084 legacy_name = g_strdup_printf("legacy-%s", name);
1085 if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
1086 object_property_parse(OBJECT(dev), value, legacy_name, &err);
1087 } else {
1088 object_property_parse(OBJECT(dev), value, name, &err);
1089 }
1090 g_free(legacy_name);
1091
1092 if (err) {
1093 qerror_report_err(err);
1094 error_free(err);
1095 return -1;
1096 }
1097 return 0;
1098 }
1099
1100 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1101 {
1102 Error *errp = NULL;
1103 object_property_set_bool(OBJECT(dev), value, name, &errp);
1104 assert_no_error(errp);
1105 }
1106
1107 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1108 {
1109 Error *errp = NULL;
1110 object_property_set_int(OBJECT(dev), value, name, &errp);
1111 assert_no_error(errp);
1112 }
1113
1114 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1115 {
1116 Error *errp = NULL;
1117 object_property_set_int(OBJECT(dev), value, name, &errp);
1118 assert_no_error(errp);
1119 }
1120
1121 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1122 {
1123 Error *errp = NULL;
1124 object_property_set_int(OBJECT(dev), value, name, &errp);
1125 assert_no_error(errp);
1126 }
1127
1128 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1129 {
1130 Error *errp = NULL;
1131 object_property_set_int(OBJECT(dev), value, name, &errp);
1132 assert_no_error(errp);
1133 }
1134
1135 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1136 {
1137 Error *errp = NULL;
1138 object_property_set_int(OBJECT(dev), value, name, &errp);
1139 assert_no_error(errp);
1140 }
1141
1142 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
1143 {
1144 Error *errp = NULL;
1145 object_property_set_str(OBJECT(dev), value, name, &errp);
1146 assert_no_error(errp);
1147 }
1148
1149 int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
1150 {
1151 Error *errp = NULL;
1152 const char *bdrv_name = value ? bdrv_get_device_name(value) : "";
1153 object_property_set_str(OBJECT(dev), bdrv_name,
1154 name, &errp);
1155 if (errp) {
1156 qerror_report_err(errp);
1157 error_free(errp);
1158 return -1;
1159 }
1160 return 0;
1161 }
1162
1163 void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value)
1164 {
1165 if (qdev_prop_set_drive(dev, name, value) < 0) {
1166 exit(1);
1167 }
1168 }
1169 void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
1170 {
1171 Error *errp = NULL;
1172 assert(!value || value->label);
1173 object_property_set_str(OBJECT(dev),
1174 value ? value->label : "", name, &errp);
1175 assert_no_error(errp);
1176 }
1177
1178 void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value)
1179 {
1180 Error *errp = NULL;
1181 assert(!value || value->name);
1182 object_property_set_str(OBJECT(dev),
1183 value ? value->name : "", name, &errp);
1184 assert_no_error(errp);
1185 }
1186
1187 void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
1188 {
1189 Error *errp = NULL;
1190 object_property_set_int(OBJECT(dev), value ? value->id : -1, name, &errp);
1191 assert_no_error(errp);
1192 }
1193
1194 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
1195 {
1196 Error *errp = NULL;
1197 char str[2 * 6 + 5 + 1];
1198 snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1199 value[0], value[1], value[2], value[3], value[4], value[5]);
1200
1201 object_property_set_str(OBJECT(dev), str, name, &errp);
1202 assert_no_error(errp);
1203 }
1204
1205 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1206 {
1207 Property *prop;
1208 Error *errp = NULL;
1209
1210 prop = qdev_prop_find(dev, name);
1211 object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
1212 name, &errp);
1213 assert_no_error(errp);
1214 }
1215
1216 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1217 {
1218 Property *prop;
1219 void **ptr;
1220
1221 prop = qdev_prop_find(dev, name);
1222 assert(prop && prop->info == &qdev_prop_ptr);
1223 ptr = qdev_get_prop_ptr(dev, prop);
1224 *ptr = value;
1225 }
1226
1227 static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
1228
1229 static void qdev_prop_register_global(GlobalProperty *prop)
1230 {
1231 QTAILQ_INSERT_TAIL(&global_props, prop, next);
1232 }
1233
1234 void qdev_prop_register_global_list(GlobalProperty *props)
1235 {
1236 int i;
1237
1238 for (i = 0; props[i].driver != NULL; i++) {
1239 qdev_prop_register_global(props+i);
1240 }
1241 }
1242
1243 void qdev_prop_set_globals(DeviceState *dev)
1244 {
1245 ObjectClass *class = object_get_class(OBJECT(dev));
1246
1247 do {
1248 GlobalProperty *prop;
1249 QTAILQ_FOREACH(prop, &global_props, next) {
1250 if (strcmp(object_class_get_name(class), prop->driver) != 0) {
1251 continue;
1252 }
1253 if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
1254 exit(1);
1255 }
1256 }
1257 class = object_class_get_parent(class);
1258 } while (class);
1259 }
1260
1261 static int qdev_add_one_global(QemuOpts *opts, void *opaque)
1262 {
1263 GlobalProperty *g;
1264
1265 g = g_malloc0(sizeof(*g));
1266 g->driver = qemu_opt_get(opts, "driver");
1267 g->property = qemu_opt_get(opts, "property");
1268 g->value = qemu_opt_get(opts, "value");
1269 qdev_prop_register_global(g);
1270 return 0;
1271 }
1272
1273 void qemu_add_globals(void)
1274 {
1275 qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0);
1276 }