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 "hw/qdev.h"
30#include "sysemu/sysemu.h"
31#include "qapi/error.h"
32#include "qapi/qapi-events-misc.h"
33#include "qapi/qmp/qerror.h"
34#include "qapi/visitor.h"
35#include "qemu/error-report.h"
36#include "qemu/option.h"
37#include "hw/hotplug.h"
38#include "hw/boards.h"
39#include "hw/sysbus.h"
40
41bool qdev_hotplug = false;
42static bool qdev_hot_added = false;
43bool qdev_hot_removed = false;
44
45const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
46{
47 DeviceClass *dc = DEVICE_GET_CLASS(dev);
48 return dc->vmsd;
49}
50
51static void bus_remove_child(BusState *bus, DeviceState *child)
52{
53 BusChild *kid;
54
55 QTAILQ_FOREACH(kid, &bus->children, sibling) {
56 if (kid->child == child) {
57 char name[32];
58
59 snprintf(name, sizeof(name), "child[%d]", kid->index);
60 QTAILQ_REMOVE(&bus->children, kid, sibling);
61
62
63 object_property_del(OBJECT(bus), name, NULL);
64 object_unref(OBJECT(kid->child));
65 g_free(kid);
66 return;
67 }
68 }
69}
70
71static void bus_add_child(BusState *bus, DeviceState *child)
72{
73 char name[32];
74 BusChild *kid = g_malloc0(sizeof(*kid));
75
76 kid->index = bus->max_index++;
77 kid->child = child;
78 object_ref(OBJECT(kid->child));
79
80 QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
81
82
83 snprintf(name, sizeof(name), "child[%d]", kid->index);
84 object_property_add_link(OBJECT(bus), name,
85 object_get_typename(OBJECT(child)),
86 (Object **)&kid->child,
87 NULL,
88 0,
89 NULL);
90}
91
92void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
93{
94 bool replugging = dev->parent_bus != NULL;
95
96 if (replugging) {
97
98
99
100
101 object_ref(OBJECT(dev));
102 bus_remove_child(dev->parent_bus, dev);
103 object_unref(OBJECT(dev->parent_bus));
104 }
105 dev->parent_bus = bus;
106 object_ref(OBJECT(bus));
107 bus_add_child(bus, dev);
108 if (replugging) {
109 object_unref(OBJECT(dev));
110 }
111}
112
113
114
115
116DeviceState *qdev_create(BusState *bus, const char *name)
117{
118 DeviceState *dev;
119
120 dev = qdev_try_create(bus, name);
121 if (!dev) {
122 if (bus) {
123 error_report("Unknown device '%s' for bus '%s'", name,
124 object_get_typename(OBJECT(bus)));
125 } else {
126 error_report("Unknown device '%s' for default sysbus", name);
127 }
128 abort();
129 }
130
131 return dev;
132}
133
134DeviceState *qdev_try_create(BusState *bus, const char *type)
135{
136 DeviceState *dev;
137
138 if (object_class_by_name(type) == NULL) {
139 return NULL;
140 }
141 dev = DEVICE(object_new(type));
142 if (!dev) {
143 return NULL;
144 }
145
146 if (!bus) {
147
148
149
150
151
152 g_assert(object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE));
153 bus = sysbus_get_default();
154 }
155
156 qdev_set_parent_bus(dev, bus);
157 object_unref(OBJECT(dev));
158 return dev;
159}
160
161static QTAILQ_HEAD(device_listeners, DeviceListener) device_listeners
162 = QTAILQ_HEAD_INITIALIZER(device_listeners);
163
164enum ListenerDirection { Forward, Reverse };
165
166#define DEVICE_LISTENER_CALL(_callback, _direction, _args...) \
167 do { \
168 DeviceListener *_listener; \
169 \
170 switch (_direction) { \
171 case Forward: \
172 QTAILQ_FOREACH(_listener, &device_listeners, link) { \
173 if (_listener->_callback) { \
174 _listener->_callback(_listener, ##_args); \
175 } \
176 } \
177 break; \
178 case Reverse: \
179 QTAILQ_FOREACH_REVERSE(_listener, &device_listeners, \
180 device_listeners, link) { \
181 if (_listener->_callback) { \
182 _listener->_callback(_listener, ##_args); \
183 } \
184 } \
185 break; \
186 default: \
187 abort(); \
188 } \
189 } while (0)
190
191static int device_listener_add(DeviceState *dev, void *opaque)
192{
193 DEVICE_LISTENER_CALL(realize, Forward, dev);
194
195 return 0;
196}
197
198void device_listener_register(DeviceListener *listener)
199{
200 QTAILQ_INSERT_TAIL(&device_listeners, listener, link);
201
202 qbus_walk_children(sysbus_get_default(), NULL, NULL, device_listener_add,
203 NULL, NULL);
204}
205
206void device_listener_unregister(DeviceListener *listener)
207{
208 QTAILQ_REMOVE(&device_listeners, listener, link);
209}
210
211void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
212 int required_for_version)
213{
214 assert(!dev->realized);
215 dev->instance_id_alias = alias_id;
216 dev->alias_required_for_version = required_for_version;
217}
218
219HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
220{
221 MachineState *machine;
222 MachineClass *mc;
223 Object *m_obj = qdev_get_machine();
224
225 if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
226 machine = MACHINE(m_obj);
227 mc = MACHINE_GET_CLASS(machine);
228 if (mc->get_hotplug_handler) {
229 return mc->get_hotplug_handler(machine, dev);
230 }
231 }
232
233 return NULL;
234}
235
236HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
237{
238 HotplugHandler *hotplug_ctrl;
239
240 if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
241 hotplug_ctrl = dev->parent_bus->hotplug_handler;
242 } else {
243 hotplug_ctrl = qdev_get_machine_hotplug_handler(dev);
244 }
245 return hotplug_ctrl;
246}
247
248static int qdev_reset_one(DeviceState *dev, void *opaque)
249{
250 device_reset(dev);
251
252 return 0;
253}
254
255static int qbus_reset_one(BusState *bus, void *opaque)
256{
257 BusClass *bc = BUS_GET_CLASS(bus);
258 if (bc->reset) {
259 bc->reset(bus);
260 }
261 return 0;
262}
263
264void qdev_reset_all(DeviceState *dev)
265{
266 qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
267}
268
269void qdev_reset_all_fn(void *opaque)
270{
271 qdev_reset_all(DEVICE(opaque));
272}
273
274void qbus_reset_all(BusState *bus)
275{
276 qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
277}
278
279void qbus_reset_all_fn(void *opaque)
280{
281 BusState *bus = opaque;
282 qbus_reset_all(bus);
283}
284
285
286void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
287 DeviceState *dev, Error **errp)
288{
289
290 object_unparent(OBJECT(dev));
291}
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306void qdev_init_nofail(DeviceState *dev)
307{
308 Error *err = NULL;
309
310 assert(!dev->realized);
311
312 object_ref(OBJECT(dev));
313 object_property_set_bool(OBJECT(dev), true, "realized", &err);
314 if (err) {
315 error_reportf_err(err, "Initialization of device %s failed: ",
316 object_get_typename(OBJECT(dev)));
317 exit(1);
318 }
319 object_unref(OBJECT(dev));
320}
321
322void qdev_machine_creation_done(void)
323{
324
325
326
327
328 qdev_hotplug = true;
329}
330
331bool qdev_machine_modified(void)
332{
333 return qdev_hot_added || qdev_hot_removed;
334}
335
336BusState *qdev_get_parent_bus(DeviceState *dev)
337{
338 return dev->parent_bus;
339}
340
341static NamedGPIOList *qdev_get_named_gpio_list(DeviceState *dev,
342 const char *name)
343{
344 NamedGPIOList *ngl;
345
346 QLIST_FOREACH(ngl, &dev->gpios, node) {
347
348
349
350 if ((!ngl->name && !name) ||
351 (name && ngl->name && strcmp(name, ngl->name) == 0)) {
352 return ngl;
353 }
354 }
355
356 ngl = g_malloc0(sizeof(*ngl));
357 ngl->name = g_strdup(name);
358 QLIST_INSERT_HEAD(&dev->gpios, ngl, node);
359 return ngl;
360}
361
362void qdev_init_gpio_in_named_with_opaque(DeviceState *dev,
363 qemu_irq_handler handler,
364 void *opaque,
365 const char *name, int n)
366{
367 int i;
368 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
369
370 assert(gpio_list->num_out == 0 || !name);
371 gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler,
372 opaque, n);
373
374 if (!name) {
375 name = "unnamed-gpio-in";
376 }
377 for (i = gpio_list->num_in; i < gpio_list->num_in + n; i++) {
378 gchar *propname = g_strdup_printf("%s[%u]", name, i);
379
380 object_property_add_child(OBJECT(dev), propname,
381 OBJECT(gpio_list->in[i]), &error_abort);
382 g_free(propname);
383 }
384
385 gpio_list->num_in += n;
386}
387
388void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
389{
390 qdev_init_gpio_in_named(dev, handler, NULL, n);
391}
392
393void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins,
394 const char *name, int n)
395{
396 int i;
397 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
398
399 assert(gpio_list->num_in == 0 || !name);
400
401 if (!name) {
402 name = "unnamed-gpio-out";
403 }
404 memset(pins, 0, sizeof(*pins) * n);
405 for (i = 0; i < n; ++i) {
406 gchar *propname = g_strdup_printf("%s[%u]", name,
407 gpio_list->num_out + i);
408
409 object_property_add_link(OBJECT(dev), propname, TYPE_IRQ,
410 (Object **)&pins[i],
411 object_property_allow_set_link,
412 OBJ_PROP_LINK_STRONG,
413 &error_abort);
414 g_free(propname);
415 }
416 gpio_list->num_out += n;
417}
418
419void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
420{
421 qdev_init_gpio_out_named(dev, pins, NULL, n);
422}
423
424qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n)
425{
426 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
427
428 assert(n >= 0 && n < gpio_list->num_in);
429 return gpio_list->in[n];
430}
431
432qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
433{
434 return qdev_get_gpio_in_named(dev, NULL, n);
435}
436
437void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
438 qemu_irq pin)
439{
440 char *propname = g_strdup_printf("%s[%d]",
441 name ? name : "unnamed-gpio-out", n);
442 if (pin) {
443
444
445
446
447
448 object_property_add_child(container_get(qdev_get_machine(),
449 "/unattached"),
450 "non-qdev-gpio[*]", OBJECT(pin), NULL);
451 }
452 object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort);
453 g_free(propname);
454}
455
456qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n)
457{
458 char *propname = g_strdup_printf("%s[%d]",
459 name ? name : "unnamed-gpio-out", n);
460
461 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
462 NULL);
463
464 return ret;
465}
466
467
468
469static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev,
470 const char *name, int n)
471{
472 char *propname = g_strdup_printf("%s[%d]",
473 name ? name : "unnamed-gpio-out", n);
474
475 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
476 NULL);
477 if (ret) {
478 object_property_set_link(OBJECT(dev), NULL, propname, NULL);
479 }
480 g_free(propname);
481 return ret;
482}
483
484qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt,
485 const char *name, int n)
486{
487 qemu_irq disconnected = qdev_disconnect_gpio_out_named(dev, name, n);
488 qdev_connect_gpio_out_named(dev, name, n, icpt);
489 return disconnected;
490}
491
492void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
493{
494 qdev_connect_gpio_out_named(dev, NULL, n, pin);
495}
496
497void qdev_pass_gpios(DeviceState *dev, DeviceState *container,
498 const char *name)
499{
500 int i;
501 NamedGPIOList *ngl = qdev_get_named_gpio_list(dev, name);
502
503 for (i = 0; i < ngl->num_in; i++) {
504 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-in";
505 char *propname = g_strdup_printf("%s[%d]", nm, i);
506
507 object_property_add_alias(OBJECT(container), propname,
508 OBJECT(dev), propname,
509 &error_abort);
510 g_free(propname);
511 }
512 for (i = 0; i < ngl->num_out; i++) {
513 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-out";
514 char *propname = g_strdup_printf("%s[%d]", nm, i);
515
516 object_property_add_alias(OBJECT(container), propname,
517 OBJECT(dev), propname,
518 &error_abort);
519 g_free(propname);
520 }
521 QLIST_REMOVE(ngl, node);
522 QLIST_INSERT_HEAD(&container->gpios, ngl, node);
523}
524
525BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
526{
527 BusState *bus;
528 Object *child = object_resolve_path_component(OBJECT(dev), name);
529
530 bus = (BusState *)object_dynamic_cast(child, TYPE_BUS);
531 if (bus) {
532 return bus;
533 }
534
535 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
536 if (strcmp(name, bus->name) == 0) {
537 return bus;
538 }
539 }
540 return NULL;
541}
542
543int qdev_walk_children(DeviceState *dev,
544 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
545 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
546 void *opaque)
547{
548 BusState *bus;
549 int err;
550
551 if (pre_devfn) {
552 err = pre_devfn(dev, opaque);
553 if (err) {
554 return err;
555 }
556 }
557
558 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
559 err = qbus_walk_children(bus, pre_devfn, pre_busfn,
560 post_devfn, post_busfn, opaque);
561 if (err < 0) {
562 return err;
563 }
564 }
565
566 if (post_devfn) {
567 err = post_devfn(dev, opaque);
568 if (err) {
569 return err;
570 }
571 }
572
573 return 0;
574}
575
576DeviceState *qdev_find_recursive(BusState *bus, const char *id)
577{
578 BusChild *kid;
579 DeviceState *ret;
580 BusState *child;
581
582 QTAILQ_FOREACH(kid, &bus->children, sibling) {
583 DeviceState *dev = kid->child;
584
585 if (dev->id && strcmp(dev->id, id) == 0) {
586 return dev;
587 }
588
589 QLIST_FOREACH(child, &dev->child_bus, sibling) {
590 ret = qdev_find_recursive(child, id);
591 if (ret) {
592 return ret;
593 }
594 }
595 }
596 return NULL;
597}
598
599char *qdev_get_dev_path(DeviceState *dev)
600{
601 BusClass *bc;
602
603 if (!dev || !dev->parent_bus) {
604 return NULL;
605 }
606
607 bc = BUS_GET_CLASS(dev->parent_bus);
608 if (bc->get_dev_path) {
609 return bc->get_dev_path(dev);
610 }
611
612 return NULL;
613}
614
615
616
617
618
619static void qdev_get_legacy_property(Object *obj, Visitor *v,
620 const char *name, void *opaque,
621 Error **errp)
622{
623 DeviceState *dev = DEVICE(obj);
624 Property *prop = opaque;
625
626 char buffer[1024];
627 char *ptr = buffer;
628
629 prop->info->print(dev, prop, buffer, sizeof(buffer));
630 visit_type_str(v, name, &ptr, errp);
631}
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
650 Error **errp)
651{
652 gchar *name;
653
654
655 if (!prop->info->print && prop->info->get) {
656 return;
657 }
658
659 if (prop->info->create) {
660 return;
661 }
662
663 name = g_strdup_printf("legacy-%s", prop->name);
664 object_property_add(OBJECT(dev), name, "str",
665 prop->info->print ? qdev_get_legacy_property : prop->info->get,
666 NULL,
667 NULL,
668 prop, errp);
669
670 g_free(name);
671}
672
673
674
675
676
677
678
679
680
681
682
683void qdev_property_add_static(DeviceState *dev, Property *prop,
684 Error **errp)
685{
686 Error *local_err = NULL;
687 Object *obj = OBJECT(dev);
688
689 if (prop->info->create) {
690 prop->info->create(obj, prop, &local_err);
691 } else {
692
693
694
695
696
697 if (!prop->info->get && !prop->info->set) {
698 return;
699 }
700 object_property_add(obj, prop->name, prop->info->name,
701 prop->info->get, prop->info->set,
702 prop->info->release,
703 prop, &local_err);
704 }
705
706 if (local_err) {
707 error_propagate(errp, local_err);
708 return;
709 }
710
711 object_property_set_description(obj, prop->name,
712 prop->info->description,
713 &error_abort);
714
715 if (prop->set_default) {
716 prop->info->set_default_value(obj, prop);
717 }
718}
719
720
721
722
723void qdev_alias_all_properties(DeviceState *target, Object *source)
724{
725 ObjectClass *class;
726 Property *prop;
727
728 class = object_get_class(OBJECT(target));
729 do {
730 DeviceClass *dc = DEVICE_CLASS(class);
731
732 for (prop = dc->props; prop && prop->name; prop++) {
733 object_property_add_alias(source, prop->name,
734 OBJECT(target), prop->name,
735 &error_abort);
736 }
737 class = object_class_get_parent(class);
738 } while (class != object_class_by_name(TYPE_DEVICE));
739}
740
741static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
742{
743 GSList **list = opaque;
744 DeviceState *dev = (DeviceState *)object_dynamic_cast(OBJECT(obj),
745 TYPE_DEVICE);
746
747 if (dev == NULL) {
748 return 0;
749 }
750
751 if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) {
752 *list = g_slist_append(*list, dev);
753 }
754
755 return 0;
756}
757
758GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
759{
760 GSList *list = NULL;
761
762 object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);
763
764 return list;
765}
766
767static bool device_get_realized(Object *obj, Error **errp)
768{
769 DeviceState *dev = DEVICE(obj);
770 return dev->realized;
771}
772
773static bool check_only_migratable(Object *obj, Error **err)
774{
775 DeviceClass *dc = DEVICE_GET_CLASS(obj);
776
777 if (!vmstate_check_only_migratable(dc->vmsd)) {
778 error_setg(err, "Device %s is not migratable, but "
779 "--only-migratable was specified",
780 object_get_typename(obj));
781 return false;
782 }
783
784 return true;
785}
786
787static void device_set_realized(Object *obj, bool value, Error **errp)
788{
789 DeviceState *dev = DEVICE(obj);
790 DeviceClass *dc = DEVICE_GET_CLASS(dev);
791 HotplugHandler *hotplug_ctrl;
792 BusState *bus;
793 Error *local_err = NULL;
794 bool unattached_parent = false;
795 static int unattached_count;
796
797 if (dev->hotplugged && !dc->hotpluggable) {
798 error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
799 return;
800 }
801
802 if (value && !dev->realized) {
803 if (!check_only_migratable(obj, &local_err)) {
804 goto fail;
805 }
806
807 if (!obj->parent) {
808 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
809
810 object_property_add_child(container_get(qdev_get_machine(),
811 "/unattached"),
812 name, obj, &error_abort);
813 unattached_parent = true;
814 g_free(name);
815 }
816
817 hotplug_ctrl = qdev_get_hotplug_handler(dev);
818 if (hotplug_ctrl) {
819 hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err);
820 if (local_err != NULL) {
821 goto fail;
822 }
823 }
824
825 if (dc->realize) {
826 dc->realize(dev, &local_err);
827 }
828
829 if (local_err != NULL) {
830 goto fail;
831 }
832
833 DEVICE_LISTENER_CALL(realize, Forward, dev);
834
835 if (hotplug_ctrl) {
836 hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
837 }
838
839 if (local_err != NULL) {
840 goto post_realize_fail;
841 }
842
843
844
845
846
847 g_free(dev->canonical_path);
848 dev->canonical_path = object_get_canonical_path(OBJECT(dev));
849
850 if (qdev_get_vmsd(dev)) {
851 if (vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
852 dev->instance_id_alias,
853 dev->alias_required_for_version,
854 &local_err) < 0) {
855 goto post_realize_fail;
856 }
857 }
858
859 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
860 object_property_set_bool(OBJECT(bus), true, "realized",
861 &local_err);
862 if (local_err != NULL) {
863 goto child_realize_fail;
864 }
865 }
866 if (dev->hotplugged) {
867 device_reset(dev);
868 }
869 dev->pending_deleted_event = false;
870
871 if (hotplug_ctrl) {
872 hotplug_handler_post_plug(hotplug_ctrl, dev);
873 }
874 } else if (!value && dev->realized) {
875 Error **local_errp = NULL;
876 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
877 local_errp = local_err ? NULL : &local_err;
878 object_property_set_bool(OBJECT(bus), false, "realized",
879 local_errp);
880 }
881 if (qdev_get_vmsd(dev)) {
882 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
883 }
884 if (dc->unrealize) {
885 local_errp = local_err ? NULL : &local_err;
886 dc->unrealize(dev, local_errp);
887 }
888 dev->pending_deleted_event = true;
889 DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
890 }
891
892 if (local_err != NULL) {
893 goto fail;
894 }
895
896 dev->realized = value;
897 return;
898
899child_realize_fail:
900 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
901 object_property_set_bool(OBJECT(bus), false, "realized",
902 NULL);
903 }
904
905 if (qdev_get_vmsd(dev)) {
906 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
907 }
908
909post_realize_fail:
910 g_free(dev->canonical_path);
911 dev->canonical_path = NULL;
912 if (dc->unrealize) {
913 dc->unrealize(dev, NULL);
914 }
915
916fail:
917 error_propagate(errp, local_err);
918 if (unattached_parent) {
919 object_unparent(OBJECT(dev));
920 unattached_count--;
921 }
922}
923
924static bool device_get_hotpluggable(Object *obj, Error **errp)
925{
926 DeviceClass *dc = DEVICE_GET_CLASS(obj);
927 DeviceState *dev = DEVICE(obj);
928
929 return dc->hotpluggable && (dev->parent_bus == NULL ||
930 qbus_is_hotpluggable(dev->parent_bus));
931}
932
933static bool device_get_hotplugged(Object *obj, Error **err)
934{
935 DeviceState *dev = DEVICE(obj);
936
937 return dev->hotplugged;
938}
939
940static void device_initfn(Object *obj)
941{
942 DeviceState *dev = DEVICE(obj);
943 ObjectClass *class;
944 Property *prop;
945
946 if (qdev_hotplug) {
947 dev->hotplugged = 1;
948 qdev_hot_added = true;
949 }
950
951 dev->instance_id_alias = -1;
952 dev->realized = false;
953
954 object_property_add_bool(obj, "realized",
955 device_get_realized, device_set_realized, NULL);
956 object_property_add_bool(obj, "hotpluggable",
957 device_get_hotpluggable, NULL, NULL);
958 object_property_add_bool(obj, "hotplugged",
959 device_get_hotplugged, NULL,
960 &error_abort);
961
962 class = object_get_class(OBJECT(dev));
963 do {
964 for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
965 qdev_property_add_legacy(dev, prop, &error_abort);
966 qdev_property_add_static(dev, prop, &error_abort);
967 }
968 class = object_class_get_parent(class);
969 } while (class != object_class_by_name(TYPE_DEVICE));
970
971 object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
972 (Object **)&dev->parent_bus, NULL, 0,
973 &error_abort);
974 QLIST_INIT(&dev->gpios);
975}
976
977static void device_post_init(Object *obj)
978{
979 qdev_prop_set_globals(DEVICE(obj));
980}
981
982
983static void device_finalize(Object *obj)
984{
985 NamedGPIOList *ngl, *next;
986
987 DeviceState *dev = DEVICE(obj);
988
989 QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
990 QLIST_REMOVE(ngl, node);
991 qemu_free_irqs(ngl->in, ngl->num_in);
992 g_free(ngl->name);
993 g_free(ngl);
994
995
996
997 }
998
999
1000 if (dev->pending_deleted_event) {
1001 g_assert(dev->canonical_path);
1002
1003 qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path,
1004 &error_abort);
1005 g_free(dev->canonical_path);
1006 dev->canonical_path = NULL;
1007 }
1008
1009 qemu_opts_del(dev->opts);
1010}
1011
1012static void device_class_base_init(ObjectClass *class, void *data)
1013{
1014 DeviceClass *klass = DEVICE_CLASS(class);
1015
1016
1017
1018
1019 klass->props = NULL;
1020}
1021
1022static void device_unparent(Object *obj)
1023{
1024 DeviceState *dev = DEVICE(obj);
1025 BusState *bus;
1026
1027 if (dev->realized) {
1028 object_property_set_bool(obj, false, "realized", NULL);
1029 }
1030 while (dev->num_child_bus) {
1031 bus = QLIST_FIRST(&dev->child_bus);
1032 object_unparent(OBJECT(bus));
1033 }
1034 if (dev->parent_bus) {
1035 bus_remove_child(dev->parent_bus, dev);
1036 object_unref(OBJECT(dev->parent_bus));
1037 dev->parent_bus = NULL;
1038 }
1039}
1040
1041static void device_class_init(ObjectClass *class, void *data)
1042{
1043 DeviceClass *dc = DEVICE_CLASS(class);
1044
1045 class->unparent = device_unparent;
1046
1047
1048
1049
1050
1051
1052
1053 dc->hotpluggable = true;
1054 dc->user_creatable = true;
1055}
1056
1057void device_class_set_parent_reset(DeviceClass *dc,
1058 DeviceReset dev_reset,
1059 DeviceReset *parent_reset)
1060{
1061 *parent_reset = dc->reset;
1062 dc->reset = dev_reset;
1063}
1064
1065void device_class_set_parent_realize(DeviceClass *dc,
1066 DeviceRealize dev_realize,
1067 DeviceRealize *parent_realize)
1068{
1069 *parent_realize = dc->realize;
1070 dc->realize = dev_realize;
1071}
1072
1073void device_class_set_parent_unrealize(DeviceClass *dc,
1074 DeviceUnrealize dev_unrealize,
1075 DeviceUnrealize *parent_unrealize)
1076{
1077 *parent_unrealize = dc->unrealize;
1078 dc->unrealize = dev_unrealize;
1079}
1080
1081void device_reset(DeviceState *dev)
1082{
1083 DeviceClass *klass = DEVICE_GET_CLASS(dev);
1084
1085 if (klass->reset) {
1086 klass->reset(dev);
1087 }
1088}
1089
1090Object *qdev_get_machine(void)
1091{
1092 static Object *dev;
1093
1094 if (dev == NULL) {
1095 dev = container_get(object_get_root(), "/machine");
1096 }
1097
1098 return dev;
1099}
1100
1101static const TypeInfo device_type_info = {
1102 .name = TYPE_DEVICE,
1103 .parent = TYPE_OBJECT,
1104 .instance_size = sizeof(DeviceState),
1105 .instance_init = device_initfn,
1106 .instance_post_init = device_post_init,
1107 .instance_finalize = device_finalize,
1108 .class_base_init = device_class_base_init,
1109 .class_init = device_class_init,
1110 .abstract = true,
1111 .class_size = sizeof(DeviceClass),
1112};
1113
1114static void qdev_register_types(void)
1115{
1116 type_register_static(&device_type_info);
1117}
1118
1119type_init(qdev_register_types)
1120