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