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