]> Git Repo - qemu.git/blame - hw/core/qdev.c
Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20150210.0' into...
[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
aae9460e
PB
129/* Create a new device. This only initializes the device state structure
130 and allows properties to be set. qdev_init should be called to
131 initialize the actual device emulation. */
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
171/* Initialize a device. Device properties should be set before calling
172 this function. IRQs and MMIO regions should be connected/mapped after
18cfeb52
MA
173 calling this function.
174 On failure, destroy the device and return negative value.
175 Return 0 on success. */
81a322d4 176int qdev_init(DeviceState *dev)
aae9460e 177{
249d4172 178 Error *local_err = NULL;
959f733a 179
7983c8a3 180 assert(!dev->realized);
6e008585 181
249d4172
AF
182 object_property_set_bool(OBJECT(dev), true, "realized", &local_err);
183 if (local_err != NULL) {
cffc5113 184 qerror_report_err(local_err);
249d4172 185 error_free(local_err);
02a5c4c9 186 object_unparent(OBJECT(dev));
249d4172 187 return -1;
18cfeb52 188 }
249d4172
AF
189 return 0;
190}
da57febf 191
707ff800
PD
192static QTAILQ_HEAD(device_listeners, DeviceListener) device_listeners
193 = QTAILQ_HEAD_INITIALIZER(device_listeners);
194
195enum ListenerDirection { Forward, Reverse };
196
197#define DEVICE_LISTENER_CALL(_callback, _direction, _args...) \
198 do { \
199 DeviceListener *_listener; \
200 \
201 switch (_direction) { \
202 case Forward: \
203 QTAILQ_FOREACH(_listener, &device_listeners, link) { \
204 if (_listener->_callback) { \
205 _listener->_callback(_listener, ##_args); \
206 } \
207 } \
208 break; \
209 case Reverse: \
210 QTAILQ_FOREACH_REVERSE(_listener, &device_listeners, \
211 device_listeners, link) { \
212 if (_listener->_callback) { \
213 _listener->_callback(_listener, ##_args); \
214 } \
215 } \
216 break; \
217 default: \
218 abort(); \
219 } \
220 } while (0)
221
222static int device_listener_add(DeviceState *dev, void *opaque)
223{
224 DEVICE_LISTENER_CALL(realize, Forward, dev);
225
226 return 0;
227}
228
229void device_listener_register(DeviceListener *listener)
230{
231 QTAILQ_INSERT_TAIL(&device_listeners, listener, link);
232
233 qbus_walk_children(sysbus_get_default(), NULL, NULL, device_listener_add,
234 NULL, NULL);
235}
236
237void device_listener_unregister(DeviceListener *listener)
238{
239 QTAILQ_REMOVE(&device_listeners, listener, link);
240}
241
a7737e44 242static void device_realize(DeviceState *dev, Error **errp)
249d4172
AF
243{
244 DeviceClass *dc = DEVICE_GET_CLASS(dev);
da57febf 245
249d4172
AF
246 if (dc->init) {
247 int rc = dc->init(dev);
248 if (rc < 0) {
a7737e44 249 error_setg(errp, "Device initialization failed.");
249d4172
AF
250 return;
251 }
5ab28c83 252 }
02e2da45
PB
253}
254
fe6c2117
AF
255static void device_unrealize(DeviceState *dev, Error **errp)
256{
257 DeviceClass *dc = DEVICE_GET_CLASS(dev);
258
259 if (dc->exit) {
260 int rc = dc->exit(dev);
261 if (rc < 0) {
262 error_setg(errp, "Device exit failed.");
263 return;
264 }
265 }
266}
267
4d2ffa08
JK
268void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
269 int required_for_version)
270{
7983c8a3 271 assert(!dev->realized);
4d2ffa08
JK
272 dev->instance_id_alias = alias_id;
273 dev->alias_required_for_version = required_for_version;
274}
275
7716b8ca
IM
276static HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
277{
278 HotplugHandler *hotplug_ctrl = NULL;
279
280 if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
281 hotplug_ctrl = dev->parent_bus->hotplug_handler;
282 } else if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
283 MachineState *machine = MACHINE(qdev_get_machine());
284 MachineClass *mc = MACHINE_GET_CLASS(machine);
285
286 if (mc->get_hotplug_handler) {
287 hotplug_ctrl = mc->get_hotplug_handler(machine, dev);
288 }
289 }
290 return hotplug_ctrl;
291}
292
56f9107e 293void qdev_unplug(DeviceState *dev, Error **errp)
3418bd25 294{
6e008585 295 DeviceClass *dc = DEVICE_GET_CLASS(dev);
7716b8ca
IM
296 HotplugHandler *hotplug_ctrl;
297 HotplugHandlerClass *hdc;
6e008585 298
39b888bd 299 if (dev->parent_bus && !qbus_is_hotpluggable(dev->parent_bus)) {
56f9107e
LC
300 error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
301 return;
3418bd25 302 }
593831de 303
1a37eca1
IM
304 if (!dc->hotpluggable) {
305 error_set(errp, QERR_DEVICE_NO_HOTPLUG,
306 object_get_typename(OBJECT(dev)));
307 return;
308 }
309
0ac8ef71
AW
310 qdev_hot_removed = true;
311
7716b8ca
IM
312 hotplug_ctrl = qdev_get_hotplug_handler(dev);
313 /* hotpluggable device MUST have HotplugHandler, if it doesn't
314 * then something is very wrong with it */
315 g_assert(hotplug_ctrl);
316
317 /* If device supports async unplug just request it to be done,
318 * otherwise just remove it synchronously */
319 hdc = HOTPLUG_HANDLER_GET_CLASS(hotplug_ctrl);
320 if (hdc->unplug_request) {
321 hotplug_handler_unplug_request(hotplug_ctrl, dev, errp);
5e954943 322 } else {
7716b8ca 323 hotplug_handler_unplug(hotplug_ctrl, dev, errp);
56f9107e 324 }
3418bd25
GH
325}
326
ec990eb6
AL
327static int qdev_reset_one(DeviceState *dev, void *opaque)
328{
94afdadc 329 device_reset(dev);
ec990eb6
AL
330
331 return 0;
332}
333
b4694b7c
IY
334static int qbus_reset_one(BusState *bus, void *opaque)
335{
0d936928
AL
336 BusClass *bc = BUS_GET_CLASS(bus);
337 if (bc->reset) {
dcc20931 338 bc->reset(bus);
b4694b7c
IY
339 }
340 return 0;
341}
342
5af0a04b
IY
343void qdev_reset_all(DeviceState *dev)
344{
dcc20931 345 qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
5af0a04b
IY
346}
347
d0508c36
PB
348void qbus_reset_all(BusState *bus)
349{
dcc20931 350 qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
d0508c36
PB
351}
352
80376c3f
IY
353void qbus_reset_all_fn(void *opaque)
354{
355 BusState *bus = opaque;
d0508c36 356 qbus_reset_all(bus);
80376c3f
IY
357}
358
3418bd25 359/* can be used as ->unplug() callback for the simple cases */
014176f9
IM
360void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
361 DeviceState *dev, Error **errp)
362{
2d9a982f
IM
363 /* just zap it */
364 object_unparent(OBJECT(dev));
014176f9 365}
3b29a101
MT
366
367/* Like qdev_init(), but terminate program via error_report() instead of
e23a1b33
MA
368 returning an error value. This is okay during machine creation.
369 Don't use for hotplug, because there callers need to recover from
370 failure. Exception: if you know the device's init() callback can't
371 fail, then qdev_init_nofail() can't fail either, and is therefore
372 usable even then. But relying on the device implementation that
373 way is somewhat unclean, and best avoided. */
374void qdev_init_nofail(DeviceState *dev)
375{
7de3abe5
AL
376 const char *typename = object_get_typename(OBJECT(dev));
377
bd6c9a61 378 if (qdev_init(dev) < 0) {
7de3abe5 379 error_report("Initialization of device %s failed", typename);
bd6c9a61
MA
380 exit(1);
381 }
e23a1b33
MA
382}
383
3418bd25
GH
384void qdev_machine_creation_done(void)
385{
386 /*
387 * ok, initial machine setup is done, starting from now we can
388 * only create hotpluggable devices
389 */
390 qdev_hotplug = 1;
391}
392
0ac8ef71
AW
393bool qdev_machine_modified(void)
394{
395 return qdev_hot_added || qdev_hot_removed;
396}
397
02e2da45 398BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 399{
02e2da45 400 return dev->parent_bus;
aae9460e
PB
401}
402
a5f54290
PC
403static NamedGPIOList *qdev_get_named_gpio_list(DeviceState *dev,
404 const char *name)
405{
406 NamedGPIOList *ngl;
407
408 QLIST_FOREACH(ngl, &dev->gpios, node) {
409 /* NULL is a valid and matchable name, otherwise do a normal
410 * strcmp match.
411 */
412 if ((!ngl->name && !name) ||
413 (name && ngl->name && strcmp(name, ngl->name) == 0)) {
414 return ngl;
415 }
416 }
417
418 ngl = g_malloc0(sizeof(*ngl));
419 ngl->name = g_strdup(name);
420 QLIST_INSERT_HEAD(&dev->gpios, ngl, node);
421 return ngl;
422}
423
424void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler,
425 const char *name, int n)
426{
a69bef1c 427 int i;
a5f54290 428 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
a69bef1c 429 char *propname = g_strdup_printf("%s[*]", name ? name : "unnamed-gpio-in");
a5f54290 430
b235a71f 431 assert(gpio_list->num_out == 0 || !name);
a5f54290
PC
432 gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler,
433 dev, n);
a69bef1c
PC
434
435 for (i = gpio_list->num_in; i < gpio_list->num_in + n; i++) {
436 object_property_add_child(OBJECT(dev), propname,
437 OBJECT(gpio_list->in[i]), &error_abort);
438 }
439 g_free(propname);
440
a5f54290
PC
441 gpio_list->num_in += n;
442}
443
aae9460e
PB
444void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
445{
a5f54290
PC
446 qdev_init_gpio_in_named(dev, handler, NULL, n);
447}
448
449void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins,
450 const char *name, int n)
451{
688b057a 452 int i;
a5f54290 453 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
688b057a 454 char *propname = g_strdup_printf("%s[*]", name ? name : "unnamed-gpio-out");
a5f54290 455
b235a71f 456 assert(gpio_list->num_in == 0 || !name);
aef0869e 457 gpio_list->num_out += n;
688b057a
PC
458
459 for (i = 0; i < n; ++i) {
460 memset(&pins[i], 0, sizeof(*pins));
461 object_property_add_link(OBJECT(dev), propname, TYPE_IRQ,
462 (Object **)&pins[i],
463 object_property_allow_set_link,
464 OBJ_PROP_LINK_UNREF_ON_RELEASE,
465 &error_abort);
466 }
467 g_free(propname);
aae9460e
PB
468}
469
470void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
471{
a5f54290
PC
472 qdev_init_gpio_out_named(dev, pins, NULL, n);
473}
474
475qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n)
476{
477 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
478
479 assert(n >= 0 && n < gpio_list->num_in);
480 return gpio_list->in[n];
aae9460e
PB
481}
482
483qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
484{
a5f54290
PC
485 return qdev_get_gpio_in_named(dev, NULL, n);
486}
487
488void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
489 qemu_irq pin)
490{
02757df2
PC
491 char *propname = g_strdup_printf("%s[%d]",
492 name ? name : "unnamed-gpio-out", n);
493 if (pin) {
494 /* We need a name for object_property_set_link to work. If the
495 * object has a parent, object_property_add_child will come back
496 * with an error without doing anything. If it has none, it will
497 * never fail. So we can just call it with a NULL Error pointer.
498 */
499 object_property_add_child(qdev_get_machine(), "non-qdev-gpio[*]",
500 OBJECT(pin), NULL);
501 }
502 object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort);
503 g_free(propname);
aae9460e
PB
504}
505
b7973186
AG
506qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n)
507{
508 char *propname = g_strdup_printf("%s[%d]",
509 name ? name : "unnamed-gpio-out", n);
510
511 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
512 NULL);
513
514 return ret;
515}
516
0c24db2b
PC
517/* disconnect a GPIO ouput, returning the disconnected input (if any) */
518
519static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev,
520 const char *name, int n)
521{
522 char *propname = g_strdup_printf("%s[%d]",
523 name ? name : "unnamed-gpio-out", n);
524
525 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
526 NULL);
527 if (ret) {
528 object_property_set_link(OBJECT(dev), NULL, propname, NULL);
529 }
530 g_free(propname);
531 return ret;
532}
a5f54290 533
0c24db2b
PC
534qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt,
535 const char *name, int n)
536{
537 qemu_irq disconnected = qdev_disconnect_gpio_out_named(dev, name, n);
538 qdev_connect_gpio_out_named(dev, name, n, icpt);
539 return disconnected;
aae9460e
PB
540}
541
542void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
543{
a5f54290 544 qdev_connect_gpio_out_named(dev, NULL, n, pin);
aae9460e
PB
545}
546
17a96a14
PC
547void qdev_pass_gpios(DeviceState *dev, DeviceState *container,
548 const char *name)
549{
550 int i;
551 NamedGPIOList *ngl = qdev_get_named_gpio_list(dev, name);
552
553 for (i = 0; i < ngl->num_in; i++) {
554 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-in";
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);
560 }
561 for (i = 0; i < ngl->num_out; i++) {
562 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-out";
563 char *propname = g_strdup_printf("%s[%d]", nm, i);
564
565 object_property_add_alias(OBJECT(container), propname,
566 OBJECT(dev), propname,
567 &error_abort);
568 }
569 QLIST_REMOVE(ngl, node);
570 QLIST_INSERT_HEAD(&container->gpios, ngl, node);
571}
572
02e2da45 573BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 574{
02e2da45 575 BusState *bus;
4d6ae674 576
72cf2d4f 577 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 578 if (strcmp(name, bus->name) == 0) {
02e2da45 579 return bus;
4d6ae674
PB
580 }
581 }
582 return NULL;
583}
584
0293214b
PB
585int qbus_walk_children(BusState *bus,
586 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
587 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
588 void *opaque)
81699d8a 589{
0866aca1 590 BusChild *kid;
81699d8a
AL
591 int err;
592
0293214b
PB
593 if (pre_busfn) {
594 err = pre_busfn(bus, opaque);
81699d8a
AL
595 if (err) {
596 return err;
597 }
598 }
599
0866aca1 600 QTAILQ_FOREACH(kid, &bus->children, sibling) {
0293214b
PB
601 err = qdev_walk_children(kid->child,
602 pre_devfn, pre_busfn,
603 post_devfn, post_busfn, opaque);
81699d8a
AL
604 if (err < 0) {
605 return err;
606 }
607 }
608
0293214b
PB
609 if (post_busfn) {
610 err = post_busfn(bus, opaque);
611 if (err) {
612 return err;
613 }
614 }
615
81699d8a
AL
616 return 0;
617}
618
0293214b
PB
619int qdev_walk_children(DeviceState *dev,
620 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
621 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
622 void *opaque)
81699d8a
AL
623{
624 BusState *bus;
625 int err;
626
0293214b
PB
627 if (pre_devfn) {
628 err = pre_devfn(dev, opaque);
81699d8a
AL
629 if (err) {
630 return err;
631 }
632 }
633
634 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
0293214b
PB
635 err = qbus_walk_children(bus, pre_devfn, pre_busfn,
636 post_devfn, post_busfn, opaque);
81699d8a
AL
637 if (err < 0) {
638 return err;
639 }
640 }
641
0293214b
PB
642 if (post_devfn) {
643 err = post_devfn(dev, opaque);
644 if (err) {
645 return err;
646 }
647 }
648
81699d8a
AL
649 return 0;
650}
651
a2ee6b4f 652DeviceState *qdev_find_recursive(BusState *bus, const char *id)
3418bd25 653{
0866aca1
AL
654 BusChild *kid;
655 DeviceState *ret;
3418bd25
GH
656 BusState *child;
657
0866aca1
AL
658 QTAILQ_FOREACH(kid, &bus->children, sibling) {
659 DeviceState *dev = kid->child;
660
661 if (dev->id && strcmp(dev->id, id) == 0) {
3418bd25 662 return dev;
0866aca1
AL
663 }
664
3418bd25
GH
665 QLIST_FOREACH(child, &dev->child_bus, sibling) {
666 ret = qdev_find_recursive(child, id);
667 if (ret) {
668 return ret;
669 }
670 }
671 }
672 return NULL;
673}
674
013e1182 675static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
02e2da45 676{
ac7d1ba6 677 const char *typename = object_get_typename(OBJECT(bus));
61de3676 678 BusClass *bc;
d271de9f 679 char *buf;
61de3676 680 int i, len, bus_id;
02e2da45 681
013e1182
PB
682 bus->parent = parent;
683
684 if (name) {
685 bus->name = g_strdup(name);
ac7d1ba6 686 } else if (bus->parent && bus->parent->id) {
61de3676
AG
687 /* parent device has id -> use it plus parent-bus-id for bus name */
688 bus_id = bus->parent->num_child_bus;
689
ac7d1ba6 690 len = strlen(bus->parent->id) + 16;
7267c094 691 buf = g_malloc(len);
61de3676 692 snprintf(buf, len, "%s.%d", bus->parent->id, bus_id);
d271de9f
GH
693 bus->name = buf;
694 } else {
61de3676
AG
695 /* no id -> use lowercase bus type plus global bus-id for bus name */
696 bc = BUS_GET_CLASS(bus);
697 bus_id = bc->automatic_ids++;
698
0d936928 699 len = strlen(typename) + 16;
7267c094 700 buf = g_malloc(len);
61de3676
AG
701 len = snprintf(buf, len, "%s.%d", typename, bus_id);
702 for (i = 0; i < len; i++) {
bb87ece5 703 buf[i] = qemu_tolower(buf[i]);
61de3676 704 }
d271de9f
GH
705 bus->name = buf;
706 }
707
ac7d1ba6
AL
708 if (bus->parent) {
709 QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
710 bus->parent->num_child_bus++;
711 object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
b09995ae 712 object_unref(OBJECT(bus));
8185d216 713 } else if (bus != sysbus_get_default()) {
80376c3f
IY
714 /* TODO: once all bus devices are qdevified,
715 only reset handler for main_system_bus should be registered here. */
716 qemu_register_reset(qbus_reset_all_fn, bus);
02e2da45 717 }
cd739fb6
GH
718}
719
6853d27a
PB
720static void bus_unparent(Object *obj)
721{
722 BusState *bus = BUS(obj);
723 BusChild *kid;
724
725 while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
726 DeviceState *dev = kid->child;
02a5c4c9 727 object_unparent(OBJECT(dev));
6853d27a
PB
728 }
729 if (bus->parent) {
730 QLIST_REMOVE(bus, sibling);
731 bus->parent->num_child_bus--;
732 bus->parent = NULL;
733 } else {
734 assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
735 qemu_unregister_reset(qbus_reset_all_fn, bus);
736 }
737}
738
a7737e44 739static bool bus_get_realized(Object *obj, Error **errp)
02e7f85d
BD
740{
741 BusState *bus = BUS(obj);
742
743 return bus->realized;
744}
745
a7737e44 746static void bus_set_realized(Object *obj, bool value, Error **errp)
02e7f85d
BD
747{
748 BusState *bus = BUS(obj);
749 BusClass *bc = BUS_GET_CLASS(bus);
5942a190 750 BusChild *kid;
02e7f85d
BD
751 Error *local_err = NULL;
752
753 if (value && !bus->realized) {
754 if (bc->realize) {
755 bc->realize(bus, &local_err);
02e7f85d 756 }
5942a190
PB
757
758 /* TODO: recursive realization */
02e7f85d 759 } else if (!value && bus->realized) {
5942a190
PB
760 QTAILQ_FOREACH(kid, &bus->children, sibling) {
761 DeviceState *dev = kid->child;
762 object_property_set_bool(OBJECT(dev), false, "realized",
763 &local_err);
764 if (local_err != NULL) {
765 break;
766 }
767 }
768 if (bc->unrealize && local_err == NULL) {
02e7f85d 769 bc->unrealize(bus, &local_err);
02e7f85d
BD
770 }
771 }
772
b7b34d05
PB
773 if (local_err != NULL) {
774 error_propagate(errp, local_err);
775 return;
776 }
02e7f85d 777
b7b34d05 778 bus->realized = value;
02e7f85d
BD
779}
780
fb17dfe0 781void qbus_create_inplace(void *bus, size_t size, const char *typename,
0d936928 782 DeviceState *parent, const char *name)
cd739fb6 783{
213f0c4f 784 object_initialize(bus, size, typename);
013e1182 785 qbus_realize(bus, parent, name);
02e2da45 786}
cae4956e 787
0d936928 788BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
2da8bb92 789{
cd739fb6
GH
790 BusState *bus;
791
0d936928 792 bus = BUS(object_new(typename));
013e1182 793 qbus_realize(bus, parent, name);
ac7d1ba6 794
02e2da45 795 return bus;
2da8bb92
IY
796}
797
0d936928
AL
798static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
799{
800 BusClass *bc = BUS_GET_CLASS(bus);
801
802 if (bc->get_fw_dev_path) {
803 return bc->get_fw_dev_path(dev);
131ec1bd 804 }
0d936928
AL
805
806 return NULL;
131ec1bd
GH
807}
808
6b1566cb
PB
809static char *qdev_get_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
810{
811 Object *obj = OBJECT(dev);
812 char *d = NULL;
813
814 while (!d && obj->parent) {
815 obj = obj->parent;
816 d = fw_path_provider_try_get_dev_path(obj, bus, dev);
817 }
818 return d;
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;
991 DeviceState *dev = DEVICE(obj);
992
993 if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) {
994 *list = g_slist_append(*list, dev);
995 }
996
66e56b13
ZG
997 return 0;
998}
999
4cae4d5a
MA
1000GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
1001{
1002 GSList *list = NULL;
1003
1004 object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);
1005
1006 return list;
1007}
1008
a7737e44 1009static bool device_get_realized(Object *obj, Error **errp)
249d4172
AF
1010{
1011 DeviceState *dev = DEVICE(obj);
1012 return dev->realized;
1013}
1014
a7737e44 1015static void device_set_realized(Object *obj, bool value, Error **errp)
249d4172
AF
1016{
1017 DeviceState *dev = DEVICE(obj);
1018 DeviceClass *dc = DEVICE_GET_CLASS(dev);
7716b8ca 1019 HotplugHandler *hotplug_ctrl;
5c21ce77 1020 BusState *bus;
249d4172
AF
1021 Error *local_err = NULL;
1022
1a37eca1 1023 if (dev->hotplugged && !dc->hotpluggable) {
a7737e44 1024 error_set(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
1a37eca1
IM
1025 return;
1026 }
1027
249d4172 1028 if (value && !dev->realized) {
d578029e 1029 if (!obj->parent) {
249d4172
AF
1030 static int unattached_count;
1031 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
1032
1033 object_property_add_child(container_get(qdev_get_machine(),
1034 "/unattached"),
d578029e 1035 name, obj, &error_abort);
249d4172
AF
1036 g_free(name);
1037 }
1038
a7ddba52
IM
1039 if (dc->realize) {
1040 dc->realize(dev, &local_err);
1041 }
1042
1d45a705
GA
1043 if (local_err != NULL) {
1044 goto fail;
1045 }
1046
707ff800
PD
1047 DEVICE_LISTENER_CALL(realize, Forward, dev);
1048
7716b8ca
IM
1049 hotplug_ctrl = qdev_get_hotplug_handler(dev);
1050 if (hotplug_ctrl) {
1051 hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
5e954943
IM
1052 }
1053
1d45a705
GA
1054 if (local_err != NULL) {
1055 goto post_realize_fail;
1056 }
1057
1058 if (qdev_get_vmsd(dev)) {
249d4172
AF
1059 vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
1060 dev->instance_id_alias,
1061 dev->alias_required_for_version);
1062 }
1d45a705
GA
1063
1064 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
1065 object_property_set_bool(OBJECT(bus), true, "realized",
5c21ce77 1066 &local_err);
1d45a705
GA
1067 if (local_err != NULL) {
1068 goto child_realize_fail;
5c21ce77
BD
1069 }
1070 }
1d45a705 1071 if (dev->hotplugged) {
249d4172
AF
1072 device_reset(dev);
1073 }
352e8da7 1074 dev->pending_deleted_event = false;
249d4172 1075 } else if (!value && dev->realized) {
cd4520ad 1076 Error **local_errp = NULL;
5c21ce77 1077 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
cd4520ad 1078 local_errp = local_err ? NULL : &local_err;
5c21ce77 1079 object_property_set_bool(OBJECT(bus), false, "realized",
cd4520ad 1080 local_errp);
5c21ce77 1081 }
cd4520ad 1082 if (qdev_get_vmsd(dev)) {
fe6c2117
AF
1083 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
1084 }
cd4520ad
GA
1085 if (dc->unrealize) {
1086 local_errp = local_err ? NULL : &local_err;
1087 dc->unrealize(dev, local_errp);
249d4172 1088 }
352e8da7 1089 dev->pending_deleted_event = true;
707ff800 1090 DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
249d4172
AF
1091 }
1092
1093 if (local_err != NULL) {
1d45a705 1094 goto fail;
249d4172
AF
1095 }
1096
1097 dev->realized = value;
1d45a705
GA
1098 return;
1099
1100child_realize_fail:
1101 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
1102 object_property_set_bool(OBJECT(bus), false, "realized",
1103 NULL);
1104 }
1105
1106 if (qdev_get_vmsd(dev)) {
1107 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
1108 }
1109
1110post_realize_fail:
1111 if (dc->unrealize) {
1112 dc->unrealize(dev, NULL);
1113 }
1114
1115fail:
1116 error_propagate(errp, local_err);
1117 return;
249d4172
AF
1118}
1119
a7737e44 1120static bool device_get_hotpluggable(Object *obj, Error **errp)
1a37eca1
IM
1121{
1122 DeviceClass *dc = DEVICE_GET_CLASS(obj);
1123 DeviceState *dev = DEVICE(obj);
1124
2b81b35f 1125 return dc->hotpluggable && (dev->parent_bus == NULL ||
39b888bd 1126 qbus_is_hotpluggable(dev->parent_bus));
1a37eca1
IM
1127}
1128
d012ffc1
IM
1129static bool device_get_hotplugged(Object *obj, Error **err)
1130{
1131 DeviceState *dev = DEVICE(obj);
1132
1133 return dev->hotplugged;
1134}
1135
1136static void device_set_hotplugged(Object *obj, bool value, Error **err)
1137{
1138 DeviceState *dev = DEVICE(obj);
1139
1140 dev->hotplugged = value;
1141}
1142
9674bfe4
AL
1143static void device_initfn(Object *obj)
1144{
1145 DeviceState *dev = DEVICE(obj);
bce54474 1146 ObjectClass *class;
9674bfe4
AL
1147 Property *prop;
1148
1149 if (qdev_hotplug) {
1150 dev->hotplugged = 1;
1151 qdev_hot_added = true;
1152 }
1153
1154 dev->instance_id_alias = -1;
7983c8a3 1155 dev->realized = false;
9674bfe4 1156
249d4172
AF
1157 object_property_add_bool(obj, "realized",
1158 device_get_realized, device_set_realized, NULL);
1a37eca1
IM
1159 object_property_add_bool(obj, "hotpluggable",
1160 device_get_hotpluggable, NULL, NULL);
d012ffc1
IM
1161 object_property_add_bool(obj, "hotplugged",
1162 device_get_hotplugged, device_set_hotplugged,
1163 &error_abort);
249d4172 1164
bce54474
PB
1165 class = object_get_class(OBJECT(dev));
1166 do {
1167 for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
5433a0a8
PC
1168 qdev_property_add_legacy(dev, prop, &error_abort);
1169 qdev_property_add_static(dev, prop, &error_abort);
bce54474 1170 }
bce54474
PB
1171 class = object_class_get_parent(class);
1172 } while (class != object_class_by_name(TYPE_DEVICE));
9674bfe4 1173
f968fc68 1174 object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
39f72ef9 1175 (Object **)&dev->parent_bus, NULL, 0,
9561fda8 1176 &error_abort);
a5f54290 1177 QLIST_INIT(&dev->gpios);
9674bfe4
AL
1178}
1179
99a0b036
EH
1180static void device_post_init(Object *obj)
1181{
31962700
EH
1182 Error *err = NULL;
1183 qdev_prop_set_globals(DEVICE(obj), &err);
1184 if (err) {
1185 qerror_report_err(err);
1186 error_free(err);
1187 exit(EXIT_FAILURE);
1188 }
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)
This page took 0.924243 seconds and 4 git commands to generate.