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