xref: /openbmc/qemu/hw/core/qdev-properties.c (revision 354908ce)
1 #include "qemu/osdep.h"
2 #include "net/net.h"
3 #include "hw/qdev-properties.h"
4 #include "qapi/error.h"
5 #include "hw/pci/pci.h"
6 #include "qapi/qapi-types-block.h"
7 #include "qapi/qapi-types-misc.h"
8 #include "qapi/qmp/qerror.h"
9 #include "qemu/ctype.h"
10 #include "qemu/error-report.h"
11 #include "qapi/qapi-types-migration.h"
12 #include "hw/block/block.h"
13 #include "net/hub.h"
14 #include "qapi/visitor.h"
15 #include "chardev/char.h"
16 #include "qemu/uuid.h"
17 #include "qemu/units.h"
18 
19 void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
20                                   Error **errp)
21 {
22     if (dev->id) {
23         error_setg(errp, "Attempt to set property '%s' on device '%s' "
24                    "(type '%s') after it was realized", name, dev->id,
25                    object_get_typename(OBJECT(dev)));
26     } else {
27         error_setg(errp, "Attempt to set property '%s' on anonymous device "
28                    "(type '%s') after it was realized", name,
29                    object_get_typename(OBJECT(dev)));
30     }
31 }
32 
33 void qdev_prop_allow_set_link_before_realize(const Object *obj,
34                                              const char *name,
35                                              Object *val, Error **errp)
36 {
37     DeviceState *dev = DEVICE(obj);
38 
39     if (dev->realized) {
40         error_setg(errp, "Attempt to set link property '%s' on device '%s' "
41                    "(type '%s') after it was realized",
42                    name, dev->id, object_get_typename(obj));
43     }
44 }
45 
46 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
47 {
48     void *ptr = dev;
49     ptr += prop->offset;
50     return ptr;
51 }
52 
53 static void get_enum(Object *obj, Visitor *v, const char *name, void *opaque,
54                      Error **errp)
55 {
56     DeviceState *dev = DEVICE(obj);
57     Property *prop = opaque;
58     int *ptr = qdev_get_prop_ptr(dev, prop);
59 
60     visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
61 }
62 
63 static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque,
64                      Error **errp)
65 {
66     DeviceState *dev = DEVICE(obj);
67     Property *prop = opaque;
68     int *ptr = qdev_get_prop_ptr(dev, prop);
69 
70     if (dev->realized) {
71         qdev_prop_set_after_realize(dev, name, errp);
72         return;
73     }
74 
75     visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
76 }
77 
78 static void set_default_value_enum(ObjectProperty *op, const Property *prop)
79 {
80     object_property_set_default_str(op,
81         qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
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 
103 static void prop_get_bit(Object *obj, Visitor *v, const char *name,
104                          void *opaque, Error **errp)
105 {
106     DeviceState *dev = DEVICE(obj);
107     Property *prop = opaque;
108     uint32_t *p = qdev_get_prop_ptr(dev, prop);
109     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
110 
111     visit_type_bool(v, name, &value, errp);
112 }
113 
114 static void prop_set_bit(Object *obj, Visitor *v, const char *name,
115                          void *opaque, Error **errp)
116 {
117     DeviceState *dev = DEVICE(obj);
118     Property *prop = opaque;
119     Error *local_err = NULL;
120     bool value;
121 
122     if (dev->realized) {
123         qdev_prop_set_after_realize(dev, name, errp);
124         return;
125     }
126 
127     visit_type_bool(v, name, &value, &local_err);
128     if (local_err) {
129         error_propagate(errp, local_err);
130         return;
131     }
132     bit_prop_set(dev, prop, value);
133 }
134 
135 static void set_default_value_bool(ObjectProperty *op, const Property *prop)
136 {
137     object_property_set_default_bool(op, prop->defval.u);
138 }
139 
140 const PropertyInfo qdev_prop_bit = {
141     .name  = "bool",
142     .description = "on/off",
143     .get   = prop_get_bit,
144     .set   = prop_set_bit,
145     .set_default_value = set_default_value_bool,
146 };
147 
148 /* Bit64 */
149 
150 static uint64_t qdev_get_prop_mask64(Property *prop)
151 {
152     assert(prop->info == &qdev_prop_bit64);
153     return 0x1ull << prop->bitnr;
154 }
155 
156 static void bit64_prop_set(DeviceState *dev, Property *props, bool val)
157 {
158     uint64_t *p = qdev_get_prop_ptr(dev, props);
159     uint64_t mask = qdev_get_prop_mask64(props);
160     if (val) {
161         *p |= mask;
162     } else {
163         *p &= ~mask;
164     }
165 }
166 
167 static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
168                            void *opaque, Error **errp)
169 {
170     DeviceState *dev = DEVICE(obj);
171     Property *prop = opaque;
172     uint64_t *p = qdev_get_prop_ptr(dev, prop);
173     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
174 
175     visit_type_bool(v, name, &value, errp);
176 }
177 
178 static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
179                            void *opaque, Error **errp)
180 {
181     DeviceState *dev = DEVICE(obj);
182     Property *prop = opaque;
183     Error *local_err = NULL;
184     bool value;
185 
186     if (dev->realized) {
187         qdev_prop_set_after_realize(dev, name, errp);
188         return;
189     }
190 
191     visit_type_bool(v, name, &value, &local_err);
192     if (local_err) {
193         error_propagate(errp, local_err);
194         return;
195     }
196     bit64_prop_set(dev, prop, value);
197 }
198 
199 const PropertyInfo qdev_prop_bit64 = {
200     .name  = "bool",
201     .description = "on/off",
202     .get   = prop_get_bit64,
203     .set   = prop_set_bit64,
204     .set_default_value = set_default_value_bool,
205 };
206 
207 /* --- bool --- */
208 
209 static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
210                      Error **errp)
211 {
212     DeviceState *dev = DEVICE(obj);
213     Property *prop = opaque;
214     bool *ptr = qdev_get_prop_ptr(dev, prop);
215 
216     visit_type_bool(v, name, ptr, errp);
217 }
218 
219 static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
220                      Error **errp)
221 {
222     DeviceState *dev = DEVICE(obj);
223     Property *prop = opaque;
224     bool *ptr = qdev_get_prop_ptr(dev, prop);
225 
226     if (dev->realized) {
227         qdev_prop_set_after_realize(dev, name, errp);
228         return;
229     }
230 
231     visit_type_bool(v, name, ptr, errp);
232 }
233 
234 const PropertyInfo qdev_prop_bool = {
235     .name  = "bool",
236     .get   = get_bool,
237     .set   = set_bool,
238     .set_default_value = set_default_value_bool,
239 };
240 
241 /* --- 8bit integer --- */
242 
243 static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
244                       Error **errp)
245 {
246     DeviceState *dev = DEVICE(obj);
247     Property *prop = opaque;
248     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
249 
250     visit_type_uint8(v, name, ptr, errp);
251 }
252 
253 static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
254                       Error **errp)
255 {
256     DeviceState *dev = DEVICE(obj);
257     Property *prop = opaque;
258     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
259 
260     if (dev->realized) {
261         qdev_prop_set_after_realize(dev, name, errp);
262         return;
263     }
264 
265     visit_type_uint8(v, name, ptr, errp);
266 }
267 
268 static void set_default_value_int(ObjectProperty *op, const Property *prop)
269 {
270     object_property_set_default_int(op, prop->defval.i);
271 }
272 
273 static void set_default_value_uint(ObjectProperty *op, const Property *prop)
274 {
275     object_property_set_default_uint(op, prop->defval.u);
276 }
277 
278 const PropertyInfo qdev_prop_uint8 = {
279     .name  = "uint8",
280     .get   = get_uint8,
281     .set   = set_uint8,
282     .set_default_value = set_default_value_uint,
283 };
284 
285 /* --- 16bit integer --- */
286 
287 static void get_uint16(Object *obj, Visitor *v, const char *name,
288                        void *opaque, Error **errp)
289 {
290     DeviceState *dev = DEVICE(obj);
291     Property *prop = opaque;
292     uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
293 
294     visit_type_uint16(v, name, ptr, errp);
295 }
296 
297 static void set_uint16(Object *obj, Visitor *v, const char *name,
298                        void *opaque, Error **errp)
299 {
300     DeviceState *dev = DEVICE(obj);
301     Property *prop = opaque;
302     uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
303 
304     if (dev->realized) {
305         qdev_prop_set_after_realize(dev, name, errp);
306         return;
307     }
308 
309     visit_type_uint16(v, name, ptr, errp);
310 }
311 
312 const PropertyInfo qdev_prop_uint16 = {
313     .name  = "uint16",
314     .get   = get_uint16,
315     .set   = set_uint16,
316     .set_default_value = set_default_value_uint,
317 };
318 
319 /* --- 32bit integer --- */
320 
321 static void get_uint32(Object *obj, Visitor *v, const char *name,
322                        void *opaque, Error **errp)
323 {
324     DeviceState *dev = DEVICE(obj);
325     Property *prop = opaque;
326     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
327 
328     visit_type_uint32(v, name, ptr, errp);
329 }
330 
331 static void set_uint32(Object *obj, Visitor *v, const char *name,
332                        void *opaque, Error **errp)
333 {
334     DeviceState *dev = DEVICE(obj);
335     Property *prop = opaque;
336     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
337 
338     if (dev->realized) {
339         qdev_prop_set_after_realize(dev, name, errp);
340         return;
341     }
342 
343     visit_type_uint32(v, name, ptr, errp);
344 }
345 
346 static void get_int32(Object *obj, Visitor *v, const char *name, void *opaque,
347                       Error **errp)
348 {
349     DeviceState *dev = DEVICE(obj);
350     Property *prop = opaque;
351     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
352 
353     visit_type_int32(v, name, ptr, errp);
354 }
355 
356 static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
357                       Error **errp)
358 {
359     DeviceState *dev = DEVICE(obj);
360     Property *prop = opaque;
361     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
362 
363     if (dev->realized) {
364         qdev_prop_set_after_realize(dev, name, errp);
365         return;
366     }
367 
368     visit_type_int32(v, name, ptr, errp);
369 }
370 
371 const PropertyInfo qdev_prop_uint32 = {
372     .name  = "uint32",
373     .get   = get_uint32,
374     .set   = set_uint32,
375     .set_default_value = set_default_value_uint,
376 };
377 
378 const PropertyInfo qdev_prop_int32 = {
379     .name  = "int32",
380     .get   = get_int32,
381     .set   = set_int32,
382     .set_default_value = set_default_value_int,
383 };
384 
385 /* --- 64bit integer --- */
386 
387 static void get_uint64(Object *obj, Visitor *v, const char *name,
388                        void *opaque, Error **errp)
389 {
390     DeviceState *dev = DEVICE(obj);
391     Property *prop = opaque;
392     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
393 
394     visit_type_uint64(v, name, ptr, errp);
395 }
396 
397 static void set_uint64(Object *obj, Visitor *v, const char *name,
398                        void *opaque, Error **errp)
399 {
400     DeviceState *dev = DEVICE(obj);
401     Property *prop = opaque;
402     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
403 
404     if (dev->realized) {
405         qdev_prop_set_after_realize(dev, name, errp);
406         return;
407     }
408 
409     visit_type_uint64(v, name, ptr, errp);
410 }
411 
412 static void get_int64(Object *obj, Visitor *v, const char *name,
413                       void *opaque, Error **errp)
414 {
415     DeviceState *dev = DEVICE(obj);
416     Property *prop = opaque;
417     int64_t *ptr = qdev_get_prop_ptr(dev, prop);
418 
419     visit_type_int64(v, name, ptr, errp);
420 }
421 
422 static void set_int64(Object *obj, Visitor *v, const char *name,
423                       void *opaque, Error **errp)
424 {
425     DeviceState *dev = DEVICE(obj);
426     Property *prop = opaque;
427     int64_t *ptr = qdev_get_prop_ptr(dev, prop);
428 
429     if (dev->realized) {
430         qdev_prop_set_after_realize(dev, name, errp);
431         return;
432     }
433 
434     visit_type_int64(v, name, ptr, errp);
435 }
436 
437 const PropertyInfo qdev_prop_uint64 = {
438     .name  = "uint64",
439     .get   = get_uint64,
440     .set   = set_uint64,
441     .set_default_value = set_default_value_uint,
442 };
443 
444 const PropertyInfo qdev_prop_int64 = {
445     .name  = "int64",
446     .get   = get_int64,
447     .set   = set_int64,
448     .set_default_value = set_default_value_int,
449 };
450 
451 /* --- string --- */
452 
453 static void release_string(Object *obj, const char *name, void *opaque)
454 {
455     Property *prop = opaque;
456     g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
457 }
458 
459 static void get_string(Object *obj, Visitor *v, const char *name,
460                        void *opaque, Error **errp)
461 {
462     DeviceState *dev = DEVICE(obj);
463     Property *prop = opaque;
464     char **ptr = qdev_get_prop_ptr(dev, prop);
465 
466     if (!*ptr) {
467         char *str = (char *)"";
468         visit_type_str(v, name, &str, errp);
469     } else {
470         visit_type_str(v, name, ptr, errp);
471     }
472 }
473 
474 static void set_string(Object *obj, Visitor *v, const char *name,
475                        void *opaque, Error **errp)
476 {
477     DeviceState *dev = DEVICE(obj);
478     Property *prop = opaque;
479     char **ptr = qdev_get_prop_ptr(dev, prop);
480     Error *local_err = NULL;
481     char *str;
482 
483     if (dev->realized) {
484         qdev_prop_set_after_realize(dev, name, errp);
485         return;
486     }
487 
488     visit_type_str(v, name, &str, &local_err);
489     if (local_err) {
490         error_propagate(errp, local_err);
491         return;
492     }
493     g_free(*ptr);
494     *ptr = str;
495 }
496 
497 const PropertyInfo qdev_prop_string = {
498     .name  = "str",
499     .release = release_string,
500     .get   = get_string,
501     .set   = set_string,
502 };
503 
504 /* --- mac address --- */
505 
506 /*
507  * accepted syntax versions:
508  *   01:02:03:04:05:06
509  *   01-02-03-04-05-06
510  */
511 static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
512                     Error **errp)
513 {
514     DeviceState *dev = DEVICE(obj);
515     Property *prop = opaque;
516     MACAddr *mac = qdev_get_prop_ptr(dev, prop);
517     char buffer[2 * 6 + 5 + 1];
518     char *p = buffer;
519 
520     snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
521              mac->a[0], mac->a[1], mac->a[2],
522              mac->a[3], mac->a[4], mac->a[5]);
523 
524     visit_type_str(v, name, &p, errp);
525 }
526 
527 static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
528                     Error **errp)
529 {
530     DeviceState *dev = DEVICE(obj);
531     Property *prop = opaque;
532     MACAddr *mac = qdev_get_prop_ptr(dev, prop);
533     Error *local_err = NULL;
534     int i, pos;
535     char *str, *p;
536 
537     if (dev->realized) {
538         qdev_prop_set_after_realize(dev, name, errp);
539         return;
540     }
541 
542     visit_type_str(v, name, &str, &local_err);
543     if (local_err) {
544         error_propagate(errp, local_err);
545         return;
546     }
547 
548     for (i = 0, pos = 0; i < 6; i++, pos += 3) {
549         if (!qemu_isxdigit(str[pos])) {
550             goto inval;
551         }
552         if (!qemu_isxdigit(str[pos+1])) {
553             goto inval;
554         }
555         if (i == 5) {
556             if (str[pos+2] != '\0') {
557                 goto inval;
558             }
559         } else {
560             if (str[pos+2] != ':' && str[pos+2] != '-') {
561                 goto inval;
562             }
563         }
564         mac->a[i] = strtol(str+pos, &p, 16);
565     }
566     g_free(str);
567     return;
568 
569 inval:
570     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
571     g_free(str);
572 }
573 
574 const PropertyInfo qdev_prop_macaddr = {
575     .name  = "str",
576     .description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56",
577     .get   = get_mac,
578     .set   = set_mac,
579 };
580 
581 /* --- on/off/auto --- */
582 
583 const PropertyInfo qdev_prop_on_off_auto = {
584     .name = "OnOffAuto",
585     .description = "on/off/auto",
586     .enum_table = &OnOffAuto_lookup,
587     .get = get_enum,
588     .set = set_enum,
589     .set_default_value = set_default_value_enum,
590 };
591 
592 /* --- lost tick policy --- */
593 
594 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
595 
596 const PropertyInfo qdev_prop_losttickpolicy = {
597     .name  = "LostTickPolicy",
598     .enum_table  = &LostTickPolicy_lookup,
599     .get   = get_enum,
600     .set   = set_enum,
601     .set_default_value = set_default_value_enum,
602 };
603 
604 /* --- Block device error handling policy --- */
605 
606 QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int));
607 
608 const PropertyInfo qdev_prop_blockdev_on_error = {
609     .name = "BlockdevOnError",
610     .description = "Error handling policy, "
611                    "report/ignore/enospc/stop/auto",
612     .enum_table = &BlockdevOnError_lookup,
613     .get = get_enum,
614     .set = set_enum,
615     .set_default_value = set_default_value_enum,
616 };
617 
618 /* --- BIOS CHS translation */
619 
620 QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
621 
622 const PropertyInfo qdev_prop_bios_chs_trans = {
623     .name = "BiosAtaTranslation",
624     .description = "Logical CHS translation algorithm, "
625                    "auto/none/lba/large/rechs",
626     .enum_table = &BiosAtaTranslation_lookup,
627     .get = get_enum,
628     .set = set_enum,
629     .set_default_value = set_default_value_enum,
630 };
631 
632 /* --- FDC default drive types */
633 
634 const PropertyInfo qdev_prop_fdc_drive_type = {
635     .name = "FdcDriveType",
636     .description = "FDC drive type, "
637                    "144/288/120/none/auto",
638     .enum_table = &FloppyDriveType_lookup,
639     .get = get_enum,
640     .set = set_enum,
641     .set_default_value = set_default_value_enum,
642 };
643 
644 /* --- MultiFDCompression --- */
645 
646 const PropertyInfo qdev_prop_multifd_compression = {
647     .name = "MultiFDCompression",
648     .description = "multifd_compression values, "
649                    "none/zlib/zstd",
650     .enum_table = &MultiFDCompression_lookup,
651     .get = get_enum,
652     .set = set_enum,
653     .set_default_value = set_default_value_enum,
654 };
655 
656 /* --- pci address --- */
657 
658 /*
659  * bus-local address, i.e. "$slot" or "$slot.$fn"
660  */
661 static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
662                           void *opaque, Error **errp)
663 {
664     DeviceState *dev = DEVICE(obj);
665     Property *prop = opaque;
666     int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
667     unsigned int slot, fn, n;
668     Error *local_err = NULL;
669     char *str;
670 
671     if (dev->realized) {
672         qdev_prop_set_after_realize(dev, name, errp);
673         return;
674     }
675 
676     visit_type_str(v, name, &str, &local_err);
677     if (local_err) {
678         error_free(local_err);
679         local_err = NULL;
680         visit_type_int32(v, name, &value, &local_err);
681         if (local_err) {
682             error_propagate(errp, local_err);
683         } else if (value < -1 || value > 255) {
684             error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
685                        name ? name : "null", "pci_devfn");
686         } else {
687             *ptr = value;
688         }
689         return;
690     }
691 
692     if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
693         fn = 0;
694         if (sscanf(str, "%x%n", &slot, &n) != 1) {
695             goto invalid;
696         }
697     }
698     if (str[n] != '\0' || fn > 7 || slot > 31) {
699         goto invalid;
700     }
701     *ptr = slot << 3 | fn;
702     g_free(str);
703     return;
704 
705 invalid:
706     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
707     g_free(str);
708 }
709 
710 static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest,
711                            size_t len)
712 {
713     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
714 
715     if (*ptr == -1) {
716         return snprintf(dest, len, "<unset>");
717     } else {
718         return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
719     }
720 }
721 
722 const PropertyInfo qdev_prop_pci_devfn = {
723     .name  = "int32",
724     .description = "Slot and optional function number, example: 06.0 or 06",
725     .print = print_pci_devfn,
726     .get   = get_int32,
727     .set   = set_pci_devfn,
728     .set_default_value = set_default_value_int,
729 };
730 
731 /* --- 32bit unsigned int 'size' type --- */
732 
733 static void get_size32(Object *obj, Visitor *v, const char *name, void *opaque,
734                        Error **errp)
735 {
736     DeviceState *dev = DEVICE(obj);
737     Property *prop = opaque;
738     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
739     uint64_t value = *ptr;
740 
741     visit_type_size(v, name, &value, errp);
742 }
743 
744 static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
745                        Error **errp)
746 {
747     DeviceState *dev = DEVICE(obj);
748     Property *prop = opaque;
749     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
750     uint64_t value;
751     Error *local_err = NULL;
752 
753     if (dev->realized) {
754         qdev_prop_set_after_realize(dev, name, errp);
755         return;
756     }
757 
758     visit_type_size(v, name, &value, &local_err);
759     if (local_err) {
760         error_propagate(errp, local_err);
761         return;
762     }
763 
764     if (value > UINT32_MAX) {
765         error_setg(errp,
766                    "Property %s.%s doesn't take value %" PRIu64
767                    " (maximum: %u)",
768                    dev->id ? : "", name, value, UINT32_MAX);
769         return;
770     }
771 
772     *ptr = value;
773 }
774 
775 const PropertyInfo qdev_prop_size32 = {
776     .name  = "size",
777     .get = get_size32,
778     .set = set_size32,
779     .set_default_value = set_default_value_uint,
780 };
781 
782 /* --- blocksize --- */
783 
784 /* lower limit is sector size */
785 #define MIN_BLOCK_SIZE          512
786 #define MIN_BLOCK_SIZE_STR      "512 B"
787 /*
788  * upper limit is arbitrary, 2 MiB looks sufficient for all sensible uses, and
789  * matches qcow2 cluster size limit
790  */
791 #define MAX_BLOCK_SIZE          (2 * MiB)
792 #define MAX_BLOCK_SIZE_STR      "2 MiB"
793 
794 static void set_blocksize(Object *obj, Visitor *v, const char *name,
795                           void *opaque, Error **errp)
796 {
797     DeviceState *dev = DEVICE(obj);
798     Property *prop = opaque;
799     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
800     uint64_t value;
801     Error *local_err = NULL;
802 
803     if (dev->realized) {
804         qdev_prop_set_after_realize(dev, name, errp);
805         return;
806     }
807 
808     visit_type_size(v, name, &value, &local_err);
809     if (local_err) {
810         error_propagate(errp, local_err);
811         return;
812     }
813     /* value of 0 means "unset" */
814     if (value && (value < MIN_BLOCK_SIZE || value > MAX_BLOCK_SIZE)) {
815         error_setg(errp,
816                    "Property %s.%s doesn't take value %" PRIu64
817                    " (minimum: " MIN_BLOCK_SIZE_STR
818                    ", maximum: " MAX_BLOCK_SIZE_STR ")",
819                    dev->id ? : "", name, value);
820         return;
821     }
822 
823     /* We rely on power-of-2 blocksizes for bitmasks */
824     if ((value & (value - 1)) != 0) {
825         error_setg(errp,
826                   "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2",
827                   dev->id ?: "", name, (int64_t)value);
828         return;
829     }
830 
831     *ptr = value;
832 }
833 
834 const PropertyInfo qdev_prop_blocksize = {
835     .name  = "size",
836     .description = "A power of two between " MIN_BLOCK_SIZE_STR
837                    " and " MAX_BLOCK_SIZE_STR,
838     .get   = get_size32,
839     .set   = set_blocksize,
840     .set_default_value = set_default_value_uint,
841 };
842 
843 /* --- pci host address --- */
844 
845 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
846                                  void *opaque, Error **errp)
847 {
848     DeviceState *dev = DEVICE(obj);
849     Property *prop = opaque;
850     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
851     char buffer[] = "ffff:ff:ff.f";
852     char *p = buffer;
853     int rc = 0;
854 
855     /*
856      * Catch "invalid" device reference from vfio-pci and allow the
857      * default buffer representing the non-existent device to be used.
858      */
859     if (~addr->domain || ~addr->bus || ~addr->slot || ~addr->function) {
860         rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%0d",
861                       addr->domain, addr->bus, addr->slot, addr->function);
862         assert(rc == sizeof(buffer) - 1);
863     }
864 
865     visit_type_str(v, name, &p, errp);
866 }
867 
868 /*
869  * Parse [<domain>:]<bus>:<slot>.<func>
870  *   if <domain> is not supplied, it's assumed to be 0.
871  */
872 static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
873                                  void *opaque, Error **errp)
874 {
875     DeviceState *dev = DEVICE(obj);
876     Property *prop = opaque;
877     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
878     Error *local_err = NULL;
879     char *str, *p;
880     char *e;
881     unsigned long val;
882     unsigned long dom = 0, bus = 0;
883     unsigned int slot = 0, func = 0;
884 
885     if (dev->realized) {
886         qdev_prop_set_after_realize(dev, name, errp);
887         return;
888     }
889 
890     visit_type_str(v, name, &str, &local_err);
891     if (local_err) {
892         error_propagate(errp, local_err);
893         return;
894     }
895 
896     p = str;
897     val = strtoul(p, &e, 16);
898     if (e == p || *e != ':') {
899         goto inval;
900     }
901     bus = val;
902 
903     p = e + 1;
904     val = strtoul(p, &e, 16);
905     if (e == p) {
906         goto inval;
907     }
908     if (*e == ':') {
909         dom = bus;
910         bus = val;
911         p = e + 1;
912         val = strtoul(p, &e, 16);
913         if (e == p) {
914             goto inval;
915         }
916     }
917     slot = val;
918 
919     if (*e != '.') {
920         goto inval;
921     }
922     p = e + 1;
923     val = strtoul(p, &e, 10);
924     if (e == p) {
925         goto inval;
926     }
927     func = val;
928 
929     if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
930         goto inval;
931     }
932 
933     if (*e) {
934         goto inval;
935     }
936 
937     addr->domain = dom;
938     addr->bus = bus;
939     addr->slot = slot;
940     addr->function = func;
941 
942     g_free(str);
943     return;
944 
945 inval:
946     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
947     g_free(str);
948 }
949 
950 const PropertyInfo qdev_prop_pci_host_devaddr = {
951     .name = "str",
952     .description = "Address (bus/device/function) of "
953                    "the host device, example: 04:10.0",
954     .get = get_pci_host_devaddr,
955     .set = set_pci_host_devaddr,
956 };
957 
958 /* --- UUID --- */
959 
960 static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
961                      Error **errp)
962 {
963     DeviceState *dev = DEVICE(obj);
964     Property *prop = opaque;
965     QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
966     char buffer[UUID_FMT_LEN + 1];
967     char *p = buffer;
968 
969     qemu_uuid_unparse(uuid, buffer);
970 
971     visit_type_str(v, name, &p, errp);
972 }
973 
974 #define UUID_VALUE_AUTO        "auto"
975 
976 static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
977                     Error **errp)
978 {
979     DeviceState *dev = DEVICE(obj);
980     Property *prop = opaque;
981     QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
982     Error *local_err = NULL;
983     char *str;
984 
985     if (dev->realized) {
986         qdev_prop_set_after_realize(dev, name, errp);
987         return;
988     }
989 
990     visit_type_str(v, name, &str, &local_err);
991     if (local_err) {
992         error_propagate(errp, local_err);
993         return;
994     }
995 
996     if (!strcmp(str, UUID_VALUE_AUTO)) {
997         qemu_uuid_generate(uuid);
998     } else if (qemu_uuid_parse(str, uuid) < 0) {
999         error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
1000     }
1001     g_free(str);
1002 }
1003 
1004 static void set_default_uuid_auto(ObjectProperty *op, const Property *prop)
1005 {
1006     object_property_set_default_str(op, UUID_VALUE_AUTO);
1007 }
1008 
1009 const PropertyInfo qdev_prop_uuid = {
1010     .name  = "str",
1011     .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
1012         "\" for random value (default)",
1013     .get   = get_uuid,
1014     .set   = set_uuid,
1015     .set_default_value = set_default_uuid_auto,
1016 };
1017 
1018 /* --- support for array properties --- */
1019 
1020 /* Used as an opaque for the object properties we add for each
1021  * array element. Note that the struct Property must be first
1022  * in the struct so that a pointer to this works as the opaque
1023  * for the underlying element's property hooks as well as for
1024  * our own release callback.
1025  */
1026 typedef struct {
1027     struct Property prop;
1028     char *propname;
1029     ObjectPropertyRelease *release;
1030 } ArrayElementProperty;
1031 
1032 /* object property release callback for array element properties:
1033  * we call the underlying element's property release hook, and
1034  * then free the memory we allocated when we added the property.
1035  */
1036 static void array_element_release(Object *obj, const char *name, void *opaque)
1037 {
1038     ArrayElementProperty *p = opaque;
1039     if (p->release) {
1040         p->release(obj, name, opaque);
1041     }
1042     g_free(p->propname);
1043     g_free(p);
1044 }
1045 
1046 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
1047                               void *opaque, Error **errp)
1048 {
1049     /* Setter for the property which defines the length of a
1050      * variable-sized property array. As well as actually setting the
1051      * array-length field in the device struct, we have to create the
1052      * array itself and dynamically add the corresponding properties.
1053      */
1054     DeviceState *dev = DEVICE(obj);
1055     Property *prop = opaque;
1056     uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
1057     void **arrayptr = (void *)dev + prop->arrayoffset;
1058     Error *local_err = NULL;
1059     void *eltptr;
1060     const char *arrayname;
1061     int i;
1062 
1063     if (dev->realized) {
1064         qdev_prop_set_after_realize(dev, name, errp);
1065         return;
1066     }
1067     if (*alenptr) {
1068         error_setg(errp, "array size property %s may not be set more than once",
1069                    name);
1070         return;
1071     }
1072     visit_type_uint32(v, name, alenptr, &local_err);
1073     if (local_err) {
1074         error_propagate(errp, local_err);
1075         return;
1076     }
1077     if (!*alenptr) {
1078         return;
1079     }
1080 
1081     /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
1082      * strip it off so we can get the name of the array itself.
1083      */
1084     assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
1085                    strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
1086     arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
1087 
1088     /* Note that it is the responsibility of the individual device's deinit
1089      * to free the array proper.
1090      */
1091     *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
1092     for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
1093         char *propname = g_strdup_printf("%s[%d]", arrayname, i);
1094         ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
1095         arrayprop->release = prop->arrayinfo->release;
1096         arrayprop->propname = propname;
1097         arrayprop->prop.info = prop->arrayinfo;
1098         arrayprop->prop.name = propname;
1099         /* This ugly piece of pointer arithmetic sets up the offset so
1100          * that when the underlying get/set hooks call qdev_get_prop_ptr
1101          * they get the right answer despite the array element not actually
1102          * being inside the device struct.
1103          */
1104         arrayprop->prop.offset = eltptr - (void *)dev;
1105         assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
1106         object_property_add(obj, propname,
1107                             arrayprop->prop.info->name,
1108                             arrayprop->prop.info->get,
1109                             arrayprop->prop.info->set,
1110                             array_element_release,
1111                             arrayprop);
1112     }
1113 }
1114 
1115 const PropertyInfo qdev_prop_arraylen = {
1116     .name = "uint32",
1117     .get = get_uint32,
1118     .set = set_prop_arraylen,
1119     .set_default_value = set_default_value_uint,
1120 };
1121 
1122 /* --- public helpers --- */
1123 
1124 static Property *qdev_prop_walk(Property *props, const char *name)
1125 {
1126     if (!props) {
1127         return NULL;
1128     }
1129     while (props->name) {
1130         if (strcmp(props->name, name) == 0) {
1131             return props;
1132         }
1133         props++;
1134     }
1135     return NULL;
1136 }
1137 
1138 static Property *qdev_prop_find(DeviceState *dev, const char *name)
1139 {
1140     ObjectClass *class;
1141     Property *prop;
1142 
1143     /* device properties */
1144     class = object_get_class(OBJECT(dev));
1145     do {
1146         prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name);
1147         if (prop) {
1148             return prop;
1149         }
1150         class = object_class_get_parent(class);
1151     } while (class != object_class_by_name(TYPE_DEVICE));
1152 
1153     return NULL;
1154 }
1155 
1156 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
1157                                     Property *prop, const char *value)
1158 {
1159     switch (ret) {
1160     case -EEXIST:
1161         error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
1162                   object_get_typename(OBJECT(dev)), prop->name, value);
1163         break;
1164     default:
1165     case -EINVAL:
1166         error_setg(errp, QERR_PROPERTY_VALUE_BAD,
1167                    object_get_typename(OBJECT(dev)), prop->name, value);
1168         break;
1169     case -ENOENT:
1170         error_setg(errp, "Property '%s.%s' can't find value '%s'",
1171                   object_get_typename(OBJECT(dev)), prop->name, value);
1172         break;
1173     case 0:
1174         break;
1175     }
1176 }
1177 
1178 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1179 {
1180     object_property_set_bool(OBJECT(dev), value, name, &error_abort);
1181 }
1182 
1183 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1184 {
1185     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1186 }
1187 
1188 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1189 {
1190     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1191 }
1192 
1193 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1194 {
1195     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1196 }
1197 
1198 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1199 {
1200     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1201 }
1202 
1203 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1204 {
1205     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1206 }
1207 
1208 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
1209 {
1210     object_property_set_str(OBJECT(dev), value, name, &error_abort);
1211 }
1212 
1213 void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
1214                            const uint8_t *value)
1215 {
1216     char str[2 * 6 + 5 + 1];
1217     snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1218              value[0], value[1], value[2], value[3], value[4], value[5]);
1219 
1220     object_property_set_str(OBJECT(dev), str, name, &error_abort);
1221 }
1222 
1223 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1224 {
1225     Property *prop;
1226 
1227     prop = qdev_prop_find(dev, name);
1228     object_property_set_str(OBJECT(dev),
1229                             qapi_enum_lookup(prop->info->enum_table, value),
1230                             name, &error_abort);
1231 }
1232 
1233 static GPtrArray *global_props(void)
1234 {
1235     static GPtrArray *gp;
1236 
1237     if (!gp) {
1238         gp = g_ptr_array_new();
1239     }
1240 
1241     return gp;
1242 }
1243 
1244 void qdev_prop_register_global(GlobalProperty *prop)
1245 {
1246     g_ptr_array_add(global_props(), prop);
1247 }
1248 
1249 int qdev_prop_check_globals(void)
1250 {
1251     int i, ret = 0;
1252 
1253     for (i = 0; i < global_props()->len; i++) {
1254         GlobalProperty *prop;
1255         ObjectClass *oc;
1256         DeviceClass *dc;
1257 
1258         prop = g_ptr_array_index(global_props(), i);
1259         if (prop->used) {
1260             continue;
1261         }
1262         oc = object_class_by_name(prop->driver);
1263         oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
1264         if (!oc) {
1265             warn_report("global %s.%s has invalid class name",
1266                         prop->driver, prop->property);
1267             ret = 1;
1268             continue;
1269         }
1270         dc = DEVICE_CLASS(oc);
1271         if (!dc->hotpluggable && !prop->used) {
1272             warn_report("global %s.%s=%s not used",
1273                         prop->driver, prop->property, prop->value);
1274             ret = 1;
1275             continue;
1276         }
1277     }
1278     return ret;
1279 }
1280 
1281 void qdev_prop_set_globals(DeviceState *dev)
1282 {
1283     object_apply_global_props(OBJECT(dev), global_props(),
1284                               dev->hotplugged ? NULL : &error_fatal);
1285 }
1286 
1287 /* --- 64bit unsigned int 'size' type --- */
1288 
1289 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
1290                      Error **errp)
1291 {
1292     DeviceState *dev = DEVICE(obj);
1293     Property *prop = opaque;
1294     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1295 
1296     visit_type_size(v, name, ptr, errp);
1297 }
1298 
1299 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
1300                      Error **errp)
1301 {
1302     DeviceState *dev = DEVICE(obj);
1303     Property *prop = opaque;
1304     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1305 
1306     visit_type_size(v, name, ptr, errp);
1307 }
1308 
1309 const PropertyInfo qdev_prop_size = {
1310     .name  = "size",
1311     .get = get_size,
1312     .set = set_size,
1313     .set_default_value = set_default_value_uint,
1314 };
1315 
1316 /* --- object link property --- */
1317 
1318 static void create_link_property(ObjectClass *oc, Property *prop)
1319 {
1320     object_class_property_add_link(oc, prop->name, prop->link_type,
1321                                    prop->offset,
1322                                    qdev_prop_allow_set_link_before_realize,
1323                                    OBJ_PROP_LINK_STRONG);
1324 }
1325 
1326 const PropertyInfo qdev_prop_link = {
1327     .name = "link",
1328     .create = create_link_property,
1329 };
1330 
1331 /* --- OffAutoPCIBAR off/auto/bar0/bar1/bar2/bar3/bar4/bar5 --- */
1332 
1333 const PropertyInfo qdev_prop_off_auto_pcibar = {
1334     .name = "OffAutoPCIBAR",
1335     .description = "off/auto/bar0/bar1/bar2/bar3/bar4/bar5",
1336     .enum_table = &OffAutoPCIBAR_lookup,
1337     .get = get_enum,
1338     .set = set_enum,
1339     .set_default_value = set_default_value_enum,
1340 };
1341 
1342 /* --- PCIELinkSpeed 2_5/5/8/16 -- */
1343 
1344 static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
1345                                    void *opaque, Error **errp)
1346 {
1347     DeviceState *dev = DEVICE(obj);
1348     Property *prop = opaque;
1349     PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
1350     int speed;
1351 
1352     switch (*p) {
1353     case QEMU_PCI_EXP_LNK_2_5GT:
1354         speed = PCIE_LINK_SPEED_2_5;
1355         break;
1356     case QEMU_PCI_EXP_LNK_5GT:
1357         speed = PCIE_LINK_SPEED_5;
1358         break;
1359     case QEMU_PCI_EXP_LNK_8GT:
1360         speed = PCIE_LINK_SPEED_8;
1361         break;
1362     case QEMU_PCI_EXP_LNK_16GT:
1363         speed = PCIE_LINK_SPEED_16;
1364         break;
1365     default:
1366         /* Unreachable */
1367         abort();
1368     }
1369 
1370     visit_type_enum(v, prop->name, &speed, prop->info->enum_table, errp);
1371 }
1372 
1373 static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
1374                                    void *opaque, Error **errp)
1375 {
1376     DeviceState *dev = DEVICE(obj);
1377     Property *prop = opaque;
1378     PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
1379     int speed;
1380     Error *local_err = NULL;
1381 
1382     if (dev->realized) {
1383         qdev_prop_set_after_realize(dev, name, errp);
1384         return;
1385     }
1386 
1387     visit_type_enum(v, prop->name, &speed, prop->info->enum_table, &local_err);
1388     if (local_err) {
1389         error_propagate(errp, local_err);
1390         return;
1391     }
1392 
1393     switch (speed) {
1394     case PCIE_LINK_SPEED_2_5:
1395         *p = QEMU_PCI_EXP_LNK_2_5GT;
1396         break;
1397     case PCIE_LINK_SPEED_5:
1398         *p = QEMU_PCI_EXP_LNK_5GT;
1399         break;
1400     case PCIE_LINK_SPEED_8:
1401         *p = QEMU_PCI_EXP_LNK_8GT;
1402         break;
1403     case PCIE_LINK_SPEED_16:
1404         *p = QEMU_PCI_EXP_LNK_16GT;
1405         break;
1406     default:
1407         /* Unreachable */
1408         abort();
1409     }
1410 }
1411 
1412 const PropertyInfo qdev_prop_pcie_link_speed = {
1413     .name = "PCIELinkSpeed",
1414     .description = "2_5/5/8/16",
1415     .enum_table = &PCIELinkSpeed_lookup,
1416     .get = get_prop_pcielinkspeed,
1417     .set = set_prop_pcielinkspeed,
1418     .set_default_value = set_default_value_enum,
1419 };
1420 
1421 /* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */
1422 
1423 static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
1424                                    void *opaque, Error **errp)
1425 {
1426     DeviceState *dev = DEVICE(obj);
1427     Property *prop = opaque;
1428     PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
1429     int width;
1430 
1431     switch (*p) {
1432     case QEMU_PCI_EXP_LNK_X1:
1433         width = PCIE_LINK_WIDTH_1;
1434         break;
1435     case QEMU_PCI_EXP_LNK_X2:
1436         width = PCIE_LINK_WIDTH_2;
1437         break;
1438     case QEMU_PCI_EXP_LNK_X4:
1439         width = PCIE_LINK_WIDTH_4;
1440         break;
1441     case QEMU_PCI_EXP_LNK_X8:
1442         width = PCIE_LINK_WIDTH_8;
1443         break;
1444     case QEMU_PCI_EXP_LNK_X12:
1445         width = PCIE_LINK_WIDTH_12;
1446         break;
1447     case QEMU_PCI_EXP_LNK_X16:
1448         width = PCIE_LINK_WIDTH_16;
1449         break;
1450     case QEMU_PCI_EXP_LNK_X32:
1451         width = PCIE_LINK_WIDTH_32;
1452         break;
1453     default:
1454         /* Unreachable */
1455         abort();
1456     }
1457 
1458     visit_type_enum(v, prop->name, &width, prop->info->enum_table, errp);
1459 }
1460 
1461 static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
1462                                    void *opaque, Error **errp)
1463 {
1464     DeviceState *dev = DEVICE(obj);
1465     Property *prop = opaque;
1466     PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
1467     int width;
1468     Error *local_err = NULL;
1469 
1470     if (dev->realized) {
1471         qdev_prop_set_after_realize(dev, name, errp);
1472         return;
1473     }
1474 
1475     visit_type_enum(v, prop->name, &width, prop->info->enum_table, &local_err);
1476     if (local_err) {
1477         error_propagate(errp, local_err);
1478         return;
1479     }
1480 
1481     switch (width) {
1482     case PCIE_LINK_WIDTH_1:
1483         *p = QEMU_PCI_EXP_LNK_X1;
1484         break;
1485     case PCIE_LINK_WIDTH_2:
1486         *p = QEMU_PCI_EXP_LNK_X2;
1487         break;
1488     case PCIE_LINK_WIDTH_4:
1489         *p = QEMU_PCI_EXP_LNK_X4;
1490         break;
1491     case PCIE_LINK_WIDTH_8:
1492         *p = QEMU_PCI_EXP_LNK_X8;
1493         break;
1494     case PCIE_LINK_WIDTH_12:
1495         *p = QEMU_PCI_EXP_LNK_X12;
1496         break;
1497     case PCIE_LINK_WIDTH_16:
1498         *p = QEMU_PCI_EXP_LNK_X16;
1499         break;
1500     case PCIE_LINK_WIDTH_32:
1501         *p = QEMU_PCI_EXP_LNK_X32;
1502         break;
1503     default:
1504         /* Unreachable */
1505         abort();
1506     }
1507 }
1508 
1509 const PropertyInfo qdev_prop_pcie_link_width = {
1510     .name = "PCIELinkWidth",
1511     .description = "1/2/4/8/12/16/32",
1512     .enum_table = &PCIELinkWidth_lookup,
1513     .get = get_prop_pcielinkwidth,
1514     .set = set_prop_pcielinkwidth,
1515     .set_default_value = set_default_value_enum,
1516 };
1517