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