]> Git Repo - qemu.git/blob - hw/qdev.c
Merge remote-tracking branch 'mjt/mjt-iov2' 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 "net.h"
29 #include "qdev.h"
30 #include "sysemu.h"
31 #include "error.h"
32
33 int qdev_hotplug = 0;
34 static bool qdev_hot_added = false;
35 static bool qdev_hot_removed = false;
36
37 /* Register a new device type.  */
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 bool qdev_exists(const char *name)
56 {
57     return !!object_class_by_name(name);
58 }
59
60 static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
61                                      Error **errp);
62
63 static void bus_remove_child(BusState *bus, DeviceState *child)
64 {
65     BusChild *kid;
66
67     QTAILQ_FOREACH(kid, &bus->children, sibling) {
68         if (kid->child == child) {
69             char name[32];
70
71             snprintf(name, sizeof(name), "child[%d]", kid->index);
72             QTAILQ_REMOVE(&bus->children, kid, sibling);
73             object_property_del(OBJECT(bus), name, NULL);
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
92     QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
93
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     bus_add_child(bus, dev);
105 }
106
107 /* Create a new device.  This only initializes the device state structure
108    and allows properties to be set.  qdev_init should be called to
109    initialize the actual device emulation.  */
110 DeviceState *qdev_create(BusState *bus, const char *name)
111 {
112     DeviceState *dev;
113
114     dev = qdev_try_create(bus, name);
115     if (!dev) {
116         if (bus) {
117             hw_error("Unknown device '%s' for bus '%s'\n", name,
118                      object_get_typename(OBJECT(bus)));
119         } else {
120             hw_error("Unknown device '%s' for default sysbus\n", name);
121         }
122     }
123
124     return dev;
125 }
126
127 DeviceState *qdev_try_create(BusState *bus, const char *type)
128 {
129     DeviceState *dev;
130
131     if (object_class_by_name(type) == NULL) {
132         return NULL;
133     }
134     dev = DEVICE(object_new(type));
135     if (!dev) {
136         return NULL;
137     }
138
139     if (!bus) {
140         bus = sysbus_get_default();
141     }
142
143     qdev_set_parent_bus(dev, bus);
144
145     return dev;
146 }
147
148 /* Initialize a device.  Device properties should be set before calling
149    this function.  IRQs and MMIO regions should be connected/mapped after
150    calling this function.
151    On failure, destroy the device and return negative value.
152    Return 0 on success.  */
153 int qdev_init(DeviceState *dev)
154 {
155     DeviceClass *dc = DEVICE_GET_CLASS(dev);
156     int rc;
157
158     assert(dev->state == DEV_STATE_CREATED);
159
160     rc = dc->init(dev);
161     if (rc < 0) {
162         object_unparent(OBJECT(dev));
163         qdev_free(dev);
164         return rc;
165     }
166
167     if (!OBJECT(dev)->parent) {
168         static int unattached_count = 0;
169         gchar *name = g_strdup_printf("device[%d]", unattached_count++);
170
171         object_property_add_child(container_get(qdev_get_machine(),
172                                                 "/unattached"),
173                                   name, OBJECT(dev), NULL);
174         g_free(name);
175     }
176
177     if (qdev_get_vmsd(dev)) {
178         vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
179                                        dev->instance_id_alias,
180                                        dev->alias_required_for_version);
181     }
182     dev->state = DEV_STATE_INITIALIZED;
183     if (dev->hotplugged) {
184         device_reset(dev);
185     }
186     return 0;
187 }
188
189 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
190                                  int required_for_version)
191 {
192     assert(dev->state == DEV_STATE_CREATED);
193     dev->instance_id_alias = alias_id;
194     dev->alias_required_for_version = required_for_version;
195 }
196
197 void qdev_unplug(DeviceState *dev, Error **errp)
198 {
199     DeviceClass *dc = DEVICE_GET_CLASS(dev);
200
201     if (!dev->parent_bus->allow_hotplug) {
202         error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
203         return;
204     }
205     assert(dc->unplug != NULL);
206
207     qdev_hot_removed = true;
208
209     if (dc->unplug(dev) < 0) {
210         error_set(errp, QERR_UNDEFINED_ERROR);
211         return;
212     }
213 }
214
215 static int qdev_reset_one(DeviceState *dev, void *opaque)
216 {
217     device_reset(dev);
218
219     return 0;
220 }
221
222 static int qbus_reset_one(BusState *bus, void *opaque)
223 {
224     BusClass *bc = BUS_GET_CLASS(bus);
225     if (bc->reset) {
226         return bc->reset(bus);
227     }
228     return 0;
229 }
230
231 void qdev_reset_all(DeviceState *dev)
232 {
233     qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
234 }
235
236 void qbus_reset_all_fn(void *opaque)
237 {
238     BusState *bus = opaque;
239     qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
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     object_unparent(OBJECT(dev));
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_delete(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     assert(dev->num_gpio_in == 0);
297     dev->num_gpio_in = n;
298     dev->gpio_in = qemu_allocate_irqs(handler, dev, 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 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
321 {
322     qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
323     if (nd->vlan)
324         qdev_prop_set_vlan(dev, "vlan", nd->vlan);
325     if (nd->netdev)
326         qdev_prop_set_netdev(dev, "netdev", nd->netdev);
327     if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
328         object_property_find(OBJECT(dev), "vectors", NULL)) {
329         qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
330     }
331     nd->instantiated = 1;
332 }
333
334 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
335 {
336     BusState *bus;
337
338     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
339         if (strcmp(name, bus->name) == 0) {
340             return bus;
341         }
342     }
343     return NULL;
344 }
345
346 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
347                        qbus_walkerfn *busfn, void *opaque)
348 {
349     BusChild *kid;
350     int err;
351
352     if (busfn) {
353         err = busfn(bus, opaque);
354         if (err) {
355             return err;
356         }
357     }
358
359     QTAILQ_FOREACH(kid, &bus->children, sibling) {
360         err = qdev_walk_children(kid->child, devfn, busfn, opaque);
361         if (err < 0) {
362             return err;
363         }
364     }
365
366     return 0;
367 }
368
369 int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
370                        qbus_walkerfn *busfn, void *opaque)
371 {
372     BusState *bus;
373     int err;
374
375     if (devfn) {
376         err = devfn(dev, opaque);
377         if (err) {
378             return err;
379         }
380     }
381
382     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
383         err = qbus_walk_children(bus, devfn, busfn, opaque);
384         if (err < 0) {
385             return err;
386         }
387     }
388
389     return 0;
390 }
391
392 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
393 {
394     BusChild *kid;
395     DeviceState *ret;
396     BusState *child;
397
398     QTAILQ_FOREACH(kid, &bus->children, sibling) {
399         DeviceState *dev = kid->child;
400
401         if (dev->id && strcmp(dev->id, id) == 0) {
402             return dev;
403         }
404
405         QLIST_FOREACH(child, &dev->child_bus, sibling) {
406             ret = qdev_find_recursive(child, id);
407             if (ret) {
408                 return ret;
409             }
410         }
411     }
412     return NULL;
413 }
414
415 static void qbus_realize(BusState *bus)
416 {
417     const char *typename = object_get_typename(OBJECT(bus));
418     char *buf;
419     int i,len;
420
421     if (bus->name) {
422         /* use supplied name */
423     } else if (bus->parent && bus->parent->id) {
424         /* parent device has id -> use it for bus name */
425         len = strlen(bus->parent->id) + 16;
426         buf = g_malloc(len);
427         snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
428         bus->name = buf;
429     } else {
430         /* no id -> use lowercase bus type for bus name */
431         len = strlen(typename) + 16;
432         buf = g_malloc(len);
433         len = snprintf(buf, len, "%s.%d", typename,
434                        bus->parent ? bus->parent->num_child_bus : 0);
435         for (i = 0; i < len; i++)
436             buf[i] = qemu_tolower(buf[i]);
437         bus->name = buf;
438     }
439
440     if (bus->parent) {
441         QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
442         bus->parent->num_child_bus++;
443         object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
444     } else if (bus != sysbus_get_default()) {
445         /* TODO: once all bus devices are qdevified,
446            only reset handler for main_system_bus should be registered here. */
447         qemu_register_reset(qbus_reset_all_fn, bus);
448     }
449 }
450
451 void qbus_create_inplace(BusState *bus, const char *typename,
452                          DeviceState *parent, const char *name)
453 {
454     object_initialize(bus, typename);
455
456     bus->parent = parent;
457     bus->name = name ? g_strdup(name) : NULL;
458     qbus_realize(bus);
459 }
460
461 BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
462 {
463     BusState *bus;
464
465     bus = BUS(object_new(typename));
466     bus->qom_allocated = true;
467
468     bus->parent = parent;
469     bus->name = name ? g_strdup(name) : NULL;
470     qbus_realize(bus);
471
472     return bus;
473 }
474
475 void qbus_free(BusState *bus)
476 {
477     if (bus->qom_allocated) {
478         object_delete(OBJECT(bus));
479     } else {
480         object_finalize(OBJECT(bus));
481         if (bus->glib_allocated) {
482             g_free(bus);
483         }
484     }
485 }
486
487 static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
488 {
489     BusClass *bc = BUS_GET_CLASS(bus);
490
491     if (bc->get_fw_dev_path) {
492         return bc->get_fw_dev_path(dev);
493     }
494
495     return NULL;
496 }
497
498 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
499 {
500     int l = 0;
501
502     if (dev && dev->parent_bus) {
503         char *d;
504         l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
505         d = bus_get_fw_dev_path(dev->parent_bus, dev);
506         if (d) {
507             l += snprintf(p + l, size - l, "%s", d);
508             g_free(d);
509         } else {
510             l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
511         }
512     }
513     l += snprintf(p + l , size - l, "/");
514
515     return l;
516 }
517
518 char* qdev_get_fw_dev_path(DeviceState *dev)
519 {
520     char path[128];
521     int l;
522
523     l = qdev_get_fw_dev_path_helper(dev, path, 128);
524
525     path[l-1] = '\0';
526
527     return strdup(path);
528 }
529
530 char *qdev_get_dev_path(DeviceState *dev)
531 {
532     BusClass *bc;
533
534     if (!dev || !dev->parent_bus) {
535         return NULL;
536     }
537
538     bc = BUS_GET_CLASS(dev->parent_bus);
539     if (bc->get_dev_path) {
540         return bc->get_dev_path(dev);
541     }
542
543     return NULL;
544 }
545
546 /**
547  * Legacy property handling
548  */
549
550 static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
551                                      const char *name, Error **errp)
552 {
553     DeviceState *dev = DEVICE(obj);
554     Property *prop = opaque;
555
556     char buffer[1024];
557     char *ptr = buffer;
558
559     prop->info->print(dev, prop, buffer, sizeof(buffer));
560     visit_type_str(v, &ptr, name, errp);
561 }
562
563 static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
564                                      const char *name, Error **errp)
565 {
566     DeviceState *dev = DEVICE(obj);
567     Property *prop = opaque;
568     Error *local_err = NULL;
569     char *ptr = NULL;
570     int ret;
571
572     if (dev->state != DEV_STATE_CREATED) {
573         error_set(errp, QERR_PERMISSION_DENIED);
574         return;
575     }
576
577     visit_type_str(v, &ptr, name, &local_err);
578     if (local_err) {
579         error_propagate(errp, local_err);
580         return;
581     }
582
583     ret = prop->info->parse(dev, prop, ptr);
584     error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
585     g_free(ptr);
586 }
587
588 /**
589  * @qdev_add_legacy_property - adds a legacy property
590  *
591  * Do not use this is new code!  Properties added through this interface will
592  * be given names and types in the "legacy" namespace.
593  *
594  * Legacy properties are string versions of other OOM properties.  The format
595  * of the string depends on the property type.
596  */
597 void qdev_property_add_legacy(DeviceState *dev, Property *prop,
598                               Error **errp)
599 {
600     gchar *name, *type;
601
602     /* Register pointer properties as legacy properties */
603     if (!prop->info->print && !prop->info->parse &&
604         (prop->info->set || prop->info->get)) {
605         return;
606     }
607
608     name = g_strdup_printf("legacy-%s", prop->name);
609     type = g_strdup_printf("legacy<%s>",
610                            prop->info->legacy_name ?: prop->info->name);
611
612     object_property_add(OBJECT(dev), name, type,
613                         prop->info->print ? qdev_get_legacy_property : prop->info->get,
614                         prop->info->parse ? qdev_set_legacy_property : prop->info->set,
615                         NULL,
616                         prop, errp);
617
618     g_free(type);
619     g_free(name);
620 }
621
622 /**
623  * @qdev_property_add_static - add a @Property to a device.
624  *
625  * Static properties access data in a struct.  The actual type of the
626  * property and the field depends on the property type.
627  */
628 void qdev_property_add_static(DeviceState *dev, Property *prop,
629                               Error **errp)
630 {
631     Error *local_err = NULL;
632     Object *obj = OBJECT(dev);
633
634     /*
635      * TODO qdev_prop_ptr does not have getters or setters.  It must
636      * go now that it can be replaced with links.  The test should be
637      * removed along with it: all static properties are read/write.
638      */
639     if (!prop->info->get && !prop->info->set) {
640         return;
641     }
642
643     object_property_add(obj, prop->name, prop->info->name,
644                         prop->info->get, prop->info->set,
645                         prop->info->release,
646                         prop, &local_err);
647
648     if (local_err) {
649         error_propagate(errp, local_err);
650         return;
651     }
652     if (prop->qtype == QTYPE_NONE) {
653         return;
654     }
655
656     if (prop->qtype == QTYPE_QBOOL) {
657         object_property_set_bool(obj, prop->defval, prop->name, &local_err);
658     } else if (prop->info->enum_table) {
659         object_property_set_str(obj, prop->info->enum_table[prop->defval],
660                                 prop->name, &local_err);
661     } else if (prop->qtype == QTYPE_QINT) {
662         object_property_set_int(obj, prop->defval, prop->name, &local_err);
663     }
664     assert_no_error(local_err);
665 }
666
667 static void device_initfn(Object *obj)
668 {
669     DeviceState *dev = DEVICE(obj);
670     ObjectClass *class;
671     Property *prop;
672
673     if (qdev_hotplug) {
674         dev->hotplugged = 1;
675         qdev_hot_added = true;
676     }
677
678     dev->instance_id_alias = -1;
679     dev->state = DEV_STATE_CREATED;
680
681     class = object_get_class(OBJECT(dev));
682     do {
683         for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
684             qdev_property_add_legacy(dev, prop, NULL);
685             qdev_property_add_static(dev, prop, NULL);
686         }
687         class = object_class_get_parent(class);
688     } while (class != object_class_by_name(TYPE_DEVICE));
689     qdev_prop_set_globals(dev);
690
691     object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
692                              (Object **)&dev->parent_bus, NULL);
693 }
694
695 /* Unlink device from bus and free the structure.  */
696 static void device_finalize(Object *obj)
697 {
698     DeviceState *dev = DEVICE(obj);
699     BusState *bus;
700     DeviceClass *dc = DEVICE_GET_CLASS(dev);
701
702     if (dev->state == DEV_STATE_INITIALIZED) {
703         while (dev->num_child_bus) {
704             bus = QLIST_FIRST(&dev->child_bus);
705             qbus_free(bus);
706         }
707         if (qdev_get_vmsd(dev)) {
708             vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
709         }
710         if (dc->exit) {
711             dc->exit(dev);
712         }
713         if (dev->opts) {
714             qemu_opts_del(dev->opts);
715         }
716     }
717     if (dev->parent_bus) {
718         bus_remove_child(dev->parent_bus, dev);
719     }
720 }
721
722 static void device_class_base_init(ObjectClass *class, void *data)
723 {
724     DeviceClass *klass = DEVICE_CLASS(class);
725
726     /* We explicitly look up properties in the superclasses,
727      * so do not propagate them to the subclasses.
728      */
729     klass->props = NULL;
730 }
731
732 void device_reset(DeviceState *dev)
733 {
734     DeviceClass *klass = DEVICE_GET_CLASS(dev);
735
736     if (klass->reset) {
737         klass->reset(dev);
738     }
739 }
740
741 Object *qdev_get_machine(void)
742 {
743     static Object *dev;
744
745     if (dev == NULL) {
746         dev = container_get(object_get_root(), "/machine");
747     }
748
749     return dev;
750 }
751
752 static TypeInfo device_type_info = {
753     .name = TYPE_DEVICE,
754     .parent = TYPE_OBJECT,
755     .instance_size = sizeof(DeviceState),
756     .instance_init = device_initfn,
757     .instance_finalize = device_finalize,
758     .class_base_init = device_class_base_init,
759     .abstract = true,
760     .class_size = sizeof(DeviceClass),
761 };
762
763 static void qbus_initfn(Object *obj)
764 {
765     BusState *bus = BUS(obj);
766
767     QTAILQ_INIT(&bus->children);
768 }
769
770 static void qbus_finalize(Object *obj)
771 {
772     BusState *bus = BUS(obj);
773     BusChild *kid;
774
775     while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
776         DeviceState *dev = kid->child;
777         qdev_free(dev);
778     }
779     if (bus->parent) {
780         QLIST_REMOVE(bus, sibling);
781         bus->parent->num_child_bus--;
782     } else {
783         assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
784         qemu_unregister_reset(qbus_reset_all_fn, bus);
785     }
786     g_free((char *)bus->name);
787 }
788
789 static const TypeInfo bus_info = {
790     .name = TYPE_BUS,
791     .parent = TYPE_OBJECT,
792     .instance_size = sizeof(BusState),
793     .abstract = true,
794     .class_size = sizeof(BusClass),
795     .instance_init = qbus_initfn,
796     .instance_finalize = qbus_finalize,
797 };
798
799 static void qdev_register_types(void)
800 {
801     type_register_static(&bus_info);
802     type_register_static(&device_type_info);
803 }
804
805 type_init(qdev_register_types)
This page took 0.069646 seconds and 4 git commands to generate.