qdev: remove info from class
[qemu.git] / hw / qdev.c
1 /*
2 * Dynamic device configuration and creation.
3 *
4 * Copyright (c) 2009 CodeSourcery
5 *
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.
10 *
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.
15 *
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/>.
18 */
19
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
26 this API directly. */
27
28 #include "net.h"
29 #include "qdev.h"
30 #include "sysemu.h"
31 #include "monitor.h"
32
33 static int qdev_hotplug = 0;
34 static bool qdev_hot_added = false;
35 static bool qdev_hot_removed = false;
36
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);
40
41 DeviceInfo *device_info_list;
42
43 static BusState *qbus_find_recursive(BusState *bus, const char *name,
44 const BusInfo *info);
45 static BusState *qbus_find(const char *path);
46
47 /* Register a new device type. */
48 static void qdev_subclass_init(ObjectClass *klass, void *data)
49 {
50 DeviceClass *dc = DEVICE_CLASS(klass);
51 DeviceInfo *info = data;
52
53 dc->fw_name = info->fw_name;
54 dc->alias = info->alias;
55 dc->desc = info->desc;
56 dc->props = info->props;
57 dc->no_user = info->no_user;
58
59 dc->reset = info->reset;
60
61 dc->vmsd = info->vmsd;
62
63 dc->init = info->init;
64 dc->unplug = info->unplug;
65 dc->exit = info->exit;
66 dc->bus_info = info->bus_info;
67
68 if (info->class_init) {
69 info->class_init(klass, data);
70 }
71 }
72
73 const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
74 {
75 DeviceClass *dc = DEVICE_GET_CLASS(dev);
76 return dc->vmsd;
77 }
78
79 BusInfo *qdev_get_bus_info(DeviceState *dev)
80 {
81 DeviceClass *dc = DEVICE_GET_CLASS(dev);
82 return dc->bus_info;
83 }
84
85 Property *qdev_get_props(DeviceState *dev)
86 {
87 DeviceClass *dc = DEVICE_GET_CLASS(dev);
88 return dc->props;
89 }
90
91 const char *qdev_fw_name(DeviceState *dev)
92 {
93 DeviceClass *dc = DEVICE_GET_CLASS(dev);
94
95 if (dc->fw_name) {
96 return dc->fw_name;
97 } else if (dc->alias) {
98 return dc->alias;
99 }
100
101 return object_get_typename(OBJECT(dev));
102 }
103
104 void qdev_register_subclass(DeviceInfo *info, const char *parent)
105 {
106 TypeInfo type_info = {};
107
108 assert(info->size >= sizeof(DeviceState));
109 assert(!info->next);
110
111 type_info.name = info->name;
112 type_info.parent = parent;
113 type_info.instance_size = info->size;
114 type_info.class_init = qdev_subclass_init;
115 type_info.class_data = info;
116
117 type_register_static(&type_info);
118
119 info->next = device_info_list;
120 device_info_list = info;
121 }
122
123 void qdev_register(DeviceInfo *info)
124 {
125 qdev_register_subclass(info, TYPE_DEVICE);
126 }
127
128 static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
129 {
130 DeviceInfo *info;
131
132 /* first check device names */
133 for (info = device_info_list; info != NULL; info = info->next) {
134 if (bus_info && info->bus_info != bus_info)
135 continue;
136 if (strcmp(info->name, name) != 0)
137 continue;
138 return info;
139 }
140
141 /* failing that check the aliases */
142 for (info = device_info_list; info != NULL; info = info->next) {
143 if (bus_info && info->bus_info != bus_info)
144 continue;
145 if (!info->alias)
146 continue;
147 if (strcmp(info->alias, name) != 0)
148 continue;
149 return info;
150 }
151 return NULL;
152 }
153
154 bool qdev_exists(const char *name)
155 {
156 return !!qdev_find_info(NULL, name);
157 }
158
159 static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
160 Error **errp);
161
162 static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
163 {
164 DeviceState *dev;
165 Property *prop;
166
167 assert(bus->info == info->bus_info);
168 dev = DEVICE(object_new(info->name));
169 dev->parent_bus = bus;
170 qdev_prop_set_defaults(dev, qdev_get_props(dev));
171 qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
172 qdev_prop_set_globals(dev);
173 QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
174 if (qdev_hotplug) {
175 assert(bus->allow_hotplug);
176 dev->hotplugged = 1;
177 qdev_hot_added = true;
178 }
179 dev->instance_id_alias = -1;
180 QTAILQ_INIT(&dev->properties);
181 dev->state = DEV_STATE_CREATED;
182
183 for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
184 qdev_property_add_legacy(dev, prop, NULL);
185 qdev_property_add_static(dev, prop, NULL);
186 }
187
188 for (prop = qdev_get_bus_info(dev)->props; prop && prop->name; prop++) {
189 qdev_property_add_legacy(dev, prop, NULL);
190 qdev_property_add_static(dev, prop, NULL);
191 }
192
193 qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL);
194
195 return dev;
196 }
197
198 /* Create a new device. This only initializes the device state structure
199 and allows properties to be set. qdev_init should be called to
200 initialize the actual device emulation. */
201 DeviceState *qdev_create(BusState *bus, const char *name)
202 {
203 DeviceState *dev;
204
205 dev = qdev_try_create(bus, name);
206 if (!dev) {
207 if (bus) {
208 hw_error("Unknown device '%s' for bus '%s'\n", name,
209 bus->info->name);
210 } else {
211 hw_error("Unknown device '%s' for default sysbus\n", name);
212 }
213 }
214
215 return dev;
216 }
217
218 DeviceState *qdev_try_create(BusState *bus, const char *name)
219 {
220 DeviceInfo *info;
221
222 if (!bus) {
223 bus = sysbus_get_default();
224 }
225
226 info = qdev_find_info(bus->info, name);
227 if (!info) {
228 return NULL;
229 }
230
231 return qdev_create_from_info(bus, info);
232 }
233
234 static void qdev_print_devinfo(DeviceInfo *info)
235 {
236 error_printf("name \"%s\", bus %s",
237 info->name, info->bus_info->name);
238 if (info->alias) {
239 error_printf(", alias \"%s\"", info->alias);
240 }
241 if (info->desc) {
242 error_printf(", desc \"%s\"", info->desc);
243 }
244 if (info->no_user) {
245 error_printf(", no-user");
246 }
247 error_printf("\n");
248 }
249
250 static int set_property(const char *name, const char *value, void *opaque)
251 {
252 DeviceState *dev = opaque;
253
254 if (strcmp(name, "driver") == 0)
255 return 0;
256 if (strcmp(name, "bus") == 0)
257 return 0;
258
259 if (qdev_prop_parse(dev, name, value) == -1) {
260 return -1;
261 }
262 return 0;
263 }
264
265 int qdev_device_help(QemuOpts *opts)
266 {
267 const char *driver;
268 DeviceInfo *info;
269 Property *prop;
270
271 driver = qemu_opt_get(opts, "driver");
272 if (driver && !strcmp(driver, "?")) {
273 for (info = device_info_list; info != NULL; info = info->next) {
274 if (info->no_user) {
275 continue; /* not available, don't show */
276 }
277 qdev_print_devinfo(info);
278 }
279 return 1;
280 }
281
282 if (!driver || !qemu_opt_get(opts, "?")) {
283 return 0;
284 }
285
286 info = qdev_find_info(NULL, driver);
287 if (!info) {
288 return 0;
289 }
290
291 for (prop = info->props; prop && prop->name; prop++) {
292 /*
293 * TODO Properties without a parser are just for dirty hacks.
294 * qdev_prop_ptr is the only such PropertyInfo. It's marked
295 * for removal. This conditional should be removed along with
296 * it.
297 */
298 if (!prop->info->parse) {
299 continue; /* no way to set it, don't show */
300 }
301 error_printf("%s.%s=%s\n", info->name, prop->name,
302 prop->info->legacy_name ?: prop->info->name);
303 }
304 for (prop = info->bus_info->props; prop && prop->name; prop++) {
305 if (!prop->info->parse) {
306 continue; /* no way to set it, don't show */
307 }
308 error_printf("%s.%s=%s\n", info->name, prop->name,
309 prop->info->legacy_name ?: prop->info->name);
310 }
311 return 1;
312 }
313
314 static DeviceState *qdev_get_peripheral(void)
315 {
316 static DeviceState *dev;
317
318 if (dev == NULL) {
319 dev = qdev_create(NULL, "container");
320 qdev_property_add_child(qdev_get_root(), "peripheral", dev, NULL);
321 qdev_init_nofail(dev);
322 }
323
324 return dev;
325 }
326
327 static DeviceState *qdev_get_peripheral_anon(void)
328 {
329 static DeviceState *dev;
330
331 if (dev == NULL) {
332 dev = qdev_create(NULL, "container");
333 qdev_property_add_child(qdev_get_root(), "peripheral-anon", dev, NULL);
334 qdev_init_nofail(dev);
335 }
336
337 return dev;
338 }
339
340 DeviceState *qdev_device_add(QemuOpts *opts)
341 {
342 const char *driver, *path, *id;
343 DeviceInfo *info;
344 DeviceState *qdev;
345 BusState *bus;
346
347 driver = qemu_opt_get(opts, "driver");
348 if (!driver) {
349 qerror_report(QERR_MISSING_PARAMETER, "driver");
350 return NULL;
351 }
352
353 /* find driver */
354 info = qdev_find_info(NULL, driver);
355 if (!info || info->no_user) {
356 qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
357 error_printf_unless_qmp("Try with argument '?' for a list.\n");
358 return NULL;
359 }
360
361 /* find bus */
362 path = qemu_opt_get(opts, "bus");
363 if (path != NULL) {
364 bus = qbus_find(path);
365 if (!bus) {
366 return NULL;
367 }
368 if (bus->info != info->bus_info) {
369 qerror_report(QERR_BAD_BUS_FOR_DEVICE,
370 driver, bus->info->name);
371 return NULL;
372 }
373 } else {
374 bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
375 if (!bus) {
376 qerror_report(QERR_NO_BUS_FOR_DEVICE,
377 info->name, info->bus_info->name);
378 return NULL;
379 }
380 }
381 if (qdev_hotplug && !bus->allow_hotplug) {
382 qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
383 return NULL;
384 }
385
386 /* create device, set properties */
387 qdev = qdev_create_from_info(bus, info);
388 id = qemu_opts_id(opts);
389 if (id) {
390 qdev->id = id;
391 qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL);
392 } else {
393 static int anon_count;
394 gchar *name = g_strdup_printf("device[%d]", anon_count++);
395 qdev_property_add_child(qdev_get_peripheral_anon(), name,
396 qdev, NULL);
397 g_free(name);
398 }
399 if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
400 qdev_free(qdev);
401 return NULL;
402 }
403 if (qdev_init(qdev) < 0) {
404 qerror_report(QERR_DEVICE_INIT_FAILED, driver);
405 return NULL;
406 }
407 qdev->opts = opts;
408 return qdev;
409 }
410
411 /* Initialize a device. Device properties should be set before calling
412 this function. IRQs and MMIO regions should be connected/mapped after
413 calling this function.
414 On failure, destroy the device and return negative value.
415 Return 0 on success. */
416 int qdev_init(DeviceState *dev)
417 {
418 DeviceClass *dc = DEVICE_GET_CLASS(dev);
419 int rc;
420
421 assert(dev->state == DEV_STATE_CREATED);
422
423 /* FIXME hopefully this doesn't break anything */
424 rc = dc->init(dev, NULL);
425 if (rc < 0) {
426 qdev_free(dev);
427 return rc;
428 }
429 if (qdev_get_vmsd(dev)) {
430 vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
431 dev->instance_id_alias,
432 dev->alias_required_for_version);
433 }
434 dev->state = DEV_STATE_INITIALIZED;
435 if (dev->hotplugged) {
436 device_reset(dev);
437 }
438 return 0;
439 }
440
441 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
442 int required_for_version)
443 {
444 assert(dev->state == DEV_STATE_CREATED);
445 dev->instance_id_alias = alias_id;
446 dev->alias_required_for_version = required_for_version;
447 }
448
449 int qdev_unplug(DeviceState *dev)
450 {
451 DeviceClass *dc = DEVICE_GET_CLASS(dev);
452
453 if (!dev->parent_bus->allow_hotplug) {
454 qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
455 return -1;
456 }
457 assert(dc->unplug != NULL);
458
459 qdev_hot_removed = true;
460
461 return dc->unplug(dev);
462 }
463
464 static int qdev_reset_one(DeviceState *dev, void *opaque)
465 {
466 device_reset(dev);
467
468 return 0;
469 }
470
471 BusState *sysbus_get_default(void)
472 {
473 if (!main_system_bus) {
474 main_system_bus_create();
475 }
476 return main_system_bus;
477 }
478
479 static int qbus_reset_one(BusState *bus, void *opaque)
480 {
481 if (bus->info->reset) {
482 return bus->info->reset(bus);
483 }
484 return 0;
485 }
486
487 void qdev_reset_all(DeviceState *dev)
488 {
489 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
490 }
491
492 void qbus_reset_all_fn(void *opaque)
493 {
494 BusState *bus = opaque;
495 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
496 }
497
498 /* can be used as ->unplug() callback for the simple cases */
499 int qdev_simple_unplug_cb(DeviceState *dev)
500 {
501 /* just zap it */
502 qdev_free(dev);
503 return 0;
504 }
505
506
507 /* Like qdev_init(), but terminate program via error_report() instead of
508 returning an error value. This is okay during machine creation.
509 Don't use for hotplug, because there callers need to recover from
510 failure. Exception: if you know the device's init() callback can't
511 fail, then qdev_init_nofail() can't fail either, and is therefore
512 usable even then. But relying on the device implementation that
513 way is somewhat unclean, and best avoided. */
514 void qdev_init_nofail(DeviceState *dev)
515 {
516 if (qdev_init(dev) < 0) {
517 error_report("Initialization of device %s failed",
518 object_get_typename(OBJECT(dev)));
519 exit(1);
520 }
521 }
522
523 static void qdev_property_del_all(DeviceState *dev)
524 {
525 while (!QTAILQ_EMPTY(&dev->properties)) {
526 DeviceProperty *prop = QTAILQ_FIRST(&dev->properties);
527
528 QTAILQ_REMOVE(&dev->properties, prop, node);
529
530 if (prop->release) {
531 prop->release(dev, prop->name, prop->opaque);
532 }
533
534 g_free(prop->name);
535 g_free(prop->type);
536 g_free(prop);
537 }
538 }
539
540 static void qdev_property_del_child(DeviceState *dev, DeviceState *child, Error **errp)
541 {
542 DeviceProperty *prop;
543
544 QTAILQ_FOREACH(prop, &dev->properties, node) {
545 if (strstart(prop->type, "child<", NULL) && prop->opaque == child) {
546 break;
547 }
548 }
549
550 g_assert(prop != NULL);
551
552 QTAILQ_REMOVE(&dev->properties, prop, node);
553
554 if (prop->release) {
555 prop->release(dev, prop->name, prop->opaque);
556 }
557
558 g_free(prop->name);
559 g_free(prop->type);
560 g_free(prop);
561 }
562
563 /* Unlink device from bus and free the structure. */
564 void qdev_free(DeviceState *dev)
565 {
566 BusState *bus;
567 Property *prop;
568 DeviceClass *dc = DEVICE_GET_CLASS(dev);
569
570 qdev_property_del_all(dev);
571
572 if (dev->state == DEV_STATE_INITIALIZED) {
573 while (dev->num_child_bus) {
574 bus = QLIST_FIRST(&dev->child_bus);
575 qbus_free(bus);
576 }
577 if (qdev_get_vmsd(dev)) {
578 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
579 }
580 if (dc->exit) {
581 dc->exit(dev);
582 }
583 if (dev->opts) {
584 qemu_opts_del(dev->opts);
585 }
586 }
587 QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
588 for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
589 if (prop->info->free) {
590 prop->info->free(dev, prop);
591 }
592 }
593 if (dev->parent) {
594 qdev_property_del_child(dev->parent, dev, NULL);
595 }
596 if (dev->ref != 0) {
597 qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
598 }
599 object_delete(OBJECT(dev));
600 }
601
602 void qdev_machine_creation_done(void)
603 {
604 /*
605 * ok, initial machine setup is done, starting from now we can
606 * only create hotpluggable devices
607 */
608 qdev_hotplug = 1;
609 }
610
611 bool qdev_machine_modified(void)
612 {
613 return qdev_hot_added || qdev_hot_removed;
614 }
615
616 /* Get a character (serial) device interface. */
617 CharDriverState *qdev_init_chardev(DeviceState *dev)
618 {
619 static int next_serial;
620
621 /* FIXME: This function needs to go away: use chardev properties! */
622 return serial_hds[next_serial++];
623 }
624
625 BusState *qdev_get_parent_bus(DeviceState *dev)
626 {
627 return dev->parent_bus;
628 }
629
630 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
631 {
632 assert(dev->num_gpio_in == 0);
633 dev->num_gpio_in = n;
634 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
635 }
636
637 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
638 {
639 assert(dev->num_gpio_out == 0);
640 dev->num_gpio_out = n;
641 dev->gpio_out = pins;
642 }
643
644 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
645 {
646 assert(n >= 0 && n < dev->num_gpio_in);
647 return dev->gpio_in[n];
648 }
649
650 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
651 {
652 assert(n >= 0 && n < dev->num_gpio_out);
653 dev->gpio_out[n] = pin;
654 }
655
656 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
657 {
658 qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
659 if (nd->vlan)
660 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
661 if (nd->netdev)
662 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
663 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
664 qdev_prop_exists(dev, "vectors")) {
665 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
666 }
667 nd->instantiated = 1;
668 }
669
670 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
671 {
672 BusState *bus;
673
674 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
675 if (strcmp(name, bus->name) == 0) {
676 return bus;
677 }
678 }
679 return NULL;
680 }
681
682 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
683 qbus_walkerfn *busfn, void *opaque)
684 {
685 DeviceState *dev;
686 int err;
687
688 if (busfn) {
689 err = busfn(bus, opaque);
690 if (err) {
691 return err;
692 }
693 }
694
695 QTAILQ_FOREACH(dev, &bus->children, sibling) {
696 err = qdev_walk_children(dev, devfn, busfn, opaque);
697 if (err < 0) {
698 return err;
699 }
700 }
701
702 return 0;
703 }
704
705 int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
706 qbus_walkerfn *busfn, void *opaque)
707 {
708 BusState *bus;
709 int err;
710
711 if (devfn) {
712 err = devfn(dev, opaque);
713 if (err) {
714 return err;
715 }
716 }
717
718 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
719 err = qbus_walk_children(bus, devfn, busfn, opaque);
720 if (err < 0) {
721 return err;
722 }
723 }
724
725 return 0;
726 }
727
728 static BusState *qbus_find_recursive(BusState *bus, const char *name,
729 const BusInfo *info)
730 {
731 DeviceState *dev;
732 BusState *child, *ret;
733 int match = 1;
734
735 if (name && (strcmp(bus->name, name) != 0)) {
736 match = 0;
737 }
738 if (info && (bus->info != info)) {
739 match = 0;
740 }
741 if (match) {
742 return bus;
743 }
744
745 QTAILQ_FOREACH(dev, &bus->children, sibling) {
746 QLIST_FOREACH(child, &dev->child_bus, sibling) {
747 ret = qbus_find_recursive(child, name, info);
748 if (ret) {
749 return ret;
750 }
751 }
752 }
753 return NULL;
754 }
755
756 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
757 {
758 DeviceState *dev, *ret;
759 BusState *child;
760
761 QTAILQ_FOREACH(dev, &bus->children, sibling) {
762 if (dev->id && strcmp(dev->id, id) == 0)
763 return dev;
764 QLIST_FOREACH(child, &dev->child_bus, sibling) {
765 ret = qdev_find_recursive(child, id);
766 if (ret) {
767 return ret;
768 }
769 }
770 }
771 return NULL;
772 }
773
774 static void qbus_list_bus(DeviceState *dev)
775 {
776 BusState *child;
777 const char *sep = " ";
778
779 error_printf("child busses at \"%s\":",
780 dev->id ? dev->id : object_get_typename(OBJECT(dev)));
781 QLIST_FOREACH(child, &dev->child_bus, sibling) {
782 error_printf("%s\"%s\"", sep, child->name);
783 sep = ", ";
784 }
785 error_printf("\n");
786 }
787
788 static void qbus_list_dev(BusState *bus)
789 {
790 DeviceState *dev;
791 const char *sep = " ";
792
793 error_printf("devices at \"%s\":", bus->name);
794 QTAILQ_FOREACH(dev, &bus->children, sibling) {
795 error_printf("%s\"%s\"", sep, object_get_typename(OBJECT(dev)));
796 if (dev->id)
797 error_printf("/\"%s\"", dev->id);
798 sep = ", ";
799 }
800 error_printf("\n");
801 }
802
803 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
804 {
805 BusState *child;
806
807 QLIST_FOREACH(child, &dev->child_bus, sibling) {
808 if (strcmp(child->name, elem) == 0) {
809 return child;
810 }
811 }
812 return NULL;
813 }
814
815 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
816 {
817 DeviceState *dev;
818
819 /*
820 * try to match in order:
821 * (1) instance id, if present
822 * (2) driver name
823 * (3) driver alias, if present
824 */
825 QTAILQ_FOREACH(dev, &bus->children, sibling) {
826 if (dev->id && strcmp(dev->id, elem) == 0) {
827 return dev;
828 }
829 }
830 QTAILQ_FOREACH(dev, &bus->children, sibling) {
831 if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) {
832 return dev;
833 }
834 }
835 QTAILQ_FOREACH(dev, &bus->children, sibling) {
836 DeviceClass *dc = DEVICE_GET_CLASS(dev);
837
838 if (dc->alias && strcmp(dc->alias, elem) == 0) {
839 return dev;
840 }
841 }
842 return NULL;
843 }
844
845 static BusState *qbus_find(const char *path)
846 {
847 DeviceState *dev;
848 BusState *bus;
849 char elem[128];
850 int pos, len;
851
852 /* find start element */
853 if (path[0] == '/') {
854 bus = main_system_bus;
855 pos = 0;
856 } else {
857 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
858 assert(!path[0]);
859 elem[0] = len = 0;
860 }
861 bus = qbus_find_recursive(main_system_bus, elem, NULL);
862 if (!bus) {
863 qerror_report(QERR_BUS_NOT_FOUND, elem);
864 return NULL;
865 }
866 pos = len;
867 }
868
869 for (;;) {
870 assert(path[pos] == '/' || !path[pos]);
871 while (path[pos] == '/') {
872 pos++;
873 }
874 if (path[pos] == '\0') {
875 return bus;
876 }
877
878 /* find device */
879 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
880 assert(0);
881 elem[0] = len = 0;
882 }
883 pos += len;
884 dev = qbus_find_dev(bus, elem);
885 if (!dev) {
886 qerror_report(QERR_DEVICE_NOT_FOUND, elem);
887 if (!monitor_cur_is_qmp()) {
888 qbus_list_dev(bus);
889 }
890 return NULL;
891 }
892
893 assert(path[pos] == '/' || !path[pos]);
894 while (path[pos] == '/') {
895 pos++;
896 }
897 if (path[pos] == '\0') {
898 /* last specified element is a device. If it has exactly
899 * one child bus accept it nevertheless */
900 switch (dev->num_child_bus) {
901 case 0:
902 qerror_report(QERR_DEVICE_NO_BUS, elem);
903 return NULL;
904 case 1:
905 return QLIST_FIRST(&dev->child_bus);
906 default:
907 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
908 if (!monitor_cur_is_qmp()) {
909 qbus_list_bus(dev);
910 }
911 return NULL;
912 }
913 }
914
915 /* find bus */
916 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
917 assert(0);
918 elem[0] = len = 0;
919 }
920 pos += len;
921 bus = qbus_find_bus(dev, elem);
922 if (!bus) {
923 qerror_report(QERR_BUS_NOT_FOUND, elem);
924 if (!monitor_cur_is_qmp()) {
925 qbus_list_bus(dev);
926 }
927 return NULL;
928 }
929 }
930 }
931
932 void qbus_create_inplace(BusState *bus, BusInfo *info,
933 DeviceState *parent, const char *name)
934 {
935 char *buf;
936 int i,len;
937
938 bus->info = info;
939 bus->parent = parent;
940
941 if (name) {
942 /* use supplied name */
943 bus->name = g_strdup(name);
944 } else if (parent && parent->id) {
945 /* parent device has id -> use it for bus name */
946 len = strlen(parent->id) + 16;
947 buf = g_malloc(len);
948 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
949 bus->name = buf;
950 } else {
951 /* no id -> use lowercase bus type for bus name */
952 len = strlen(info->name) + 16;
953 buf = g_malloc(len);
954 len = snprintf(buf, len, "%s.%d", info->name,
955 parent ? parent->num_child_bus : 0);
956 for (i = 0; i < len; i++)
957 buf[i] = qemu_tolower(buf[i]);
958 bus->name = buf;
959 }
960
961 QTAILQ_INIT(&bus->children);
962 if (parent) {
963 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
964 parent->num_child_bus++;
965 } else if (bus != main_system_bus) {
966 /* TODO: once all bus devices are qdevified,
967 only reset handler for main_system_bus should be registered here. */
968 qemu_register_reset(qbus_reset_all_fn, bus);
969 }
970 }
971
972 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
973 {
974 BusState *bus;
975
976 bus = g_malloc0(info->size);
977 bus->qdev_allocated = 1;
978 qbus_create_inplace(bus, info, parent, name);
979 return bus;
980 }
981
982 static void main_system_bus_create(void)
983 {
984 /* assign main_system_bus before qbus_create_inplace()
985 * in order to make "if (bus != main_system_bus)" work */
986 main_system_bus = g_malloc0(system_bus_info.size);
987 main_system_bus->qdev_allocated = 1;
988 qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
989 "main-system-bus");
990 }
991
992 void qbus_free(BusState *bus)
993 {
994 DeviceState *dev;
995
996 while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
997 qdev_free(dev);
998 }
999 if (bus->parent) {
1000 QLIST_REMOVE(bus, sibling);
1001 bus->parent->num_child_bus--;
1002 } else {
1003 assert(bus != main_system_bus); /* main_system_bus is never freed */
1004 qemu_unregister_reset(qbus_reset_all_fn, bus);
1005 }
1006 g_free((void*)bus->name);
1007 if (bus->qdev_allocated) {
1008 g_free(bus);
1009 }
1010 }
1011
1012 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
1013 static void qbus_print(Monitor *mon, BusState *bus, int indent);
1014
1015 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
1016 const char *prefix, int indent)
1017 {
1018 char buf[64];
1019
1020 if (!props)
1021 return;
1022 while (props->name) {
1023 /*
1024 * TODO Properties without a print method are just for dirty
1025 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
1026 * marked for removal. The test props->info->print should be
1027 * removed along with it.
1028 */
1029 if (props->info->print) {
1030 props->info->print(dev, props, buf, sizeof(buf));
1031 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
1032 }
1033 props++;
1034 }
1035 }
1036
1037 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
1038 {
1039 BusState *child;
1040 qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
1041 dev->id ? dev->id : "");
1042 indent += 2;
1043 if (dev->num_gpio_in) {
1044 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
1045 }
1046 if (dev->num_gpio_out) {
1047 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
1048 }
1049 qdev_print_props(mon, dev, qdev_get_props(dev), "dev", indent);
1050 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
1051 if (dev->parent_bus->info->print_dev)
1052 dev->parent_bus->info->print_dev(mon, dev, indent);
1053 QLIST_FOREACH(child, &dev->child_bus, sibling) {
1054 qbus_print(mon, child, indent);
1055 }
1056 }
1057
1058 static void qbus_print(Monitor *mon, BusState *bus, int indent)
1059 {
1060 struct DeviceState *dev;
1061
1062 qdev_printf("bus: %s\n", bus->name);
1063 indent += 2;
1064 qdev_printf("type %s\n", bus->info->name);
1065 QTAILQ_FOREACH(dev, &bus->children, sibling) {
1066 qdev_print(mon, dev, indent);
1067 }
1068 }
1069 #undef qdev_printf
1070
1071 void do_info_qtree(Monitor *mon)
1072 {
1073 if (main_system_bus)
1074 qbus_print(mon, main_system_bus, 0);
1075 }
1076
1077 void do_info_qdm(Monitor *mon)
1078 {
1079 DeviceInfo *info;
1080
1081 for (info = device_info_list; info != NULL; info = info->next) {
1082 qdev_print_devinfo(info);
1083 }
1084 }
1085
1086 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
1087 {
1088 QemuOpts *opts;
1089
1090 opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
1091 if (!opts) {
1092 return -1;
1093 }
1094 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
1095 qemu_opts_del(opts);
1096 return 0;
1097 }
1098 if (!qdev_device_add(opts)) {
1099 qemu_opts_del(opts);
1100 return -1;
1101 }
1102 return 0;
1103 }
1104
1105 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
1106 {
1107 const char *id = qdict_get_str(qdict, "id");
1108 DeviceState *dev;
1109
1110 dev = qdev_find_recursive(main_system_bus, id);
1111 if (NULL == dev) {
1112 qerror_report(QERR_DEVICE_NOT_FOUND, id);
1113 return -1;
1114 }
1115 return qdev_unplug(dev);
1116 }
1117
1118 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
1119 {
1120 int l = 0;
1121
1122 if (dev && dev->parent_bus) {
1123 char *d;
1124 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
1125 if (dev->parent_bus->info->get_fw_dev_path) {
1126 d = dev->parent_bus->info->get_fw_dev_path(dev);
1127 l += snprintf(p + l, size - l, "%s", d);
1128 g_free(d);
1129 } else {
1130 l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
1131 }
1132 }
1133 l += snprintf(p + l , size - l, "/");
1134
1135 return l;
1136 }
1137
1138 char* qdev_get_fw_dev_path(DeviceState *dev)
1139 {
1140 char path[128];
1141 int l;
1142
1143 l = qdev_get_fw_dev_path_helper(dev, path, 128);
1144
1145 path[l-1] = '\0';
1146
1147 return strdup(path);
1148 }
1149
1150 char *qdev_get_type(DeviceState *dev, Error **errp)
1151 {
1152 return g_strdup(object_get_typename(OBJECT(dev)));
1153 }
1154
1155 void qdev_ref(DeviceState *dev)
1156 {
1157 dev->ref++;
1158 }
1159
1160 void qdev_unref(DeviceState *dev)
1161 {
1162 g_assert(dev->ref > 0);
1163 dev->ref--;
1164 }
1165
1166 void qdev_property_add(DeviceState *dev, const char *name, const char *type,
1167 DevicePropertyAccessor *get, DevicePropertyAccessor *set,
1168 DevicePropertyRelease *release,
1169 void *opaque, Error **errp)
1170 {
1171 DeviceProperty *prop = g_malloc0(sizeof(*prop));
1172
1173 prop->name = g_strdup(name);
1174 prop->type = g_strdup(type);
1175
1176 prop->get = get;
1177 prop->set = set;
1178 prop->release = release;
1179 prop->opaque = opaque;
1180
1181 QTAILQ_INSERT_TAIL(&dev->properties, prop, node);
1182 }
1183
1184 static DeviceProperty *qdev_property_find(DeviceState *dev, const char *name)
1185 {
1186 DeviceProperty *prop;
1187
1188 QTAILQ_FOREACH(prop, &dev->properties, node) {
1189 if (strcmp(prop->name, name) == 0) {
1190 return prop;
1191 }
1192 }
1193
1194 return NULL;
1195 }
1196
1197 void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
1198 Error **errp)
1199 {
1200 DeviceProperty *prop = qdev_property_find(dev, name);
1201
1202 if (prop == NULL) {
1203 error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1204 return;
1205 }
1206
1207 if (!prop->get) {
1208 error_set(errp, QERR_PERMISSION_DENIED);
1209 } else {
1210 prop->get(dev, v, prop->opaque, name, errp);
1211 }
1212 }
1213
1214 void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
1215 Error **errp)
1216 {
1217 DeviceProperty *prop = qdev_property_find(dev, name);
1218
1219 if (prop == NULL) {
1220 error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1221 return;
1222 }
1223
1224 if (!prop->set) {
1225 error_set(errp, QERR_PERMISSION_DENIED);
1226 } else {
1227 prop->set(dev, v, prop->opaque, name, errp);
1228 }
1229 }
1230
1231 const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **errp)
1232 {
1233 DeviceProperty *prop = qdev_property_find(dev, name);
1234
1235 if (prop == NULL) {
1236 error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1237 return NULL;
1238 }
1239
1240 return prop->type;
1241 }
1242
1243 /**
1244 * Legacy property handling
1245 */
1246
1247 static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1248 const char *name, Error **errp)
1249 {
1250 Property *prop = opaque;
1251
1252 char buffer[1024];
1253 char *ptr = buffer;
1254
1255 prop->info->print(dev, prop, buffer, sizeof(buffer));
1256 visit_type_str(v, &ptr, name, errp);
1257 }
1258
1259 static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1260 const char *name, Error **errp)
1261 {
1262 Property *prop = opaque;
1263 Error *local_err = NULL;
1264 char *ptr = NULL;
1265 int ret;
1266
1267 if (dev->state != DEV_STATE_CREATED) {
1268 error_set(errp, QERR_PERMISSION_DENIED);
1269 return;
1270 }
1271
1272 visit_type_str(v, &ptr, name, &local_err);
1273 if (local_err) {
1274 error_propagate(errp, local_err);
1275 return;
1276 }
1277
1278 ret = prop->info->parse(dev, prop, ptr);
1279 error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
1280 g_free(ptr);
1281 }
1282
1283 /**
1284 * @qdev_add_legacy_property - adds a legacy property
1285 *
1286 * Do not use this is new code! Properties added through this interface will
1287 * be given names and types in the "legacy" namespace.
1288 *
1289 * Legacy properties are always processed as strings. The format of the string
1290 * depends on the property type.
1291 */
1292 void qdev_property_add_legacy(DeviceState *dev, Property *prop,
1293 Error **errp)
1294 {
1295 gchar *name, *type;
1296
1297 name = g_strdup_printf("legacy-%s", prop->name);
1298 type = g_strdup_printf("legacy<%s>",
1299 prop->info->legacy_name ?: prop->info->name);
1300
1301 qdev_property_add(dev, name, type,
1302 prop->info->print ? qdev_get_legacy_property : NULL,
1303 prop->info->parse ? qdev_set_legacy_property : NULL,
1304 NULL,
1305 prop, errp);
1306
1307 g_free(type);
1308 g_free(name);
1309 }
1310
1311 /**
1312 * @qdev_property_add_static - add a @Property to a device.
1313 *
1314 * Static properties access data in a struct. The actual type of the
1315 * property and the field depends on the property type.
1316 */
1317 void qdev_property_add_static(DeviceState *dev, Property *prop,
1318 Error **errp)
1319 {
1320 qdev_property_add(dev, prop->name, prop->info->name,
1321 prop->info->get, prop->info->set,
1322 NULL,
1323 prop, errp);
1324 }
1325
1326 DeviceState *qdev_get_root(void)
1327 {
1328 static DeviceState *qdev_root;
1329
1330 if (!qdev_root) {
1331 qdev_root = qdev_create(NULL, "container");
1332 qdev_init_nofail(qdev_root);
1333 }
1334
1335 return qdev_root;
1336 }
1337
1338 static void qdev_get_child_property(DeviceState *dev, Visitor *v, void *opaque,
1339 const char *name, Error **errp)
1340 {
1341 DeviceState *child = opaque;
1342 gchar *path;
1343
1344 path = qdev_get_canonical_path(child);
1345 visit_type_str(v, &path, name, errp);
1346 g_free(path);
1347 }
1348
1349 static void qdev_release_child_property(DeviceState *dev, const char *name,
1350 void *opaque)
1351 {
1352 DeviceState *child = opaque;
1353
1354 qdev_unref(child);
1355 }
1356
1357 void qdev_property_add_child(DeviceState *dev, const char *name,
1358 DeviceState *child, Error **errp)
1359 {
1360 gchar *type;
1361
1362 type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
1363
1364 qdev_property_add(dev, name, type, qdev_get_child_property,
1365 NULL, qdev_release_child_property,
1366 child, errp);
1367
1368 qdev_ref(child);
1369 g_assert(child->parent == NULL);
1370 child->parent = dev;
1371
1372 g_free(type);
1373 }
1374
1375 static void qdev_get_link_property(DeviceState *dev, Visitor *v, void *opaque,
1376 const char *name, Error **errp)
1377 {
1378 DeviceState **child = opaque;
1379 gchar *path;
1380
1381 if (*child) {
1382 path = qdev_get_canonical_path(*child);
1383 visit_type_str(v, &path, name, errp);
1384 g_free(path);
1385 } else {
1386 path = (gchar *)"";
1387 visit_type_str(v, &path, name, errp);
1388 }
1389 }
1390
1391 static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque,
1392 const char *name, Error **errp)
1393 {
1394 DeviceState **child = opaque;
1395 bool ambiguous = false;
1396 const char *type;
1397 char *path;
1398
1399 type = qdev_property_get_type(dev, name, NULL);
1400
1401 visit_type_str(v, &path, name, errp);
1402
1403 if (*child) {
1404 qdev_unref(*child);
1405 }
1406
1407 if (strcmp(path, "") != 0) {
1408 DeviceState *target;
1409
1410 target = qdev_resolve_path(path, &ambiguous);
1411 if (target) {
1412 gchar *target_type;
1413
1414 target_type = g_strdup_printf("link<%s>", object_get_typename(OBJECT(target)));
1415 if (strcmp(target_type, type) == 0) {
1416 *child = target;
1417 qdev_ref(target);
1418 } else {
1419 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
1420 }
1421
1422 g_free(target_type);
1423 } else {
1424 error_set(errp, QERR_DEVICE_NOT_FOUND, path);
1425 }
1426 } else {
1427 *child = NULL;
1428 }
1429
1430 g_free(path);
1431 }
1432
1433 void qdev_property_add_link(DeviceState *dev, const char *name,
1434 const char *type, DeviceState **child,
1435 Error **errp)
1436 {
1437 gchar *full_type;
1438
1439 full_type = g_strdup_printf("link<%s>", type);
1440
1441 qdev_property_add(dev, name, full_type,
1442 qdev_get_link_property,
1443 qdev_set_link_property,
1444 NULL, child, errp);
1445
1446 g_free(full_type);
1447 }
1448
1449 gchar *qdev_get_canonical_path(DeviceState *dev)
1450 {
1451 DeviceState *root = qdev_get_root();
1452 char *newpath = NULL, *path = NULL;
1453
1454 while (dev != root) {
1455 DeviceProperty *prop = NULL;
1456
1457 g_assert(dev->parent != NULL);
1458
1459 QTAILQ_FOREACH(prop, &dev->parent->properties, node) {
1460 if (!strstart(prop->type, "child<", NULL)) {
1461 continue;
1462 }
1463
1464 if (prop->opaque == dev) {
1465 if (path) {
1466 newpath = g_strdup_printf("%s/%s", prop->name, path);
1467 g_free(path);
1468 path = newpath;
1469 } else {
1470 path = g_strdup(prop->name);
1471 }
1472 break;
1473 }
1474 }
1475
1476 g_assert(prop != NULL);
1477
1478 dev = dev->parent;
1479 }
1480
1481 newpath = g_strdup_printf("/%s", path);
1482 g_free(path);
1483
1484 return newpath;
1485 }
1486
1487 static DeviceState *qdev_resolve_abs_path(DeviceState *parent,
1488 gchar **parts,
1489 int index)
1490 {
1491 DeviceProperty *prop;
1492 DeviceState *child;
1493
1494 if (parts[index] == NULL) {
1495 return parent;
1496 }
1497
1498 if (strcmp(parts[index], "") == 0) {
1499 return qdev_resolve_abs_path(parent, parts, index + 1);
1500 }
1501
1502 prop = qdev_property_find(parent, parts[index]);
1503 if (prop == NULL) {
1504 return NULL;
1505 }
1506
1507 child = NULL;
1508 if (strstart(prop->type, "link<", NULL)) {
1509 DeviceState **pchild = prop->opaque;
1510 if (*pchild) {
1511 child = *pchild;
1512 }
1513 } else if (strstart(prop->type, "child<", NULL)) {
1514 child = prop->opaque;
1515 }
1516
1517 if (!child) {
1518 return NULL;
1519 }
1520
1521 return qdev_resolve_abs_path(child, parts, index + 1);
1522 }
1523
1524 static DeviceState *qdev_resolve_partial_path(DeviceState *parent,
1525 gchar **parts,
1526 bool *ambiguous)
1527 {
1528 DeviceState *dev;
1529 DeviceProperty *prop;
1530
1531 dev = qdev_resolve_abs_path(parent, parts, 0);
1532
1533 QTAILQ_FOREACH(prop, &parent->properties, node) {
1534 DeviceState *found;
1535
1536 if (!strstart(prop->type, "child<", NULL)) {
1537 continue;
1538 }
1539
1540 found = qdev_resolve_partial_path(prop->opaque, parts, ambiguous);
1541 if (found) {
1542 if (dev) {
1543 if (ambiguous) {
1544 *ambiguous = true;
1545 }
1546 return NULL;
1547 }
1548 dev = found;
1549 }
1550
1551 if (ambiguous && *ambiguous) {
1552 return NULL;
1553 }
1554 }
1555
1556 return dev;
1557 }
1558
1559 DeviceState *qdev_resolve_path(const char *path, bool *ambiguous)
1560 {
1561 bool partial_path = true;
1562 DeviceState *dev;
1563 gchar **parts;
1564
1565 parts = g_strsplit(path, "/", 0);
1566 if (parts == NULL || parts[0] == NULL) {
1567 g_strfreev(parts);
1568 return qdev_get_root();
1569 }
1570
1571 if (strcmp(parts[0], "") == 0) {
1572 partial_path = false;
1573 }
1574
1575 if (partial_path) {
1576 if (ambiguous) {
1577 *ambiguous = false;
1578 }
1579 dev = qdev_resolve_partial_path(qdev_get_root(), parts, ambiguous);
1580 } else {
1581 dev = qdev_resolve_abs_path(qdev_get_root(), parts, 1);
1582 }
1583
1584 g_strfreev(parts);
1585
1586 return dev;
1587 }
1588
1589 typedef struct StringProperty
1590 {
1591 char *(*get)(DeviceState *, Error **);
1592 void (*set)(DeviceState *, const char *, Error **);
1593 } StringProperty;
1594
1595 static void qdev_property_get_str(DeviceState *dev, Visitor *v, void *opaque,
1596 const char *name, Error **errp)
1597 {
1598 StringProperty *prop = opaque;
1599 char *value;
1600
1601 value = prop->get(dev, errp);
1602 if (value) {
1603 visit_type_str(v, &value, name, errp);
1604 g_free(value);
1605 }
1606 }
1607
1608 static void qdev_property_set_str(DeviceState *dev, Visitor *v, void *opaque,
1609 const char *name, Error **errp)
1610 {
1611 StringProperty *prop = opaque;
1612 char *value;
1613 Error *local_err = NULL;
1614
1615 visit_type_str(v, &value, name, &local_err);
1616 if (local_err) {
1617 error_propagate(errp, local_err);
1618 return;
1619 }
1620
1621 prop->set(dev, value, errp);
1622 g_free(value);
1623 }
1624
1625 static void qdev_property_release_str(DeviceState *dev, const char *name,
1626 void *opaque)
1627 {
1628 StringProperty *prop = opaque;
1629 g_free(prop);
1630 }
1631
1632 void qdev_property_add_str(DeviceState *dev, const char *name,
1633 char *(*get)(DeviceState *, Error **),
1634 void (*set)(DeviceState *, const char *, Error **),
1635 Error **errp)
1636 {
1637 StringProperty *prop = g_malloc0(sizeof(*prop));
1638
1639 prop->get = get;
1640 prop->set = set;
1641
1642 qdev_property_add(dev, name, "string",
1643 get ? qdev_property_get_str : NULL,
1644 set ? qdev_property_set_str : NULL,
1645 qdev_property_release_str,
1646 prop, errp);
1647 }
1648
1649 void qdev_machine_init(void)
1650 {
1651 qdev_get_peripheral_anon();
1652 qdev_get_peripheral();
1653 }
1654
1655 void device_reset(DeviceState *dev)
1656 {
1657 DeviceClass *klass = DEVICE_GET_CLASS(dev);
1658
1659 if (klass->reset) {
1660 klass->reset(dev);
1661 }
1662 }
1663
1664 static TypeInfo device_type_info = {
1665 .name = TYPE_DEVICE,
1666 .parent = TYPE_OBJECT,
1667 .instance_size = sizeof(DeviceState),
1668 .abstract = true,
1669 .class_size = sizeof(DeviceClass),
1670 };
1671
1672 static void init_qdev(void)
1673 {
1674 type_register_static(&device_type_info);
1675 }
1676
1677 device_init(init_qdev);