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