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