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