2 * Dynamic device configuration and creation.
4 * Copyright (c) 2009 CodeSourcery
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 /* The theory here is that it should be possible to create a machine without
21 knowledge of specific devices. Historically board init routines have
22 passed a bunch of arguments to each device, requiring the board know
23 exactly which device it is dealing with. This file provides an abstract
24 API for device configuration and initialization. Devices will generally
25 inherit from a particular bus (e.g. PCI or I2C) rather than
33 static int qdev_hotplug
= 0;
34 static bool qdev_hot_added
= false;
35 static bool qdev_hot_removed
= false;
37 /* This is a nasty hack to allow passing a NULL bus to qdev_create. */
38 static BusState
*main_system_bus
;
39 static void main_system_bus_create(void);
41 DeviceInfo
*device_info_list
;
43 static BusState
*qbus_find_recursive(BusState
*bus
, const char *name
,
45 static BusState
*qbus_find(const char *path
);
47 /* Register a new device type. */
48 void qdev_register(DeviceInfo
*info
)
50 assert(info
->size
>= sizeof(DeviceState
));
53 info
->next
= device_info_list
;
54 device_info_list
= info
;
57 static DeviceInfo
*qdev_find_info(BusInfo
*bus_info
, const char *name
)
61 /* first check device names */
62 for (info
= device_info_list
; info
!= NULL
; info
= info
->next
) {
63 if (bus_info
&& info
->bus_info
!= bus_info
)
65 if (strcmp(info
->name
, name
) != 0)
70 /* failing that check the aliases */
71 for (info
= device_info_list
; info
!= NULL
; info
= info
->next
) {
72 if (bus_info
&& info
->bus_info
!= bus_info
)
76 if (strcmp(info
->alias
, name
) != 0)
83 static DeviceState
*qdev_create_from_info(BusState
*bus
, DeviceInfo
*info
)
88 assert(bus
->info
== info
->bus_info
);
89 dev
= g_malloc0(info
->size
);
91 dev
->parent_bus
= bus
;
92 qdev_prop_set_defaults(dev
, dev
->info
->props
);
93 qdev_prop_set_defaults(dev
, dev
->parent_bus
->info
->props
);
94 qdev_prop_set_globals(dev
);
95 QTAILQ_INSERT_HEAD(&bus
->children
, dev
, sibling
);
97 assert(bus
->allow_hotplug
);
99 qdev_hot_added
= true;
101 dev
->instance_id_alias
= -1;
102 QTAILQ_INIT(&dev
->properties
);
103 dev
->state
= DEV_STATE_CREATED
;
105 for (prop
= dev
->info
->props
; prop
&& prop
->name
; prop
++) {
106 qdev_property_add_legacy(dev
, prop
, NULL
);
109 for (prop
= dev
->info
->bus_info
->props
; prop
&& prop
->name
; prop
++) {
110 qdev_property_add_legacy(dev
, prop
, NULL
);
116 /* Create a new device. This only initializes the device state structure
117 and allows properties to be set. qdev_init should be called to
118 initialize the actual device emulation. */
119 DeviceState
*qdev_create(BusState
*bus
, const char *name
)
123 dev
= qdev_try_create(bus
, name
);
126 hw_error("Unknown device '%s' for bus '%s'\n", name
,
129 hw_error("Unknown device '%s' for default sysbus\n", name
);
136 DeviceState
*qdev_try_create(BusState
*bus
, const char *name
)
141 bus
= sysbus_get_default();
144 info
= qdev_find_info(bus
->info
, name
);
149 return qdev_create_from_info(bus
, info
);
152 static void qdev_print_devinfo(DeviceInfo
*info
)
154 error_printf("name \"%s\", bus %s",
155 info
->name
, info
->bus_info
->name
);
157 error_printf(", alias \"%s\"", info
->alias
);
160 error_printf(", desc \"%s\"", info
->desc
);
163 error_printf(", no-user");
168 static int set_property(const char *name
, const char *value
, void *opaque
)
170 DeviceState
*dev
= opaque
;
172 if (strcmp(name
, "driver") == 0)
174 if (strcmp(name
, "bus") == 0)
177 if (qdev_prop_parse(dev
, name
, value
) == -1) {
183 int qdev_device_help(QemuOpts
*opts
)
189 driver
= qemu_opt_get(opts
, "driver");
190 if (driver
&& !strcmp(driver
, "?")) {
191 for (info
= device_info_list
; info
!= NULL
; info
= info
->next
) {
193 continue; /* not available, don't show */
195 qdev_print_devinfo(info
);
200 if (!driver
|| !qemu_opt_get(opts
, "?")) {
204 info
= qdev_find_info(NULL
, driver
);
209 for (prop
= info
->props
; prop
&& prop
->name
; prop
++) {
211 * TODO Properties without a parser are just for dirty hacks.
212 * qdev_prop_ptr is the only such PropertyInfo. It's marked
213 * for removal. This conditional should be removed along with
216 if (!prop
->info
->parse
) {
217 continue; /* no way to set it, don't show */
219 error_printf("%s.%s=%s\n", info
->name
, prop
->name
, prop
->info
->name
);
221 for (prop
= info
->bus_info
->props
; prop
&& prop
->name
; prop
++) {
222 if (!prop
->info
->parse
) {
223 continue; /* no way to set it, don't show */
225 error_printf("%s.%s=%s\n", info
->name
, prop
->name
, prop
->info
->name
);
230 static DeviceState
*qdev_get_peripheral(void)
232 static DeviceState
*dev
;
235 dev
= qdev_create(NULL
, "container");
236 qdev_property_add_child(qdev_get_root(), "peripheral", dev
, NULL
);
237 qdev_init_nofail(dev
);
243 DeviceState
*qdev_device_add(QemuOpts
*opts
)
245 const char *driver
, *path
, *id
;
250 driver
= qemu_opt_get(opts
, "driver");
252 qerror_report(QERR_MISSING_PARAMETER
, "driver");
257 info
= qdev_find_info(NULL
, driver
);
258 if (!info
|| info
->no_user
) {
259 qerror_report(QERR_INVALID_PARAMETER_VALUE
, "driver", "a driver name");
260 error_printf_unless_qmp("Try with argument '?' for a list.\n");
265 path
= qemu_opt_get(opts
, "bus");
267 bus
= qbus_find(path
);
271 if (bus
->info
!= info
->bus_info
) {
272 qerror_report(QERR_BAD_BUS_FOR_DEVICE
,
273 driver
, bus
->info
->name
);
277 bus
= qbus_find_recursive(main_system_bus
, NULL
, info
->bus_info
);
279 qerror_report(QERR_NO_BUS_FOR_DEVICE
,
280 info
->name
, info
->bus_info
->name
);
284 if (qdev_hotplug
&& !bus
->allow_hotplug
) {
285 qerror_report(QERR_BUS_NO_HOTPLUG
, bus
->name
);
289 /* create device, set properties */
290 qdev
= qdev_create_from_info(bus
, info
);
291 id
= qemu_opts_id(opts
);
294 qdev_property_add_child(qdev_get_peripheral(), qdev
->id
, qdev
, NULL
);
296 if (qemu_opt_foreach(opts
, set_property
, qdev
, 1) != 0) {
300 if (qdev_init(qdev
) < 0) {
301 qerror_report(QERR_DEVICE_INIT_FAILED
, driver
);
308 /* Initialize a device. Device properties should be set before calling
309 this function. IRQs and MMIO regions should be connected/mapped after
310 calling this function.
311 On failure, destroy the device and return negative value.
312 Return 0 on success. */
313 int qdev_init(DeviceState
*dev
)
317 assert(dev
->state
== DEV_STATE_CREATED
);
318 rc
= dev
->info
->init(dev
, dev
->info
);
323 if (dev
->info
->vmsd
) {
324 vmstate_register_with_alias_id(dev
, -1, dev
->info
->vmsd
, dev
,
325 dev
->instance_id_alias
,
326 dev
->alias_required_for_version
);
328 dev
->state
= DEV_STATE_INITIALIZED
;
329 if (dev
->hotplugged
&& dev
->info
->reset
) {
330 dev
->info
->reset(dev
);
335 void qdev_set_legacy_instance_id(DeviceState
*dev
, int alias_id
,
336 int required_for_version
)
338 assert(dev
->state
== DEV_STATE_CREATED
);
339 dev
->instance_id_alias
= alias_id
;
340 dev
->alias_required_for_version
= required_for_version
;
343 int qdev_unplug(DeviceState
*dev
)
345 if (!dev
->parent_bus
->allow_hotplug
) {
346 qerror_report(QERR_BUS_NO_HOTPLUG
, dev
->parent_bus
->name
);
349 assert(dev
->info
->unplug
!= NULL
);
352 qerror_report(QERR_DEVICE_IN_USE
, dev
->id
?:"");
356 qdev_hot_removed
= true;
358 return dev
->info
->unplug(dev
);
361 static int qdev_reset_one(DeviceState
*dev
, void *opaque
)
363 if (dev
->info
->reset
) {
364 dev
->info
->reset(dev
);
370 BusState
*sysbus_get_default(void)
372 if (!main_system_bus
) {
373 main_system_bus_create();
375 return main_system_bus
;
378 static int qbus_reset_one(BusState
*bus
, void *opaque
)
380 if (bus
->info
->reset
) {
381 return bus
->info
->reset(bus
);
386 void qdev_reset_all(DeviceState
*dev
)
388 qdev_walk_children(dev
, qdev_reset_one
, qbus_reset_one
, NULL
);
391 void qbus_reset_all_fn(void *opaque
)
393 BusState
*bus
= opaque
;
394 qbus_walk_children(bus
, qdev_reset_one
, qbus_reset_one
, NULL
);
397 /* can be used as ->unplug() callback for the simple cases */
398 int qdev_simple_unplug_cb(DeviceState
*dev
)
406 /* Like qdev_init(), but terminate program via error_report() instead of
407 returning an error value. This is okay during machine creation.
408 Don't use for hotplug, because there callers need to recover from
409 failure. Exception: if you know the device's init() callback can't
410 fail, then qdev_init_nofail() can't fail either, and is therefore
411 usable even then. But relying on the device implementation that
412 way is somewhat unclean, and best avoided. */
413 void qdev_init_nofail(DeviceState
*dev
)
415 DeviceInfo
*info
= dev
->info
;
417 if (qdev_init(dev
) < 0) {
418 error_report("Initialization of device %s failed", info
->name
);
423 static void qdev_property_del_all(DeviceState
*dev
)
425 while (!QTAILQ_EMPTY(&dev
->properties
)) {
426 DeviceProperty
*prop
= QTAILQ_FIRST(&dev
->properties
);
428 QTAILQ_REMOVE(&dev
->properties
, prop
, node
);
431 prop
->release(dev
, prop
->name
, prop
->opaque
);
440 /* Unlink device from bus and free the structure. */
441 void qdev_free(DeviceState
*dev
)
446 qdev_property_del_all(dev
);
448 if (dev
->state
== DEV_STATE_INITIALIZED
) {
449 while (dev
->num_child_bus
) {
450 bus
= QLIST_FIRST(&dev
->child_bus
);
454 vmstate_unregister(dev
, dev
->info
->vmsd
, dev
);
456 dev
->info
->exit(dev
);
458 qemu_opts_del(dev
->opts
);
460 QTAILQ_REMOVE(&dev
->parent_bus
->children
, dev
, sibling
);
461 for (prop
= dev
->info
->props
; prop
&& prop
->name
; prop
++) {
462 if (prop
->info
->free
) {
463 prop
->info
->free(dev
, prop
);
469 void qdev_machine_creation_done(void)
472 * ok, initial machine setup is done, starting from now we can
473 * only create hotpluggable devices
478 bool qdev_machine_modified(void)
480 return qdev_hot_added
|| qdev_hot_removed
;
483 /* Get a character (serial) device interface. */
484 CharDriverState
*qdev_init_chardev(DeviceState
*dev
)
486 static int next_serial
;
488 /* FIXME: This function needs to go away: use chardev properties! */
489 return serial_hds
[next_serial
++];
492 BusState
*qdev_get_parent_bus(DeviceState
*dev
)
494 return dev
->parent_bus
;
497 void qdev_init_gpio_in(DeviceState
*dev
, qemu_irq_handler handler
, int n
)
499 assert(dev
->num_gpio_in
== 0);
500 dev
->num_gpio_in
= n
;
501 dev
->gpio_in
= qemu_allocate_irqs(handler
, dev
, n
);
504 void qdev_init_gpio_out(DeviceState
*dev
, qemu_irq
*pins
, int n
)
506 assert(dev
->num_gpio_out
== 0);
507 dev
->num_gpio_out
= n
;
508 dev
->gpio_out
= pins
;
511 qemu_irq
qdev_get_gpio_in(DeviceState
*dev
, int n
)
513 assert(n
>= 0 && n
< dev
->num_gpio_in
);
514 return dev
->gpio_in
[n
];
517 void qdev_connect_gpio_out(DeviceState
* dev
, int n
, qemu_irq pin
)
519 assert(n
>= 0 && n
< dev
->num_gpio_out
);
520 dev
->gpio_out
[n
] = pin
;
523 void qdev_set_nic_properties(DeviceState
*dev
, NICInfo
*nd
)
525 qdev_prop_set_macaddr(dev
, "mac", nd
->macaddr
.a
);
527 qdev_prop_set_vlan(dev
, "vlan", nd
->vlan
);
529 qdev_prop_set_netdev(dev
, "netdev", nd
->netdev
);
530 if (nd
->nvectors
!= DEV_NVECTORS_UNSPECIFIED
&&
531 qdev_prop_exists(dev
, "vectors")) {
532 qdev_prop_set_uint32(dev
, "vectors", nd
->nvectors
);
534 nd
->instantiated
= 1;
537 BusState
*qdev_get_child_bus(DeviceState
*dev
, const char *name
)
541 QLIST_FOREACH(bus
, &dev
->child_bus
, sibling
) {
542 if (strcmp(name
, bus
->name
) == 0) {
549 int qbus_walk_children(BusState
*bus
, qdev_walkerfn
*devfn
,
550 qbus_walkerfn
*busfn
, void *opaque
)
556 err
= busfn(bus
, opaque
);
562 QTAILQ_FOREACH(dev
, &bus
->children
, sibling
) {
563 err
= qdev_walk_children(dev
, devfn
, busfn
, opaque
);
572 int qdev_walk_children(DeviceState
*dev
, qdev_walkerfn
*devfn
,
573 qbus_walkerfn
*busfn
, void *opaque
)
579 err
= devfn(dev
, opaque
);
585 QLIST_FOREACH(bus
, &dev
->child_bus
, sibling
) {
586 err
= qbus_walk_children(bus
, devfn
, busfn
, opaque
);
595 static BusState
*qbus_find_recursive(BusState
*bus
, const char *name
,
599 BusState
*child
, *ret
;
602 if (name
&& (strcmp(bus
->name
, name
) != 0)) {
605 if (info
&& (bus
->info
!= info
)) {
612 QTAILQ_FOREACH(dev
, &bus
->children
, sibling
) {
613 QLIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
614 ret
= qbus_find_recursive(child
, name
, info
);
623 DeviceState
*qdev_find_recursive(BusState
*bus
, const char *id
)
625 DeviceState
*dev
, *ret
;
628 QTAILQ_FOREACH(dev
, &bus
->children
, sibling
) {
629 if (dev
->id
&& strcmp(dev
->id
, id
) == 0)
631 QLIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
632 ret
= qdev_find_recursive(child
, id
);
641 static void qbus_list_bus(DeviceState
*dev
)
644 const char *sep
= " ";
646 error_printf("child busses at \"%s\":",
647 dev
->id
? dev
->id
: dev
->info
->name
);
648 QLIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
649 error_printf("%s\"%s\"", sep
, child
->name
);
655 static void qbus_list_dev(BusState
*bus
)
658 const char *sep
= " ";
660 error_printf("devices at \"%s\":", bus
->name
);
661 QTAILQ_FOREACH(dev
, &bus
->children
, sibling
) {
662 error_printf("%s\"%s\"", sep
, dev
->info
->name
);
664 error_printf("/\"%s\"", dev
->id
);
670 static BusState
*qbus_find_bus(DeviceState
*dev
, char *elem
)
674 QLIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
675 if (strcmp(child
->name
, elem
) == 0) {
682 static DeviceState
*qbus_find_dev(BusState
*bus
, char *elem
)
687 * try to match in order:
688 * (1) instance id, if present
690 * (3) driver alias, if present
692 QTAILQ_FOREACH(dev
, &bus
->children
, sibling
) {
693 if (dev
->id
&& strcmp(dev
->id
, elem
) == 0) {
697 QTAILQ_FOREACH(dev
, &bus
->children
, sibling
) {
698 if (strcmp(dev
->info
->name
, elem
) == 0) {
702 QTAILQ_FOREACH(dev
, &bus
->children
, sibling
) {
703 if (dev
->info
->alias
&& strcmp(dev
->info
->alias
, elem
) == 0) {
710 static BusState
*qbus_find(const char *path
)
717 /* find start element */
718 if (path
[0] == '/') {
719 bus
= main_system_bus
;
722 if (sscanf(path
, "%127[^/]%n", elem
, &len
) != 1) {
726 bus
= qbus_find_recursive(main_system_bus
, elem
, NULL
);
728 qerror_report(QERR_BUS_NOT_FOUND
, elem
);
735 assert(path
[pos
] == '/' || !path
[pos
]);
736 while (path
[pos
] == '/') {
739 if (path
[pos
] == '\0') {
744 if (sscanf(path
+pos
, "%127[^/]%n", elem
, &len
) != 1) {
749 dev
= qbus_find_dev(bus
, elem
);
751 qerror_report(QERR_DEVICE_NOT_FOUND
, elem
);
752 if (!monitor_cur_is_qmp()) {
758 assert(path
[pos
] == '/' || !path
[pos
]);
759 while (path
[pos
] == '/') {
762 if (path
[pos
] == '\0') {
763 /* last specified element is a device. If it has exactly
764 * one child bus accept it nevertheless */
765 switch (dev
->num_child_bus
) {
767 qerror_report(QERR_DEVICE_NO_BUS
, elem
);
770 return QLIST_FIRST(&dev
->child_bus
);
772 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES
, elem
);
773 if (!monitor_cur_is_qmp()) {
781 if (sscanf(path
+pos
, "%127[^/]%n", elem
, &len
) != 1) {
786 bus
= qbus_find_bus(dev
, elem
);
788 qerror_report(QERR_BUS_NOT_FOUND
, elem
);
789 if (!monitor_cur_is_qmp()) {
797 void qbus_create_inplace(BusState
*bus
, BusInfo
*info
,
798 DeviceState
*parent
, const char *name
)
804 bus
->parent
= parent
;
807 /* use supplied name */
808 bus
->name
= g_strdup(name
);
809 } else if (parent
&& parent
->id
) {
810 /* parent device has id -> use it for bus name */
811 len
= strlen(parent
->id
) + 16;
813 snprintf(buf
, len
, "%s.%d", parent
->id
, parent
->num_child_bus
);
816 /* no id -> use lowercase bus type for bus name */
817 len
= strlen(info
->name
) + 16;
819 len
= snprintf(buf
, len
, "%s.%d", info
->name
,
820 parent
? parent
->num_child_bus
: 0);
821 for (i
= 0; i
< len
; i
++)
822 buf
[i
] = qemu_tolower(buf
[i
]);
826 QTAILQ_INIT(&bus
->children
);
828 QLIST_INSERT_HEAD(&parent
->child_bus
, bus
, sibling
);
829 parent
->num_child_bus
++;
830 } else if (bus
!= main_system_bus
) {
831 /* TODO: once all bus devices are qdevified,
832 only reset handler for main_system_bus should be registered here. */
833 qemu_register_reset(qbus_reset_all_fn
, bus
);
837 BusState
*qbus_create(BusInfo
*info
, DeviceState
*parent
, const char *name
)
841 bus
= g_malloc0(info
->size
);
842 bus
->qdev_allocated
= 1;
843 qbus_create_inplace(bus
, info
, parent
, name
);
847 static void main_system_bus_create(void)
849 /* assign main_system_bus before qbus_create_inplace()
850 * in order to make "if (bus != main_system_bus)" work */
851 main_system_bus
= g_malloc0(system_bus_info
.size
);
852 main_system_bus
->qdev_allocated
= 1;
853 qbus_create_inplace(main_system_bus
, &system_bus_info
, NULL
,
857 void qbus_free(BusState
*bus
)
861 while ((dev
= QTAILQ_FIRST(&bus
->children
)) != NULL
) {
865 QLIST_REMOVE(bus
, sibling
);
866 bus
->parent
->num_child_bus
--;
868 assert(bus
!= main_system_bus
); /* main_system_bus is never freed */
869 qemu_unregister_reset(qbus_reset_all_fn
, bus
);
871 g_free((void*)bus
->name
);
872 if (bus
->qdev_allocated
) {
877 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
878 static void qbus_print(Monitor
*mon
, BusState
*bus
, int indent
);
880 static void qdev_print_props(Monitor
*mon
, DeviceState
*dev
, Property
*props
,
881 const char *prefix
, int indent
)
887 while (props
->name
) {
889 * TODO Properties without a print method are just for dirty
890 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
891 * marked for removal. The test props->info->print should be
892 * removed along with it.
894 if (props
->info
->print
) {
895 props
->info
->print(dev
, props
, buf
, sizeof(buf
));
896 qdev_printf("%s-prop: %s = %s\n", prefix
, props
->name
, buf
);
902 static void qdev_print(Monitor
*mon
, DeviceState
*dev
, int indent
)
905 qdev_printf("dev: %s, id \"%s\"\n", dev
->info
->name
,
906 dev
->id
? dev
->id
: "");
908 if (dev
->num_gpio_in
) {
909 qdev_printf("gpio-in %d\n", dev
->num_gpio_in
);
911 if (dev
->num_gpio_out
) {
912 qdev_printf("gpio-out %d\n", dev
->num_gpio_out
);
914 qdev_print_props(mon
, dev
, dev
->info
->props
, "dev", indent
);
915 qdev_print_props(mon
, dev
, dev
->parent_bus
->info
->props
, "bus", indent
);
916 if (dev
->parent_bus
->info
->print_dev
)
917 dev
->parent_bus
->info
->print_dev(mon
, dev
, indent
);
918 QLIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
919 qbus_print(mon
, child
, indent
);
923 static void qbus_print(Monitor
*mon
, BusState
*bus
, int indent
)
925 struct DeviceState
*dev
;
927 qdev_printf("bus: %s\n", bus
->name
);
929 qdev_printf("type %s\n", bus
->info
->name
);
930 QTAILQ_FOREACH(dev
, &bus
->children
, sibling
) {
931 qdev_print(mon
, dev
, indent
);
936 void do_info_qtree(Monitor
*mon
)
939 qbus_print(mon
, main_system_bus
, 0);
942 void do_info_qdm(Monitor
*mon
)
946 for (info
= device_info_list
; info
!= NULL
; info
= info
->next
) {
947 qdev_print_devinfo(info
);
951 int do_device_add(Monitor
*mon
, const QDict
*qdict
, QObject
**ret_data
)
955 opts
= qemu_opts_from_qdict(qemu_find_opts("device"), qdict
);
959 if (!monitor_cur_is_qmp() && qdev_device_help(opts
)) {
963 if (!qdev_device_add(opts
)) {
970 int do_device_del(Monitor
*mon
, const QDict
*qdict
, QObject
**ret_data
)
972 const char *id
= qdict_get_str(qdict
, "id");
975 dev
= qdev_find_recursive(main_system_bus
, id
);
977 qerror_report(QERR_DEVICE_NOT_FOUND
, id
);
980 return qdev_unplug(dev
);
983 static int qdev_get_fw_dev_path_helper(DeviceState
*dev
, char *p
, int size
)
987 if (dev
&& dev
->parent_bus
) {
989 l
= qdev_get_fw_dev_path_helper(dev
->parent_bus
->parent
, p
, size
);
990 if (dev
->parent_bus
->info
->get_fw_dev_path
) {
991 d
= dev
->parent_bus
->info
->get_fw_dev_path(dev
);
992 l
+= snprintf(p
+ l
, size
- l
, "%s", d
);
995 l
+= snprintf(p
+ l
, size
- l
, "%s", dev
->info
->name
);
998 l
+= snprintf(p
+ l
, size
- l
, "/");
1003 char* qdev_get_fw_dev_path(DeviceState
*dev
)
1008 l
= qdev_get_fw_dev_path_helper(dev
, path
, 128);
1012 return strdup(path
);
1015 void qdev_ref(DeviceState
*dev
)
1020 void qdev_unref(DeviceState
*dev
)
1022 g_assert(dev
->ref
> 0);
1026 void qdev_property_add(DeviceState
*dev
, const char *name
, const char *type
,
1027 DevicePropertyAccessor
*get
, DevicePropertyAccessor
*set
,
1028 DevicePropertyRelease
*release
,
1029 void *opaque
, Error
**errp
)
1031 DeviceProperty
*prop
= g_malloc0(sizeof(*prop
));
1033 prop
->name
= g_strdup(name
);
1034 prop
->type
= g_strdup(type
);
1038 prop
->release
= release
;
1039 prop
->opaque
= opaque
;
1041 QTAILQ_INSERT_TAIL(&dev
->properties
, prop
, node
);
1044 static DeviceProperty
*qdev_property_find(DeviceState
*dev
, const char *name
)
1046 DeviceProperty
*prop
;
1048 QTAILQ_FOREACH(prop
, &dev
->properties
, node
) {
1049 if (strcmp(prop
->name
, name
) == 0) {
1057 void qdev_property_get(DeviceState
*dev
, Visitor
*v
, const char *name
,
1060 DeviceProperty
*prop
= qdev_property_find(dev
, name
);
1063 error_set(errp
, QERR_PROPERTY_NOT_FOUND
, dev
->id
?:"", name
);
1068 error_set(errp
, QERR_PERMISSION_DENIED
);
1070 prop
->get(dev
, v
, prop
->opaque
, name
, errp
);
1074 void qdev_property_set(DeviceState
*dev
, Visitor
*v
, const char *name
,
1077 DeviceProperty
*prop
= qdev_property_find(dev
, name
);
1080 error_set(errp
, QERR_PROPERTY_NOT_FOUND
, dev
->id
?:"", name
);
1085 error_set(errp
, QERR_PERMISSION_DENIED
);
1087 prop
->set(dev
, prop
->opaque
, v
, name
, errp
);
1091 const char *qdev_property_get_type(DeviceState
*dev
, const char *name
, Error
**errp
)
1093 DeviceProperty
*prop
= qdev_property_find(dev
, name
);
1096 error_set(errp
, QERR_PROPERTY_NOT_FOUND
, dev
->id
?:"", name
);
1104 * Legacy property handling
1107 static void qdev_get_legacy_property(DeviceState
*dev
, Visitor
*v
, void *opaque
,
1108 const char *name
, Error
**errp
)
1110 Property
*prop
= opaque
;
1112 if (prop
->info
->print
) {
1116 prop
->info
->print(dev
, prop
, buffer
, sizeof(buffer
));
1117 visit_type_str(v
, &ptr
, name
, errp
);
1119 error_set(errp
, QERR_PERMISSION_DENIED
);
1123 static void qdev_set_legacy_property(DeviceState
*dev
, Visitor
*v
, void *opaque
,
1124 const char *name
, Error
**errp
)
1126 Property
*prop
= opaque
;
1128 if (dev
->state
!= DEV_STATE_CREATED
) {
1129 error_set(errp
, QERR_PERMISSION_DENIED
);
1133 if (prop
->info
->parse
) {
1134 Error
*local_err
= NULL
;
1137 visit_type_str(v
, &ptr
, name
, &local_err
);
1140 ret
= prop
->info
->parse(dev
, prop
, ptr
);
1142 error_set(errp
, QERR_INVALID_PARAMETER_VALUE
,
1143 name
, prop
->info
->name
);
1147 error_propagate(errp
, local_err
);
1150 error_set(errp
, QERR_PERMISSION_DENIED
);
1155 * @qdev_add_legacy_property - adds a legacy property
1157 * Do not use this is new code! Properties added through this interface will
1158 * be given types in the "legacy<>" type namespace.
1160 * Legacy properties are always processed as strings. The format of the string
1161 * depends on the property type.
1163 void qdev_property_add_legacy(DeviceState
*dev
, Property
*prop
,
1168 type
= g_strdup_printf("legacy<%s>", prop
->info
->name
);
1170 qdev_property_add(dev
, prop
->name
, type
,
1171 qdev_get_legacy_property
,
1172 qdev_set_legacy_property
,
1179 DeviceState
*qdev_get_root(void)
1181 static DeviceState
*qdev_root
;
1184 qdev_root
= qdev_create(NULL
, "container");
1185 qdev_init_nofail(qdev_root
);
1191 static void qdev_get_child_property(DeviceState
*dev
, Visitor
*v
, void *opaque
,
1192 const char *name
, Error
**errp
)
1194 DeviceState
*child
= opaque
;
1197 path
= qdev_get_canonical_path(child
);
1198 visit_type_str(v
, &path
, name
, errp
);
1202 void qdev_property_add_child(DeviceState
*dev
, const char *name
,
1203 DeviceState
*child
, Error
**errp
)
1207 type
= g_strdup_printf("child<%s>", child
->info
->name
);
1209 qdev_property_add(dev
, name
, type
, qdev_get_child_property
,
1210 NULL
, NULL
, child
, errp
);
1217 static void qdev_get_link_property(DeviceState
*dev
, Visitor
*v
, void *opaque
,
1218 const char *name
, Error
**errp
)
1220 DeviceState
**child
= opaque
;
1224 path
= qdev_get_canonical_path(*child
);
1225 visit_type_str(v
, &path
, name
, errp
);
1229 visit_type_str(v
, &path
, name
, errp
);
1233 static void qdev_set_link_property(DeviceState
*dev
, Visitor
*v
, void *opaque
,
1234 const char *name
, Error
**errp
)
1236 DeviceState
**child
= opaque
;
1237 bool ambiguous
= false;
1241 type
= qdev_property_get_type(dev
, name
, NULL
);
1243 visit_type_str(v
, &path
, name
, errp
);
1249 if (strcmp(path
, "") != 0) {
1250 DeviceState
*target
;
1252 target
= qdev_resolve_path(path
, &ambiguous
);
1256 target_type
= g_strdup_printf("link<%s>", target
->info
->name
);
1257 if (strcmp(target_type
, type
) == 0) {
1261 error_set(errp
, QERR_INVALID_PARAMETER_TYPE
, name
, type
);
1264 g_free(target_type
);
1266 error_set(errp
, QERR_DEVICE_NOT_FOUND
, path
);
1275 void qdev_property_add_link(DeviceState
*dev
, const char *name
,
1276 const char *type
, DeviceState
**child
,
1281 full_type
= g_strdup_printf("link<%s>", type
);
1283 qdev_property_add(dev
, name
, full_type
,
1284 qdev_get_link_property
,
1285 qdev_set_link_property
,
1291 static gchar
*qdev_get_path_in(DeviceState
*parent
, DeviceState
*dev
)
1293 DeviceProperty
*prop
;
1295 if (parent
== dev
) {
1296 return g_strdup("");
1299 QTAILQ_FOREACH(prop
, &parent
->properties
, node
) {
1302 if (!strstart(prop
->type
, "child<", NULL
)) {
1306 /* Check to see if the device is one of parent's children */
1307 if (prop
->opaque
== dev
) {
1308 return g_strdup(prop
->name
);
1311 /* Check to see if the device is a child of our child */
1312 subpath
= qdev_get_path_in(prop
->opaque
, dev
);
1316 path
= g_strdup_printf("%s/%s", prop
->name
, subpath
);
1326 gchar
*qdev_get_canonical_path(DeviceState
*dev
)
1328 gchar
*path
, *newpath
;
1330 path
= qdev_get_path_in(qdev_get_root(), dev
);
1331 g_assert(path
!= NULL
);
1333 newpath
= g_strdup_printf("/%s", path
);
1339 static DeviceState
*qdev_resolve_abs_path(DeviceState
*parent
,
1343 DeviceProperty
*prop
;
1346 if (parts
[index
] == NULL
) {
1350 if (strcmp(parts
[index
], "") == 0) {
1351 return qdev_resolve_abs_path(parent
, parts
, index
+ 1);
1354 prop
= qdev_property_find(parent
, parts
[index
]);
1360 if (strstart(prop
->type
, "link<", NULL
)) {
1361 DeviceState
**pchild
= prop
->opaque
;
1365 } else if (strstart(prop
->type
, "child<", NULL
)) {
1366 child
= prop
->opaque
;
1373 return qdev_resolve_abs_path(child
, parts
, index
+ 1);
1376 static DeviceState
*qdev_resolve_partial_path(DeviceState
*parent
,
1381 DeviceProperty
*prop
;
1383 dev
= qdev_resolve_abs_path(parent
, parts
, 0);
1385 QTAILQ_FOREACH(prop
, &parent
->properties
, node
) {
1388 if (!strstart(prop
->type
, "child<", NULL
)) {
1392 found
= qdev_resolve_partial_path(prop
->opaque
, parts
, ambiguous
);
1403 if (ambiguous
&& *ambiguous
) {
1411 DeviceState
*qdev_resolve_path(const char *path
, bool *ambiguous
)
1413 bool partial_path
= true;
1417 parts
= g_strsplit(path
, "/", 0);
1418 if (parts
== NULL
|| parts
[0] == NULL
) {
1420 return qdev_get_root();
1423 if (strcmp(parts
[0], "") == 0) {
1424 partial_path
= false;
1431 dev
= qdev_resolve_partial_path(qdev_get_root(), parts
, ambiguous
);
1433 dev
= qdev_resolve_abs_path(qdev_get_root(), parts
, 1);