]> Git Repo - qemu.git/blob - hw/qdev.c
qdev: move unrealization of devices from finalize to unparent
[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 "qdev.h"
29 #include "sysemu/sysemu.h"
30 #include "qapi/error.h"
31 #include "qapi/visitor.h"
32
33 int qdev_hotplug = 0;
34 static bool qdev_hot_added = false;
35 static bool qdev_hot_removed = false;
36
37 const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
38 {
39     DeviceClass *dc = DEVICE_GET_CLASS(dev);
40     return dc->vmsd;
41 }
42
43 const char *qdev_fw_name(DeviceState *dev)
44 {
45     DeviceClass *dc = DEVICE_GET_CLASS(dev);
46
47     if (dc->fw_name) {
48         return dc->fw_name;
49     }
50
51     return object_get_typename(OBJECT(dev));
52 }
53
54 static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
55                                      Error **errp);
56
57 static void bus_remove_child(BusState *bus, DeviceState *child)
58 {
59     BusChild *kid;
60
61     QTAILQ_FOREACH(kid, &bus->children, sibling) {
62         if (kid->child == child) {
63             char name[32];
64
65             snprintf(name, sizeof(name), "child[%d]", kid->index);
66             QTAILQ_REMOVE(&bus->children, kid, sibling);
67
68             /* This gives back ownership of kid->child back to us.  */
69             object_property_del(OBJECT(bus), name, NULL);
70             object_unref(OBJECT(kid->child));
71             g_free(kid);
72             return;
73         }
74     }
75 }
76
77 static void bus_add_child(BusState *bus, DeviceState *child)
78 {
79     char name[32];
80     BusChild *kid = g_malloc0(sizeof(*kid));
81
82     if (qdev_hotplug) {
83         assert(bus->allow_hotplug);
84     }
85
86     kid->index = bus->max_index++;
87     kid->child = child;
88     object_ref(OBJECT(kid->child));
89
90     QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
91
92     /* This transfers ownership of kid->child to the property.  */
93     snprintf(name, sizeof(name), "child[%d]", kid->index);
94     object_property_add_link(OBJECT(bus), name,
95                              object_get_typename(OBJECT(child)),
96                              (Object **)&kid->child,
97                              NULL);
98 }
99
100 void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
101 {
102     dev->parent_bus = bus;
103     bus_add_child(bus, dev);
104 }
105
106 /* Create a new device.  This only initializes the device state structure
107    and allows properties to be set.  qdev_init should be called to
108    initialize the actual device emulation.  */
109 DeviceState *qdev_create(BusState *bus, const char *name)
110 {
111     DeviceState *dev;
112
113     dev = qdev_try_create(bus, name);
114     if (!dev) {
115         if (bus) {
116             error_report("Unknown device '%s' for bus '%s'\n", name,
117                          object_get_typename(OBJECT(bus)));
118             abort();
119         } else {
120             error_report("Unknown device '%s' for default sysbus\n", name);
121             abort();
122         }
123     }
124
125     return dev;
126 }
127
128 DeviceState *qdev_try_create(BusState *bus, const char *type)
129 {
130     DeviceState *dev;
131
132     if (object_class_by_name(type) == NULL) {
133         return NULL;
134     }
135     dev = DEVICE(object_new(type));
136     if (!dev) {
137         return NULL;
138     }
139
140     if (!bus) {
141         bus = sysbus_get_default();
142     }
143
144     qdev_set_parent_bus(dev, bus);
145
146     return dev;
147 }
148
149 /* Initialize a device.  Device properties should be set before calling
150    this function.  IRQs and MMIO regions should be connected/mapped after
151    calling this function.
152    On failure, destroy the device and return negative value.
153    Return 0 on success.  */
154 int qdev_init(DeviceState *dev)
155 {
156     Error *local_err = NULL;
157
158     assert(!dev->realized);
159
160     object_property_set_bool(OBJECT(dev), true, "realized", &local_err);
161     if (local_err != NULL) {
162         error_free(local_err);
163         qdev_free(dev);
164         return -1;
165     }
166     return 0;
167 }
168
169 static void device_realize(DeviceState *dev, Error **err)
170 {
171     DeviceClass *dc = DEVICE_GET_CLASS(dev);
172
173     if (dc->init) {
174         int rc = dc->init(dev);
175         if (rc < 0) {
176             error_setg(err, "Device initialization failed.");
177             return;
178         }
179     }
180 }
181
182 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
183                                  int required_for_version)
184 {
185     assert(!dev->realized);
186     dev->instance_id_alias = alias_id;
187     dev->alias_required_for_version = required_for_version;
188 }
189
190 void qdev_unplug(DeviceState *dev, Error **errp)
191 {
192     DeviceClass *dc = DEVICE_GET_CLASS(dev);
193
194     if (!dev->parent_bus->allow_hotplug) {
195         error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
196         return;
197     }
198     assert(dc->unplug != NULL);
199
200     qdev_hot_removed = true;
201
202     if (dc->unplug(dev) < 0) {
203         error_set(errp, QERR_UNDEFINED_ERROR);
204         return;
205     }
206 }
207
208 static int qdev_reset_one(DeviceState *dev, void *opaque)
209 {
210     device_reset(dev);
211
212     return 0;
213 }
214
215 static int qbus_reset_one(BusState *bus, void *opaque)
216 {
217     BusClass *bc = BUS_GET_CLASS(bus);
218     if (bc->reset) {
219         return bc->reset(bus);
220     }
221     return 0;
222 }
223
224 void qdev_reset_all(DeviceState *dev)
225 {
226     qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
227 }
228
229 void qbus_reset_all(BusState *bus)
230 {
231     qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
232 }
233
234 void qbus_reset_all_fn(void *opaque)
235 {
236     BusState *bus = opaque;
237     qbus_reset_all(bus);
238 }
239
240 /* can be used as ->unplug() callback for the simple cases */
241 int qdev_simple_unplug_cb(DeviceState *dev)
242 {
243     /* just zap it */
244     qdev_free(dev);
245     return 0;
246 }
247
248
249 /* Like qdev_init(), but terminate program via error_report() instead of
250    returning an error value.  This is okay during machine creation.
251    Don't use for hotplug, because there callers need to recover from
252    failure.  Exception: if you know the device's init() callback can't
253    fail, then qdev_init_nofail() can't fail either, and is therefore
254    usable even then.  But relying on the device implementation that
255    way is somewhat unclean, and best avoided.  */
256 void qdev_init_nofail(DeviceState *dev)
257 {
258     const char *typename = object_get_typename(OBJECT(dev));
259
260     if (qdev_init(dev) < 0) {
261         error_report("Initialization of device %s failed", typename);
262         exit(1);
263     }
264 }
265
266 /* Unlink device from bus and free the structure.  */
267 void qdev_free(DeviceState *dev)
268 {
269     object_delete(OBJECT(dev));
270 }
271
272 void qdev_machine_creation_done(void)
273 {
274     /*
275      * ok, initial machine setup is done, starting from now we can
276      * only create hotpluggable devices
277      */
278     qdev_hotplug = 1;
279 }
280
281 bool qdev_machine_modified(void)
282 {
283     return qdev_hot_added || qdev_hot_removed;
284 }
285
286 BusState *qdev_get_parent_bus(DeviceState *dev)
287 {
288     return dev->parent_bus;
289 }
290
291 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
292 {
293     dev->gpio_in = qemu_extend_irqs(dev->gpio_in, dev->num_gpio_in, handler,
294                                         dev, n);
295     dev->num_gpio_in += n;
296 }
297
298 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
299 {
300     assert(dev->num_gpio_out == 0);
301     dev->num_gpio_out = n;
302     dev->gpio_out = pins;
303 }
304
305 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
306 {
307     assert(n >= 0 && n < dev->num_gpio_in);
308     return dev->gpio_in[n];
309 }
310
311 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
312 {
313     assert(n >= 0 && n < dev->num_gpio_out);
314     dev->gpio_out[n] = pin;
315 }
316
317 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
318 {
319     BusState *bus;
320
321     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
322         if (strcmp(name, bus->name) == 0) {
323             return bus;
324         }
325     }
326     return NULL;
327 }
328
329 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
330                        qbus_walkerfn *busfn, void *opaque)
331 {
332     BusChild *kid;
333     int err;
334
335     if (busfn) {
336         err = busfn(bus, opaque);
337         if (err) {
338             return err;
339         }
340     }
341
342     QTAILQ_FOREACH(kid, &bus->children, sibling) {
343         err = qdev_walk_children(kid->child, devfn, busfn, opaque);
344         if (err < 0) {
345             return err;
346         }
347     }
348
349     return 0;
350 }
351
352 int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
353                        qbus_walkerfn *busfn, void *opaque)
354 {
355     BusState *bus;
356     int err;
357
358     if (devfn) {
359         err = devfn(dev, opaque);
360         if (err) {
361             return err;
362         }
363     }
364
365     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
366         err = qbus_walk_children(bus, devfn, busfn, opaque);
367         if (err < 0) {
368             return err;
369         }
370     }
371
372     return 0;
373 }
374
375 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
376 {
377     BusChild *kid;
378     DeviceState *ret;
379     BusState *child;
380
381     QTAILQ_FOREACH(kid, &bus->children, sibling) {
382         DeviceState *dev = kid->child;
383
384         if (dev->id && strcmp(dev->id, id) == 0) {
385             return dev;
386         }
387
388         QLIST_FOREACH(child, &dev->child_bus, sibling) {
389             ret = qdev_find_recursive(child, id);
390             if (ret) {
391                 return ret;
392             }
393         }
394     }
395     return NULL;
396 }
397
398 static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
399 {
400     const char *typename = object_get_typename(OBJECT(bus));
401     char *buf;
402     int i,len;
403
404     bus->parent = parent;
405
406     if (name) {
407         bus->name = g_strdup(name);
408     } else if (bus->parent && bus->parent->id) {
409         /* parent device has id -> use it for bus name */
410         len = strlen(bus->parent->id) + 16;
411         buf = g_malloc(len);
412         snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
413         bus->name = buf;
414     } else {
415         /* no id -> use lowercase bus type for bus name */
416         len = strlen(typename) + 16;
417         buf = g_malloc(len);
418         len = snprintf(buf, len, "%s.%d", typename,
419                        bus->parent ? bus->parent->num_child_bus : 0);
420         for (i = 0; i < len; i++)
421             buf[i] = qemu_tolower(buf[i]);
422         bus->name = buf;
423     }
424
425     if (bus->parent) {
426         QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
427         bus->parent->num_child_bus++;
428         object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
429     } else if (bus != sysbus_get_default()) {
430         /* TODO: once all bus devices are qdevified,
431            only reset handler for main_system_bus should be registered here. */
432         qemu_register_reset(qbus_reset_all_fn, bus);
433     }
434 }
435
436 static void bus_unparent(Object *obj)
437 {
438     BusState *bus = BUS(obj);
439     BusChild *kid;
440
441     while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
442         DeviceState *dev = kid->child;
443         qdev_free(dev);
444     }
445     if (bus->parent) {
446         QLIST_REMOVE(bus, sibling);
447         bus->parent->num_child_bus--;
448         bus->parent = NULL;
449     } else {
450         assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
451         qemu_unregister_reset(qbus_reset_all_fn, bus);
452     }
453 }
454
455 void qbus_create_inplace(void *bus, const char *typename,
456                          DeviceState *parent, const char *name)
457 {
458     object_initialize(bus, typename);
459     qbus_realize(bus, parent, name);
460 }
461
462 BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
463 {
464     BusState *bus;
465
466     bus = BUS(object_new(typename));
467     qbus_realize(bus, parent, name);
468
469     return bus;
470 }
471
472 void qbus_free(BusState *bus)
473 {
474     object_delete(OBJECT(bus));
475 }
476
477 static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
478 {
479     BusClass *bc = BUS_GET_CLASS(bus);
480
481     if (bc->get_fw_dev_path) {
482         return bc->get_fw_dev_path(dev);
483     }
484
485     return NULL;
486 }
487
488 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
489 {
490     int l = 0;
491
492     if (dev && dev->parent_bus) {
493         char *d;
494         l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
495         d = bus_get_fw_dev_path(dev->parent_bus, dev);
496         if (d) {
497             l += snprintf(p + l, size - l, "%s", d);
498             g_free(d);
499         } else {
500             l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
501         }
502     }
503     l += snprintf(p + l , size - l, "/");
504
505     return l;
506 }
507
508 char* qdev_get_fw_dev_path(DeviceState *dev)
509 {
510     char path[128];
511     int l;
512
513     l = qdev_get_fw_dev_path_helper(dev, path, 128);
514
515     path[l-1] = '\0';
516
517     return g_strdup(path);
518 }
519
520 char *qdev_get_dev_path(DeviceState *dev)
521 {
522     BusClass *bc;
523
524     if (!dev || !dev->parent_bus) {
525         return NULL;
526     }
527
528     bc = BUS_GET_CLASS(dev->parent_bus);
529     if (bc->get_dev_path) {
530         return bc->get_dev_path(dev);
531     }
532
533     return NULL;
534 }
535
536 /**
537  * Legacy property handling
538  */
539
540 static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
541                                      const char *name, Error **errp)
542 {
543     DeviceState *dev = DEVICE(obj);
544     Property *prop = opaque;
545
546     char buffer[1024];
547     char *ptr = buffer;
548
549     prop->info->print(dev, prop, buffer, sizeof(buffer));
550     visit_type_str(v, &ptr, name, errp);
551 }
552
553 static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
554                                      const char *name, Error **errp)
555 {
556     DeviceState *dev = DEVICE(obj);
557     Property *prop = opaque;
558     Error *local_err = NULL;
559     char *ptr = NULL;
560     int ret;
561
562     if (dev->realized) {
563         error_set(errp, QERR_PERMISSION_DENIED);
564         return;
565     }
566
567     visit_type_str(v, &ptr, name, &local_err);
568     if (local_err) {
569         error_propagate(errp, local_err);
570         return;
571     }
572
573     ret = prop->info->parse(dev, prop, ptr);
574     error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
575     g_free(ptr);
576 }
577
578 /**
579  * @qdev_add_legacy_property - adds a legacy property
580  *
581  * Do not use this is new code!  Properties added through this interface will
582  * be given names and types in the "legacy" namespace.
583  *
584  * Legacy properties are string versions of other OOM properties.  The format
585  * of the string depends on the property type.
586  */
587 void qdev_property_add_legacy(DeviceState *dev, Property *prop,
588                               Error **errp)
589 {
590     gchar *name, *type;
591
592     /* Register pointer properties as legacy properties */
593     if (!prop->info->print && !prop->info->parse &&
594         (prop->info->set || prop->info->get)) {
595         return;
596     }
597
598     name = g_strdup_printf("legacy-%s", prop->name);
599     type = g_strdup_printf("legacy<%s>",
600                            prop->info->legacy_name ?: prop->info->name);
601
602     object_property_add(OBJECT(dev), name, type,
603                         prop->info->print ? qdev_get_legacy_property : prop->info->get,
604                         prop->info->parse ? qdev_set_legacy_property : prop->info->set,
605                         NULL,
606                         prop, errp);
607
608     g_free(type);
609     g_free(name);
610 }
611
612 /**
613  * @qdev_property_add_static - add a @Property to a device.
614  *
615  * Static properties access data in a struct.  The actual type of the
616  * property and the field depends on the property type.
617  */
618 void qdev_property_add_static(DeviceState *dev, Property *prop,
619                               Error **errp)
620 {
621     Error *local_err = NULL;
622     Object *obj = OBJECT(dev);
623
624     /*
625      * TODO qdev_prop_ptr does not have getters or setters.  It must
626      * go now that it can be replaced with links.  The test should be
627      * removed along with it: all static properties are read/write.
628      */
629     if (!prop->info->get && !prop->info->set) {
630         return;
631     }
632
633     object_property_add(obj, prop->name, prop->info->name,
634                         prop->info->get, prop->info->set,
635                         prop->info->release,
636                         prop, &local_err);
637
638     if (local_err) {
639         error_propagate(errp, local_err);
640         return;
641     }
642     if (prop->qtype == QTYPE_NONE) {
643         return;
644     }
645
646     if (prop->qtype == QTYPE_QBOOL) {
647         object_property_set_bool(obj, prop->defval, prop->name, &local_err);
648     } else if (prop->info->enum_table) {
649         object_property_set_str(obj, prop->info->enum_table[prop->defval],
650                                 prop->name, &local_err);
651     } else if (prop->qtype == QTYPE_QINT) {
652         object_property_set_int(obj, prop->defval, prop->name, &local_err);
653     }
654     assert_no_error(local_err);
655 }
656
657 static bool device_get_realized(Object *obj, Error **err)
658 {
659     DeviceState *dev = DEVICE(obj);
660     return dev->realized;
661 }
662
663 static void device_set_realized(Object *obj, bool value, Error **err)
664 {
665     DeviceState *dev = DEVICE(obj);
666     DeviceClass *dc = DEVICE_GET_CLASS(dev);
667     Error *local_err = NULL;
668
669     if (value && !dev->realized) {
670         if (dc->realize) {
671             dc->realize(dev, &local_err);
672         }
673
674         if (!obj->parent && local_err == NULL) {
675             static int unattached_count;
676             gchar *name = g_strdup_printf("device[%d]", unattached_count++);
677
678             object_property_add_child(container_get(qdev_get_machine(),
679                                                     "/unattached"),
680                                       name, obj, &local_err);
681             g_free(name);
682         }
683
684         if (qdev_get_vmsd(dev) && local_err == NULL) {
685             vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
686                                            dev->instance_id_alias,
687                                            dev->alias_required_for_version);
688         }
689         if (dev->hotplugged && local_err == NULL) {
690             device_reset(dev);
691         }
692     } else if (!value && dev->realized) {
693         if (dc->unrealize) {
694             dc->unrealize(dev, &local_err);
695         }
696     }
697
698     if (local_err != NULL) {
699         error_propagate(err, local_err);
700         return;
701     }
702
703     dev->realized = value;
704 }
705
706 static void device_initfn(Object *obj)
707 {
708     DeviceState *dev = DEVICE(obj);
709     ObjectClass *class;
710     Property *prop;
711
712     if (qdev_hotplug) {
713         dev->hotplugged = 1;
714         qdev_hot_added = true;
715     }
716
717     dev->instance_id_alias = -1;
718     dev->realized = false;
719
720     object_property_add_bool(obj, "realized",
721                              device_get_realized, device_set_realized, NULL);
722
723     class = object_get_class(OBJECT(dev));
724     do {
725         for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
726             qdev_property_add_legacy(dev, prop, NULL);
727             qdev_property_add_static(dev, prop, NULL);
728         }
729         class = object_class_get_parent(class);
730     } while (class != object_class_by_name(TYPE_DEVICE));
731     qdev_prop_set_globals(dev);
732
733     object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
734                              (Object **)&dev->parent_bus, NULL);
735 }
736
737 /* Unlink device from bus and free the structure.  */
738 static void device_finalize(Object *obj)
739 {
740     DeviceState *dev = DEVICE(obj);
741     if (dev->opts) {
742         qemu_opts_del(dev->opts);
743     }
744 }
745
746 static void device_class_base_init(ObjectClass *class, void *data)
747 {
748     DeviceClass *klass = DEVICE_CLASS(class);
749
750     /* We explicitly look up properties in the superclasses,
751      * so do not propagate them to the subclasses.
752      */
753     klass->props = NULL;
754 }
755
756 static void device_unparent(Object *obj)
757 {
758     DeviceState *dev = DEVICE(obj);
759     DeviceClass *dc = DEVICE_GET_CLASS(dev);
760     BusState *bus;
761
762     while (dev->num_child_bus) {
763         bus = QLIST_FIRST(&dev->child_bus);
764         qbus_free(bus);
765     }
766     if (dev->realized) {
767         if (qdev_get_vmsd(dev)) {
768             vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
769         }
770         if (dc->exit) {
771             dc->exit(dev);
772         }
773     }
774     if (dev->parent_bus) {
775         bus_remove_child(dev->parent_bus, dev);
776     }
777 }
778
779 static void device_class_init(ObjectClass *class, void *data)
780 {
781     DeviceClass *dc = DEVICE_CLASS(class);
782
783     class->unparent = device_unparent;
784     dc->realize = device_realize;
785 }
786
787 void device_reset(DeviceState *dev)
788 {
789     DeviceClass *klass = DEVICE_GET_CLASS(dev);
790
791     if (klass->reset) {
792         klass->reset(dev);
793     }
794 }
795
796 Object *qdev_get_machine(void)
797 {
798     static Object *dev;
799
800     if (dev == NULL) {
801         dev = container_get(object_get_root(), "/machine");
802     }
803
804     return dev;
805 }
806
807 static const TypeInfo device_type_info = {
808     .name = TYPE_DEVICE,
809     .parent = TYPE_OBJECT,
810     .instance_size = sizeof(DeviceState),
811     .instance_init = device_initfn,
812     .instance_finalize = device_finalize,
813     .class_base_init = device_class_base_init,
814     .class_init = device_class_init,
815     .abstract = true,
816     .class_size = sizeof(DeviceClass),
817 };
818
819 static void qbus_initfn(Object *obj)
820 {
821     BusState *bus = BUS(obj);
822
823     QTAILQ_INIT(&bus->children);
824 }
825
826 static void bus_class_init(ObjectClass *class, void *data)
827 {
828     class->unparent = bus_unparent;
829 }
830
831 static void qbus_finalize(Object *obj)
832 {
833     BusState *bus = BUS(obj);
834
835     g_free((char *)bus->name);
836 }
837
838 static const TypeInfo bus_info = {
839     .name = TYPE_BUS,
840     .parent = TYPE_OBJECT,
841     .instance_size = sizeof(BusState),
842     .abstract = true,
843     .class_size = sizeof(BusClass),
844     .instance_init = qbus_initfn,
845     .instance_finalize = qbus_finalize,
846     .class_init = bus_class_init,
847 };
848
849 static void qdev_register_types(void)
850 {
851     type_register_static(&bus_info);
852     type_register_static(&device_type_info);
853 }
854
855 type_init(qdev_register_types)
This page took 0.072418 seconds and 4 git commands to generate.