1 #include "qemu/osdep.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"
11 #include "qapi/visitor.h"
12 #include "chardev/char.h"
13 #include "qemu/uuid.h"
15 void qdev_prop_set_after_realize(DeviceState
*dev
, const char *name
,
19 error_setg(errp
, "Attempt to set property '%s' on device '%s' "
20 "(type '%s') after it was realized", name
, dev
->id
,
21 object_get_typename(OBJECT(dev
)));
23 error_setg(errp
, "Attempt to set property '%s' on anonymous device "
24 "(type '%s') after it was realized", name
,
25 object_get_typename(OBJECT(dev
)));
29 void qdev_prop_allow_set_link_before_realize(const Object
*obj
,
31 Object
*val
, Error
**errp
)
33 DeviceState
*dev
= DEVICE(obj
);
36 error_setg(errp
, "Attempt to set link property '%s' on device '%s' "
37 "(type '%s') after it was realized",
38 name
, dev
->id
, object_get_typename(obj
));
42 void *qdev_get_prop_ptr(DeviceState
*dev
, Property
*prop
)
49 static void get_enum(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
52 DeviceState
*dev
= DEVICE(obj
);
53 Property
*prop
= opaque
;
54 int *ptr
= qdev_get_prop_ptr(dev
, prop
);
56 visit_type_enum(v
, prop
->name
, ptr
, prop
->info
->enum_table
, errp
);
59 static void set_enum(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
62 DeviceState
*dev
= DEVICE(obj
);
63 Property
*prop
= opaque
;
64 int *ptr
= qdev_get_prop_ptr(dev
, prop
);
67 qdev_prop_set_after_realize(dev
, name
, errp
);
71 visit_type_enum(v
, prop
->name
, ptr
, prop
->info
->enum_table
, errp
);
74 static void set_default_value_enum(Object
*obj
, const Property
*prop
)
76 object_property_set_str(obj
,
77 qapi_enum_lookup(prop
->info
->enum_table
,
79 prop
->name
, &error_abort
);
84 static uint32_t qdev_get_prop_mask(Property
*prop
)
86 assert(prop
->info
== &qdev_prop_bit
);
87 return 0x1 << prop
->bitnr
;
90 static void bit_prop_set(DeviceState
*dev
, Property
*props
, bool val
)
92 uint32_t *p
= qdev_get_prop_ptr(dev
, props
);
93 uint32_t mask
= qdev_get_prop_mask(props
);
101 static void prop_get_bit(Object
*obj
, Visitor
*v
, const char *name
,
102 void *opaque
, Error
**errp
)
104 DeviceState
*dev
= DEVICE(obj
);
105 Property
*prop
= opaque
;
106 uint32_t *p
= qdev_get_prop_ptr(dev
, prop
);
107 bool value
= (*p
& qdev_get_prop_mask(prop
)) != 0;
109 visit_type_bool(v
, name
, &value
, errp
);
112 static void prop_set_bit(Object
*obj
, Visitor
*v
, const char *name
,
113 void *opaque
, Error
**errp
)
115 DeviceState
*dev
= DEVICE(obj
);
116 Property
*prop
= opaque
;
117 Error
*local_err
= NULL
;
121 qdev_prop_set_after_realize(dev
, name
, errp
);
125 visit_type_bool(v
, name
, &value
, &local_err
);
127 error_propagate(errp
, local_err
);
130 bit_prop_set(dev
, prop
, value
);
133 static void set_default_value_bool(Object
*obj
, const Property
*prop
)
135 object_property_set_bool(obj
, prop
->defval
.u
, prop
->name
, &error_abort
);
138 const PropertyInfo qdev_prop_bit
= {
140 .description
= "on/off",
143 .set_default_value
= set_default_value_bool
,
148 static uint64_t qdev_get_prop_mask64(Property
*prop
)
150 assert(prop
->info
== &qdev_prop_bit64
);
151 return 0x1ull
<< prop
->bitnr
;
154 static void bit64_prop_set(DeviceState
*dev
, Property
*props
, bool val
)
156 uint64_t *p
= qdev_get_prop_ptr(dev
, props
);
157 uint64_t mask
= qdev_get_prop_mask64(props
);
165 static void prop_get_bit64(Object
*obj
, Visitor
*v
, const char *name
,
166 void *opaque
, Error
**errp
)
168 DeviceState
*dev
= DEVICE(obj
);
169 Property
*prop
= opaque
;
170 uint64_t *p
= qdev_get_prop_ptr(dev
, prop
);
171 bool value
= (*p
& qdev_get_prop_mask64(prop
)) != 0;
173 visit_type_bool(v
, name
, &value
, errp
);
176 static void prop_set_bit64(Object
*obj
, Visitor
*v
, const char *name
,
177 void *opaque
, Error
**errp
)
179 DeviceState
*dev
= DEVICE(obj
);
180 Property
*prop
= opaque
;
181 Error
*local_err
= NULL
;
185 qdev_prop_set_after_realize(dev
, name
, errp
);
189 visit_type_bool(v
, name
, &value
, &local_err
);
191 error_propagate(errp
, local_err
);
194 bit64_prop_set(dev
, prop
, value
);
197 const PropertyInfo qdev_prop_bit64
= {
199 .description
= "on/off",
200 .get
= prop_get_bit64
,
201 .set
= prop_set_bit64
,
202 .set_default_value
= set_default_value_bool
,
207 static void get_bool(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
210 DeviceState
*dev
= DEVICE(obj
);
211 Property
*prop
= opaque
;
212 bool *ptr
= qdev_get_prop_ptr(dev
, prop
);
214 visit_type_bool(v
, name
, ptr
, errp
);
217 static void set_bool(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
220 DeviceState
*dev
= DEVICE(obj
);
221 Property
*prop
= opaque
;
222 bool *ptr
= qdev_get_prop_ptr(dev
, prop
);
225 qdev_prop_set_after_realize(dev
, name
, errp
);
229 visit_type_bool(v
, name
, ptr
, errp
);
232 const PropertyInfo qdev_prop_bool
= {
236 .set_default_value
= set_default_value_bool
,
239 /* --- 8bit integer --- */
241 static void get_uint8(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
244 DeviceState
*dev
= DEVICE(obj
);
245 Property
*prop
= opaque
;
246 uint8_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
248 visit_type_uint8(v
, name
, ptr
, errp
);
251 static void set_uint8(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
254 DeviceState
*dev
= DEVICE(obj
);
255 Property
*prop
= opaque
;
256 uint8_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
259 qdev_prop_set_after_realize(dev
, name
, errp
);
263 visit_type_uint8(v
, name
, ptr
, errp
);
266 static void set_default_value_int(Object
*obj
, const Property
*prop
)
268 object_property_set_int(obj
, prop
->defval
.i
, prop
->name
, &error_abort
);
271 static void set_default_value_uint(Object
*obj
, const Property
*prop
)
273 object_property_set_uint(obj
, prop
->defval
.u
, prop
->name
, &error_abort
);
276 const PropertyInfo qdev_prop_uint8
= {
280 .set_default_value
= set_default_value_uint
,
283 /* --- 16bit integer --- */
285 static void get_uint16(Object
*obj
, Visitor
*v
, const char *name
,
286 void *opaque
, Error
**errp
)
288 DeviceState
*dev
= DEVICE(obj
);
289 Property
*prop
= opaque
;
290 uint16_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
292 visit_type_uint16(v
, name
, ptr
, errp
);
295 static void set_uint16(Object
*obj
, Visitor
*v
, const char *name
,
296 void *opaque
, Error
**errp
)
298 DeviceState
*dev
= DEVICE(obj
);
299 Property
*prop
= opaque
;
300 uint16_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
303 qdev_prop_set_after_realize(dev
, name
, errp
);
307 visit_type_uint16(v
, name
, ptr
, errp
);
310 const PropertyInfo qdev_prop_uint16
= {
314 .set_default_value
= set_default_value_uint
,
317 /* --- 32bit integer --- */
319 static void get_uint32(Object
*obj
, Visitor
*v
, const char *name
,
320 void *opaque
, Error
**errp
)
322 DeviceState
*dev
= DEVICE(obj
);
323 Property
*prop
= opaque
;
324 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
326 visit_type_uint32(v
, name
, ptr
, errp
);
329 static void set_uint32(Object
*obj
, Visitor
*v
, const char *name
,
330 void *opaque
, Error
**errp
)
332 DeviceState
*dev
= DEVICE(obj
);
333 Property
*prop
= opaque
;
334 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
337 qdev_prop_set_after_realize(dev
, name
, errp
);
341 visit_type_uint32(v
, name
, ptr
, errp
);
344 static void get_int32(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
347 DeviceState
*dev
= DEVICE(obj
);
348 Property
*prop
= opaque
;
349 int32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
351 visit_type_int32(v
, name
, ptr
, errp
);
354 static void set_int32(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
357 DeviceState
*dev
= DEVICE(obj
);
358 Property
*prop
= opaque
;
359 int32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
362 qdev_prop_set_after_realize(dev
, name
, errp
);
366 visit_type_int32(v
, name
, ptr
, errp
);
369 const PropertyInfo qdev_prop_uint32
= {
373 .set_default_value
= set_default_value_uint
,
376 const PropertyInfo qdev_prop_int32
= {
380 .set_default_value
= set_default_value_int
,
383 /* --- 64bit integer --- */
385 static void get_uint64(Object
*obj
, Visitor
*v
, const char *name
,
386 void *opaque
, Error
**errp
)
388 DeviceState
*dev
= DEVICE(obj
);
389 Property
*prop
= opaque
;
390 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
392 visit_type_uint64(v
, name
, ptr
, errp
);
395 static void set_uint64(Object
*obj
, Visitor
*v
, const char *name
,
396 void *opaque
, Error
**errp
)
398 DeviceState
*dev
= DEVICE(obj
);
399 Property
*prop
= opaque
;
400 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
403 qdev_prop_set_after_realize(dev
, name
, errp
);
407 visit_type_uint64(v
, name
, ptr
, errp
);
410 static void get_int64(Object
*obj
, Visitor
*v
, const char *name
,
411 void *opaque
, Error
**errp
)
413 DeviceState
*dev
= DEVICE(obj
);
414 Property
*prop
= opaque
;
415 int64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
417 visit_type_int64(v
, name
, ptr
, errp
);
420 static void set_int64(Object
*obj
, Visitor
*v
, const char *name
,
421 void *opaque
, Error
**errp
)
423 DeviceState
*dev
= DEVICE(obj
);
424 Property
*prop
= opaque
;
425 int64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
428 qdev_prop_set_after_realize(dev
, name
, errp
);
432 visit_type_int64(v
, name
, ptr
, errp
);
435 const PropertyInfo qdev_prop_uint64
= {
439 .set_default_value
= set_default_value_uint
,
442 const PropertyInfo qdev_prop_int64
= {
446 .set_default_value
= set_default_value_int
,
451 static void release_string(Object
*obj
, const char *name
, void *opaque
)
453 Property
*prop
= opaque
;
454 g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj
), prop
));
457 static void get_string(Object
*obj
, Visitor
*v
, const char *name
,
458 void *opaque
, Error
**errp
)
460 DeviceState
*dev
= DEVICE(obj
);
461 Property
*prop
= opaque
;
462 char **ptr
= qdev_get_prop_ptr(dev
, prop
);
465 char *str
= (char *)"";
466 visit_type_str(v
, name
, &str
, errp
);
468 visit_type_str(v
, name
, ptr
, errp
);
472 static void set_string(Object
*obj
, Visitor
*v
, const char *name
,
473 void *opaque
, Error
**errp
)
475 DeviceState
*dev
= DEVICE(obj
);
476 Property
*prop
= opaque
;
477 char **ptr
= qdev_get_prop_ptr(dev
, prop
);
478 Error
*local_err
= NULL
;
482 qdev_prop_set_after_realize(dev
, name
, errp
);
486 visit_type_str(v
, name
, &str
, &local_err
);
488 error_propagate(errp
, local_err
);
495 const PropertyInfo qdev_prop_string
= {
497 .release
= release_string
,
502 /* --- pointer --- */
504 /* Not a proper property, just for dirty hacks. TODO Remove it! */
505 const PropertyInfo qdev_prop_ptr
= {
509 /* --- mac address --- */
512 * accepted syntax versions:
516 static void get_mac(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
519 DeviceState
*dev
= DEVICE(obj
);
520 Property
*prop
= opaque
;
521 MACAddr
*mac
= qdev_get_prop_ptr(dev
, prop
);
522 char buffer
[2 * 6 + 5 + 1];
525 snprintf(buffer
, sizeof(buffer
), "%02x:%02x:%02x:%02x:%02x:%02x",
526 mac
->a
[0], mac
->a
[1], mac
->a
[2],
527 mac
->a
[3], mac
->a
[4], mac
->a
[5]);
529 visit_type_str(v
, name
, &p
, errp
);
532 static void set_mac(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
535 DeviceState
*dev
= DEVICE(obj
);
536 Property
*prop
= opaque
;
537 MACAddr
*mac
= qdev_get_prop_ptr(dev
, prop
);
538 Error
*local_err
= NULL
;
543 qdev_prop_set_after_realize(dev
, name
, errp
);
547 visit_type_str(v
, name
, &str
, &local_err
);
549 error_propagate(errp
, local_err
);
553 for (i
= 0, pos
= 0; i
< 6; i
++, pos
+= 3) {
554 if (!qemu_isxdigit(str
[pos
])) {
557 if (!qemu_isxdigit(str
[pos
+1])) {
561 if (str
[pos
+2] != '\0') {
565 if (str
[pos
+2] != ':' && str
[pos
+2] != '-') {
569 mac
->a
[i
] = strtol(str
+pos
, &p
, 16);
575 error_set_from_qdev_prop_error(errp
, EINVAL
, dev
, prop
, str
);
579 const PropertyInfo qdev_prop_macaddr
= {
581 .description
= "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56",
586 /* --- on/off/auto --- */
588 const PropertyInfo qdev_prop_on_off_auto
= {
590 .description
= "on/off/auto",
591 .enum_table
= &OnOffAuto_lookup
,
594 .set_default_value
= set_default_value_enum
,
597 /* --- lost tick policy --- */
599 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy
) != sizeof(int));
601 const PropertyInfo qdev_prop_losttickpolicy
= {
602 .name
= "LostTickPolicy",
603 .enum_table
= &LostTickPolicy_lookup
,
606 .set_default_value
= set_default_value_enum
,
609 /* --- Block device error handling policy --- */
611 QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError
) != sizeof(int));
613 const PropertyInfo qdev_prop_blockdev_on_error
= {
614 .name
= "BlockdevOnError",
615 .description
= "Error handling policy, "
616 "report/ignore/enospc/stop/auto",
617 .enum_table
= &BlockdevOnError_lookup
,
620 .set_default_value
= set_default_value_enum
,
623 /* --- BIOS CHS translation */
625 QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation
) != sizeof(int));
627 const PropertyInfo qdev_prop_bios_chs_trans
= {
628 .name
= "BiosAtaTranslation",
629 .description
= "Logical CHS translation algorithm, "
630 "auto/none/lba/large/rechs",
631 .enum_table
= &BiosAtaTranslation_lookup
,
634 .set_default_value
= set_default_value_enum
,
637 /* --- FDC default drive types */
639 const PropertyInfo qdev_prop_fdc_drive_type
= {
640 .name
= "FdcDriveType",
641 .description
= "FDC drive type, "
642 "144/288/120/none/auto",
643 .enum_table
= &FloppyDriveType_lookup
,
646 .set_default_value
= set_default_value_enum
,
649 /* --- pci address --- */
652 * bus-local address, i.e. "$slot" or "$slot.$fn"
654 static void set_pci_devfn(Object
*obj
, Visitor
*v
, const char *name
,
655 void *opaque
, Error
**errp
)
657 DeviceState
*dev
= DEVICE(obj
);
658 Property
*prop
= opaque
;
659 int32_t value
, *ptr
= qdev_get_prop_ptr(dev
, prop
);
660 unsigned int slot
, fn
, n
;
661 Error
*local_err
= NULL
;
665 qdev_prop_set_after_realize(dev
, name
, errp
);
669 visit_type_str(v
, name
, &str
, &local_err
);
671 error_free(local_err
);
673 visit_type_int32(v
, name
, &value
, &local_err
);
675 error_propagate(errp
, local_err
);
676 } else if (value
< -1 || value
> 255) {
677 error_setg(errp
, QERR_INVALID_PARAMETER_VALUE
,
678 name
? name
: "null", "pci_devfn");
685 if (sscanf(str
, "%x.%x%n", &slot
, &fn
, &n
) != 2) {
687 if (sscanf(str
, "%x%n", &slot
, &n
) != 1) {
691 if (str
[n
] != '\0' || fn
> 7 || slot
> 31) {
694 *ptr
= slot
<< 3 | fn
;
699 error_set_from_qdev_prop_error(errp
, EINVAL
, dev
, prop
, str
);
703 static int print_pci_devfn(DeviceState
*dev
, Property
*prop
, char *dest
,
706 int32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
709 return snprintf(dest
, len
, "<unset>");
711 return snprintf(dest
, len
, "%02x.%x", *ptr
>> 3, *ptr
& 7);
715 const PropertyInfo qdev_prop_pci_devfn
= {
717 .description
= "Slot and optional function number, example: 06.0 or 06",
718 .print
= print_pci_devfn
,
720 .set
= set_pci_devfn
,
721 .set_default_value
= set_default_value_int
,
724 /* --- blocksize --- */
726 static void set_blocksize(Object
*obj
, Visitor
*v
, const char *name
,
727 void *opaque
, Error
**errp
)
729 DeviceState
*dev
= DEVICE(obj
);
730 Property
*prop
= opaque
;
731 uint16_t value
, *ptr
= qdev_get_prop_ptr(dev
, prop
);
732 Error
*local_err
= NULL
;
733 const int64_t min
= 512;
734 const int64_t max
= 32768;
737 qdev_prop_set_after_realize(dev
, name
, errp
);
741 visit_type_uint16(v
, name
, &value
, &local_err
);
743 error_propagate(errp
, local_err
);
746 /* value of 0 means "unset" */
747 if (value
&& (value
< min
|| value
> max
)) {
748 error_setg(errp
, QERR_PROPERTY_VALUE_OUT_OF_RANGE
,
749 dev
->id
? : "", name
, (int64_t)value
, min
, max
);
753 /* We rely on power-of-2 blocksizes for bitmasks */
754 if ((value
& (value
- 1)) != 0) {
756 "Property %s.%s doesn't take value '%" PRId64
"', it's not a power of 2",
757 dev
->id
?: "", name
, (int64_t)value
);
764 const PropertyInfo qdev_prop_blocksize
= {
766 .description
= "A power of two between 512 and 32768",
768 .set
= set_blocksize
,
769 .set_default_value
= set_default_value_uint
,
772 /* --- pci host address --- */
774 static void get_pci_host_devaddr(Object
*obj
, Visitor
*v
, const char *name
,
775 void *opaque
, Error
**errp
)
777 DeviceState
*dev
= DEVICE(obj
);
778 Property
*prop
= opaque
;
779 PCIHostDeviceAddress
*addr
= qdev_get_prop_ptr(dev
, prop
);
780 char buffer
[] = "ffff:ff:ff.f";
785 * Catch "invalid" device reference from vfio-pci and allow the
786 * default buffer representing the non-existent device to be used.
788 if (~addr
->domain
|| ~addr
->bus
|| ~addr
->slot
|| ~addr
->function
) {
789 rc
= snprintf(buffer
, sizeof(buffer
), "%04x:%02x:%02x.%0d",
790 addr
->domain
, addr
->bus
, addr
->slot
, addr
->function
);
791 assert(rc
== sizeof(buffer
) - 1);
794 visit_type_str(v
, name
, &p
, errp
);
798 * Parse [<domain>:]<bus>:<slot>.<func>
799 * if <domain> is not supplied, it's assumed to be 0.
801 static void set_pci_host_devaddr(Object
*obj
, Visitor
*v
, const char *name
,
802 void *opaque
, Error
**errp
)
804 DeviceState
*dev
= DEVICE(obj
);
805 Property
*prop
= opaque
;
806 PCIHostDeviceAddress
*addr
= qdev_get_prop_ptr(dev
, prop
);
807 Error
*local_err
= NULL
;
811 unsigned long dom
= 0, bus
= 0;
812 unsigned int slot
= 0, func
= 0;
815 qdev_prop_set_after_realize(dev
, name
, errp
);
819 visit_type_str(v
, name
, &str
, &local_err
);
821 error_propagate(errp
, local_err
);
826 val
= strtoul(p
, &e
, 16);
827 if (e
== p
|| *e
!= ':') {
833 val
= strtoul(p
, &e
, 16);
841 val
= strtoul(p
, &e
, 16);
852 val
= strtoul(p
, &e
, 10);
858 if (dom
> 0xffff || bus
> 0xff || slot
> 0x1f || func
> 7) {
869 addr
->function
= func
;
875 error_set_from_qdev_prop_error(errp
, EINVAL
, dev
, prop
, str
);
879 const PropertyInfo qdev_prop_pci_host_devaddr
= {
881 .description
= "Address (bus/device/function) of "
882 "the host device, example: 04:10.0",
883 .get
= get_pci_host_devaddr
,
884 .set
= set_pci_host_devaddr
,
889 static void get_uuid(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
892 DeviceState
*dev
= DEVICE(obj
);
893 Property
*prop
= opaque
;
894 QemuUUID
*uuid
= qdev_get_prop_ptr(dev
, prop
);
895 char buffer
[UUID_FMT_LEN
+ 1];
898 qemu_uuid_unparse(uuid
, buffer
);
900 visit_type_str(v
, name
, &p
, errp
);
903 #define UUID_VALUE_AUTO "auto"
905 static void set_uuid(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
908 DeviceState
*dev
= DEVICE(obj
);
909 Property
*prop
= opaque
;
910 QemuUUID
*uuid
= qdev_get_prop_ptr(dev
, prop
);
911 Error
*local_err
= NULL
;
915 qdev_prop_set_after_realize(dev
, name
, errp
);
919 visit_type_str(v
, name
, &str
, &local_err
);
921 error_propagate(errp
, local_err
);
925 if (!strcmp(str
, UUID_VALUE_AUTO
)) {
926 qemu_uuid_generate(uuid
);
927 } else if (qemu_uuid_parse(str
, uuid
) < 0) {
928 error_set_from_qdev_prop_error(errp
, EINVAL
, dev
, prop
, str
);
933 static void set_default_uuid_auto(Object
*obj
, const Property
*prop
)
935 object_property_set_str(obj
, UUID_VALUE_AUTO
, prop
->name
, &error_abort
);
938 const PropertyInfo qdev_prop_uuid
= {
940 .description
= "UUID (aka GUID) or \"" UUID_VALUE_AUTO
941 "\" for random value (default)",
944 .set_default_value
= set_default_uuid_auto
,
947 /* --- support for array properties --- */
949 /* Used as an opaque for the object properties we add for each
950 * array element. Note that the struct Property must be first
951 * in the struct so that a pointer to this works as the opaque
952 * for the underlying element's property hooks as well as for
953 * our own release callback.
956 struct Property prop
;
958 ObjectPropertyRelease
*release
;
959 } ArrayElementProperty
;
961 /* object property release callback for array element properties:
962 * we call the underlying element's property release hook, and
963 * then free the memory we allocated when we added the property.
965 static void array_element_release(Object
*obj
, const char *name
, void *opaque
)
967 ArrayElementProperty
*p
= opaque
;
969 p
->release(obj
, name
, opaque
);
975 static void set_prop_arraylen(Object
*obj
, Visitor
*v
, const char *name
,
976 void *opaque
, Error
**errp
)
978 /* Setter for the property which defines the length of a
979 * variable-sized property array. As well as actually setting the
980 * array-length field in the device struct, we have to create the
981 * array itself and dynamically add the corresponding properties.
983 DeviceState
*dev
= DEVICE(obj
);
984 Property
*prop
= opaque
;
985 uint32_t *alenptr
= qdev_get_prop_ptr(dev
, prop
);
986 void **arrayptr
= (void *)dev
+ prop
->arrayoffset
;
987 Error
*local_err
= NULL
;
989 const char *arrayname
;
993 qdev_prop_set_after_realize(dev
, name
, errp
);
997 error_setg(errp
, "array size property %s may not be set more than once",
1001 visit_type_uint32(v
, name
, alenptr
, &local_err
);
1003 error_propagate(errp
, local_err
);
1010 /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
1011 * strip it off so we can get the name of the array itself.
1013 assert(strncmp(name
, PROP_ARRAY_LEN_PREFIX
,
1014 strlen(PROP_ARRAY_LEN_PREFIX
)) == 0);
1015 arrayname
= name
+ strlen(PROP_ARRAY_LEN_PREFIX
);
1017 /* Note that it is the responsibility of the individual device's deinit
1018 * to free the array proper.
1020 *arrayptr
= eltptr
= g_malloc0(*alenptr
* prop
->arrayfieldsize
);
1021 for (i
= 0; i
< *alenptr
; i
++, eltptr
+= prop
->arrayfieldsize
) {
1022 char *propname
= g_strdup_printf("%s[%d]", arrayname
, i
);
1023 ArrayElementProperty
*arrayprop
= g_new0(ArrayElementProperty
, 1);
1024 arrayprop
->release
= prop
->arrayinfo
->release
;
1025 arrayprop
->propname
= propname
;
1026 arrayprop
->prop
.info
= prop
->arrayinfo
;
1027 arrayprop
->prop
.name
= propname
;
1028 /* This ugly piece of pointer arithmetic sets up the offset so
1029 * that when the underlying get/set hooks call qdev_get_prop_ptr
1030 * they get the right answer despite the array element not actually
1031 * being inside the device struct.
1033 arrayprop
->prop
.offset
= eltptr
- (void *)dev
;
1034 assert(qdev_get_prop_ptr(dev
, &arrayprop
->prop
) == eltptr
);
1035 object_property_add(obj
, propname
,
1036 arrayprop
->prop
.info
->name
,
1037 arrayprop
->prop
.info
->get
,
1038 arrayprop
->prop
.info
->set
,
1039 array_element_release
,
1040 arrayprop
, &local_err
);
1042 error_propagate(errp
, local_err
);
1048 const PropertyInfo qdev_prop_arraylen
= {
1051 .set
= set_prop_arraylen
,
1052 .set_default_value
= set_default_value_uint
,
1055 /* --- public helpers --- */
1057 static Property
*qdev_prop_walk(Property
*props
, const char *name
)
1062 while (props
->name
) {
1063 if (strcmp(props
->name
, name
) == 0) {
1071 static Property
*qdev_prop_find(DeviceState
*dev
, const char *name
)
1076 /* device properties */
1077 class = object_get_class(OBJECT(dev
));
1079 prop
= qdev_prop_walk(DEVICE_CLASS(class)->props
, name
);
1083 class = object_class_get_parent(class);
1084 } while (class != object_class_by_name(TYPE_DEVICE
));
1089 void error_set_from_qdev_prop_error(Error
**errp
, int ret
, DeviceState
*dev
,
1090 Property
*prop
, const char *value
)
1094 error_setg(errp
, "Property '%s.%s' can't take value '%s', it's in use",
1095 object_get_typename(OBJECT(dev
)), prop
->name
, value
);
1099 error_setg(errp
, QERR_PROPERTY_VALUE_BAD
,
1100 object_get_typename(OBJECT(dev
)), prop
->name
, value
);
1103 error_setg(errp
, "Property '%s.%s' can't find value '%s'",
1104 object_get_typename(OBJECT(dev
)), prop
->name
, value
);
1111 void qdev_prop_set_bit(DeviceState
*dev
, const char *name
, bool value
)
1113 object_property_set_bool(OBJECT(dev
), value
, name
, &error_abort
);
1116 void qdev_prop_set_uint8(DeviceState
*dev
, const char *name
, uint8_t value
)
1118 object_property_set_int(OBJECT(dev
), value
, name
, &error_abort
);
1121 void qdev_prop_set_uint16(DeviceState
*dev
, const char *name
, uint16_t value
)
1123 object_property_set_int(OBJECT(dev
), value
, name
, &error_abort
);
1126 void qdev_prop_set_uint32(DeviceState
*dev
, const char *name
, uint32_t value
)
1128 object_property_set_int(OBJECT(dev
), value
, name
, &error_abort
);
1131 void qdev_prop_set_int32(DeviceState
*dev
, const char *name
, int32_t value
)
1133 object_property_set_int(OBJECT(dev
), value
, name
, &error_abort
);
1136 void qdev_prop_set_uint64(DeviceState
*dev
, const char *name
, uint64_t value
)
1138 object_property_set_int(OBJECT(dev
), value
, name
, &error_abort
);
1141 void qdev_prop_set_string(DeviceState
*dev
, const char *name
, const char *value
)
1143 object_property_set_str(OBJECT(dev
), value
, name
, &error_abort
);
1146 void qdev_prop_set_macaddr(DeviceState
*dev
, const char *name
,
1147 const uint8_t *value
)
1149 char str
[2 * 6 + 5 + 1];
1150 snprintf(str
, sizeof(str
), "%02x:%02x:%02x:%02x:%02x:%02x",
1151 value
[0], value
[1], value
[2], value
[3], value
[4], value
[5]);
1153 object_property_set_str(OBJECT(dev
), str
, name
, &error_abort
);
1156 void qdev_prop_set_enum(DeviceState
*dev
, const char *name
, int value
)
1160 prop
= qdev_prop_find(dev
, name
);
1161 object_property_set_str(OBJECT(dev
),
1162 qapi_enum_lookup(prop
->info
->enum_table
, value
),
1163 name
, &error_abort
);
1166 void qdev_prop_set_ptr(DeviceState
*dev
, const char *name
, void *value
)
1171 prop
= qdev_prop_find(dev
, name
);
1172 assert(prop
&& prop
->info
== &qdev_prop_ptr
);
1173 ptr
= qdev_get_prop_ptr(dev
, prop
);
1177 static GList
*global_props
;
1179 void qdev_prop_register_global(GlobalProperty
*prop
)
1181 global_props
= g_list_append(global_props
, prop
);
1184 void register_compat_prop(const char *driver
,
1185 const char *property
,
1188 GlobalProperty
*p
= g_new0(GlobalProperty
, 1);
1190 /* Any compat_props must never cause error */
1191 p
->errp
= &error_abort
;
1193 p
->property
= property
;
1195 qdev_prop_register_global(p
);
1198 void register_compat_props_array(GlobalProperty
*prop
)
1200 for (; prop
&& prop
->driver
; prop
++) {
1201 register_compat_prop(prop
->driver
, prop
->property
, prop
->value
);
1205 void qdev_prop_register_global_list(GlobalProperty
*props
)
1209 for (i
= 0; props
[i
].driver
!= NULL
; i
++) {
1210 qdev_prop_register_global(props
+i
);
1214 int qdev_prop_check_globals(void)
1219 for (l
= global_props
; l
; l
= l
->next
) {
1220 GlobalProperty
*prop
= l
->data
;
1226 if (!prop
->user_provided
) {
1229 oc
= object_class_by_name(prop
->driver
);
1230 oc
= object_class_dynamic_cast(oc
, TYPE_DEVICE
);
1232 warn_report("global %s.%s has invalid class name",
1233 prop
->driver
, prop
->property
);
1237 dc
= DEVICE_CLASS(oc
);
1238 if (!dc
->hotpluggable
&& !prop
->used
) {
1239 warn_report("global %s.%s=%s not used",
1240 prop
->driver
, prop
->property
, prop
->value
);
1248 void qdev_prop_set_globals(DeviceState
*dev
)
1252 for (l
= global_props
; l
; l
= l
->next
) {
1253 GlobalProperty
*prop
= l
->data
;
1256 if (object_dynamic_cast(OBJECT(dev
), prop
->driver
) == NULL
) {
1260 object_property_parse(OBJECT(dev
), prop
->value
, prop
->property
, &err
);
1262 error_prepend(&err
, "can't apply global %s.%s=%s: ",
1263 prop
->driver
, prop
->property
, prop
->value
);
1264 if (!dev
->hotplugged
&& prop
->errp
) {
1265 error_propagate(prop
->errp
, err
);
1267 assert(prop
->user_provided
);
1268 warn_report_err(err
);
1274 /* --- 64bit unsigned int 'size' type --- */
1276 static void get_size(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
1279 DeviceState
*dev
= DEVICE(obj
);
1280 Property
*prop
= opaque
;
1281 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
1283 visit_type_size(v
, name
, ptr
, errp
);
1286 static void set_size(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
1289 DeviceState
*dev
= DEVICE(obj
);
1290 Property
*prop
= opaque
;
1291 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
1293 visit_type_size(v
, name
, ptr
, errp
);
1296 const PropertyInfo qdev_prop_size
= {
1300 .set_default_value
= set_default_value_uint
,
1303 /* --- object link property --- */
1305 static void create_link_property(Object
*obj
, Property
*prop
, Error
**errp
)
1307 Object
**child
= qdev_get_prop_ptr(DEVICE(obj
), prop
);
1309 object_property_add_link(obj
, prop
->name
, prop
->link_type
,
1311 qdev_prop_allow_set_link_before_realize
,
1312 OBJ_PROP_LINK_UNREF_ON_RELEASE
,
1316 const PropertyInfo qdev_prop_link
= {
1318 .create
= create_link_property
,
1321 /* --- OffAutoPCIBAR off/auto/bar0/bar1/bar2/bar3/bar4/bar5 --- */
1323 const PropertyInfo qdev_prop_off_auto_pcibar
= {
1324 .name
= "OffAutoPCIBAR",
1325 .description
= "off/auto/bar0/bar1/bar2/bar3/bar4/bar5",
1326 .enum_table
= &OffAutoPCIBAR_lookup
,
1329 .set_default_value
= set_default_value_enum
,