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