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