]> git.proxmox.com Git - mirror_qemu.git/blame - hw/core/qdev.c
qom: Introduce instance_post_init hook
[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"
9c17d615 29#include "sysemu/sysemu.h"
7b1b5d19 30#include "qapi/error.h"
b4a42f81 31#include "qapi/qmp/qerror.h"
7b1b5d19 32#include "qapi/visitor.h"
0402a5d6
MT
33#include "qapi/qmp/qjson.h"
34#include "monitor/monitor.h"
aae9460e 35
ee46d8a5 36int qdev_hotplug = 0;
0ac8ef71
AW
37static bool qdev_hot_added = false;
38static bool qdev_hot_removed = false;
3418bd25 39
4be9f0d1
AL
40const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
41{
6e008585
AL
42 DeviceClass *dc = DEVICE_GET_CLASS(dev);
43 return dc->vmsd;
4be9f0d1
AL
44}
45
4be9f0d1
AL
46const char *qdev_fw_name(DeviceState *dev)
47{
6e008585 48 DeviceClass *dc = DEVICE_GET_CLASS(dev);
4be9f0d1 49
6e008585
AL
50 if (dc->fw_name) {
51 return dc->fw_name;
4be9f0d1
AL
52 }
53
54 return object_get_typename(OBJECT(dev));
55}
56
ca2cc788
PB
57static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
58 Error **errp);
59
0866aca1 60static void bus_remove_child(BusState *bus, DeviceState *child)
0c17542d 61{
0866aca1
AL
62 BusChild *kid;
63
64 QTAILQ_FOREACH(kid, &bus->children, sibling) {
65 if (kid->child == child) {
66 char name[32];
67
68 snprintf(name, sizeof(name), "child[%d]", kid->index);
69 QTAILQ_REMOVE(&bus->children, kid, sibling);
9d127820
PB
70
71 /* This gives back ownership of kid->child back to us. */
0866aca1 72 object_property_del(OBJECT(bus), name, NULL);
9d127820 73 object_unref(OBJECT(kid->child));
0866aca1
AL
74 g_free(kid);
75 return;
76 }
77 }
78}
79
80static void bus_add_child(BusState *bus, DeviceState *child)
81{
82 char name[32];
83 BusChild *kid = g_malloc0(sizeof(*kid));
0c17542d 84
0c17542d
MA
85 if (qdev_hotplug) {
86 assert(bus->allow_hotplug);
0c17542d 87 }
a5296ca9 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)),
99 (Object **)&kid->child,
100 NULL);
101}
102
103void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
104{
9fbe6127 105 dev->parent_bus = bus;
62d7ba66 106 object_ref(OBJECT(bus));
0866aca1 107 bus_add_child(bus, dev);
0c17542d
MA
108}
109
aae9460e
PB
110/* Create a new device. This only initializes the device state structure
111 and allows properties to be set. qdev_init should be called to
112 initialize the actual device emulation. */
02e2da45 113DeviceState *qdev_create(BusState *bus, const char *name)
0bcdeda7
BS
114{
115 DeviceState *dev;
116
117 dev = qdev_try_create(bus, name);
118 if (!dev) {
e92714c7 119 if (bus) {
312fd5f2 120 error_report("Unknown device '%s' for bus '%s'", name,
23e3fbec 121 object_get_typename(OBJECT(bus)));
e92714c7 122 } else {
312fd5f2 123 error_report("Unknown device '%s' for default sysbus", name);
e92714c7 124 }
01ed1d52 125 abort();
0bcdeda7
BS
126 }
127
128 return dev;
129}
130
da57febf 131DeviceState *qdev_try_create(BusState *bus, const char *type)
aae9460e 132{
9fbe6127
AL
133 DeviceState *dev;
134
da57febf 135 if (object_class_by_name(type) == NULL) {
4ed658ca
AF
136 return NULL;
137 }
da57febf 138 dev = DEVICE(object_new(type));
9fbe6127
AL
139 if (!dev) {
140 return NULL;
141 }
142
10c4c98a 143 if (!bus) {
68694897 144 bus = sysbus_get_default();
10c4c98a
GH
145 }
146
9fbe6127 147 qdev_set_parent_bus(dev, bus);
b09995ae 148 object_unref(OBJECT(dev));
9fbe6127 149 return dev;
aae9460e
PB
150}
151
152/* Initialize a device. Device properties should be set before calling
153 this function. IRQs and MMIO regions should be connected/mapped after
18cfeb52
MA
154 calling this function.
155 On failure, destroy the device and return negative value.
156 Return 0 on success. */
81a322d4 157int qdev_init(DeviceState *dev)
aae9460e 158{
249d4172 159 Error *local_err = NULL;
959f733a 160
7983c8a3 161 assert(!dev->realized);
6e008585 162
249d4172
AF
163 object_property_set_bool(OBJECT(dev), true, "realized", &local_err);
164 if (local_err != NULL) {
cffc5113 165 qerror_report_err(local_err);
249d4172 166 error_free(local_err);
18cfeb52 167 qdev_free(dev);
249d4172 168 return -1;
18cfeb52 169 }
249d4172
AF
170 return 0;
171}
da57febf 172
249d4172
AF
173static void device_realize(DeviceState *dev, Error **err)
174{
175 DeviceClass *dc = DEVICE_GET_CLASS(dev);
da57febf 176
249d4172
AF
177 if (dc->init) {
178 int rc = dc->init(dev);
179 if (rc < 0) {
180 error_setg(err, "Device initialization failed.");
181 return;
182 }
5ab28c83 183 }
02e2da45
PB
184}
185
fe6c2117
AF
186static void device_unrealize(DeviceState *dev, Error **errp)
187{
188 DeviceClass *dc = DEVICE_GET_CLASS(dev);
189
190 if (dc->exit) {
191 int rc = dc->exit(dev);
192 if (rc < 0) {
193 error_setg(errp, "Device exit failed.");
194 return;
195 }
196 }
197}
198
4d2ffa08
JK
199void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
200 int required_for_version)
201{
7983c8a3 202 assert(!dev->realized);
4d2ffa08
JK
203 dev->instance_id_alias = alias_id;
204 dev->alias_required_for_version = required_for_version;
205}
206
56f9107e 207void qdev_unplug(DeviceState *dev, Error **errp)
3418bd25 208{
6e008585
AL
209 DeviceClass *dc = DEVICE_GET_CLASS(dev);
210
120dc38f 211 if (dev->parent_bus && !dev->parent_bus->allow_hotplug) {
56f9107e
LC
212 error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
213 return;
3418bd25 214 }
6e008585 215 assert(dc->unplug != NULL);
593831de 216
0ac8ef71
AW
217 qdev_hot_removed = true;
218
56f9107e
LC
219 if (dc->unplug(dev) < 0) {
220 error_set(errp, QERR_UNDEFINED_ERROR);
221 return;
222 }
3418bd25
GH
223}
224
ec990eb6
AL
225static int qdev_reset_one(DeviceState *dev, void *opaque)
226{
94afdadc 227 device_reset(dev);
ec990eb6
AL
228
229 return 0;
230}
231
b4694b7c
IY
232static int qbus_reset_one(BusState *bus, void *opaque)
233{
0d936928
AL
234 BusClass *bc = BUS_GET_CLASS(bus);
235 if (bc->reset) {
236 return bc->reset(bus);
b4694b7c
IY
237 }
238 return 0;
239}
240
5af0a04b
IY
241void qdev_reset_all(DeviceState *dev)
242{
243 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
244}
245
d0508c36
PB
246void qbus_reset_all(BusState *bus)
247{
248 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
249}
250
80376c3f
IY
251void qbus_reset_all_fn(void *opaque)
252{
253 BusState *bus = opaque;
d0508c36 254 qbus_reset_all(bus);
80376c3f
IY
255}
256
3418bd25
GH
257/* can be used as ->unplug() callback for the simple cases */
258int qdev_simple_unplug_cb(DeviceState *dev)
259{
260 /* just zap it */
261 qdev_free(dev);
262 return 0;
263}
264
3b29a101
MT
265
266/* Like qdev_init(), but terminate program via error_report() instead of
e23a1b33
MA
267 returning an error value. This is okay during machine creation.
268 Don't use for hotplug, because there callers need to recover from
269 failure. Exception: if you know the device's init() callback can't
270 fail, then qdev_init_nofail() can't fail either, and is therefore
271 usable even then. But relying on the device implementation that
272 way is somewhat unclean, and best avoided. */
273void qdev_init_nofail(DeviceState *dev)
274{
7de3abe5
AL
275 const char *typename = object_get_typename(OBJECT(dev));
276
bd6c9a61 277 if (qdev_init(dev) < 0) {
7de3abe5 278 error_report("Initialization of device %s failed", typename);
bd6c9a61
MA
279 exit(1);
280 }
e23a1b33
MA
281}
282
02e2da45
PB
283/* Unlink device from bus and free the structure. */
284void qdev_free(DeviceState *dev)
285{
dc7389b7 286 object_unparent(OBJECT(dev));
aae9460e
PB
287}
288
3418bd25
GH
289void qdev_machine_creation_done(void)
290{
291 /*
292 * ok, initial machine setup is done, starting from now we can
293 * only create hotpluggable devices
294 */
295 qdev_hotplug = 1;
296}
297
0ac8ef71
AW
298bool qdev_machine_modified(void)
299{
300 return qdev_hot_added || qdev_hot_removed;
301}
302
02e2da45 303BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 304{
02e2da45 305 return dev->parent_bus;
aae9460e
PB
306}
307
aae9460e
PB
308void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
309{
1e5b31e6
PC
310 dev->gpio_in = qemu_extend_irqs(dev->gpio_in, dev->num_gpio_in, handler,
311 dev, n);
312 dev->num_gpio_in += n;
aae9460e
PB
313}
314
315void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
316{
317 assert(dev->num_gpio_out == 0);
318 dev->num_gpio_out = n;
319 dev->gpio_out = pins;
320}
321
322qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
323{
324 assert(n >= 0 && n < dev->num_gpio_in);
325 return dev->gpio_in[n];
326}
327
328void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
329{
330 assert(n >= 0 && n < dev->num_gpio_out);
331 dev->gpio_out[n] = pin;
332}
333
02e2da45 334BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 335{
02e2da45 336 BusState *bus;
4d6ae674 337
72cf2d4f 338 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 339 if (strcmp(name, bus->name) == 0) {
02e2da45 340 return bus;
4d6ae674
PB
341 }
342 }
343 return NULL;
344}
345
81699d8a
AL
346int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
347 qbus_walkerfn *busfn, void *opaque)
348{
0866aca1 349 BusChild *kid;
81699d8a
AL
350 int err;
351
352 if (busfn) {
353 err = busfn(bus, opaque);
354 if (err) {
355 return err;
356 }
357 }
358
0866aca1
AL
359 QTAILQ_FOREACH(kid, &bus->children, sibling) {
360 err = qdev_walk_children(kid->child, devfn, busfn, opaque);
81699d8a
AL
361 if (err < 0) {
362 return err;
363 }
364 }
365
366 return 0;
367}
368
369int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
370 qbus_walkerfn *busfn, void *opaque)
371{
372 BusState *bus;
373 int err;
374
375 if (devfn) {
376 err = devfn(dev, opaque);
377 if (err) {
378 return err;
379 }
380 }
381
382 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
383 err = qbus_walk_children(bus, devfn, busfn, opaque);
384 if (err < 0) {
385 return err;
386 }
387 }
388
389 return 0;
390}
391
a2ee6b4f 392DeviceState *qdev_find_recursive(BusState *bus, const char *id)
3418bd25 393{
0866aca1
AL
394 BusChild *kid;
395 DeviceState *ret;
3418bd25
GH
396 BusState *child;
397
0866aca1
AL
398 QTAILQ_FOREACH(kid, &bus->children, sibling) {
399 DeviceState *dev = kid->child;
400
401 if (dev->id && strcmp(dev->id, id) == 0) {
3418bd25 402 return dev;
0866aca1
AL
403 }
404
3418bd25
GH
405 QLIST_FOREACH(child, &dev->child_bus, sibling) {
406 ret = qdev_find_recursive(child, id);
407 if (ret) {
408 return ret;
409 }
410 }
411 }
412 return NULL;
413}
414
013e1182 415static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
02e2da45 416{
ac7d1ba6 417 const char *typename = object_get_typename(OBJECT(bus));
d271de9f
GH
418 char *buf;
419 int i,len;
02e2da45 420
013e1182
PB
421 bus->parent = parent;
422
423 if (name) {
424 bus->name = g_strdup(name);
ac7d1ba6 425 } else if (bus->parent && bus->parent->id) {
d271de9f 426 /* parent device has id -> use it for bus name */
ac7d1ba6 427 len = strlen(bus->parent->id) + 16;
7267c094 428 buf = g_malloc(len);
ac7d1ba6 429 snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
d271de9f
GH
430 bus->name = buf;
431 } else {
432 /* no id -> use lowercase bus type for bus name */
0d936928 433 len = strlen(typename) + 16;
7267c094 434 buf = g_malloc(len);
0d936928 435 len = snprintf(buf, len, "%s.%d", typename,
ac7d1ba6 436 bus->parent ? bus->parent->num_child_bus : 0);
d271de9f 437 for (i = 0; i < len; i++)
bb87ece5 438 buf[i] = qemu_tolower(buf[i]);
d271de9f
GH
439 bus->name = buf;
440 }
441
ac7d1ba6
AL
442 if (bus->parent) {
443 QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
444 bus->parent->num_child_bus++;
445 object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
b09995ae 446 object_unref(OBJECT(bus));
8185d216 447 } else if (bus != sysbus_get_default()) {
80376c3f
IY
448 /* TODO: once all bus devices are qdevified,
449 only reset handler for main_system_bus should be registered here. */
450 qemu_register_reset(qbus_reset_all_fn, bus);
02e2da45 451 }
cd739fb6
GH
452}
453
6853d27a
PB
454static void bus_unparent(Object *obj)
455{
456 BusState *bus = BUS(obj);
457 BusChild *kid;
458
459 while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
460 DeviceState *dev = kid->child;
461 qdev_free(dev);
462 }
463 if (bus->parent) {
464 QLIST_REMOVE(bus, sibling);
465 bus->parent->num_child_bus--;
466 bus->parent = NULL;
467 } else {
468 assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
469 qemu_unregister_reset(qbus_reset_all_fn, bus);
470 }
471}
472
39355c38 473void qbus_create_inplace(void *bus, const char *typename,
0d936928 474 DeviceState *parent, const char *name)
cd739fb6 475{
0d936928 476 object_initialize(bus, typename);
013e1182 477 qbus_realize(bus, parent, name);
02e2da45 478}
cae4956e 479
0d936928 480BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
2da8bb92 481{
cd739fb6
GH
482 BusState *bus;
483
0d936928 484 bus = BUS(object_new(typename));
013e1182 485 qbus_realize(bus, parent, name);
ac7d1ba6 486
02e2da45 487 return bus;
2da8bb92
IY
488}
489
131ec1bd
GH
490void qbus_free(BusState *bus)
491{
dc7389b7 492 object_unparent(OBJECT(bus));
0d936928
AL
493}
494
495static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
496{
497 BusClass *bc = BUS_GET_CLASS(bus);
498
499 if (bc->get_fw_dev_path) {
500 return bc->get_fw_dev_path(dev);
131ec1bd 501 }
0d936928
AL
502
503 return NULL;
131ec1bd
GH
504}
505
1ca4d09a
GN
506static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
507{
508 int l = 0;
509
510 if (dev && dev->parent_bus) {
511 char *d;
512 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
0d936928
AL
513 d = bus_get_fw_dev_path(dev->parent_bus, dev);
514 if (d) {
1ca4d09a 515 l += snprintf(p + l, size - l, "%s", d);
7267c094 516 g_free(d);
1ca4d09a 517 } else {
bbfa18fc 518 return l;
1ca4d09a
GN
519 }
520 }
521 l += snprintf(p + l , size - l, "/");
522
523 return l;
524}
525
526char* qdev_get_fw_dev_path(DeviceState *dev)
527{
528 char path[128];
529 int l;
530
531 l = qdev_get_fw_dev_path_helper(dev, path, 128);
532
533 path[l-1] = '\0';
534
a5cf8262 535 return g_strdup(path);
1ca4d09a 536}
85ed303b 537
09e5ab63 538char *qdev_get_dev_path(DeviceState *dev)
85ed303b 539{
0d936928 540 BusClass *bc;
09e5ab63
AL
541
542 if (!dev || !dev->parent_bus) {
543 return NULL;
544 }
545
0d936928
AL
546 bc = BUS_GET_CLASS(dev->parent_bus);
547 if (bc->get_dev_path) {
548 return bc->get_dev_path(dev);
09e5ab63
AL
549 }
550
551 return NULL;
44677ded 552}
a5296ca9
AL
553
554/**
555 * Legacy property handling
556 */
557
57c9fafe 558static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
a5296ca9
AL
559 const char *name, Error **errp)
560{
57c9fafe 561 DeviceState *dev = DEVICE(obj);
a5296ca9
AL
562 Property *prop = opaque;
563
e3cb6ba6
PB
564 char buffer[1024];
565 char *ptr = buffer;
a5296ca9 566
e3cb6ba6
PB
567 prop->info->print(dev, prop, buffer, sizeof(buffer));
568 visit_type_str(v, &ptr, name, errp);
a5296ca9
AL
569}
570
57c9fafe 571static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
a5296ca9
AL
572 const char *name, Error **errp)
573{
57c9fafe 574 DeviceState *dev = DEVICE(obj);
a5296ca9 575 Property *prop = opaque;
e3cb6ba6
PB
576 Error *local_err = NULL;
577 char *ptr = NULL;
578 int ret;
a5296ca9 579
7983c8a3 580 if (dev->realized) {
b000dfbd 581 qdev_prop_set_after_realize(dev, name, errp);
a5296ca9
AL
582 return;
583 }
584
e3cb6ba6
PB
585 visit_type_str(v, &ptr, name, &local_err);
586 if (local_err) {
587 error_propagate(errp, local_err);
588 return;
589 }
a5296ca9 590
e3cb6ba6 591 ret = prop->info->parse(dev, prop, ptr);
7db4c4e8 592 error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
e3cb6ba6 593 g_free(ptr);
a5296ca9
AL
594}
595
596/**
597 * @qdev_add_legacy_property - adds a legacy property
598 *
599 * Do not use this is new code! Properties added through this interface will
ca2cc788 600 * be given names and types in the "legacy" namespace.
a5296ca9 601 *
68ee3569
PB
602 * Legacy properties are string versions of other OOM properties. The format
603 * of the string depends on the property type.
a5296ca9
AL
604 */
605void qdev_property_add_legacy(DeviceState *dev, Property *prop,
606 Error **errp)
607{
ca2cc788 608 gchar *name, *type;
a5296ca9 609
f3be016d
AL
610 /* Register pointer properties as legacy properties */
611 if (!prop->info->print && !prop->info->parse &&
612 (prop->info->set || prop->info->get)) {
68ee3569
PB
613 return;
614 }
f3be016d 615
ca2cc788 616 name = g_strdup_printf("legacy-%s", prop->name);
cafe5bdb
PB
617 type = g_strdup_printf("legacy<%s>",
618 prop->info->legacy_name ?: prop->info->name);
a5296ca9 619
57c9fafe 620 object_property_add(OBJECT(dev), name, type,
68ee3569
PB
621 prop->info->print ? qdev_get_legacy_property : prop->info->get,
622 prop->info->parse ? qdev_set_legacy_property : prop->info->set,
57c9fafe
AL
623 NULL,
624 prop, errp);
a5296ca9
AL
625
626 g_free(type);
ca2cc788
PB
627 g_free(name);
628}
629
630/**
631 * @qdev_property_add_static - add a @Property to a device.
632 *
633 * Static properties access data in a struct. The actual type of the
634 * property and the field depends on the property type.
635 */
636void qdev_property_add_static(DeviceState *dev, Property *prop,
637 Error **errp)
638{
fdae245f
PB
639 Error *local_err = NULL;
640 Object *obj = OBJECT(dev);
641
d822979b
PB
642 /*
643 * TODO qdev_prop_ptr does not have getters or setters. It must
644 * go now that it can be replaced with links. The test should be
645 * removed along with it: all static properties are read/write.
646 */
647 if (!prop->info->get && !prop->info->set) {
648 return;
649 }
650
fdae245f 651 object_property_add(obj, prop->name, prop->info->name,
57c9fafe 652 prop->info->get, prop->info->set,
dd0ba250 653 prop->info->release,
fdae245f
PB
654 prop, &local_err);
655
656 if (local_err) {
657 error_propagate(errp, local_err);
658 return;
659 }
660 if (prop->qtype == QTYPE_NONE) {
661 return;
662 }
663
664 if (prop->qtype == QTYPE_QBOOL) {
665 object_property_set_bool(obj, prop->defval, prop->name, &local_err);
666 } else if (prop->info->enum_table) {
667 object_property_set_str(obj, prop->info->enum_table[prop->defval],
668 prop->name, &local_err);
669 } else if (prop->qtype == QTYPE_QINT) {
670 object_property_set_int(obj, prop->defval, prop->name, &local_err);
671 }
672 assert_no_error(local_err);
6a146eba 673}
1de81d28 674
249d4172
AF
675static bool device_get_realized(Object *obj, Error **err)
676{
677 DeviceState *dev = DEVICE(obj);
678 return dev->realized;
679}
680
681static void device_set_realized(Object *obj, bool value, Error **err)
682{
683 DeviceState *dev = DEVICE(obj);
684 DeviceClass *dc = DEVICE_GET_CLASS(dev);
685 Error *local_err = NULL;
686
687 if (value && !dev->realized) {
249d4172
AF
688 if (!obj->parent && local_err == NULL) {
689 static int unattached_count;
690 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
691
692 object_property_add_child(container_get(qdev_get_machine(),
693 "/unattached"),
694 name, obj, &local_err);
695 g_free(name);
696 }
697
a7ddba52
IM
698 if (dc->realize) {
699 dc->realize(dev, &local_err);
700 }
701
249d4172
AF
702 if (qdev_get_vmsd(dev) && local_err == NULL) {
703 vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
704 dev->instance_id_alias,
705 dev->alias_required_for_version);
706 }
707 if (dev->hotplugged && local_err == NULL) {
708 device_reset(dev);
709 }
710 } else if (!value && dev->realized) {
fe6c2117
AF
711 if (qdev_get_vmsd(dev)) {
712 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
713 }
249d4172
AF
714 if (dc->unrealize) {
715 dc->unrealize(dev, &local_err);
716 }
717 }
718
719 if (local_err != NULL) {
720 error_propagate(err, local_err);
721 return;
722 }
723
724 dev->realized = value;
725}
726
9674bfe4
AL
727static void device_initfn(Object *obj)
728{
729 DeviceState *dev = DEVICE(obj);
bce54474 730 ObjectClass *class;
9674bfe4 731 Property *prop;
e769bdc2 732 Error *err = NULL;
9674bfe4
AL
733
734 if (qdev_hotplug) {
735 dev->hotplugged = 1;
736 qdev_hot_added = true;
737 }
738
739 dev->instance_id_alias = -1;
7983c8a3 740 dev->realized = false;
9674bfe4 741
249d4172
AF
742 object_property_add_bool(obj, "realized",
743 device_get_realized, device_set_realized, NULL);
744
bce54474
PB
745 class = object_get_class(OBJECT(dev));
746 do {
747 for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
e769bdc2
PM
748 qdev_property_add_legacy(dev, prop, &err);
749 assert_no_error(err);
750 qdev_property_add_static(dev, prop, &err);
751 assert_no_error(err);
bce54474 752 }
bce54474
PB
753 class = object_class_get_parent(class);
754 } while (class != object_class_by_name(TYPE_DEVICE));
b1fe9bcb
AF
755 qdev_prop_set_globals(dev, &err);
756 if (err != NULL) {
757 qerror_report_err(err);
758 error_free(err);
759 exit(1);
760 }
9674bfe4 761
f968fc68 762 object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
e769bdc2
PM
763 (Object **)&dev->parent_bus, &err);
764 assert_no_error(err);
9674bfe4
AL
765}
766
60adba37
AL
767/* Unlink device from bus and free the structure. */
768static void device_finalize(Object *obj)
769{
770 DeviceState *dev = DEVICE(obj);
06f7f2bb
PB
771 if (dev->opts) {
772 qemu_opts_del(dev->opts);
60adba37 773 }
60adba37
AL
774}
775
bce54474
PB
776static void device_class_base_init(ObjectClass *class, void *data)
777{
778 DeviceClass *klass = DEVICE_CLASS(class);
779
780 /* We explicitly look up properties in the superclasses,
781 * so do not propagate them to the subclasses.
782 */
783 klass->props = NULL;
60adba37
AL
784}
785
5d5b24d0 786static void device_unparent(Object *obj)
667d22d1
PB
787{
788 DeviceState *dev = DEVICE(obj);
06f7f2bb 789 BusState *bus;
0402a5d6 790 QObject *event_data;
b1ee5829 791 bool have_realized = dev->realized;
667d22d1 792
06f7f2bb
PB
793 while (dev->num_child_bus) {
794 bus = QLIST_FIRST(&dev->child_bus);
795 qbus_free(bus);
796 }
797 if (dev->realized) {
fe6c2117 798 object_property_set_bool(obj, false, "realized", NULL);
06f7f2bb
PB
799 }
800 if (dev->parent_bus) {
5d5b24d0 801 bus_remove_child(dev->parent_bus, dev);
62d7ba66
PB
802 object_unref(OBJECT(dev->parent_bus));
803 dev->parent_bus = NULL;
5d5b24d0 804 }
0402a5d6 805
b1ee5829
AL
806 /* Only send event if the device had been completely realized */
807 if (have_realized) {
808 gchar *path = object_get_canonical_path(OBJECT(dev));
809
810 if (dev->id) {
811 event_data = qobject_from_jsonf("{ 'device': %s, 'path': %s }",
812 dev->id, path);
813 } else {
814 event_data = qobject_from_jsonf("{ 'path': %s }", path);
815 }
816 monitor_protocol_event(QEVENT_DEVICE_DELETED, event_data);
817 qobject_decref(event_data);
818 g_free(path);
0402a5d6 819 }
667d22d1
PB
820}
821
822static void device_class_init(ObjectClass *class, void *data)
823{
249d4172
AF
824 DeviceClass *dc = DEVICE_CLASS(class);
825
5d5b24d0 826 class->unparent = device_unparent;
249d4172 827 dc->realize = device_realize;
fe6c2117 828 dc->unrealize = device_unrealize;
667d22d1
PB
829}
830
94afdadc
AL
831void device_reset(DeviceState *dev)
832{
833 DeviceClass *klass = DEVICE_GET_CLASS(dev);
834
835 if (klass->reset) {
836 klass->reset(dev);
837 }
838}
839
f05f6b4a
PB
840Object *qdev_get_machine(void)
841{
842 static Object *dev;
843
844 if (dev == NULL) {
dfe47e70 845 dev = container_get(object_get_root(), "/machine");
f05f6b4a
PB
846 }
847
848 return dev;
849}
850
8c43a6f0 851static const TypeInfo device_type_info = {
32fea402
AL
852 .name = TYPE_DEVICE,
853 .parent = TYPE_OBJECT,
854 .instance_size = sizeof(DeviceState),
9674bfe4 855 .instance_init = device_initfn,
60adba37 856 .instance_finalize = device_finalize,
bce54474 857 .class_base_init = device_class_base_init,
667d22d1 858 .class_init = device_class_init,
32fea402
AL
859 .abstract = true,
860 .class_size = sizeof(DeviceClass),
861};
862
ac7d1ba6
AL
863static void qbus_initfn(Object *obj)
864{
865 BusState *bus = BUS(obj);
866
867 QTAILQ_INIT(&bus->children);
868}
869
bbfa18fc
AK
870static char *default_bus_get_fw_dev_path(DeviceState *dev)
871{
872 return g_strdup(object_get_typename(OBJECT(dev)));
873}
874
6853d27a
PB
875static void bus_class_init(ObjectClass *class, void *data)
876{
bbfa18fc
AK
877 BusClass *bc = BUS_CLASS(class);
878
6853d27a 879 class->unparent = bus_unparent;
bbfa18fc 880 bc->get_fw_dev_path = default_bus_get_fw_dev_path;
6853d27a
PB
881}
882
ac7d1ba6
AL
883static void qbus_finalize(Object *obj)
884{
885 BusState *bus = BUS(obj);
ac7d1ba6 886
ac7d1ba6
AL
887 g_free((char *)bus->name);
888}
889
0d936928
AL
890static const TypeInfo bus_info = {
891 .name = TYPE_BUS,
892 .parent = TYPE_OBJECT,
893 .instance_size = sizeof(BusState),
894 .abstract = true,
895 .class_size = sizeof(BusClass),
ac7d1ba6
AL
896 .instance_init = qbus_initfn,
897 .instance_finalize = qbus_finalize,
6853d27a 898 .class_init = bus_class_init,
0d936928
AL
899};
900
83f7d43a 901static void qdev_register_types(void)
32fea402 902{
0d936928 903 type_register_static(&bus_info);
32fea402
AL
904 type_register_static(&device_type_info);
905}
906
83f7d43a 907type_init(qdev_register_types)