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