]> git.proxmox.com Git - mirror_qemu.git/blame - hw/core/qdev.c
qapi-schema: remove legacy<> from doc
[mirror_qemu.git] / hw / core / qdev.c
CommitLineData
aae9460e
PB
1/*
2 * Dynamic device configuration and creation.
3 *
4 * Copyright (c) 2009 CodeSourcery
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
8167ee88 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
aae9460e
PB
18 */
19
20/* The theory here is that it should be possible to create a machine without
21 knowledge of specific devices. Historically board init routines have
22 passed a bunch of arguments to each device, requiring the board know
23 exactly which device it is dealing with. This file provides an abstract
24 API for device configuration and initialization. Devices will generally
25 inherit from a particular bus (e.g. PCI or I2C) rather than
26 this API directly. */
27
83c9f4ca 28#include "hw/qdev.h"
6b1566cb 29#include "hw/fw-path-provider.h"
9c17d615 30#include "sysemu/sysemu.h"
7b1b5d19 31#include "qapi/error.h"
b4a42f81 32#include "qapi/qmp/qerror.h"
7b1b5d19 33#include "qapi/visitor.h"
0402a5d6 34#include "qapi/qmp/qjson.h"
d49b6836 35#include "qemu/error-report.h"
0ee4de6c 36#include "hw/hotplug.h"
b7454548 37#include "hw/boards.h"
24b699fb 38#include "qapi-event.h"
aae9460e 39
ee46d8a5 40int qdev_hotplug = 0;
0ac8ef71
AW
41static bool qdev_hot_added = false;
42static bool qdev_hot_removed = false;
3418bd25 43
4be9f0d1
AL
44const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
45{
6e008585
AL
46 DeviceClass *dc = DEVICE_GET_CLASS(dev);
47 return dc->vmsd;
4be9f0d1
AL
48}
49
4be9f0d1
AL
50const char *qdev_fw_name(DeviceState *dev)
51{
6e008585 52 DeviceClass *dc = DEVICE_GET_CLASS(dev);
4be9f0d1 53
6e008585
AL
54 if (dc->fw_name) {
55 return dc->fw_name;
4be9f0d1
AL
56 }
57
58 return object_get_typename(OBJECT(dev));
59}
60
ca2cc788
PB
61static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
62 Error **errp);
63
0866aca1 64static void bus_remove_child(BusState *bus, DeviceState *child)
0c17542d 65{
0866aca1
AL
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);
9d127820
PB
74
75 /* This gives back ownership of kid->child back to us. */
0866aca1 76 object_property_del(OBJECT(bus), name, NULL);
9d127820 77 object_unref(OBJECT(kid->child));
0866aca1
AL
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));
0c17542d 88
0866aca1
AL
89 kid->index = bus->max_index++;
90 kid->child = child;
9d127820 91 object_ref(OBJECT(kid->child));
a5296ca9 92
0866aca1
AL
93 QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
94
9d127820 95 /* This transfers ownership of kid->child to the property. */
0866aca1
AL
96 snprintf(name, sizeof(name), "child[%d]", kid->index);
97 object_property_add_link(OBJECT(bus), name,
98 object_get_typename(OBJECT(child)),
39f72ef9
SH
99 (Object **)&kid->child,
100 NULL, /* read-only property */
101 0, /* return ownership on prop deletion */
102 NULL);
0866aca1
AL
103}
104
105void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
106{
9fbe6127 107 dev->parent_bus = bus;
62d7ba66 108 object_ref(OBJECT(bus));
0866aca1 109 bus_add_child(bus, dev);
0c17542d
MA
110}
111
431bbb26
IM
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);
431bbb26
IM
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
0210afe6
MA
130/* Create a new device. This only initializes the device state
131 structure and allows properties to be set. The device still needs
132 to be realized. See qdev-core.h. */
02e2da45 133DeviceState *qdev_create(BusState *bus, const char *name)
0bcdeda7
BS
134{
135 DeviceState *dev;
136
137 dev = qdev_try_create(bus, name);
138 if (!dev) {
e92714c7 139 if (bus) {
312fd5f2 140 error_report("Unknown device '%s' for bus '%s'", name,
23e3fbec 141 object_get_typename(OBJECT(bus)));
e92714c7 142 } else {
312fd5f2 143 error_report("Unknown device '%s' for default sysbus", name);
e92714c7 144 }
01ed1d52 145 abort();
0bcdeda7
BS
146 }
147
148 return dev;
149}
150
da57febf 151DeviceState *qdev_try_create(BusState *bus, const char *type)
aae9460e 152{
9fbe6127
AL
153 DeviceState *dev;
154
da57febf 155 if (object_class_by_name(type) == NULL) {
4ed658ca
AF
156 return NULL;
157 }
da57febf 158 dev = DEVICE(object_new(type));
9fbe6127
AL
159 if (!dev) {
160 return NULL;
161 }
162
10c4c98a 163 if (!bus) {
68694897 164 bus = sysbus_get_default();
10c4c98a
GH
165 }
166
9fbe6127 167 qdev_set_parent_bus(dev, bus);
b09995ae 168 object_unref(OBJECT(dev));
9fbe6127 169 return dev;
aae9460e
PB
170}
171
707ff800
PD
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
a7737e44 222static void device_realize(DeviceState *dev, Error **errp)
249d4172
AF
223{
224 DeviceClass *dc = DEVICE_GET_CLASS(dev);
da57febf 225
249d4172
AF
226 if (dc->init) {
227 int rc = dc->init(dev);
228 if (rc < 0) {
a7737e44 229 error_setg(errp, "Device initialization failed.");
249d4172
AF
230 return;
231 }
5ab28c83 232 }
02e2da45
PB
233}
234
fe6c2117
AF
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
4d2ffa08
JK
248void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
249 int required_for_version)
250{
7983c8a3 251 assert(!dev->realized);
4d2ffa08
JK
252 dev->instance_id_alias = alias_id;
253 dev->alias_required_for_version = required_for_version;
254}
255
c06b2ffb 256HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
7716b8ca
IM
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
56f9107e 273void qdev_unplug(DeviceState *dev, Error **errp)
3418bd25 274{
6e008585 275 DeviceClass *dc = DEVICE_GET_CLASS(dev);
7716b8ca
IM
276 HotplugHandler *hotplug_ctrl;
277 HotplugHandlerClass *hdc;
6e008585 278
39b888bd 279 if (dev->parent_bus && !qbus_is_hotpluggable(dev->parent_bus)) {
c6bd8c70 280 error_setg(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
56f9107e 281 return;
3418bd25 282 }
593831de 283
1a37eca1 284 if (!dc->hotpluggable) {
c6bd8c70
MA
285 error_setg(errp, QERR_DEVICE_NO_HOTPLUG,
286 object_get_typename(OBJECT(dev)));
1a37eca1
IM
287 return;
288 }
289
0ac8ef71
AW
290 qdev_hot_removed = true;
291
7716b8ca
IM
292 hotplug_ctrl = qdev_get_hotplug_handler(dev);
293 /* hotpluggable device MUST have HotplugHandler, if it doesn't
294 * then something is very wrong with it */
295 g_assert(hotplug_ctrl);
296
297 /* If device supports async unplug just request it to be done,
298 * otherwise just remove it synchronously */
299 hdc = HOTPLUG_HANDLER_GET_CLASS(hotplug_ctrl);
300 if (hdc->unplug_request) {
301 hotplug_handler_unplug_request(hotplug_ctrl, dev, errp);
5e954943 302 } else {
7716b8ca 303 hotplug_handler_unplug(hotplug_ctrl, dev, errp);
56f9107e 304 }
3418bd25
GH
305}
306
ec990eb6
AL
307static int qdev_reset_one(DeviceState *dev, void *opaque)
308{
94afdadc 309 device_reset(dev);
ec990eb6
AL
310
311 return 0;
312}
313
b4694b7c
IY
314static int qbus_reset_one(BusState *bus, void *opaque)
315{
0d936928
AL
316 BusClass *bc = BUS_GET_CLASS(bus);
317 if (bc->reset) {
dcc20931 318 bc->reset(bus);
b4694b7c
IY
319 }
320 return 0;
321}
322
5af0a04b
IY
323void qdev_reset_all(DeviceState *dev)
324{
dcc20931 325 qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
5af0a04b
IY
326}
327
d0508c36
PB
328void qbus_reset_all(BusState *bus)
329{
dcc20931 330 qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
d0508c36
PB
331}
332
80376c3f
IY
333void qbus_reset_all_fn(void *opaque)
334{
335 BusState *bus = opaque;
d0508c36 336 qbus_reset_all(bus);
80376c3f
IY
337}
338
3418bd25 339/* can be used as ->unplug() callback for the simple cases */
014176f9
IM
340void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
341 DeviceState *dev, Error **errp)
342{
2d9a982f
IM
343 /* just zap it */
344 object_unparent(OBJECT(dev));
014176f9 345}
3b29a101 346
0210afe6
MA
347/*
348 * Realize @dev.
349 * Device properties should be set before calling this function. IRQs
350 * and MMIO regions should be connected/mapped after calling this
351 * function.
352 * On failure, report an error with error_report() and terminate the
353 * program. This is okay during machine creation. Don't use for
354 * hotplug, because there callers need to recover from failure.
355 * Exception: if you know the device's init() callback can't fail,
356 * then qdev_init_nofail() can't fail either, and is therefore usable
357 * even then. But relying on the device implementation that way is
358 * somewhat unclean, and best avoided.
359 */
e23a1b33
MA
360void qdev_init_nofail(DeviceState *dev)
361{
c4bacafb 362 Error *err = NULL;
7de3abe5 363
c4bacafb
MA
364 assert(!dev->realized);
365
366 object_property_set_bool(OBJECT(dev), true, "realized", &err);
367 if (err) {
368 error_report("Initialization of device %s failed: %s",
369 object_get_typename(OBJECT(dev)),
370 error_get_pretty(err));
bd6c9a61
MA
371 exit(1);
372 }
e23a1b33
MA
373}
374
3418bd25
GH
375void qdev_machine_creation_done(void)
376{
377 /*
378 * ok, initial machine setup is done, starting from now we can
379 * only create hotpluggable devices
380 */
381 qdev_hotplug = 1;
382}
383
0ac8ef71
AW
384bool qdev_machine_modified(void)
385{
386 return qdev_hot_added || qdev_hot_removed;
387}
388
02e2da45 389BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 390{
02e2da45 391 return dev->parent_bus;
aae9460e
PB
392}
393
a5f54290
PC
394static NamedGPIOList *qdev_get_named_gpio_list(DeviceState *dev,
395 const char *name)
396{
397 NamedGPIOList *ngl;
398
399 QLIST_FOREACH(ngl, &dev->gpios, node) {
400 /* NULL is a valid and matchable name, otherwise do a normal
401 * strcmp match.
402 */
403 if ((!ngl->name && !name) ||
404 (name && ngl->name && strcmp(name, ngl->name) == 0)) {
405 return ngl;
406 }
407 }
408
409 ngl = g_malloc0(sizeof(*ngl));
410 ngl->name = g_strdup(name);
411 QLIST_INSERT_HEAD(&dev->gpios, ngl, node);
412 return ngl;
413}
414
415void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler,
416 const char *name, int n)
417{
a69bef1c 418 int i;
a5f54290 419 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
a69bef1c 420 char *propname = g_strdup_printf("%s[*]", name ? name : "unnamed-gpio-in");
a5f54290 421
b235a71f 422 assert(gpio_list->num_out == 0 || !name);
a5f54290
PC
423 gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler,
424 dev, n);
a69bef1c
PC
425
426 for (i = gpio_list->num_in; i < gpio_list->num_in + n; i++) {
427 object_property_add_child(OBJECT(dev), propname,
428 OBJECT(gpio_list->in[i]), &error_abort);
429 }
430 g_free(propname);
431
a5f54290
PC
432 gpio_list->num_in += n;
433}
434
aae9460e
PB
435void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
436{
a5f54290
PC
437 qdev_init_gpio_in_named(dev, handler, NULL, n);
438}
439
440void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins,
441 const char *name, int n)
442{
688b057a 443 int i;
a5f54290 444 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
688b057a 445 char *propname = g_strdup_printf("%s[*]", name ? name : "unnamed-gpio-out");
a5f54290 446
b235a71f 447 assert(gpio_list->num_in == 0 || !name);
aef0869e 448 gpio_list->num_out += n;
688b057a
PC
449
450 for (i = 0; i < n; ++i) {
451 memset(&pins[i], 0, sizeof(*pins));
452 object_property_add_link(OBJECT(dev), propname, TYPE_IRQ,
453 (Object **)&pins[i],
454 object_property_allow_set_link,
455 OBJ_PROP_LINK_UNREF_ON_RELEASE,
456 &error_abort);
457 }
458 g_free(propname);
aae9460e
PB
459}
460
461void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
462{
a5f54290
PC
463 qdev_init_gpio_out_named(dev, pins, NULL, n);
464}
465
466qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n)
467{
468 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
469
470 assert(n >= 0 && n < gpio_list->num_in);
471 return gpio_list->in[n];
aae9460e
PB
472}
473
474qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
475{
a5f54290
PC
476 return qdev_get_gpio_in_named(dev, NULL, n);
477}
478
479void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
480 qemu_irq pin)
481{
02757df2
PC
482 char *propname = g_strdup_printf("%s[%d]",
483 name ? name : "unnamed-gpio-out", n);
484 if (pin) {
485 /* We need a name for object_property_set_link to work. If the
486 * object has a parent, object_property_add_child will come back
487 * with an error without doing anything. If it has none, it will
488 * never fail. So we can just call it with a NULL Error pointer.
489 */
88950eef
AF
490 object_property_add_child(container_get(qdev_get_machine(),
491 "/unattached"),
492 "non-qdev-gpio[*]", OBJECT(pin), NULL);
02757df2
PC
493 }
494 object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort);
495 g_free(propname);
aae9460e
PB
496}
497
b7973186
AG
498qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n)
499{
500 char *propname = g_strdup_printf("%s[%d]",
501 name ? name : "unnamed-gpio-out", n);
502
503 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
504 NULL);
505
506 return ret;
507}
508
0c24db2b
PC
509/* disconnect a GPIO ouput, returning the disconnected input (if any) */
510
511static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev,
512 const char *name, int n)
513{
514 char *propname = g_strdup_printf("%s[%d]",
515 name ? name : "unnamed-gpio-out", n);
516
517 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
518 NULL);
519 if (ret) {
520 object_property_set_link(OBJECT(dev), NULL, propname, NULL);
521 }
522 g_free(propname);
523 return ret;
524}
a5f54290 525
0c24db2b
PC
526qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt,
527 const char *name, int n)
528{
529 qemu_irq disconnected = qdev_disconnect_gpio_out_named(dev, name, n);
530 qdev_connect_gpio_out_named(dev, name, n, icpt);
531 return disconnected;
aae9460e
PB
532}
533
534void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
535{
a5f54290 536 qdev_connect_gpio_out_named(dev, NULL, n, pin);
aae9460e
PB
537}
538
17a96a14
PC
539void qdev_pass_gpios(DeviceState *dev, DeviceState *container,
540 const char *name)
541{
542 int i;
543 NamedGPIOList *ngl = qdev_get_named_gpio_list(dev, name);
544
545 for (i = 0; i < ngl->num_in; i++) {
546 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-in";
547 char *propname = g_strdup_printf("%s[%d]", nm, i);
548
549 object_property_add_alias(OBJECT(container), propname,
550 OBJECT(dev), propname,
551 &error_abort);
6bc5cf92 552 g_free(propname);
17a96a14
PC
553 }
554 for (i = 0; i < ngl->num_out; i++) {
555 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-out";
556 char *propname = g_strdup_printf("%s[%d]", nm, i);
557
558 object_property_add_alias(OBJECT(container), propname,
559 OBJECT(dev), propname,
560 &error_abort);
6bc5cf92 561 g_free(propname);
17a96a14
PC
562 }
563 QLIST_REMOVE(ngl, node);
564 QLIST_INSERT_HEAD(&container->gpios, ngl, node);
565}
566
02e2da45 567BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 568{
02e2da45 569 BusState *bus;
4d6ae674 570
72cf2d4f 571 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 572 if (strcmp(name, bus->name) == 0) {
02e2da45 573 return bus;
4d6ae674
PB
574 }
575 }
576 return NULL;
577}
578
0293214b
PB
579int qbus_walk_children(BusState *bus,
580 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
581 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
582 void *opaque)
81699d8a 583{
0866aca1 584 BusChild *kid;
81699d8a
AL
585 int err;
586
0293214b
PB
587 if (pre_busfn) {
588 err = pre_busfn(bus, opaque);
81699d8a
AL
589 if (err) {
590 return err;
591 }
592 }
593
0866aca1 594 QTAILQ_FOREACH(kid, &bus->children, sibling) {
0293214b
PB
595 err = qdev_walk_children(kid->child,
596 pre_devfn, pre_busfn,
597 post_devfn, post_busfn, opaque);
81699d8a
AL
598 if (err < 0) {
599 return err;
600 }
601 }
602
0293214b
PB
603 if (post_busfn) {
604 err = post_busfn(bus, opaque);
605 if (err) {
606 return err;
607 }
608 }
609
81699d8a
AL
610 return 0;
611}
612
0293214b
PB
613int qdev_walk_children(DeviceState *dev,
614 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
615 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
616 void *opaque)
81699d8a
AL
617{
618 BusState *bus;
619 int err;
620
0293214b
PB
621 if (pre_devfn) {
622 err = pre_devfn(dev, opaque);
81699d8a
AL
623 if (err) {
624 return err;
625 }
626 }
627
628 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
0293214b
PB
629 err = qbus_walk_children(bus, pre_devfn, pre_busfn,
630 post_devfn, post_busfn, opaque);
81699d8a
AL
631 if (err < 0) {
632 return err;
633 }
634 }
635
0293214b
PB
636 if (post_devfn) {
637 err = post_devfn(dev, opaque);
638 if (err) {
639 return err;
640 }
641 }
642
81699d8a
AL
643 return 0;
644}
645
a2ee6b4f 646DeviceState *qdev_find_recursive(BusState *bus, const char *id)
3418bd25 647{
0866aca1
AL
648 BusChild *kid;
649 DeviceState *ret;
3418bd25
GH
650 BusState *child;
651
0866aca1
AL
652 QTAILQ_FOREACH(kid, &bus->children, sibling) {
653 DeviceState *dev = kid->child;
654
655 if (dev->id && strcmp(dev->id, id) == 0) {
3418bd25 656 return dev;
0866aca1
AL
657 }
658
3418bd25
GH
659 QLIST_FOREACH(child, &dev->child_bus, sibling) {
660 ret = qdev_find_recursive(child, id);
661 if (ret) {
662 return ret;
663 }
664 }
665 }
666 return NULL;
667}
668
013e1182 669static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
02e2da45 670{
ac7d1ba6 671 const char *typename = object_get_typename(OBJECT(bus));
61de3676 672 BusClass *bc;
d271de9f 673 char *buf;
61de3676 674 int i, len, bus_id;
02e2da45 675
013e1182
PB
676 bus->parent = parent;
677
678 if (name) {
679 bus->name = g_strdup(name);
ac7d1ba6 680 } else if (bus->parent && bus->parent->id) {
61de3676
AG
681 /* parent device has id -> use it plus parent-bus-id for bus name */
682 bus_id = bus->parent->num_child_bus;
683
ac7d1ba6 684 len = strlen(bus->parent->id) + 16;
7267c094 685 buf = g_malloc(len);
61de3676 686 snprintf(buf, len, "%s.%d", bus->parent->id, bus_id);
d271de9f
GH
687 bus->name = buf;
688 } else {
61de3676
AG
689 /* no id -> use lowercase bus type plus global bus-id for bus name */
690 bc = BUS_GET_CLASS(bus);
691 bus_id = bc->automatic_ids++;
692
0d936928 693 len = strlen(typename) + 16;
7267c094 694 buf = g_malloc(len);
61de3676
AG
695 len = snprintf(buf, len, "%s.%d", typename, bus_id);
696 for (i = 0; i < len; i++) {
bb87ece5 697 buf[i] = qemu_tolower(buf[i]);
61de3676 698 }
d271de9f
GH
699 bus->name = buf;
700 }
701
ac7d1ba6
AL
702 if (bus->parent) {
703 QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
704 bus->parent->num_child_bus++;
705 object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
b09995ae 706 object_unref(OBJECT(bus));
8185d216 707 } else if (bus != sysbus_get_default()) {
80376c3f
IY
708 /* TODO: once all bus devices are qdevified,
709 only reset handler for main_system_bus should be registered here. */
710 qemu_register_reset(qbus_reset_all_fn, bus);
02e2da45 711 }
cd739fb6
GH
712}
713
6853d27a
PB
714static void bus_unparent(Object *obj)
715{
716 BusState *bus = BUS(obj);
717 BusChild *kid;
718
719 while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
720 DeviceState *dev = kid->child;
02a5c4c9 721 object_unparent(OBJECT(dev));
6853d27a
PB
722 }
723 if (bus->parent) {
724 QLIST_REMOVE(bus, sibling);
725 bus->parent->num_child_bus--;
726 bus->parent = NULL;
727 } else {
728 assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
729 qemu_unregister_reset(qbus_reset_all_fn, bus);
730 }
731}
732
a7737e44 733static bool bus_get_realized(Object *obj, Error **errp)
02e7f85d
BD
734{
735 BusState *bus = BUS(obj);
736
737 return bus->realized;
738}
739
a7737e44 740static void bus_set_realized(Object *obj, bool value, Error **errp)
02e7f85d
BD
741{
742 BusState *bus = BUS(obj);
743 BusClass *bc = BUS_GET_CLASS(bus);
5942a190 744 BusChild *kid;
02e7f85d
BD
745 Error *local_err = NULL;
746
747 if (value && !bus->realized) {
748 if (bc->realize) {
749 bc->realize(bus, &local_err);
02e7f85d 750 }
5942a190
PB
751
752 /* TODO: recursive realization */
02e7f85d 753 } else if (!value && bus->realized) {
5942a190
PB
754 QTAILQ_FOREACH(kid, &bus->children, sibling) {
755 DeviceState *dev = kid->child;
756 object_property_set_bool(OBJECT(dev), false, "realized",
757 &local_err);
758 if (local_err != NULL) {
759 break;
760 }
761 }
762 if (bc->unrealize && local_err == NULL) {
02e7f85d 763 bc->unrealize(bus, &local_err);
02e7f85d
BD
764 }
765 }
766
b7b34d05
PB
767 if (local_err != NULL) {
768 error_propagate(errp, local_err);
769 return;
770 }
02e7f85d 771
b7b34d05 772 bus->realized = value;
02e7f85d
BD
773}
774
fb17dfe0 775void qbus_create_inplace(void *bus, size_t size, const char *typename,
0d936928 776 DeviceState *parent, const char *name)
cd739fb6 777{
213f0c4f 778 object_initialize(bus, size, typename);
013e1182 779 qbus_realize(bus, parent, name);
02e2da45 780}
cae4956e 781
0d936928 782BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
2da8bb92 783{
cd739fb6
GH
784 BusState *bus;
785
0d936928 786 bus = BUS(object_new(typename));
013e1182 787 qbus_realize(bus, parent, name);
ac7d1ba6 788
02e2da45 789 return bus;
2da8bb92
IY
790}
791
0d936928
AL
792static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
793{
794 BusClass *bc = BUS_GET_CLASS(bus);
795
796 if (bc->get_fw_dev_path) {
797 return bc->get_fw_dev_path(dev);
131ec1bd 798 }
0d936928
AL
799
800 return NULL;
131ec1bd
GH
801}
802
6b1566cb
PB
803static char *qdev_get_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
804{
805 Object *obj = OBJECT(dev);
806 char *d = NULL;
807
808 while (!d && obj->parent) {
809 obj = obj->parent;
810 d = fw_path_provider_try_get_dev_path(obj, bus, dev);
811 }
812 return d;
813}
814
0be63901
GA
815char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
816{
817 Object *obj = OBJECT(dev);
818
819 return fw_path_provider_try_get_dev_path(obj, bus, dev);
820}
821
1ca4d09a
GN
822static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
823{
824 int l = 0;
825
826 if (dev && dev->parent_bus) {
827 char *d;
828 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
6b1566cb
PB
829 d = qdev_get_fw_dev_path_from_handler(dev->parent_bus, dev);
830 if (!d) {
831 d = bus_get_fw_dev_path(dev->parent_bus, dev);
832 }
0d936928 833 if (d) {
1ca4d09a 834 l += snprintf(p + l, size - l, "%s", d);
7267c094 835 g_free(d);
1ca4d09a 836 } else {
bbfa18fc 837 return l;
1ca4d09a
GN
838 }
839 }
840 l += snprintf(p + l , size - l, "/");
841
842 return l;
843}
844
845char* qdev_get_fw_dev_path(DeviceState *dev)
846{
847 char path[128];
848 int l;
849
850 l = qdev_get_fw_dev_path_helper(dev, path, 128);
851
852 path[l-1] = '\0';
853
a5cf8262 854 return g_strdup(path);
1ca4d09a 855}
85ed303b 856
09e5ab63 857char *qdev_get_dev_path(DeviceState *dev)
85ed303b 858{
0d936928 859 BusClass *bc;
09e5ab63
AL
860
861 if (!dev || !dev->parent_bus) {
862 return NULL;
863 }
864
0d936928
AL
865 bc = BUS_GET_CLASS(dev->parent_bus);
866 if (bc->get_dev_path) {
867 return bc->get_dev_path(dev);
09e5ab63
AL
868 }
869
870 return NULL;
44677ded 871}
a5296ca9
AL
872
873/**
874 * Legacy property handling
875 */
876
57c9fafe 877static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
a5296ca9
AL
878 const char *name, Error **errp)
879{
57c9fafe 880 DeviceState *dev = DEVICE(obj);
a5296ca9
AL
881 Property *prop = opaque;
882
e3cb6ba6
PB
883 char buffer[1024];
884 char *ptr = buffer;
a5296ca9 885
e3cb6ba6
PB
886 prop->info->print(dev, prop, buffer, sizeof(buffer));
887 visit_type_str(v, &ptr, name, errp);
a5296ca9
AL
888}
889
a5296ca9
AL
890/**
891 * @qdev_add_legacy_property - adds a legacy property
892 *
893 * Do not use this is new code! Properties added through this interface will
ca2cc788 894 * be given names and types in the "legacy" namespace.
a5296ca9 895 *
68ee3569
PB
896 * Legacy properties are string versions of other OOM properties. The format
897 * of the string depends on the property type.
a5296ca9 898 */
f5a014d2
SW
899static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
900 Error **errp)
a5296ca9 901{
7ce7ffe0 902 gchar *name;
a5296ca9 903
f3be016d 904 /* Register pointer properties as legacy properties */
03ff7770 905 if (!prop->info->print && prop->info->get) {
68ee3569
PB
906 return;
907 }
f3be016d 908
ca2cc788 909 name = g_strdup_printf("legacy-%s", prop->name);
7ce7ffe0 910 object_property_add(OBJECT(dev), name, "str",
68ee3569 911 prop->info->print ? qdev_get_legacy_property : prop->info->get,
03ff7770 912 NULL,
57c9fafe
AL
913 NULL,
914 prop, errp);
a5296ca9 915
ca2cc788
PB
916 g_free(name);
917}
918
919/**
920 * @qdev_property_add_static - add a @Property to a device.
921 *
922 * Static properties access data in a struct. The actual type of the
923 * property and the field depends on the property type.
924 */
925void qdev_property_add_static(DeviceState *dev, Property *prop,
926 Error **errp)
927{
fdae245f
PB
928 Error *local_err = NULL;
929 Object *obj = OBJECT(dev);
930
d822979b
PB
931 /*
932 * TODO qdev_prop_ptr does not have getters or setters. It must
933 * go now that it can be replaced with links. The test should be
934 * removed along with it: all static properties are read/write.
935 */
936 if (!prop->info->get && !prop->info->set) {
937 return;
938 }
939
fdae245f 940 object_property_add(obj, prop->name, prop->info->name,
57c9fafe 941 prop->info->get, prop->info->set,
dd0ba250 942 prop->info->release,
fdae245f
PB
943 prop, &local_err);
944
945 if (local_err) {
946 error_propagate(errp, local_err);
947 return;
948 }
b8c9cd5c
GA
949
950 object_property_set_description(obj, prop->name,
951 prop->info->description,
952 &error_abort);
953
fdae245f
PB
954 if (prop->qtype == QTYPE_NONE) {
955 return;
956 }
957
958 if (prop->qtype == QTYPE_QBOOL) {
5433a0a8 959 object_property_set_bool(obj, prop->defval, prop->name, &error_abort);
fdae245f
PB
960 } else if (prop->info->enum_table) {
961 object_property_set_str(obj, prop->info->enum_table[prop->defval],
5433a0a8 962 prop->name, &error_abort);
fdae245f 963 } else if (prop->qtype == QTYPE_QINT) {
5433a0a8 964 object_property_set_int(obj, prop->defval, prop->name, &error_abort);
fdae245f 965 }
6a146eba 966}
1de81d28 967
67cc7e0a
SH
968/* @qdev_alias_all_properties - Add alias properties to the source object for
969 * all qdev properties on the target DeviceState.
970 */
971void qdev_alias_all_properties(DeviceState *target, Object *source)
972{
973 ObjectClass *class;
974 Property *prop;
975
976 class = object_get_class(OBJECT(target));
977 do {
978 DeviceClass *dc = DEVICE_CLASS(class);
979
980 for (prop = dc->props; prop && prop->name; prop++) {
981 object_property_add_alias(source, prop->name,
982 OBJECT(target), prop->name,
983 &error_abort);
984 }
985 class = object_class_get_parent(class);
986 } while (class != object_class_by_name(TYPE_DEVICE));
987}
988
4cae4d5a 989static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
66e56b13
ZG
990{
991 GSList **list = opaque;
09d56017
JL
992 DeviceState *dev = (DeviceState *)object_dynamic_cast(OBJECT(obj),
993 TYPE_DEVICE);
994
995 if (dev == NULL) {
996 return 0;
997 }
66e56b13
ZG
998
999 if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) {
1000 *list = g_slist_append(*list, dev);
1001 }
1002
66e56b13
ZG
1003 return 0;
1004}
1005
4cae4d5a
MA
1006GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
1007{
1008 GSList *list = NULL;
1009
1010 object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);
1011
1012 return list;
1013}
1014
a7737e44 1015static bool device_get_realized(Object *obj, Error **errp)
249d4172
AF
1016{
1017 DeviceState *dev = DEVICE(obj);
1018 return dev->realized;
1019}
1020
a7737e44 1021static void device_set_realized(Object *obj, bool value, Error **errp)
249d4172
AF
1022{
1023 DeviceState *dev = DEVICE(obj);
1024 DeviceClass *dc = DEVICE_GET_CLASS(dev);
7716b8ca 1025 HotplugHandler *hotplug_ctrl;
5c21ce77 1026 BusState *bus;
249d4172
AF
1027 Error *local_err = NULL;
1028
1a37eca1 1029 if (dev->hotplugged && !dc->hotpluggable) {
c6bd8c70 1030 error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
1a37eca1
IM
1031 return;
1032 }
1033
249d4172 1034 if (value && !dev->realized) {
d578029e 1035 if (!obj->parent) {
249d4172
AF
1036 static int unattached_count;
1037 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
1038
1039 object_property_add_child(container_get(qdev_get_machine(),
1040 "/unattached"),
d578029e 1041 name, obj, &error_abort);
249d4172
AF
1042 g_free(name);
1043 }
1044
a7ddba52
IM
1045 if (dc->realize) {
1046 dc->realize(dev, &local_err);
1047 }
1048
1d45a705
GA
1049 if (local_err != NULL) {
1050 goto fail;
1051 }
1052
707ff800
PD
1053 DEVICE_LISTENER_CALL(realize, Forward, dev);
1054
7716b8ca
IM
1055 hotplug_ctrl = qdev_get_hotplug_handler(dev);
1056 if (hotplug_ctrl) {
1057 hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
5e954943
IM
1058 }
1059
1d45a705
GA
1060 if (local_err != NULL) {
1061 goto post_realize_fail;
1062 }
1063
1064 if (qdev_get_vmsd(dev)) {
249d4172
AF
1065 vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
1066 dev->instance_id_alias,
1067 dev->alias_required_for_version);
1068 }
1d45a705
GA
1069
1070 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
1071 object_property_set_bool(OBJECT(bus), true, "realized",
5c21ce77 1072 &local_err);
1d45a705
GA
1073 if (local_err != NULL) {
1074 goto child_realize_fail;
5c21ce77
BD
1075 }
1076 }
1d45a705 1077 if (dev->hotplugged) {
249d4172
AF
1078 device_reset(dev);
1079 }
352e8da7 1080 dev->pending_deleted_event = false;
249d4172 1081 } else if (!value && dev->realized) {
cd4520ad 1082 Error **local_errp = NULL;
5c21ce77 1083 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
cd4520ad 1084 local_errp = local_err ? NULL : &local_err;
5c21ce77 1085 object_property_set_bool(OBJECT(bus), false, "realized",
cd4520ad 1086 local_errp);
5c21ce77 1087 }
cd4520ad 1088 if (qdev_get_vmsd(dev)) {
fe6c2117
AF
1089 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
1090 }
cd4520ad
GA
1091 if (dc->unrealize) {
1092 local_errp = local_err ? NULL : &local_err;
1093 dc->unrealize(dev, local_errp);
249d4172 1094 }
352e8da7 1095 dev->pending_deleted_event = true;
707ff800 1096 DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
249d4172
AF
1097 }
1098
1099 if (local_err != NULL) {
1d45a705 1100 goto fail;
249d4172
AF
1101 }
1102
1103 dev->realized = value;
1d45a705
GA
1104 return;
1105
1106child_realize_fail:
1107 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
1108 object_property_set_bool(OBJECT(bus), false, "realized",
1109 NULL);
1110 }
1111
1112 if (qdev_get_vmsd(dev)) {
1113 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
1114 }
1115
1116post_realize_fail:
1117 if (dc->unrealize) {
1118 dc->unrealize(dev, NULL);
1119 }
1120
1121fail:
1122 error_propagate(errp, local_err);
1123 return;
249d4172
AF
1124}
1125
a7737e44 1126static bool device_get_hotpluggable(Object *obj, Error **errp)
1a37eca1
IM
1127{
1128 DeviceClass *dc = DEVICE_GET_CLASS(obj);
1129 DeviceState *dev = DEVICE(obj);
1130
2b81b35f 1131 return dc->hotpluggable && (dev->parent_bus == NULL ||
39b888bd 1132 qbus_is_hotpluggable(dev->parent_bus));
1a37eca1
IM
1133}
1134
d012ffc1
IM
1135static bool device_get_hotplugged(Object *obj, Error **err)
1136{
1137 DeviceState *dev = DEVICE(obj);
1138
1139 return dev->hotplugged;
1140}
1141
1142static void device_set_hotplugged(Object *obj, bool value, Error **err)
1143{
1144 DeviceState *dev = DEVICE(obj);
1145
1146 dev->hotplugged = value;
1147}
1148
9674bfe4
AL
1149static void device_initfn(Object *obj)
1150{
1151 DeviceState *dev = DEVICE(obj);
bce54474 1152 ObjectClass *class;
9674bfe4
AL
1153 Property *prop;
1154
1155 if (qdev_hotplug) {
1156 dev->hotplugged = 1;
1157 qdev_hot_added = true;
1158 }
1159
1160 dev->instance_id_alias = -1;
7983c8a3 1161 dev->realized = false;
9674bfe4 1162
249d4172
AF
1163 object_property_add_bool(obj, "realized",
1164 device_get_realized, device_set_realized, NULL);
1a37eca1
IM
1165 object_property_add_bool(obj, "hotpluggable",
1166 device_get_hotpluggable, NULL, NULL);
d012ffc1
IM
1167 object_property_add_bool(obj, "hotplugged",
1168 device_get_hotplugged, device_set_hotplugged,
1169 &error_abort);
249d4172 1170
bce54474
PB
1171 class = object_get_class(OBJECT(dev));
1172 do {
1173 for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
5433a0a8
PC
1174 qdev_property_add_legacy(dev, prop, &error_abort);
1175 qdev_property_add_static(dev, prop, &error_abort);
bce54474 1176 }
bce54474
PB
1177 class = object_class_get_parent(class);
1178 } while (class != object_class_by_name(TYPE_DEVICE));
9674bfe4 1179
f968fc68 1180 object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
39f72ef9 1181 (Object **)&dev->parent_bus, NULL, 0,
9561fda8 1182 &error_abort);
a5f54290 1183 QLIST_INIT(&dev->gpios);
9674bfe4
AL
1184}
1185
99a0b036
EH
1186static void device_post_init(Object *obj)
1187{
25f8dd96 1188 qdev_prop_set_globals(DEVICE(obj));
99a0b036
EH
1189}
1190
60adba37
AL
1191/* Unlink device from bus and free the structure. */
1192static void device_finalize(Object *obj)
1193{
a5f54290
PC
1194 NamedGPIOList *ngl, *next;
1195
60adba37 1196 DeviceState *dev = DEVICE(obj);
4ad60880 1197 qemu_opts_del(dev->opts);
a5f54290
PC
1198
1199 QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
1200 QLIST_REMOVE(ngl, node);
f173d57a 1201 qemu_free_irqs(ngl->in, ngl->num_in);
a5f54290
PC
1202 g_free(ngl->name);
1203 g_free(ngl);
1204 /* ngl->out irqs are owned by the other end and should not be freed
1205 * here
1206 */
1207 }
60adba37
AL
1208}
1209
bce54474
PB
1210static void device_class_base_init(ObjectClass *class, void *data)
1211{
1212 DeviceClass *klass = DEVICE_CLASS(class);
1213
1214 /* We explicitly look up properties in the superclasses,
1215 * so do not propagate them to the subclasses.
1216 */
1217 klass->props = NULL;
60adba37
AL
1218}
1219
5d5b24d0 1220static void device_unparent(Object *obj)
667d22d1
PB
1221{
1222 DeviceState *dev = DEVICE(obj);
06f7f2bb 1223 BusState *bus;
667d22d1 1224
5c21ce77
BD
1225 if (dev->realized) {
1226 object_property_set_bool(obj, false, "realized", NULL);
1227 }
06f7f2bb
PB
1228 while (dev->num_child_bus) {
1229 bus = QLIST_FIRST(&dev->child_bus);
6780a22c 1230 object_unparent(OBJECT(bus));
06f7f2bb 1231 }
06f7f2bb 1232 if (dev->parent_bus) {
5d5b24d0 1233 bus_remove_child(dev->parent_bus, dev);
62d7ba66
PB
1234 object_unref(OBJECT(dev->parent_bus));
1235 dev->parent_bus = NULL;
5d5b24d0 1236 }
0402a5d6 1237
b1ee5829 1238 /* Only send event if the device had been completely realized */
352e8da7 1239 if (dev->pending_deleted_event) {
b1ee5829
AL
1240 gchar *path = object_get_canonical_path(OBJECT(dev));
1241
24b699fb 1242 qapi_event_send_device_deleted(!!dev->id, dev->id, path, &error_abort);
b1ee5829 1243 g_free(path);
0402a5d6 1244 }
667d22d1
PB
1245}
1246
1247static void device_class_init(ObjectClass *class, void *data)
1248{
249d4172
AF
1249 DeviceClass *dc = DEVICE_CLASS(class);
1250
5d5b24d0 1251 class->unparent = device_unparent;
249d4172 1252 dc->realize = device_realize;
fe6c2117 1253 dc->unrealize = device_unrealize;
267a3264
IM
1254
1255 /* by default all devices were considered as hotpluggable,
1256 * so with intent to check it in generic qdev_unplug() /
1257 * device_set_realized() functions make every device
1258 * hotpluggable. Devices that shouldn't be hotpluggable,
1259 * should override it in their class_init()
1260 */
1261 dc->hotpluggable = true;
667d22d1
PB
1262}
1263
94afdadc
AL
1264void device_reset(DeviceState *dev)
1265{
1266 DeviceClass *klass = DEVICE_GET_CLASS(dev);
1267
1268 if (klass->reset) {
1269 klass->reset(dev);
1270 }
1271}
1272
f05f6b4a
PB
1273Object *qdev_get_machine(void)
1274{
1275 static Object *dev;
1276
1277 if (dev == NULL) {
dfe47e70 1278 dev = container_get(object_get_root(), "/machine");
f05f6b4a
PB
1279 }
1280
1281 return dev;
1282}
1283
8c43a6f0 1284static const TypeInfo device_type_info = {
32fea402
AL
1285 .name = TYPE_DEVICE,
1286 .parent = TYPE_OBJECT,
1287 .instance_size = sizeof(DeviceState),
9674bfe4 1288 .instance_init = device_initfn,
99a0b036 1289 .instance_post_init = device_post_init,
60adba37 1290 .instance_finalize = device_finalize,
bce54474 1291 .class_base_init = device_class_base_init,
667d22d1 1292 .class_init = device_class_init,
32fea402
AL
1293 .abstract = true,
1294 .class_size = sizeof(DeviceClass),
1295};
1296
ac7d1ba6
AL
1297static void qbus_initfn(Object *obj)
1298{
1299 BusState *bus = BUS(obj);
1300
1301 QTAILQ_INIT(&bus->children);
0ee4de6c
IM
1302 object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY,
1303 TYPE_HOTPLUG_HANDLER,
9561fda8 1304 (Object **)&bus->hotplug_handler,
39f72ef9 1305 object_property_allow_set_link,
9561fda8
SH
1306 OBJ_PROP_LINK_UNREF_ON_RELEASE,
1307 NULL);
02e7f85d
BD
1308 object_property_add_bool(obj, "realized",
1309 bus_get_realized, bus_set_realized, NULL);
ac7d1ba6
AL
1310}
1311
bbfa18fc
AK
1312static char *default_bus_get_fw_dev_path(DeviceState *dev)
1313{
1314 return g_strdup(object_get_typename(OBJECT(dev)));
1315}
1316
6853d27a
PB
1317static void bus_class_init(ObjectClass *class, void *data)
1318{
bbfa18fc
AK
1319 BusClass *bc = BUS_CLASS(class);
1320
6853d27a 1321 class->unparent = bus_unparent;
bbfa18fc 1322 bc->get_fw_dev_path = default_bus_get_fw_dev_path;
6853d27a
PB
1323}
1324
ac7d1ba6
AL
1325static void qbus_finalize(Object *obj)
1326{
1327 BusState *bus = BUS(obj);
ac7d1ba6 1328
ac7d1ba6
AL
1329 g_free((char *)bus->name);
1330}
1331
0d936928
AL
1332static const TypeInfo bus_info = {
1333 .name = TYPE_BUS,
1334 .parent = TYPE_OBJECT,
1335 .instance_size = sizeof(BusState),
1336 .abstract = true,
1337 .class_size = sizeof(BusClass),
ac7d1ba6
AL
1338 .instance_init = qbus_initfn,
1339 .instance_finalize = qbus_finalize,
6853d27a 1340 .class_init = bus_class_init,
0d936928
AL
1341};
1342
83f7d43a 1343static void qdev_register_types(void)
32fea402 1344{
0d936928 1345 type_register_static(&bus_info);
32fea402
AL
1346 type_register_static(&device_type_info);
1347}
1348
83f7d43a 1349type_init(qdev_register_types)