]> Git Repo - qemu.git/blob - hw/qdev.c
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);
This page took 0.116774 seconds and 4 git commands to generate.