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