1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include "qemu/osdep.h"
29#include "qapi/error.h"
30#include "qapi/qapi-events-qdev.h"
31#include "qapi/qmp/qdict.h"
32#include "qapi/qmp/qerror.h"
33#include "qapi/visitor.h"
34#include "qemu/error-report.h"
35#include "qemu/option.h"
36#include "hw/irq.h"
37#include "hw/qdev-properties.h"
38#include "hw/boards.h"
39#include "hw/sysbus.h"
40#include "hw/qdev-clock.h"
41#include "migration/vmstate.h"
42#include "trace.h"
43
44static bool qdev_hot_added = false;
45bool qdev_hot_removed = false;
46
47const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
48{
49 DeviceClass *dc = DEVICE_GET_CLASS(dev);
50 return dc->vmsd;
51}
52
53static void bus_free_bus_child(BusChild *kid)
54{
55 object_unref(OBJECT(kid->child));
56 g_free(kid);
57}
58
59static void bus_remove_child(BusState *bus, DeviceState *child)
60{
61 BusChild *kid;
62
63 QTAILQ_FOREACH(kid, &bus->children, sibling) {
64 if (kid->child == child) {
65 char name[32];
66
67 snprintf(name, sizeof(name), "child[%d]", kid->index);
68 QTAILQ_REMOVE_RCU(&bus->children, kid, sibling);
69
70 bus->num_children--;
71
72
73 object_property_del(OBJECT(bus), name);
74
75
76 call_rcu(kid, bus_free_bus_child, rcu);
77 break;
78 }
79 }
80}
81
82static void bus_add_child(BusState *bus, DeviceState *child)
83{
84 char name[32];
85 BusChild *kid = g_malloc0(sizeof(*kid));
86
87 bus->num_children++;
88 kid->index = bus->max_index++;
89 kid->child = child;
90 object_ref(OBJECT(kid->child));
91
92 QTAILQ_INSERT_HEAD_RCU(&bus->children, kid, sibling);
93
94
95 snprintf(name, sizeof(name), "child[%d]", kid->index);
96 object_property_add_link(OBJECT(bus), name,
97 object_get_typename(OBJECT(child)),
98 (Object **)&kid->child,
99 NULL,
100 0);
101}
102
103static bool bus_check_address(BusState *bus, DeviceState *child, Error **errp)
104{
105 BusClass *bc = BUS_GET_CLASS(bus);
106 return !bc->check_address || bc->check_address(bus, child, errp);
107}
108
109bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp)
110{
111 BusState *old_parent_bus = dev->parent_bus;
112 DeviceClass *dc = DEVICE_GET_CLASS(dev);
113
114 assert(dc->bus_type && object_dynamic_cast(OBJECT(bus), dc->bus_type));
115
116 if (!bus_check_address(bus, dev, errp)) {
117 return false;
118 }
119
120 if (old_parent_bus) {
121 trace_qdev_update_parent_bus(dev, object_get_typename(OBJECT(dev)),
122 old_parent_bus, object_get_typename(OBJECT(old_parent_bus)),
123 OBJECT(bus), object_get_typename(OBJECT(bus)));
124
125
126
127
128
129
130
131 object_ref(OBJECT(dev));
132 bus_remove_child(dev->parent_bus, dev);
133 }
134 dev->parent_bus = bus;
135 object_ref(OBJECT(bus));
136 bus_add_child(bus, dev);
137 if (dev->realized) {
138 resettable_change_parent(OBJECT(dev), OBJECT(bus),
139 OBJECT(old_parent_bus));
140 }
141 if (old_parent_bus) {
142 object_unref(OBJECT(old_parent_bus));
143 object_unref(OBJECT(dev));
144 }
145 return true;
146}
147
148DeviceState *qdev_new(const char *name)
149{
150 ObjectClass *oc = object_class_by_name(name);
151#ifdef CONFIG_MODULES
152 if (!oc) {
153 int rv = module_load_qom(name, &error_fatal);
154 if (rv > 0) {
155 oc = object_class_by_name(name);
156 } else {
157 error_report("could not find a module for type '%s'", name);
158 exit(1);
159 }
160 }
161#endif
162 if (!oc) {
163 error_report("unknown type '%s'", name);
164 abort();
165 }
166 return DEVICE(object_new(name));
167}
168
169DeviceState *qdev_try_new(const char *name)
170{
171 if (!module_object_class_by_name(name)) {
172 return NULL;
173 }
174 return DEVICE(object_new(name));
175}
176
177static QTAILQ_HEAD(, DeviceListener) device_listeners
178 = QTAILQ_HEAD_INITIALIZER(device_listeners);
179
180enum ListenerDirection { Forward, Reverse };
181
182#define DEVICE_LISTENER_CALL(_callback, _direction, _args...) \
183 do { \
184 DeviceListener *_listener; \
185 \
186 switch (_direction) { \
187 case Forward: \
188 QTAILQ_FOREACH(_listener, &device_listeners, link) { \
189 if (_listener->_callback) { \
190 _listener->_callback(_listener, ##_args); \
191 } \
192 } \
193 break; \
194 case Reverse: \
195 QTAILQ_FOREACH_REVERSE(_listener, &device_listeners, \
196 link) { \
197 if (_listener->_callback) { \
198 _listener->_callback(_listener, ##_args); \
199 } \
200 } \
201 break; \
202 default: \
203 abort(); \
204 } \
205 } while (0)
206
207static int device_listener_add(DeviceState *dev, void *opaque)
208{
209 DEVICE_LISTENER_CALL(realize, Forward, dev);
210
211 return 0;
212}
213
214void device_listener_register(DeviceListener *listener)
215{
216 QTAILQ_INSERT_TAIL(&device_listeners, listener, link);
217
218 qbus_walk_children(sysbus_get_default(), NULL, NULL, device_listener_add,
219 NULL, NULL);
220}
221
222void device_listener_unregister(DeviceListener *listener)
223{
224 QTAILQ_REMOVE(&device_listeners, listener, link);
225}
226
227bool qdev_should_hide_device(const QDict *opts, bool from_json, Error **errp)
228{
229 ERRP_GUARD();
230 DeviceListener *listener;
231
232 QTAILQ_FOREACH(listener, &device_listeners, link) {
233 if (listener->hide_device) {
234 if (listener->hide_device(listener, opts, from_json, errp)) {
235 return true;
236 } else if (*errp) {
237 return false;
238 }
239 }
240 }
241
242 return false;
243}
244
245void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
246 int required_for_version)
247{
248 assert(!dev->realized);
249 dev->instance_id_alias = alias_id;
250 dev->alias_required_for_version = required_for_version;
251}
252
253static int qdev_prereset(DeviceState *dev, void *opaque)
254{
255 trace_qdev_reset_tree(dev, object_get_typename(OBJECT(dev)));
256 return 0;
257}
258
259static int qbus_prereset(BusState *bus, void *opaque)
260{
261 trace_qbus_reset_tree(bus, object_get_typename(OBJECT(bus)));
262 return 0;
263}
264
265static int qdev_reset_one(DeviceState *dev, void *opaque)
266{
267 device_legacy_reset(dev);
268
269 return 0;
270}
271
272static int qbus_reset_one(BusState *bus, void *opaque)
273{
274 BusClass *bc = BUS_GET_CLASS(bus);
275 trace_qbus_reset(bus, object_get_typename(OBJECT(bus)));
276 if (bc->reset) {
277 bc->reset(bus);
278 }
279 return 0;
280}
281
282void qdev_reset_all(DeviceState *dev)
283{
284 trace_qdev_reset_all(dev, object_get_typename(OBJECT(dev)));
285 qdev_walk_children(dev, qdev_prereset, qbus_prereset,
286 qdev_reset_one, qbus_reset_one, NULL);
287}
288
289void qdev_reset_all_fn(void *opaque)
290{
291 qdev_reset_all(DEVICE(opaque));
292}
293
294void qbus_reset_all(BusState *bus)
295{
296 trace_qbus_reset_all(bus, object_get_typename(OBJECT(bus)));
297 qbus_walk_children(bus, qdev_prereset, qbus_prereset,
298 qdev_reset_one, qbus_reset_one, NULL);
299}
300
301void qbus_reset_all_fn(void *opaque)
302{
303 BusState *bus = opaque;
304 qbus_reset_all(bus);
305}
306
307void device_cold_reset(DeviceState *dev)
308{
309 resettable_reset(OBJECT(dev), RESET_TYPE_COLD);
310}
311
312bool device_is_in_reset(DeviceState *dev)
313{
314 return resettable_is_in_reset(OBJECT(dev));
315}
316
317static ResettableState *device_get_reset_state(Object *obj)
318{
319 DeviceState *dev = DEVICE(obj);
320 return &dev->reset;
321}
322
323static void device_reset_child_foreach(Object *obj, ResettableChildCallback cb,
324 void *opaque, ResetType type)
325{
326 DeviceState *dev = DEVICE(obj);
327 BusState *bus;
328
329 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
330 cb(OBJECT(bus), opaque, type);
331 }
332}
333
334bool qdev_realize(DeviceState *dev, BusState *bus, Error **errp)
335{
336 assert(!dev->realized && !dev->parent_bus);
337
338 if (bus) {
339 if (!qdev_set_parent_bus(dev, bus, errp)) {
340 return false;
341 }
342 } else {
343 assert(!DEVICE_GET_CLASS(dev)->bus_type);
344 }
345
346 return object_property_set_bool(OBJECT(dev), "realized", true, errp);
347}
348
349bool qdev_realize_and_unref(DeviceState *dev, BusState *bus, Error **errp)
350{
351 bool ret;
352
353 ret = qdev_realize(dev, bus, errp);
354 object_unref(OBJECT(dev));
355 return ret;
356}
357
358void qdev_unrealize(DeviceState *dev)
359{
360 object_property_set_bool(OBJECT(dev), "realized", false, &error_abort);
361}
362
363static int qdev_assert_realized_properly_cb(Object *obj, void *opaque)
364{
365 DeviceState *dev = DEVICE(object_dynamic_cast(obj, TYPE_DEVICE));
366 DeviceClass *dc;
367
368 if (dev) {
369 dc = DEVICE_GET_CLASS(dev);
370 assert(dev->realized);
371 assert(dev->parent_bus || !dc->bus_type);
372 }
373 return 0;
374}
375
376void qdev_assert_realized_properly(void)
377{
378 object_child_foreach_recursive(object_get_root(),
379 qdev_assert_realized_properly_cb, NULL);
380}
381
382bool qdev_machine_modified(void)
383{
384 return qdev_hot_added || qdev_hot_removed;
385}
386
387BusState *qdev_get_parent_bus(DeviceState *dev)
388{
389 return dev->parent_bus;
390}
391
392BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
393{
394 BusState *bus;
395 Object *child = object_resolve_path_component(OBJECT(dev), name);
396
397 bus = (BusState *)object_dynamic_cast(child, TYPE_BUS);
398 if (bus) {
399 return bus;
400 }
401
402 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
403 if (strcmp(name, bus->name) == 0) {
404 return bus;
405 }
406 }
407 return NULL;
408}
409
410int qdev_walk_children(DeviceState *dev,
411 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
412 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
413 void *opaque)
414{
415 BusState *bus;
416 int err;
417
418 if (pre_devfn) {
419 err = pre_devfn(dev, opaque);
420 if (err) {
421 return err;
422 }
423 }
424
425 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
426 err = qbus_walk_children(bus, pre_devfn, pre_busfn,
427 post_devfn, post_busfn, opaque);
428 if (err < 0) {
429 return err;
430 }
431 }
432
433 if (post_devfn) {
434 err = post_devfn(dev, opaque);
435 if (err) {
436 return err;
437 }
438 }
439
440 return 0;
441}
442
443DeviceState *qdev_find_recursive(BusState *bus, const char *id)
444{
445 BusChild *kid;
446 DeviceState *ret;
447 BusState *child;
448
449 WITH_RCU_READ_LOCK_GUARD() {
450 QTAILQ_FOREACH_RCU(kid, &bus->children, sibling) {
451 DeviceState *dev = kid->child;
452
453 if (dev->id && strcmp(dev->id, id) == 0) {
454 return dev;
455 }
456
457 QLIST_FOREACH(child, &dev->child_bus, sibling) {
458 ret = qdev_find_recursive(child, id);
459 if (ret) {
460 return ret;
461 }
462 }
463 }
464 }
465 return NULL;
466}
467
468char *qdev_get_dev_path(DeviceState *dev)
469{
470 BusClass *bc;
471
472 if (!dev || !dev->parent_bus) {
473 return NULL;
474 }
475
476 bc = BUS_GET_CLASS(dev->parent_bus);
477 if (bc->get_dev_path) {
478 return bc->get_dev_path(dev);
479 }
480
481 return NULL;
482}
483
484void qdev_add_unplug_blocker(DeviceState *dev, Error *reason)
485{
486 dev->unplug_blockers = g_slist_prepend(dev->unplug_blockers, reason);
487}
488
489void qdev_del_unplug_blocker(DeviceState *dev, Error *reason)
490{
491 dev->unplug_blockers = g_slist_remove(dev->unplug_blockers, reason);
492}
493
494bool qdev_unplug_blocked(DeviceState *dev, Error **errp)
495{
496 ERRP_GUARD();
497
498 if (dev->unplug_blockers) {
499 error_propagate(errp, error_copy(dev->unplug_blockers->data));
500 return true;
501 }
502
503 return false;
504}
505
506static bool device_get_realized(Object *obj, Error **errp)
507{
508 DeviceState *dev = DEVICE(obj);
509 return dev->realized;
510}
511
512static bool check_only_migratable(Object *obj, Error **errp)
513{
514 DeviceClass *dc = DEVICE_GET_CLASS(obj);
515
516 if (!vmstate_check_only_migratable(dc->vmsd)) {
517 error_setg(errp, "Device %s is not migratable, but "
518 "--only-migratable was specified",
519 object_get_typename(obj));
520 return false;
521 }
522
523 return true;
524}
525
526static void device_set_realized(Object *obj, bool value, Error **errp)
527{
528 DeviceState *dev = DEVICE(obj);
529 DeviceClass *dc = DEVICE_GET_CLASS(dev);
530 HotplugHandler *hotplug_ctrl;
531 BusState *bus;
532 NamedClockList *ncl;
533 Error *local_err = NULL;
534 bool unattached_parent = false;
535 static int unattached_count;
536
537 if (dev->hotplugged && !dc->hotpluggable) {
538 error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
539 return;
540 }
541
542 if (value && !dev->realized) {
543 if (!check_only_migratable(obj, errp)) {
544 goto fail;
545 }
546
547 if (!obj->parent) {
548 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
549
550 object_property_add_child(container_get(qdev_get_machine(),
551 "/unattached"),
552 name, obj);
553 unattached_parent = true;
554 g_free(name);
555 }
556
557 hotplug_ctrl = qdev_get_hotplug_handler(dev);
558 if (hotplug_ctrl) {
559 hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err);
560 if (local_err != NULL) {
561 goto fail;
562 }
563 }
564
565 if (dc->realize) {
566 dc->realize(dev, &local_err);
567 if (local_err != NULL) {
568 goto fail;
569 }
570 }
571
572 DEVICE_LISTENER_CALL(realize, Forward, dev);
573
574
575
576
577
578 g_free(dev->canonical_path);
579 dev->canonical_path = object_get_canonical_path(OBJECT(dev));
580 QLIST_FOREACH(ncl, &dev->clocks, node) {
581 if (ncl->alias) {
582 continue;
583 } else {
584 clock_setup_canonical_path(ncl->clock);
585 }
586 }
587
588 if (qdev_get_vmsd(dev)) {
589 if (vmstate_register_with_alias_id(VMSTATE_IF(dev),
590 VMSTATE_INSTANCE_ID_ANY,
591 qdev_get_vmsd(dev), dev,
592 dev->instance_id_alias,
593 dev->alias_required_for_version,
594 &local_err) < 0) {
595 goto post_realize_fail;
596 }
597 }
598
599
600
601
602
603 resettable_state_clear(&dev->reset);
604
605 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
606 if (!qbus_realize(bus, errp)) {
607 goto child_realize_fail;
608 }
609 }
610 if (dev->hotplugged) {
611
612
613
614
615 resettable_assert_reset(OBJECT(dev), RESET_TYPE_COLD);
616 resettable_change_parent(OBJECT(dev), OBJECT(dev->parent_bus),
617 NULL);
618 resettable_release_reset(OBJECT(dev), RESET_TYPE_COLD);
619 }
620 dev->pending_deleted_event = false;
621
622 if (hotplug_ctrl) {
623 hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
624 if (local_err != NULL) {
625 goto child_realize_fail;
626 }
627 }
628
629 qatomic_store_release(&dev->realized, value);
630
631 } else if (!value && dev->realized) {
632
633
634
635
636
637
638
639
640
641 qatomic_set(&dev->realized, value);
642
643
644
645
646 smp_wmb();
647
648 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
649 qbus_unrealize(bus);
650 }
651 if (qdev_get_vmsd(dev)) {
652 vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev);
653 }
654 if (dc->unrealize) {
655 dc->unrealize(dev);
656 }
657 dev->pending_deleted_event = true;
658 DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
659 }
660
661 assert(local_err == NULL);
662 return;
663
664child_realize_fail:
665 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
666 qbus_unrealize(bus);
667 }
668
669 if (qdev_get_vmsd(dev)) {
670 vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev);
671 }
672
673post_realize_fail:
674 g_free(dev->canonical_path);
675 dev->canonical_path = NULL;
676 if (dc->unrealize) {
677 dc->unrealize(dev);
678 }
679
680fail:
681 error_propagate(errp, local_err);
682 if (unattached_parent) {
683
684
685
686
687 object_unparent(OBJECT(dev));
688 unattached_count--;
689 }
690}
691
692static bool device_get_hotpluggable(Object *obj, Error **errp)
693{
694 DeviceClass *dc = DEVICE_GET_CLASS(obj);
695 DeviceState *dev = DEVICE(obj);
696
697 return dc->hotpluggable && (dev->parent_bus == NULL ||
698 qbus_is_hotpluggable(dev->parent_bus));
699}
700
701static bool device_get_hotplugged(Object *obj, Error **errp)
702{
703 DeviceState *dev = DEVICE(obj);
704
705 return dev->hotplugged;
706}
707
708static void device_initfn(Object *obj)
709{
710 DeviceState *dev = DEVICE(obj);
711
712 if (phase_check(PHASE_MACHINE_READY)) {
713 dev->hotplugged = 1;
714 qdev_hot_added = true;
715 }
716
717 dev->instance_id_alias = -1;
718 dev->realized = false;
719 dev->allow_unplug_during_migration = false;
720
721 QLIST_INIT(&dev->gpios);
722 QLIST_INIT(&dev->clocks);
723}
724
725static void device_post_init(Object *obj)
726{
727
728
729
730
731 object_apply_compat_props(obj);
732 qdev_prop_set_globals(DEVICE(obj));
733}
734
735
736static void device_finalize(Object *obj)
737{
738 NamedGPIOList *ngl, *next;
739
740 DeviceState *dev = DEVICE(obj);
741
742 g_assert(!dev->unplug_blockers);
743
744 QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
745 QLIST_REMOVE(ngl, node);
746 qemu_free_irqs(ngl->in, ngl->num_in);
747 g_free(ngl->name);
748 g_free(ngl);
749
750
751
752 }
753
754 qdev_finalize_clocklist(dev);
755
756
757 if (dev->pending_deleted_event) {
758 g_assert(dev->canonical_path);
759
760 qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path);
761 g_free(dev->canonical_path);
762 dev->canonical_path = NULL;
763 }
764
765 qobject_unref(dev->opts);
766 g_free(dev->id);
767}
768
769static void device_class_base_init(ObjectClass *class, void *data)
770{
771 DeviceClass *klass = DEVICE_CLASS(class);
772
773
774
775
776 klass->props_ = NULL;
777}
778
779static void device_unparent(Object *obj)
780{
781 DeviceState *dev = DEVICE(obj);
782 BusState *bus;
783
784 if (dev->realized) {
785 qdev_unrealize(dev);
786 }
787 while (dev->num_child_bus) {
788 bus = QLIST_FIRST(&dev->child_bus);
789 object_unparent(OBJECT(bus));
790 }
791 if (dev->parent_bus) {
792 bus_remove_child(dev->parent_bus, dev);
793 object_unref(OBJECT(dev->parent_bus));
794 dev->parent_bus = NULL;
795 }
796}
797
798static char *
799device_vmstate_if_get_id(VMStateIf *obj)
800{
801 DeviceState *dev = DEVICE(obj);
802
803 return qdev_get_dev_path(dev);
804}
805
806
807
808
809
810
811static void device_phases_reset(DeviceState *dev)
812{
813 ResettableClass *rc = RESETTABLE_GET_CLASS(dev);
814
815 if (rc->phases.enter) {
816 rc->phases.enter(OBJECT(dev), RESET_TYPE_COLD);
817 }
818 if (rc->phases.hold) {
819 rc->phases.hold(OBJECT(dev));
820 }
821 if (rc->phases.exit) {
822 rc->phases.exit(OBJECT(dev));
823 }
824}
825
826static void device_transitional_reset(Object *obj)
827{
828 DeviceClass *dc = DEVICE_GET_CLASS(obj);
829
830
831
832
833
834
835 if (dc->reset) {
836 dc->reset(DEVICE(obj));
837 }
838}
839
840
841
842
843
844static ResettableTrFunction device_get_transitional_reset(Object *obj)
845{
846 DeviceClass *dc = DEVICE_GET_CLASS(obj);
847 if (dc->reset != device_phases_reset) {
848
849
850
851
852 return device_transitional_reset;
853 }
854 return NULL;
855}
856
857static void device_class_init(ObjectClass *class, void *data)
858{
859 DeviceClass *dc = DEVICE_CLASS(class);
860 VMStateIfClass *vc = VMSTATE_IF_CLASS(class);
861 ResettableClass *rc = RESETTABLE_CLASS(class);
862
863 class->unparent = device_unparent;
864
865
866
867
868
869
870
871 dc->hotpluggable = true;
872 dc->user_creatable = true;
873 vc->get_id = device_vmstate_if_get_id;
874 rc->get_state = device_get_reset_state;
875 rc->child_foreach = device_reset_child_foreach;
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890 dc->reset = device_phases_reset;
891 rc->get_transitional_function = device_get_transitional_reset;
892
893 object_class_property_add_bool(class, "realized",
894 device_get_realized, device_set_realized);
895 object_class_property_add_bool(class, "hotpluggable",
896 device_get_hotpluggable, NULL);
897 object_class_property_add_bool(class, "hotplugged",
898 device_get_hotplugged, NULL);
899 object_class_property_add_link(class, "parent_bus", TYPE_BUS,
900 offsetof(DeviceState, parent_bus), NULL, 0);
901}
902
903void device_class_set_parent_reset(DeviceClass *dc,
904 DeviceReset dev_reset,
905 DeviceReset *parent_reset)
906{
907 *parent_reset = dc->reset;
908 dc->reset = dev_reset;
909}
910
911void device_class_set_parent_realize(DeviceClass *dc,
912 DeviceRealize dev_realize,
913 DeviceRealize *parent_realize)
914{
915 *parent_realize = dc->realize;
916 dc->realize = dev_realize;
917}
918
919void device_class_set_parent_unrealize(DeviceClass *dc,
920 DeviceUnrealize dev_unrealize,
921 DeviceUnrealize *parent_unrealize)
922{
923 *parent_unrealize = dc->unrealize;
924 dc->unrealize = dev_unrealize;
925}
926
927void device_legacy_reset(DeviceState *dev)
928{
929 DeviceClass *klass = DEVICE_GET_CLASS(dev);
930
931 trace_qdev_reset(dev, object_get_typename(OBJECT(dev)));
932 if (klass->reset) {
933 klass->reset(dev);
934 }
935}
936
937Object *qdev_get_machine(void)
938{
939 static Object *dev;
940
941 if (dev == NULL) {
942 dev = container_get(object_get_root(), "/machine");
943 }
944
945 return dev;
946}
947
948static MachineInitPhase machine_phase;
949
950bool phase_check(MachineInitPhase phase)
951{
952 return machine_phase >= phase;
953}
954
955void phase_advance(MachineInitPhase phase)
956{
957 assert(machine_phase == phase - 1);
958 machine_phase = phase;
959}
960
961static const TypeInfo device_type_info = {
962 .name = TYPE_DEVICE,
963 .parent = TYPE_OBJECT,
964 .instance_size = sizeof(DeviceState),
965 .instance_init = device_initfn,
966 .instance_post_init = device_post_init,
967 .instance_finalize = device_finalize,
968 .class_base_init = device_class_base_init,
969 .class_init = device_class_init,
970 .abstract = true,
971 .class_size = sizeof(DeviceClass),
972 .interfaces = (InterfaceInfo[]) {
973 { TYPE_VMSTATE_IF },
974 { TYPE_RESETTABLE_INTERFACE },
975 { }
976 }
977};
978
979static void qdev_register_types(void)
980{
981 type_register_static(&device_type_info);
982}
983
984type_init(qdev_register_types)
985