]> Git Repo - qemu.git/blob - hw/core/qdev-properties.c
qdev: remove PropertyInfo.qtype field
[qemu.git] / hw / core / qdev-properties.c
1 #include "qemu/osdep.h"
2 #include "net/net.h"
3 #include "hw/qdev.h"
4 #include "qapi/error.h"
5 #include "hw/pci/pci.h"
6 #include "qapi/qmp/qerror.h"
7 #include "qemu/error-report.h"
8 #include "sysemu/block-backend.h"
9 #include "hw/block/block.h"
10 #include "net/hub.h"
11 #include "qapi/visitor.h"
12 #include "chardev/char.h"
13
14 void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
15                                   Error **errp)
16 {
17     if (dev->id) {
18         error_setg(errp, "Attempt to set property '%s' on device '%s' "
19                    "(type '%s') after it was realized", name, dev->id,
20                    object_get_typename(OBJECT(dev)));
21     } else {
22         error_setg(errp, "Attempt to set property '%s' on anonymous device "
23                    "(type '%s') after it was realized", name,
24                    object_get_typename(OBJECT(dev)));
25     }
26 }
27
28 void qdev_prop_allow_set_link_before_realize(Object *obj, const char *name,
29                                              Object *val, Error **errp)
30 {
31     DeviceState *dev = DEVICE(obj);
32
33     if (dev->realized) {
34         error_setg(errp, "Attempt to set link property '%s' on device '%s' "
35                    "(type '%s') after it was realized",
36                    name, dev->id, object_get_typename(obj));
37     }
38 }
39
40 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
41 {
42     void *ptr = dev;
43     ptr += prop->offset;
44     return ptr;
45 }
46
47 static void get_enum(Object *obj, Visitor *v, const char *name, void *opaque,
48                      Error **errp)
49 {
50     DeviceState *dev = DEVICE(obj);
51     Property *prop = opaque;
52     int *ptr = qdev_get_prop_ptr(dev, prop);
53
54     visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
55 }
56
57 static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque,
58                      Error **errp)
59 {
60     DeviceState *dev = DEVICE(obj);
61     Property *prop = opaque;
62     int *ptr = qdev_get_prop_ptr(dev, prop);
63
64     if (dev->realized) {
65         qdev_prop_set_after_realize(dev, name, errp);
66         return;
67     }
68
69     visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
70 }
71
72 static void set_default_value_enum(Object *obj, const Property *prop)
73 {
74     object_property_set_str(obj, prop->info->enum_table[prop->defval],
75                             prop->name, &error_abort);
76 }
77
78 /* Bit */
79
80 static uint32_t qdev_get_prop_mask(Property *prop)
81 {
82     assert(prop->info == &qdev_prop_bit);
83     return 0x1 << prop->bitnr;
84 }
85
86 static void bit_prop_set(DeviceState *dev, Property *props, bool val)
87 {
88     uint32_t *p = qdev_get_prop_ptr(dev, props);
89     uint32_t mask = qdev_get_prop_mask(props);
90     if (val) {
91         *p |= mask;
92     } else {
93         *p &= ~mask;
94     }
95 }
96
97 static void prop_get_bit(Object *obj, Visitor *v, const char *name,
98                          void *opaque, Error **errp)
99 {
100     DeviceState *dev = DEVICE(obj);
101     Property *prop = opaque;
102     uint32_t *p = qdev_get_prop_ptr(dev, prop);
103     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
104
105     visit_type_bool(v, name, &value, errp);
106 }
107
108 static void prop_set_bit(Object *obj, Visitor *v, const char *name,
109                          void *opaque, Error **errp)
110 {
111     DeviceState *dev = DEVICE(obj);
112     Property *prop = opaque;
113     Error *local_err = NULL;
114     bool value;
115
116     if (dev->realized) {
117         qdev_prop_set_after_realize(dev, name, errp);
118         return;
119     }
120
121     visit_type_bool(v, name, &value, &local_err);
122     if (local_err) {
123         error_propagate(errp, local_err);
124         return;
125     }
126     bit_prop_set(dev, prop, value);
127 }
128
129 static void set_default_value_bool(Object *obj, const Property *prop)
130 {
131     object_property_set_bool(obj, prop->defval, prop->name, &error_abort);
132 }
133
134 PropertyInfo qdev_prop_bit = {
135     .name  = "bool",
136     .description = "on/off",
137     .get   = prop_get_bit,
138     .set   = prop_set_bit,
139     .set_default_value = set_default_value_bool,
140 };
141
142 /* Bit64 */
143
144 static uint64_t qdev_get_prop_mask64(Property *prop)
145 {
146     assert(prop->info == &qdev_prop_bit64);
147     return 0x1ull << prop->bitnr;
148 }
149
150 static void bit64_prop_set(DeviceState *dev, Property *props, bool val)
151 {
152     uint64_t *p = qdev_get_prop_ptr(dev, props);
153     uint64_t mask = qdev_get_prop_mask64(props);
154     if (val) {
155         *p |= mask;
156     } else {
157         *p &= ~mask;
158     }
159 }
160
161 static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
162                            void *opaque, Error **errp)
163 {
164     DeviceState *dev = DEVICE(obj);
165     Property *prop = opaque;
166     uint64_t *p = qdev_get_prop_ptr(dev, prop);
167     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
168
169     visit_type_bool(v, name, &value, errp);
170 }
171
172 static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
173                            void *opaque, Error **errp)
174 {
175     DeviceState *dev = DEVICE(obj);
176     Property *prop = opaque;
177     Error *local_err = NULL;
178     bool value;
179
180     if (dev->realized) {
181         qdev_prop_set_after_realize(dev, name, errp);
182         return;
183     }
184
185     visit_type_bool(v, name, &value, &local_err);
186     if (local_err) {
187         error_propagate(errp, local_err);
188         return;
189     }
190     bit64_prop_set(dev, prop, value);
191 }
192
193 PropertyInfo qdev_prop_bit64 = {
194     .name  = "bool",
195     .description = "on/off",
196     .get   = prop_get_bit64,
197     .set   = prop_set_bit64,
198     .set_default_value = set_default_value_bool,
199 };
200
201 /* --- bool --- */
202
203 static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
204                      Error **errp)
205 {
206     DeviceState *dev = DEVICE(obj);
207     Property *prop = opaque;
208     bool *ptr = qdev_get_prop_ptr(dev, prop);
209
210     visit_type_bool(v, name, ptr, errp);
211 }
212
213 static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
214                      Error **errp)
215 {
216     DeviceState *dev = DEVICE(obj);
217     Property *prop = opaque;
218     bool *ptr = qdev_get_prop_ptr(dev, prop);
219
220     if (dev->realized) {
221         qdev_prop_set_after_realize(dev, name, errp);
222         return;
223     }
224
225     visit_type_bool(v, name, ptr, errp);
226 }
227
228 PropertyInfo qdev_prop_bool = {
229     .name  = "bool",
230     .get   = get_bool,
231     .set   = set_bool,
232     .set_default_value = set_default_value_bool,
233 };
234
235 /* --- 8bit integer --- */
236
237 static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
238                       Error **errp)
239 {
240     DeviceState *dev = DEVICE(obj);
241     Property *prop = opaque;
242     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
243
244     visit_type_uint8(v, name, ptr, errp);
245 }
246
247 static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
248                       Error **errp)
249 {
250     DeviceState *dev = DEVICE(obj);
251     Property *prop = opaque;
252     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
253
254     if (dev->realized) {
255         qdev_prop_set_after_realize(dev, name, errp);
256         return;
257     }
258
259     visit_type_uint8(v, name, ptr, errp);
260 }
261
262 static void set_default_value_int(Object *obj, const Property *prop)
263 {
264     object_property_set_int(obj, prop->defval, prop->name, &error_abort);
265 }
266
267 PropertyInfo qdev_prop_uint8 = {
268     .name  = "uint8",
269     .get   = get_uint8,
270     .set   = set_uint8,
271     .set_default_value = set_default_value_int,
272 };
273
274 /* --- 16bit integer --- */
275
276 static void get_uint16(Object *obj, Visitor *v, const char *name,
277                        void *opaque, Error **errp)
278 {
279     DeviceState *dev = DEVICE(obj);
280     Property *prop = opaque;
281     uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
282
283     visit_type_uint16(v, name, ptr, errp);
284 }
285
286 static void set_uint16(Object *obj, Visitor *v, const char *name,
287                        void *opaque, Error **errp)
288 {
289     DeviceState *dev = DEVICE(obj);
290     Property *prop = opaque;
291     uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
292
293     if (dev->realized) {
294         qdev_prop_set_after_realize(dev, name, errp);
295         return;
296     }
297
298     visit_type_uint16(v, name, ptr, errp);
299 }
300
301 PropertyInfo qdev_prop_uint16 = {
302     .name  = "uint16",
303     .get   = get_uint16,
304     .set   = set_uint16,
305     .set_default_value = set_default_value_int,
306 };
307
308 /* --- 32bit integer --- */
309
310 static void get_uint32(Object *obj, Visitor *v, const char *name,
311                        void *opaque, Error **errp)
312 {
313     DeviceState *dev = DEVICE(obj);
314     Property *prop = opaque;
315     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
316
317     visit_type_uint32(v, name, ptr, errp);
318 }
319
320 static void set_uint32(Object *obj, Visitor *v, const char *name,
321                        void *opaque, Error **errp)
322 {
323     DeviceState *dev = DEVICE(obj);
324     Property *prop = opaque;
325     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
326
327     if (dev->realized) {
328         qdev_prop_set_after_realize(dev, name, errp);
329         return;
330     }
331
332     visit_type_uint32(v, name, ptr, errp);
333 }
334
335 static void get_int32(Object *obj, Visitor *v, const char *name, void *opaque,
336                       Error **errp)
337 {
338     DeviceState *dev = DEVICE(obj);
339     Property *prop = opaque;
340     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
341
342     visit_type_int32(v, name, ptr, errp);
343 }
344
345 static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
346                       Error **errp)
347 {
348     DeviceState *dev = DEVICE(obj);
349     Property *prop = opaque;
350     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
351
352     if (dev->realized) {
353         qdev_prop_set_after_realize(dev, name, errp);
354         return;
355     }
356
357     visit_type_int32(v, name, ptr, errp);
358 }
359
360 PropertyInfo qdev_prop_uint32 = {
361     .name  = "uint32",
362     .get   = get_uint32,
363     .set   = set_uint32,
364     .set_default_value = set_default_value_int,
365 };
366
367 PropertyInfo qdev_prop_int32 = {
368     .name  = "int32",
369     .get   = get_int32,
370     .set   = set_int32,
371     .set_default_value = set_default_value_int,
372 };
373
374 /* --- 64bit integer --- */
375
376 static void get_uint64(Object *obj, Visitor *v, const char *name,
377                        void *opaque, Error **errp)
378 {
379     DeviceState *dev = DEVICE(obj);
380     Property *prop = opaque;
381     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
382
383     visit_type_uint64(v, name, ptr, errp);
384 }
385
386 static void set_uint64(Object *obj, Visitor *v, const char *name,
387                        void *opaque, Error **errp)
388 {
389     DeviceState *dev = DEVICE(obj);
390     Property *prop = opaque;
391     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
392
393     if (dev->realized) {
394         qdev_prop_set_after_realize(dev, name, errp);
395         return;
396     }
397
398     visit_type_uint64(v, name, ptr, errp);
399 }
400
401 PropertyInfo qdev_prop_uint64 = {
402     .name  = "uint64",
403     .get   = get_uint64,
404     .set   = set_uint64,
405     .set_default_value = set_default_value_int,
406 };
407
408 /* --- string --- */
409
410 static void release_string(Object *obj, const char *name, void *opaque)
411 {
412     Property *prop = opaque;
413     g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
414 }
415
416 static void get_string(Object *obj, Visitor *v, const char *name,
417                        void *opaque, Error **errp)
418 {
419     DeviceState *dev = DEVICE(obj);
420     Property *prop = opaque;
421     char **ptr = qdev_get_prop_ptr(dev, prop);
422
423     if (!*ptr) {
424         char *str = (char *)"";
425         visit_type_str(v, name, &str, errp);
426     } else {
427         visit_type_str(v, name, ptr, errp);
428     }
429 }
430
431 static void set_string(Object *obj, Visitor *v, const char *name,
432                        void *opaque, Error **errp)
433 {
434     DeviceState *dev = DEVICE(obj);
435     Property *prop = opaque;
436     char **ptr = qdev_get_prop_ptr(dev, prop);
437     Error *local_err = NULL;
438     char *str;
439
440     if (dev->realized) {
441         qdev_prop_set_after_realize(dev, name, errp);
442         return;
443     }
444
445     visit_type_str(v, name, &str, &local_err);
446     if (local_err) {
447         error_propagate(errp, local_err);
448         return;
449     }
450     g_free(*ptr);
451     *ptr = str;
452 }
453
454 PropertyInfo qdev_prop_string = {
455     .name  = "str",
456     .release = release_string,
457     .get   = get_string,
458     .set   = set_string,
459 };
460
461 /* --- pointer --- */
462
463 /* Not a proper property, just for dirty hacks.  TODO Remove it!  */
464 PropertyInfo qdev_prop_ptr = {
465     .name  = "ptr",
466 };
467
468 /* --- mac address --- */
469
470 /*
471  * accepted syntax versions:
472  *   01:02:03:04:05:06
473  *   01-02-03-04-05-06
474  */
475 static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
476                     Error **errp)
477 {
478     DeviceState *dev = DEVICE(obj);
479     Property *prop = opaque;
480     MACAddr *mac = qdev_get_prop_ptr(dev, prop);
481     char buffer[2 * 6 + 5 + 1];
482     char *p = buffer;
483
484     snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
485              mac->a[0], mac->a[1], mac->a[2],
486              mac->a[3], mac->a[4], mac->a[5]);
487
488     visit_type_str(v, name, &p, errp);
489 }
490
491 static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
492                     Error **errp)
493 {
494     DeviceState *dev = DEVICE(obj);
495     Property *prop = opaque;
496     MACAddr *mac = qdev_get_prop_ptr(dev, prop);
497     Error *local_err = NULL;
498     int i, pos;
499     char *str, *p;
500
501     if (dev->realized) {
502         qdev_prop_set_after_realize(dev, name, errp);
503         return;
504     }
505
506     visit_type_str(v, name, &str, &local_err);
507     if (local_err) {
508         error_propagate(errp, local_err);
509         return;
510     }
511
512     for (i = 0, pos = 0; i < 6; i++, pos += 3) {
513         if (!qemu_isxdigit(str[pos])) {
514             goto inval;
515         }
516         if (!qemu_isxdigit(str[pos+1])) {
517             goto inval;
518         }
519         if (i == 5) {
520             if (str[pos+2] != '\0') {
521                 goto inval;
522             }
523         } else {
524             if (str[pos+2] != ':' && str[pos+2] != '-') {
525                 goto inval;
526             }
527         }
528         mac->a[i] = strtol(str+pos, &p, 16);
529     }
530     g_free(str);
531     return;
532
533 inval:
534     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
535     g_free(str);
536 }
537
538 PropertyInfo qdev_prop_macaddr = {
539     .name  = "str",
540     .description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56",
541     .get   = get_mac,
542     .set   = set_mac,
543 };
544
545 /* --- on/off/auto --- */
546
547 PropertyInfo qdev_prop_on_off_auto = {
548     .name = "OnOffAuto",
549     .description = "on/off/auto",
550     .enum_table = OnOffAuto_lookup,
551     .get = get_enum,
552     .set = set_enum,
553     .set_default_value = set_default_value_enum,
554 };
555
556 /* --- lost tick policy --- */
557
558 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
559
560 PropertyInfo qdev_prop_losttickpolicy = {
561     .name  = "LostTickPolicy",
562     .enum_table  = LostTickPolicy_lookup,
563     .get   = get_enum,
564     .set   = set_enum,
565     .set_default_value = set_default_value_enum,
566 };
567
568 /* --- Block device error handling policy --- */
569
570 QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int));
571
572 PropertyInfo qdev_prop_blockdev_on_error = {
573     .name = "BlockdevOnError",
574     .description = "Error handling policy, "
575                    "report/ignore/enospc/stop/auto",
576     .enum_table = BlockdevOnError_lookup,
577     .get = get_enum,
578     .set = set_enum,
579     .set_default_value = set_default_value_enum,
580 };
581
582 /* --- BIOS CHS translation */
583
584 QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
585
586 PropertyInfo qdev_prop_bios_chs_trans = {
587     .name = "BiosAtaTranslation",
588     .description = "Logical CHS translation algorithm, "
589                    "auto/none/lba/large/rechs",
590     .enum_table = BiosAtaTranslation_lookup,
591     .get = get_enum,
592     .set = set_enum,
593     .set_default_value = set_default_value_enum,
594 };
595
596 /* --- FDC default drive types */
597
598 PropertyInfo qdev_prop_fdc_drive_type = {
599     .name = "FdcDriveType",
600     .description = "FDC drive type, "
601                    "144/288/120/none/auto",
602     .enum_table = FloppyDriveType_lookup,
603     .get = get_enum,
604     .set = set_enum,
605     .set_default_value = set_default_value_enum,
606 };
607
608 /* --- pci address --- */
609
610 /*
611  * bus-local address, i.e. "$slot" or "$slot.$fn"
612  */
613 static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
614                           void *opaque, Error **errp)
615 {
616     DeviceState *dev = DEVICE(obj);
617     Property *prop = opaque;
618     int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
619     unsigned int slot, fn, n;
620     Error *local_err = NULL;
621     char *str;
622
623     if (dev->realized) {
624         qdev_prop_set_after_realize(dev, name, errp);
625         return;
626     }
627
628     visit_type_str(v, name, &str, &local_err);
629     if (local_err) {
630         error_free(local_err);
631         local_err = NULL;
632         visit_type_int32(v, name, &value, &local_err);
633         if (local_err) {
634             error_propagate(errp, local_err);
635         } else if (value < -1 || value > 255) {
636             error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
637                        name ? name : "null", "pci_devfn");
638         } else {
639             *ptr = value;
640         }
641         return;
642     }
643
644     if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
645         fn = 0;
646         if (sscanf(str, "%x%n", &slot, &n) != 1) {
647             goto invalid;
648         }
649     }
650     if (str[n] != '\0' || fn > 7 || slot > 31) {
651         goto invalid;
652     }
653     *ptr = slot << 3 | fn;
654     g_free(str);
655     return;
656
657 invalid:
658     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
659     g_free(str);
660 }
661
662 static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest,
663                            size_t len)
664 {
665     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
666
667     if (*ptr == -1) {
668         return snprintf(dest, len, "<unset>");
669     } else {
670         return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
671     }
672 }
673
674 PropertyInfo qdev_prop_pci_devfn = {
675     .name  = "int32",
676     .description = "Slot and optional function number, example: 06.0 or 06",
677     .print = print_pci_devfn,
678     .get   = get_int32,
679     .set   = set_pci_devfn,
680     .set_default_value = set_default_value_int,
681 };
682
683 /* --- blocksize --- */
684
685 static void set_blocksize(Object *obj, Visitor *v, const char *name,
686                           void *opaque, Error **errp)
687 {
688     DeviceState *dev = DEVICE(obj);
689     Property *prop = opaque;
690     uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
691     Error *local_err = NULL;
692     const int64_t min = 512;
693     const int64_t max = 32768;
694
695     if (dev->realized) {
696         qdev_prop_set_after_realize(dev, name, errp);
697         return;
698     }
699
700     visit_type_uint16(v, name, &value, &local_err);
701     if (local_err) {
702         error_propagate(errp, local_err);
703         return;
704     }
705     /* value of 0 means "unset" */
706     if (value && (value < min || value > max)) {
707         error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
708                    dev->id ? : "", name, (int64_t)value, min, max);
709         return;
710     }
711
712     /* We rely on power-of-2 blocksizes for bitmasks */
713     if ((value & (value - 1)) != 0) {
714         error_setg(errp,
715                   "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2",
716                   dev->id ?: "", name, (int64_t)value);
717         return;
718     }
719
720     *ptr = value;
721 }
722
723 PropertyInfo qdev_prop_blocksize = {
724     .name  = "uint16",
725     .description = "A power of two between 512 and 32768",
726     .get   = get_uint16,
727     .set   = set_blocksize,
728     .set_default_value = set_default_value_int,
729 };
730
731 /* --- pci host address --- */
732
733 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
734                                  void *opaque, Error **errp)
735 {
736     DeviceState *dev = DEVICE(obj);
737     Property *prop = opaque;
738     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
739     char buffer[] = "ffff:ff:ff.f";
740     char *p = buffer;
741     int rc = 0;
742
743     /*
744      * Catch "invalid" device reference from vfio-pci and allow the
745      * default buffer representing the non-existent device to be used.
746      */
747     if (~addr->domain || ~addr->bus || ~addr->slot || ~addr->function) {
748         rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%0d",
749                       addr->domain, addr->bus, addr->slot, addr->function);
750         assert(rc == sizeof(buffer) - 1);
751     }
752
753     visit_type_str(v, name, &p, errp);
754 }
755
756 /*
757  * Parse [<domain>:]<bus>:<slot>.<func>
758  *   if <domain> is not supplied, it's assumed to be 0.
759  */
760 static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
761                                  void *opaque, Error **errp)
762 {
763     DeviceState *dev = DEVICE(obj);
764     Property *prop = opaque;
765     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
766     Error *local_err = NULL;
767     char *str, *p;
768     char *e;
769     unsigned long val;
770     unsigned long dom = 0, bus = 0;
771     unsigned int slot = 0, func = 0;
772
773     if (dev->realized) {
774         qdev_prop_set_after_realize(dev, name, errp);
775         return;
776     }
777
778     visit_type_str(v, name, &str, &local_err);
779     if (local_err) {
780         error_propagate(errp, local_err);
781         return;
782     }
783
784     p = str;
785     val = strtoul(p, &e, 16);
786     if (e == p || *e != ':') {
787         goto inval;
788     }
789     bus = val;
790
791     p = e + 1;
792     val = strtoul(p, &e, 16);
793     if (e == p) {
794         goto inval;
795     }
796     if (*e == ':') {
797         dom = bus;
798         bus = val;
799         p = e + 1;
800         val = strtoul(p, &e, 16);
801         if (e == p) {
802             goto inval;
803         }
804     }
805     slot = val;
806
807     if (*e != '.') {
808         goto inval;
809     }
810     p = e + 1;
811     val = strtoul(p, &e, 10);
812     if (e == p) {
813         goto inval;
814     }
815     func = val;
816
817     if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
818         goto inval;
819     }
820
821     if (*e) {
822         goto inval;
823     }
824
825     addr->domain = dom;
826     addr->bus = bus;
827     addr->slot = slot;
828     addr->function = func;
829
830     g_free(str);
831     return;
832
833 inval:
834     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
835     g_free(str);
836 }
837
838 PropertyInfo qdev_prop_pci_host_devaddr = {
839     .name = "str",
840     .description = "Address (bus/device/function) of "
841                    "the host device, example: 04:10.0",
842     .get = get_pci_host_devaddr,
843     .set = set_pci_host_devaddr,
844 };
845
846 /* --- support for array properties --- */
847
848 /* Used as an opaque for the object properties we add for each
849  * array element. Note that the struct Property must be first
850  * in the struct so that a pointer to this works as the opaque
851  * for the underlying element's property hooks as well as for
852  * our own release callback.
853  */
854 typedef struct {
855     struct Property prop;
856     char *propname;
857     ObjectPropertyRelease *release;
858 } ArrayElementProperty;
859
860 /* object property release callback for array element properties:
861  * we call the underlying element's property release hook, and
862  * then free the memory we allocated when we added the property.
863  */
864 static void array_element_release(Object *obj, const char *name, void *opaque)
865 {
866     ArrayElementProperty *p = opaque;
867     if (p->release) {
868         p->release(obj, name, opaque);
869     }
870     g_free(p->propname);
871     g_free(p);
872 }
873
874 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
875                               void *opaque, Error **errp)
876 {
877     /* Setter for the property which defines the length of a
878      * variable-sized property array. As well as actually setting the
879      * array-length field in the device struct, we have to create the
880      * array itself and dynamically add the corresponding properties.
881      */
882     DeviceState *dev = DEVICE(obj);
883     Property *prop = opaque;
884     uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
885     void **arrayptr = (void *)dev + prop->arrayoffset;
886     Error *local_err = NULL;
887     void *eltptr;
888     const char *arrayname;
889     int i;
890
891     if (dev->realized) {
892         qdev_prop_set_after_realize(dev, name, errp);
893         return;
894     }
895     if (*alenptr) {
896         error_setg(errp, "array size property %s may not be set more than once",
897                    name);
898         return;
899     }
900     visit_type_uint32(v, name, alenptr, &local_err);
901     if (local_err) {
902         error_propagate(errp, local_err);
903         return;
904     }
905     if (!*alenptr) {
906         return;
907     }
908
909     /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
910      * strip it off so we can get the name of the array itself.
911      */
912     assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
913                    strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
914     arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
915
916     /* Note that it is the responsibility of the individual device's deinit
917      * to free the array proper.
918      */
919     *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
920     for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
921         char *propname = g_strdup_printf("%s[%d]", arrayname, i);
922         ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
923         arrayprop->release = prop->arrayinfo->release;
924         arrayprop->propname = propname;
925         arrayprop->prop.info = prop->arrayinfo;
926         arrayprop->prop.name = propname;
927         /* This ugly piece of pointer arithmetic sets up the offset so
928          * that when the underlying get/set hooks call qdev_get_prop_ptr
929          * they get the right answer despite the array element not actually
930          * being inside the device struct.
931          */
932         arrayprop->prop.offset = eltptr - (void *)dev;
933         assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
934         object_property_add(obj, propname,
935                             arrayprop->prop.info->name,
936                             arrayprop->prop.info->get,
937                             arrayprop->prop.info->set,
938                             array_element_release,
939                             arrayprop, &local_err);
940         if (local_err) {
941             error_propagate(errp, local_err);
942             return;
943         }
944     }
945 }
946
947 PropertyInfo qdev_prop_arraylen = {
948     .name = "uint32",
949     .get = get_uint32,
950     .set = set_prop_arraylen,
951     .set_default_value = set_default_value_int,
952 };
953
954 /* --- public helpers --- */
955
956 static Property *qdev_prop_walk(Property *props, const char *name)
957 {
958     if (!props) {
959         return NULL;
960     }
961     while (props->name) {
962         if (strcmp(props->name, name) == 0) {
963             return props;
964         }
965         props++;
966     }
967     return NULL;
968 }
969
970 static Property *qdev_prop_find(DeviceState *dev, const char *name)
971 {
972     ObjectClass *class;
973     Property *prop;
974
975     /* device properties */
976     class = object_get_class(OBJECT(dev));
977     do {
978         prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
979         if (prop) {
980             return prop;
981         }
982         class = object_class_get_parent(class);
983     } while (class != object_class_by_name(TYPE_DEVICE));
984
985     return NULL;
986 }
987
988 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
989                                     Property *prop, const char *value)
990 {
991     switch (ret) {
992     case -EEXIST:
993         error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
994                   object_get_typename(OBJECT(dev)), prop->name, value);
995         break;
996     default:
997     case -EINVAL:
998         error_setg(errp, QERR_PROPERTY_VALUE_BAD,
999                    object_get_typename(OBJECT(dev)), prop->name, value);
1000         break;
1001     case -ENOENT:
1002         error_setg(errp, "Property '%s.%s' can't find value '%s'",
1003                   object_get_typename(OBJECT(dev)), prop->name, value);
1004         break;
1005     case 0:
1006         break;
1007     }
1008 }
1009
1010 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1011 {
1012     object_property_set_bool(OBJECT(dev), value, name, &error_abort);
1013 }
1014
1015 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1016 {
1017     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1018 }
1019
1020 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1021 {
1022     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1023 }
1024
1025 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1026 {
1027     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1028 }
1029
1030 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1031 {
1032     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1033 }
1034
1035 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1036 {
1037     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1038 }
1039
1040 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
1041 {
1042     object_property_set_str(OBJECT(dev), value, name, &error_abort);
1043 }
1044
1045 void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
1046                            const uint8_t *value)
1047 {
1048     char str[2 * 6 + 5 + 1];
1049     snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1050              value[0], value[1], value[2], value[3], value[4], value[5]);
1051
1052     object_property_set_str(OBJECT(dev), str, name, &error_abort);
1053 }
1054
1055 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1056 {
1057     Property *prop;
1058
1059     prop = qdev_prop_find(dev, name);
1060     object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
1061                             name, &error_abort);
1062 }
1063
1064 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1065 {
1066     Property *prop;
1067     void **ptr;
1068
1069     prop = qdev_prop_find(dev, name);
1070     assert(prop && prop->info == &qdev_prop_ptr);
1071     ptr = qdev_get_prop_ptr(dev, prop);
1072     *ptr = value;
1073 }
1074
1075 static GList *global_props;
1076
1077 void qdev_prop_register_global(GlobalProperty *prop)
1078 {
1079     global_props = g_list_append(global_props, prop);
1080 }
1081
1082 void qdev_prop_register_global_list(GlobalProperty *props)
1083 {
1084     int i;
1085
1086     for (i = 0; props[i].driver != NULL; i++) {
1087         qdev_prop_register_global(props+i);
1088     }
1089 }
1090
1091 int qdev_prop_check_globals(void)
1092 {
1093     GList *l;
1094     int ret = 0;
1095
1096     for (l = global_props; l; l = l->next) {
1097         GlobalProperty *prop = l->data;
1098         ObjectClass *oc;
1099         DeviceClass *dc;
1100         if (prop->used) {
1101             continue;
1102         }
1103         if (!prop->user_provided) {
1104             continue;
1105         }
1106         oc = object_class_by_name(prop->driver);
1107         oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
1108         if (!oc) {
1109             error_report("Warning: global %s.%s has invalid class name",
1110                        prop->driver, prop->property);
1111             ret = 1;
1112             continue;
1113         }
1114         dc = DEVICE_CLASS(oc);
1115         if (!dc->hotpluggable && !prop->used) {
1116             error_report("Warning: global %s.%s=%s not used",
1117                        prop->driver, prop->property, prop->value);
1118             ret = 1;
1119             continue;
1120         }
1121     }
1122     return ret;
1123 }
1124
1125 static void qdev_prop_set_globals_for_type(DeviceState *dev,
1126                                            const char *typename)
1127 {
1128     GList *l;
1129
1130     for (l = global_props; l; l = l->next) {
1131         GlobalProperty *prop = l->data;
1132         Error *err = NULL;
1133
1134         if (strcmp(typename, prop->driver) != 0) {
1135             continue;
1136         }
1137         prop->used = true;
1138         object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
1139         if (err != NULL) {
1140             error_prepend(&err, "can't apply global %s.%s=%s: ",
1141                           prop->driver, prop->property, prop->value);
1142             if (!dev->hotplugged && prop->errp) {
1143                 error_propagate(prop->errp, err);
1144             } else {
1145                 assert(prop->user_provided);
1146                 error_reportf_err(err, "Warning: ");
1147             }
1148         }
1149     }
1150 }
1151
1152 void qdev_prop_set_globals(DeviceState *dev)
1153 {
1154     ObjectClass *class = object_get_class(OBJECT(dev));
1155
1156     do {
1157         qdev_prop_set_globals_for_type(dev, object_class_get_name(class));
1158         class = object_class_get_parent(class);
1159     } while (class);
1160 }
1161
1162 /* --- 64bit unsigned int 'size' type --- */
1163
1164 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
1165                      Error **errp)
1166 {
1167     DeviceState *dev = DEVICE(obj);
1168     Property *prop = opaque;
1169     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1170
1171     visit_type_size(v, name, ptr, errp);
1172 }
1173
1174 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
1175                      Error **errp)
1176 {
1177     DeviceState *dev = DEVICE(obj);
1178     Property *prop = opaque;
1179     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1180
1181     visit_type_size(v, name, ptr, errp);
1182 }
1183
1184 PropertyInfo qdev_prop_size = {
1185     .name  = "size",
1186     .get = get_size,
1187     .set = set_size,
1188     .set_default_value = set_default_value_int,
1189 };
This page took 0.091449 seconds and 4 git commands to generate.