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
836
837
838
839 g_free(dev->canonical_path);
840 dev->canonical_path = object_get_canonical_path(OBJECT(dev));
841
842 if (qdev_get_vmsd(dev)) {
843 if (vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
844 dev->instance_id_alias,
845 dev->alias_required_for_version,
846 &local_err) < 0) {
847 goto post_realize_fail;
848 }
849 }
850
851 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
852 object_property_set_bool(OBJECT(bus), true, "realized",
853 &local_err);
854 if (local_err != NULL) {
855 goto child_realize_fail;
856 }
857 }
858 if (dev->hotplugged) {
859 device_reset(dev);
860 }
861 dev->pending_deleted_event = false;
862
863 if (hotplug_ctrl) {
864 hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
865 if (local_err != NULL) {
866 goto child_realize_fail;
867 }
868 }
869
870 } else if (!value && dev->realized) {
871 Error **local_errp = NULL;
872 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
873 local_errp = local_err ? NULL : &local_err;
874 object_property_set_bool(OBJECT(bus), false, "realized",
875 local_errp);
876 }
877 if (qdev_get_vmsd(dev)) {
878 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
879 }
880 if (dc->unrealize) {
881 local_errp = local_err ? NULL : &local_err;
882 dc->unrealize(dev, local_errp);
883 }
884 dev->pending_deleted_event = true;
885 DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
886 }
887
888 if (local_err != NULL) {
889 goto fail;
890 }
891
892 dev->realized = value;
893 return;
894
895child_realize_fail:
896 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
897 object_property_set_bool(OBJECT(bus), false, "realized",
898 NULL);
899 }
900
901 if (qdev_get_vmsd(dev)) {
902 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
903 }
904
905post_realize_fail:
906 g_free(dev->canonical_path);
907 dev->canonical_path = NULL;
908 if (dc->unrealize) {
909 dc->unrealize(dev, NULL);
910 }
911
912fail:
913 error_propagate(errp, local_err);
914 if (unattached_parent) {
915 object_unparent(OBJECT(dev));
916 unattached_count--;
917 }
918}
919
920static bool device_get_hotpluggable(Object *obj, Error **errp)
921{
922 DeviceClass *dc = DEVICE_GET_CLASS(obj);
923 DeviceState *dev = DEVICE(obj);
924
925 return dc->hotpluggable && (dev->parent_bus == NULL ||
926 qbus_is_hotpluggable(dev->parent_bus));
927}
928
929static bool device_get_hotplugged(Object *obj, Error **err)
930{
931 DeviceState *dev = DEVICE(obj);
932
933 return dev->hotplugged;
934}
935
936static void device_initfn(Object *obj)
937{
938 DeviceState *dev = DEVICE(obj);
939 ObjectClass *class;
940 Property *prop;
941
942 if (qdev_hotplug) {
943 dev->hotplugged = 1;
944 qdev_hot_added = true;
945 }
946
947 dev->instance_id_alias = -1;
948 dev->realized = false;
949
950 object_property_add_bool(obj, "realized",
951 device_get_realized, device_set_realized, NULL);
952 object_property_add_bool(obj, "hotpluggable",
953 device_get_hotpluggable, NULL, NULL);
954 object_property_add_bool(obj, "hotplugged",
955 device_get_hotplugged, NULL,
956 &error_abort);
957
958 class = object_get_class(OBJECT(dev));
959 do {
960 for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
961 qdev_property_add_legacy(dev, prop, &error_abort);
962 qdev_property_add_static(dev, prop, &error_abort);
963 }
964 class = object_class_get_parent(class);
965 } while (class != object_class_by_name(TYPE_DEVICE));
966
967 object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
968 (Object **)&dev->parent_bus, NULL, 0,
969 &error_abort);
970 QLIST_INIT(&dev->gpios);
971}
972
973static void device_post_init(Object *obj)
974{
975 qdev_prop_set_globals(DEVICE(obj));
976}
977
978
979static void device_finalize(Object *obj)
980{
981 NamedGPIOList *ngl, *next;
982
983 DeviceState *dev = DEVICE(obj);
984
985 QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
986 QLIST_REMOVE(ngl, node);
987 qemu_free_irqs(ngl->in, ngl->num_in);
988 g_free(ngl->name);
989 g_free(ngl);
990
991
992
993 }
994
995
996 if (dev->pending_deleted_event) {
997 g_assert(dev->canonical_path);
998
999 qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path);
1000 g_free(dev->canonical_path);
1001 dev->canonical_path = NULL;
1002 }
1003
1004 qemu_opts_del(dev->opts);
1005}
1006
1007static void device_class_base_init(ObjectClass *class, void *data)
1008{
1009 DeviceClass *klass = DEVICE_CLASS(class);
1010
1011
1012
1013
1014 klass->props = NULL;
1015}
1016
1017static void device_unparent(Object *obj)
1018{
1019 DeviceState *dev = DEVICE(obj);
1020 BusState *bus;
1021
1022 if (dev->realized) {
1023 object_property_set_bool(obj, false, "realized", NULL);
1024 }
1025 while (dev->num_child_bus) {
1026 bus = QLIST_FIRST(&dev->child_bus);
1027 object_unparent(OBJECT(bus));
1028 }
1029 if (dev->parent_bus) {
1030 bus_remove_child(dev->parent_bus, dev);
1031 object_unref(OBJECT(dev->parent_bus));
1032 dev->parent_bus = NULL;
1033 }
1034}
1035
1036static void device_class_init(ObjectClass *class, void *data)
1037{
1038 DeviceClass *dc = DEVICE_CLASS(class);
1039
1040 class->unparent = device_unparent;
1041
1042
1043
1044
1045
1046
1047
1048 dc->hotpluggable = true;
1049 dc->user_creatable = true;
1050}
1051
1052void device_class_set_parent_reset(DeviceClass *dc,
1053 DeviceReset dev_reset,
1054 DeviceReset *parent_reset)
1055{
1056 *parent_reset = dc->reset;
1057 dc->reset = dev_reset;
1058}
1059
1060void device_class_set_parent_realize(DeviceClass *dc,
1061 DeviceRealize dev_realize,
1062 DeviceRealize *parent_realize)
1063{
1064 *parent_realize = dc->realize;
1065 dc->realize = dev_realize;
1066}
1067
1068void device_class_set_parent_unrealize(DeviceClass *dc,
1069 DeviceUnrealize dev_unrealize,
1070 DeviceUnrealize *parent_unrealize)
1071{
1072 *parent_unrealize = dc->unrealize;
1073 dc->unrealize = dev_unrealize;
1074}
1075
1076void device_reset(DeviceState *dev)
1077{
1078 DeviceClass *klass = DEVICE_GET_CLASS(dev);
1079
1080 if (klass->reset) {
1081 klass->reset(dev);
1082 }
1083}
1084
1085Object *qdev_get_machine(void)
1086{
1087 static Object *dev;
1088
1089 if (dev == NULL) {
1090 dev = container_get(object_get_root(), "/machine");
1091 }
1092
1093 return dev;
1094}
1095
1096static const TypeInfo device_type_info = {
1097 .name = TYPE_DEVICE,
1098 .parent = TYPE_OBJECT,
1099 .instance_size = sizeof(DeviceState),
1100 .instance_init = device_initfn,
1101 .instance_post_init = device_post_init,
1102 .instance_finalize = device_finalize,
1103 .class_base_init = device_class_base_init,
1104 .class_init = device_class_init,
1105 .abstract = true,
1106 .class_size = sizeof(DeviceClass),
1107};
1108
1109static void qdev_register_types(void)
1110{
1111 type_register_static(&device_type_info);
1112}
1113
1114type_init(qdev_register_types)
1115