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