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