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