]> Git Repo - qemu.git/blob - hw/qdev-properties.c
Merge branch 'eflags3' of git://github.com/rth7680/qemu
[qemu.git] / hw / qdev-properties.c
1 #include "net/net.h"
2 #include "qdev.h"
3 #include "qapi/qmp/qerror.h"
4 #include "sysemu/blockdev.h"
5 #include "hw/block-common.h"
6 #include "net/hub.h"
7 #include "qapi/visitor.h"
8 #include "char/char.h"
9
10 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
11 {
12     void *ptr = dev;
13     ptr += prop->offset;
14     return ptr;
15 }
16
17 static void get_enum(Object *obj, Visitor *v, void *opaque,
18                      const char *name, Error **errp)
19 {
20     DeviceState *dev = DEVICE(obj);
21     Property *prop = opaque;
22     int *ptr = qdev_get_prop_ptr(dev, prop);
23
24     visit_type_enum(v, ptr, prop->info->enum_table,
25                     prop->info->name, prop->name, errp);
26 }
27
28 static void set_enum(Object *obj, Visitor *v, void *opaque,
29                      const char *name, Error **errp)
30 {
31     DeviceState *dev = DEVICE(obj);
32     Property *prop = opaque;
33     int *ptr = qdev_get_prop_ptr(dev, prop);
34
35     if (dev->realized) {
36         error_set(errp, QERR_PERMISSION_DENIED);
37         return;
38     }
39
40     visit_type_enum(v, ptr, prop->info->enum_table,
41                     prop->info->name, prop->name, errp);
42 }
43
44 /* Bit */
45
46 static uint32_t qdev_get_prop_mask(Property *prop)
47 {
48     assert(prop->info == &qdev_prop_bit);
49     return 0x1 << prop->bitnr;
50 }
51
52 static void bit_prop_set(DeviceState *dev, Property *props, bool val)
53 {
54     uint32_t *p = qdev_get_prop_ptr(dev, props);
55     uint32_t mask = qdev_get_prop_mask(props);
56     if (val) {
57         *p |= mask;
58     } else {
59         *p &= ~mask;
60     }
61 }
62
63 static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
64 {
65     uint32_t *p = qdev_get_prop_ptr(dev, prop);
66     return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
67 }
68
69 static void get_bit(Object *obj, Visitor *v, void *opaque,
70                     const char *name, Error **errp)
71 {
72     DeviceState *dev = DEVICE(obj);
73     Property *prop = opaque;
74     uint32_t *p = qdev_get_prop_ptr(dev, prop);
75     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
76
77     visit_type_bool(v, &value, name, errp);
78 }
79
80 static void set_bit(Object *obj, Visitor *v, void *opaque,
81                     const char *name, Error **errp)
82 {
83     DeviceState *dev = DEVICE(obj);
84     Property *prop = opaque;
85     Error *local_err = NULL;
86     bool value;
87
88     if (dev->realized) {
89         error_set(errp, QERR_PERMISSION_DENIED);
90         return;
91     }
92
93     visit_type_bool(v, &value, name, &local_err);
94     if (local_err) {
95         error_propagate(errp, local_err);
96         return;
97     }
98     bit_prop_set(dev, prop, value);
99 }
100
101 PropertyInfo qdev_prop_bit = {
102     .name  = "boolean",
103     .legacy_name  = "on/off",
104     .print = print_bit,
105     .get   = get_bit,
106     .set   = set_bit,
107 };
108
109 /* --- 8bit integer --- */
110
111 static void get_uint8(Object *obj, Visitor *v, void *opaque,
112                       const char *name, Error **errp)
113 {
114     DeviceState *dev = DEVICE(obj);
115     Property *prop = opaque;
116     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
117
118     visit_type_uint8(v, ptr, name, errp);
119 }
120
121 static void set_uint8(Object *obj, Visitor *v, void *opaque,
122                       const char *name, Error **errp)
123 {
124     DeviceState *dev = DEVICE(obj);
125     Property *prop = opaque;
126     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
127
128     if (dev->realized) {
129         error_set(errp, QERR_PERMISSION_DENIED);
130         return;
131     }
132
133     visit_type_uint8(v, ptr, name, errp);
134 }
135
136 PropertyInfo qdev_prop_uint8 = {
137     .name  = "uint8",
138     .get   = get_uint8,
139     .set   = set_uint8,
140 };
141
142 /* --- 8bit hex value --- */
143
144 static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
145 {
146     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
147     char *end;
148
149     if (str[0] != '0' || str[1] != 'x') {
150         return -EINVAL;
151     }
152
153     *ptr = strtoul(str, &end, 16);
154     if ((*end != '\0') || (end == str)) {
155         return -EINVAL;
156     }
157
158     return 0;
159 }
160
161 static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
162 {
163     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
164     return snprintf(dest, len, "0x%" PRIx8, *ptr);
165 }
166
167 PropertyInfo qdev_prop_hex8 = {
168     .name  = "uint8",
169     .legacy_name  = "hex8",
170     .parse = parse_hex8,
171     .print = print_hex8,
172     .get   = get_uint8,
173     .set   = set_uint8,
174 };
175
176 /* --- 16bit integer --- */
177
178 static void get_uint16(Object *obj, Visitor *v, void *opaque,
179                        const char *name, Error **errp)
180 {
181     DeviceState *dev = DEVICE(obj);
182     Property *prop = opaque;
183     uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
184
185     visit_type_uint16(v, ptr, name, errp);
186 }
187
188 static void set_uint16(Object *obj, Visitor *v, void *opaque,
189                        const char *name, Error **errp)
190 {
191     DeviceState *dev = DEVICE(obj);
192     Property *prop = opaque;
193     uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
194
195     if (dev->realized) {
196         error_set(errp, QERR_PERMISSION_DENIED);
197         return;
198     }
199
200     visit_type_uint16(v, ptr, name, errp);
201 }
202
203 PropertyInfo qdev_prop_uint16 = {
204     .name  = "uint16",
205     .get   = get_uint16,
206     .set   = set_uint16,
207 };
208
209 /* --- 32bit integer --- */
210
211 static void get_uint32(Object *obj, Visitor *v, void *opaque,
212                        const char *name, Error **errp)
213 {
214     DeviceState *dev = DEVICE(obj);
215     Property *prop = opaque;
216     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
217
218     visit_type_uint32(v, ptr, name, errp);
219 }
220
221 static void set_uint32(Object *obj, Visitor *v, void *opaque,
222                        const char *name, Error **errp)
223 {
224     DeviceState *dev = DEVICE(obj);
225     Property *prop = opaque;
226     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
227
228     if (dev->realized) {
229         error_set(errp, QERR_PERMISSION_DENIED);
230         return;
231     }
232
233     visit_type_uint32(v, ptr, name, errp);
234 }
235
236 static void get_int32(Object *obj, Visitor *v, void *opaque,
237                       const char *name, Error **errp)
238 {
239     DeviceState *dev = DEVICE(obj);
240     Property *prop = opaque;
241     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
242
243     visit_type_int32(v, ptr, name, errp);
244 }
245
246 static void set_int32(Object *obj, Visitor *v, void *opaque,
247                       const char *name, Error **errp)
248 {
249     DeviceState *dev = DEVICE(obj);
250     Property *prop = opaque;
251     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
252
253     if (dev->realized) {
254         error_set(errp, QERR_PERMISSION_DENIED);
255         return;
256     }
257
258     visit_type_int32(v, ptr, name, errp);
259 }
260
261 PropertyInfo qdev_prop_uint32 = {
262     .name  = "uint32",
263     .get   = get_uint32,
264     .set   = set_uint32,
265 };
266
267 PropertyInfo qdev_prop_int32 = {
268     .name  = "int32",
269     .get   = get_int32,
270     .set   = set_int32,
271 };
272
273 /* --- 32bit hex value --- */
274
275 static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
276 {
277     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
278     char *end;
279
280     if (str[0] != '0' || str[1] != 'x') {
281         return -EINVAL;
282     }
283
284     *ptr = strtoul(str, &end, 16);
285     if ((*end != '\0') || (end == str)) {
286         return -EINVAL;
287     }
288
289     return 0;
290 }
291
292 static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
293 {
294     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
295     return snprintf(dest, len, "0x%" PRIx32, *ptr);
296 }
297
298 PropertyInfo qdev_prop_hex32 = {
299     .name  = "uint32",
300     .legacy_name  = "hex32",
301     .parse = parse_hex32,
302     .print = print_hex32,
303     .get   = get_uint32,
304     .set   = set_uint32,
305 };
306
307 /* --- 64bit integer --- */
308
309 static void get_uint64(Object *obj, Visitor *v, void *opaque,
310                        const char *name, Error **errp)
311 {
312     DeviceState *dev = DEVICE(obj);
313     Property *prop = opaque;
314     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
315
316     visit_type_uint64(v, ptr, name, errp);
317 }
318
319 static void set_uint64(Object *obj, Visitor *v, void *opaque,
320                        const char *name, Error **errp)
321 {
322     DeviceState *dev = DEVICE(obj);
323     Property *prop = opaque;
324     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
325
326     if (dev->realized) {
327         error_set(errp, QERR_PERMISSION_DENIED);
328         return;
329     }
330
331     visit_type_uint64(v, ptr, name, errp);
332 }
333
334 PropertyInfo qdev_prop_uint64 = {
335     .name  = "uint64",
336     .get   = get_uint64,
337     .set   = set_uint64,
338 };
339
340 /* --- 64bit hex value --- */
341
342 static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
343 {
344     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
345     char *end;
346
347     if (str[0] != '0' || str[1] != 'x') {
348         return -EINVAL;
349     }
350
351     *ptr = strtoull(str, &end, 16);
352     if ((*end != '\0') || (end == str)) {
353         return -EINVAL;
354     }
355
356     return 0;
357 }
358
359 static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
360 {
361     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
362     return snprintf(dest, len, "0x%" PRIx64, *ptr);
363 }
364
365 PropertyInfo qdev_prop_hex64 = {
366     .name  = "uint64",
367     .legacy_name  = "hex64",
368     .parse = parse_hex64,
369     .print = print_hex64,
370     .get   = get_uint64,
371     .set   = set_uint64,
372 };
373
374 /* --- string --- */
375
376 static void release_string(Object *obj, const char *name, void *opaque)
377 {
378     Property *prop = opaque;
379     g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
380 }
381
382 static int print_string(DeviceState *dev, Property *prop, char *dest,
383                         size_t len)
384 {
385     char **ptr = qdev_get_prop_ptr(dev, prop);
386     if (!*ptr) {
387         return snprintf(dest, len, "<null>");
388     }
389     return snprintf(dest, len, "\"%s\"", *ptr);
390 }
391
392 static void get_string(Object *obj, Visitor *v, void *opaque,
393                        const char *name, Error **errp)
394 {
395     DeviceState *dev = DEVICE(obj);
396     Property *prop = opaque;
397     char **ptr = qdev_get_prop_ptr(dev, prop);
398
399     if (!*ptr) {
400         char *str = (char *)"";
401         visit_type_str(v, &str, name, errp);
402     } else {
403         visit_type_str(v, ptr, name, errp);
404     }
405 }
406
407 static void set_string(Object *obj, Visitor *v, void *opaque,
408                        const char *name, Error **errp)
409 {
410     DeviceState *dev = DEVICE(obj);
411     Property *prop = opaque;
412     char **ptr = qdev_get_prop_ptr(dev, prop);
413     Error *local_err = NULL;
414     char *str;
415
416     if (dev->realized) {
417         error_set(errp, QERR_PERMISSION_DENIED);
418         return;
419     }
420
421     visit_type_str(v, &str, name, &local_err);
422     if (local_err) {
423         error_propagate(errp, local_err);
424         return;
425     }
426     if (*ptr) {
427         g_free(*ptr);
428     }
429     *ptr = str;
430 }
431
432 PropertyInfo qdev_prop_string = {
433     .name  = "string",
434     .print = print_string,
435     .release = release_string,
436     .get   = get_string,
437     .set   = set_string,
438 };
439
440 /* --- pointer --- */
441
442 /* Not a proper property, just for dirty hacks.  TODO Remove it!  */
443 PropertyInfo qdev_prop_ptr = {
444     .name  = "ptr",
445 };
446
447 /* --- mac address --- */
448
449 /*
450  * accepted syntax versions:
451  *   01:02:03:04:05:06
452  *   01-02-03-04-05-06
453  */
454 static void get_mac(Object *obj, Visitor *v, void *opaque,
455                     const char *name, Error **errp)
456 {
457     DeviceState *dev = DEVICE(obj);
458     Property *prop = opaque;
459     MACAddr *mac = qdev_get_prop_ptr(dev, prop);
460     char buffer[2 * 6 + 5 + 1];
461     char *p = buffer;
462
463     snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
464              mac->a[0], mac->a[1], mac->a[2],
465              mac->a[3], mac->a[4], mac->a[5]);
466
467     visit_type_str(v, &p, name, errp);
468 }
469
470 static void set_mac(Object *obj, Visitor *v, void *opaque,
471                     const char *name, Error **errp)
472 {
473     DeviceState *dev = DEVICE(obj);
474     Property *prop = opaque;
475     MACAddr *mac = qdev_get_prop_ptr(dev, prop);
476     Error *local_err = NULL;
477     int i, pos;
478     char *str, *p;
479
480     if (dev->realized) {
481         error_set(errp, QERR_PERMISSION_DENIED);
482         return;
483     }
484
485     visit_type_str(v, &str, name, &local_err);
486     if (local_err) {
487         error_propagate(errp, local_err);
488         return;
489     }
490
491     for (i = 0, pos = 0; i < 6; i++, pos += 3) {
492         if (!qemu_isxdigit(str[pos])) {
493             goto inval;
494         }
495         if (!qemu_isxdigit(str[pos+1])) {
496             goto inval;
497         }
498         if (i == 5) {
499             if (str[pos+2] != '\0') {
500                 goto inval;
501             }
502         } else {
503             if (str[pos+2] != ':' && str[pos+2] != '-') {
504                 goto inval;
505             }
506         }
507         mac->a[i] = strtol(str+pos, &p, 16);
508     }
509     g_free(str);
510     return;
511
512 inval:
513     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
514     g_free(str);
515 }
516
517 PropertyInfo qdev_prop_macaddr = {
518     .name  = "macaddr",
519     .get   = get_mac,
520     .set   = set_mac,
521 };
522
523 /* --- lost tick policy --- */
524
525 static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
526     [LOST_TICK_DISCARD] = "discard",
527     [LOST_TICK_DELAY] = "delay",
528     [LOST_TICK_MERGE] = "merge",
529     [LOST_TICK_SLEW] = "slew",
530     [LOST_TICK_MAX] = NULL,
531 };
532
533 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
534
535 PropertyInfo qdev_prop_losttickpolicy = {
536     .name  = "LostTickPolicy",
537     .enum_table  = lost_tick_policy_table,
538     .get   = get_enum,
539     .set   = set_enum,
540 };
541
542 /* --- BIOS CHS translation */
543
544 static const char *bios_chs_trans_table[] = {
545     [BIOS_ATA_TRANSLATION_AUTO] = "auto",
546     [BIOS_ATA_TRANSLATION_NONE] = "none",
547     [BIOS_ATA_TRANSLATION_LBA]  = "lba",
548 };
549
550 PropertyInfo qdev_prop_bios_chs_trans = {
551     .name = "bios-chs-trans",
552     .enum_table = bios_chs_trans_table,
553     .get = get_enum,
554     .set = set_enum,
555 };
556
557 /* --- pci address --- */
558
559 /*
560  * bus-local address, i.e. "$slot" or "$slot.$fn"
561  */
562 static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
563                           const char *name, Error **errp)
564 {
565     DeviceState *dev = DEVICE(obj);
566     Property *prop = opaque;
567     int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
568     unsigned int slot, fn, n;
569     Error *local_err = NULL;
570     char *str;
571
572     if (dev->realized) {
573         error_set(errp, QERR_PERMISSION_DENIED);
574         return;
575     }
576
577     visit_type_str(v, &str, name, &local_err);
578     if (local_err) {
579         error_free(local_err);
580         local_err = NULL;
581         visit_type_int32(v, &value, name, &local_err);
582         if (local_err) {
583             error_propagate(errp, local_err);
584         } else if (value < -1 || value > 255) {
585             error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
586                       "pci_devfn");
587         } else {
588             *ptr = value;
589         }
590         return;
591     }
592
593     if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
594         fn = 0;
595         if (sscanf(str, "%x%n", &slot, &n) != 1) {
596             goto invalid;
597         }
598     }
599     if (str[n] != '\0' || fn > 7 || slot > 31) {
600         goto invalid;
601     }
602     *ptr = slot << 3 | fn;
603     g_free(str);
604     return;
605
606 invalid:
607     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
608     g_free(str);
609 }
610
611 static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest,
612                            size_t len)
613 {
614     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
615
616     if (*ptr == -1) {
617         return snprintf(dest, len, "<unset>");
618     } else {
619         return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
620     }
621 }
622
623 PropertyInfo qdev_prop_pci_devfn = {
624     .name  = "int32",
625     .legacy_name  = "pci-devfn",
626     .print = print_pci_devfn,
627     .get   = get_int32,
628     .set   = set_pci_devfn,
629 };
630
631 /* --- blocksize --- */
632
633 static void set_blocksize(Object *obj, Visitor *v, void *opaque,
634                           const char *name, Error **errp)
635 {
636     DeviceState *dev = DEVICE(obj);
637     Property *prop = opaque;
638     uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
639     Error *local_err = NULL;
640     const int64_t min = 512;
641     const int64_t max = 32768;
642
643     if (dev->realized) {
644         error_set(errp, QERR_PERMISSION_DENIED);
645         return;
646     }
647
648     visit_type_uint16(v, &value, name, &local_err);
649     if (local_err) {
650         error_propagate(errp, local_err);
651         return;
652     }
653     if (value < min || value > max) {
654         error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
655                   dev->id?:"", name, (int64_t)value, min, max);
656         return;
657     }
658
659     /* We rely on power-of-2 blocksizes for bitmasks */
660     if ((value & (value - 1)) != 0) {
661         error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
662                   dev->id?:"", name, (int64_t)value);
663         return;
664     }
665
666     *ptr = value;
667 }
668
669 PropertyInfo qdev_prop_blocksize = {
670     .name  = "blocksize",
671     .get   = get_uint16,
672     .set   = set_blocksize,
673 };
674
675 /* --- pci host address --- */
676
677 static void get_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
678                                  const char *name, Error **errp)
679 {
680     DeviceState *dev = DEVICE(obj);
681     Property *prop = opaque;
682     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
683     char buffer[] = "xxxx:xx:xx.x";
684     char *p = buffer;
685     int rc = 0;
686
687     rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d",
688                   addr->domain, addr->bus, addr->slot, addr->function);
689     assert(rc == sizeof(buffer) - 1);
690
691     visit_type_str(v, &p, name, errp);
692 }
693
694 /*
695  * Parse [<domain>:]<bus>:<slot>.<func>
696  *   if <domain> is not supplied, it's assumed to be 0.
697  */
698 static void set_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
699                                  const char *name, Error **errp)
700 {
701     DeviceState *dev = DEVICE(obj);
702     Property *prop = opaque;
703     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
704     Error *local_err = NULL;
705     char *str, *p;
706     char *e;
707     unsigned long val;
708     unsigned long dom = 0, bus = 0;
709     unsigned int slot = 0, func = 0;
710
711     if (dev->realized) {
712         error_set(errp, QERR_PERMISSION_DENIED);
713         return;
714     }
715
716     visit_type_str(v, &str, name, &local_err);
717     if (local_err) {
718         error_propagate(errp, local_err);
719         return;
720     }
721
722     p = str;
723     val = strtoul(p, &e, 16);
724     if (e == p || *e != ':') {
725         goto inval;
726     }
727     bus = val;
728
729     p = e + 1;
730     val = strtoul(p, &e, 16);
731     if (e == p) {
732         goto inval;
733     }
734     if (*e == ':') {
735         dom = bus;
736         bus = val;
737         p = e + 1;
738         val = strtoul(p, &e, 16);
739         if (e == p) {
740             goto inval;
741         }
742     }
743     slot = val;
744
745     if (*e != '.') {
746         goto inval;
747     }
748     p = e + 1;
749     val = strtoul(p, &e, 10);
750     if (e == p) {
751         goto inval;
752     }
753     func = val;
754
755     if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
756         goto inval;
757     }
758
759     if (*e) {
760         goto inval;
761     }
762
763     addr->domain = dom;
764     addr->bus = bus;
765     addr->slot = slot;
766     addr->function = func;
767
768     g_free(str);
769     return;
770
771 inval:
772     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
773     g_free(str);
774 }
775
776 PropertyInfo qdev_prop_pci_host_devaddr = {
777     .name = "pci-host-devaddr",
778     .get = get_pci_host_devaddr,
779     .set = set_pci_host_devaddr,
780 };
781
782 /* --- public helpers --- */
783
784 static Property *qdev_prop_walk(Property *props, const char *name)
785 {
786     if (!props) {
787         return NULL;
788     }
789     while (props->name) {
790         if (strcmp(props->name, name) == 0) {
791             return props;
792         }
793         props++;
794     }
795     return NULL;
796 }
797
798 static Property *qdev_prop_find(DeviceState *dev, const char *name)
799 {
800     ObjectClass *class;
801     Property *prop;
802
803     /* device properties */
804     class = object_get_class(OBJECT(dev));
805     do {
806         prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
807         if (prop) {
808             return prop;
809         }
810         class = object_class_get_parent(class);
811     } while (class != object_class_by_name(TYPE_DEVICE));
812
813     return NULL;
814 }
815
816 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
817                                     Property *prop, const char *value)
818 {
819     switch (ret) {
820     case -EEXIST:
821         error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
822                   object_get_typename(OBJECT(dev)), prop->name, value);
823         break;
824     default:
825     case -EINVAL:
826         error_set(errp, QERR_PROPERTY_VALUE_BAD,
827                   object_get_typename(OBJECT(dev)), prop->name, value);
828         break;
829     case -ENOENT:
830         error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
831                   object_get_typename(OBJECT(dev)), prop->name, value);
832         break;
833     case 0:
834         break;
835     }
836 }
837
838 int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
839 {
840     char *legacy_name;
841     Error *err = NULL;
842
843     legacy_name = g_strdup_printf("legacy-%s", name);
844     if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
845         object_property_parse(OBJECT(dev), value, legacy_name, &err);
846     } else {
847         object_property_parse(OBJECT(dev), value, name, &err);
848     }
849     g_free(legacy_name);
850
851     if (err) {
852         qerror_report_err(err);
853         error_free(err);
854         return -1;
855     }
856     return 0;
857 }
858
859 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
860 {
861     Error *errp = NULL;
862     object_property_set_bool(OBJECT(dev), value, name, &errp);
863     assert_no_error(errp);
864 }
865
866 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
867 {
868     Error *errp = NULL;
869     object_property_set_int(OBJECT(dev), value, name, &errp);
870     assert_no_error(errp);
871 }
872
873 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
874 {
875     Error *errp = NULL;
876     object_property_set_int(OBJECT(dev), value, name, &errp);
877     assert_no_error(errp);
878 }
879
880 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
881 {
882     Error *errp = NULL;
883     object_property_set_int(OBJECT(dev), value, name, &errp);
884     assert_no_error(errp);
885 }
886
887 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
888 {
889     Error *errp = NULL;
890     object_property_set_int(OBJECT(dev), value, name, &errp);
891     assert_no_error(errp);
892 }
893
894 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
895 {
896     Error *errp = NULL;
897     object_property_set_int(OBJECT(dev), value, name, &errp);
898     assert_no_error(errp);
899 }
900
901 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
902 {
903     Error *errp = NULL;
904     object_property_set_str(OBJECT(dev), value, name, &errp);
905     assert_no_error(errp);
906 }
907
908 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
909 {
910     Error *errp = NULL;
911     char str[2 * 6 + 5 + 1];
912     snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
913              value[0], value[1], value[2], value[3], value[4], value[5]);
914
915     object_property_set_str(OBJECT(dev), str, name, &errp);
916     assert_no_error(errp);
917 }
918
919 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
920 {
921     Property *prop;
922     Error *errp = NULL;
923
924     prop = qdev_prop_find(dev, name);
925     object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
926                             name, &errp);
927     assert_no_error(errp);
928 }
929
930 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
931 {
932     Property *prop;
933     void **ptr;
934
935     prop = qdev_prop_find(dev, name);
936     assert(prop && prop->info == &qdev_prop_ptr);
937     ptr = qdev_get_prop_ptr(dev, prop);
938     *ptr = value;
939 }
940
941 static QTAILQ_HEAD(, GlobalProperty) global_props =
942         QTAILQ_HEAD_INITIALIZER(global_props);
943
944 void qdev_prop_register_global(GlobalProperty *prop)
945 {
946     QTAILQ_INSERT_TAIL(&global_props, prop, next);
947 }
948
949 void qdev_prop_register_global_list(GlobalProperty *props)
950 {
951     int i;
952
953     for (i = 0; props[i].driver != NULL; i++) {
954         qdev_prop_register_global(props+i);
955     }
956 }
957
958 void qdev_prop_set_globals(DeviceState *dev)
959 {
960     ObjectClass *class = object_get_class(OBJECT(dev));
961
962     do {
963         GlobalProperty *prop;
964         QTAILQ_FOREACH(prop, &global_props, next) {
965             if (strcmp(object_class_get_name(class), prop->driver) != 0) {
966                 continue;
967             }
968             if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
969                 exit(1);
970             }
971         }
972         class = object_class_get_parent(class);
973     } while (class);
974 }
This page took 0.074292 seconds and 4 git commands to generate.