]> git.proxmox.com Git - mirror_qemu.git/blame - hw/core/qdev.c
qdev: Legacy properties are just strings
[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);
02a5c4c9 167 object_unparent(OBJECT(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) {
dcc20931 236 bc->reset(bus);
b4694b7c
IY
237 }
238 return 0;
239}
240
5af0a04b
IY
241void qdev_reset_all(DeviceState *dev)
242{
dcc20931 243 qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
5af0a04b
IY
244}
245
d0508c36
PB
246void qbus_reset_all(BusState *bus)
247{
dcc20931 248 qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
d0508c36
PB
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 */
02a5c4c9 261 object_unparent(OBJECT(dev));
3418bd25
GH
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
3418bd25
GH
283void qdev_machine_creation_done(void)
284{
285 /*
286 * ok, initial machine setup is done, starting from now we can
287 * only create hotpluggable devices
288 */
289 qdev_hotplug = 1;
290}
291
0ac8ef71
AW
292bool qdev_machine_modified(void)
293{
294 return qdev_hot_added || qdev_hot_removed;
295}
296
02e2da45 297BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 298{
02e2da45 299 return dev->parent_bus;
aae9460e
PB
300}
301
aae9460e
PB
302void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
303{
1e5b31e6
PC
304 dev->gpio_in = qemu_extend_irqs(dev->gpio_in, dev->num_gpio_in, handler,
305 dev, n);
306 dev->num_gpio_in += n;
aae9460e
PB
307}
308
309void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
310{
311 assert(dev->num_gpio_out == 0);
312 dev->num_gpio_out = n;
313 dev->gpio_out = pins;
314}
315
316qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
317{
318 assert(n >= 0 && n < dev->num_gpio_in);
319 return dev->gpio_in[n];
320}
321
322void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
323{
324 assert(n >= 0 && n < dev->num_gpio_out);
325 dev->gpio_out[n] = pin;
326}
327
02e2da45 328BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 329{
02e2da45 330 BusState *bus;
4d6ae674 331
72cf2d4f 332 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 333 if (strcmp(name, bus->name) == 0) {
02e2da45 334 return bus;
4d6ae674
PB
335 }
336 }
337 return NULL;
338}
339
0293214b
PB
340int qbus_walk_children(BusState *bus,
341 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
342 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
343 void *opaque)
81699d8a 344{
0866aca1 345 BusChild *kid;
81699d8a
AL
346 int err;
347
0293214b
PB
348 if (pre_busfn) {
349 err = pre_busfn(bus, opaque);
81699d8a
AL
350 if (err) {
351 return err;
352 }
353 }
354
0866aca1 355 QTAILQ_FOREACH(kid, &bus->children, sibling) {
0293214b
PB
356 err = qdev_walk_children(kid->child,
357 pre_devfn, pre_busfn,
358 post_devfn, post_busfn, opaque);
81699d8a
AL
359 if (err < 0) {
360 return err;
361 }
362 }
363
0293214b
PB
364 if (post_busfn) {
365 err = post_busfn(bus, opaque);
366 if (err) {
367 return err;
368 }
369 }
370
81699d8a
AL
371 return 0;
372}
373
0293214b
PB
374int qdev_walk_children(DeviceState *dev,
375 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
376 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
377 void *opaque)
81699d8a
AL
378{
379 BusState *bus;
380 int err;
381
0293214b
PB
382 if (pre_devfn) {
383 err = pre_devfn(dev, opaque);
81699d8a
AL
384 if (err) {
385 return err;
386 }
387 }
388
389 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
0293214b
PB
390 err = qbus_walk_children(bus, pre_devfn, pre_busfn,
391 post_devfn, post_busfn, opaque);
81699d8a
AL
392 if (err < 0) {
393 return err;
394 }
395 }
396
0293214b
PB
397 if (post_devfn) {
398 err = post_devfn(dev, opaque);
399 if (err) {
400 return err;
401 }
402 }
403
81699d8a
AL
404 return 0;
405}
406
a2ee6b4f 407DeviceState *qdev_find_recursive(BusState *bus, const char *id)
3418bd25 408{
0866aca1
AL
409 BusChild *kid;
410 DeviceState *ret;
3418bd25
GH
411 BusState *child;
412
0866aca1
AL
413 QTAILQ_FOREACH(kid, &bus->children, sibling) {
414 DeviceState *dev = kid->child;
415
416 if (dev->id && strcmp(dev->id, id) == 0) {
3418bd25 417 return dev;
0866aca1
AL
418 }
419
3418bd25
GH
420 QLIST_FOREACH(child, &dev->child_bus, sibling) {
421 ret = qdev_find_recursive(child, id);
422 if (ret) {
423 return ret;
424 }
425 }
426 }
427 return NULL;
428}
429
013e1182 430static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
02e2da45 431{
ac7d1ba6 432 const char *typename = object_get_typename(OBJECT(bus));
d271de9f
GH
433 char *buf;
434 int i,len;
02e2da45 435
013e1182
PB
436 bus->parent = parent;
437
438 if (name) {
439 bus->name = g_strdup(name);
ac7d1ba6 440 } else if (bus->parent && bus->parent->id) {
d271de9f 441 /* parent device has id -> use it for bus name */
ac7d1ba6 442 len = strlen(bus->parent->id) + 16;
7267c094 443 buf = g_malloc(len);
ac7d1ba6 444 snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
d271de9f
GH
445 bus->name = buf;
446 } else {
447 /* no id -> use lowercase bus type for bus name */
0d936928 448 len = strlen(typename) + 16;
7267c094 449 buf = g_malloc(len);
0d936928 450 len = snprintf(buf, len, "%s.%d", typename,
ac7d1ba6 451 bus->parent ? bus->parent->num_child_bus : 0);
d271de9f 452 for (i = 0; i < len; i++)
bb87ece5 453 buf[i] = qemu_tolower(buf[i]);
d271de9f
GH
454 bus->name = buf;
455 }
456
ac7d1ba6
AL
457 if (bus->parent) {
458 QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
459 bus->parent->num_child_bus++;
460 object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
b09995ae 461 object_unref(OBJECT(bus));
8185d216 462 } else if (bus != sysbus_get_default()) {
80376c3f
IY
463 /* TODO: once all bus devices are qdevified,
464 only reset handler for main_system_bus should be registered here. */
465 qemu_register_reset(qbus_reset_all_fn, bus);
02e2da45 466 }
cd739fb6
GH
467}
468
6853d27a
PB
469static void bus_unparent(Object *obj)
470{
471 BusState *bus = BUS(obj);
472 BusChild *kid;
473
474 while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
475 DeviceState *dev = kid->child;
02a5c4c9 476 object_unparent(OBJECT(dev));
6853d27a
PB
477 }
478 if (bus->parent) {
479 QLIST_REMOVE(bus, sibling);
480 bus->parent->num_child_bus--;
481 bus->parent = NULL;
482 } else {
483 assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
484 qemu_unregister_reset(qbus_reset_all_fn, bus);
485 }
486}
487
fb17dfe0 488void qbus_create_inplace(void *bus, size_t size, const char *typename,
0d936928 489 DeviceState *parent, const char *name)
cd739fb6 490{
213f0c4f 491 object_initialize(bus, size, typename);
013e1182 492 qbus_realize(bus, parent, name);
02e2da45 493}
cae4956e 494
0d936928 495BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
2da8bb92 496{
cd739fb6
GH
497 BusState *bus;
498
0d936928 499 bus = BUS(object_new(typename));
013e1182 500 qbus_realize(bus, parent, name);
ac7d1ba6 501
02e2da45 502 return bus;
2da8bb92
IY
503}
504
0d936928
AL
505static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
506{
507 BusClass *bc = BUS_GET_CLASS(bus);
508
509 if (bc->get_fw_dev_path) {
510 return bc->get_fw_dev_path(dev);
131ec1bd 511 }
0d936928
AL
512
513 return NULL;
131ec1bd
GH
514}
515
1ca4d09a
GN
516static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
517{
518 int l = 0;
519
520 if (dev && dev->parent_bus) {
521 char *d;
522 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
0d936928
AL
523 d = bus_get_fw_dev_path(dev->parent_bus, dev);
524 if (d) {
1ca4d09a 525 l += snprintf(p + l, size - l, "%s", d);
7267c094 526 g_free(d);
1ca4d09a 527 } else {
bbfa18fc 528 return l;
1ca4d09a
GN
529 }
530 }
531 l += snprintf(p + l , size - l, "/");
532
533 return l;
534}
535
536char* qdev_get_fw_dev_path(DeviceState *dev)
537{
538 char path[128];
539 int l;
540
541 l = qdev_get_fw_dev_path_helper(dev, path, 128);
542
543 path[l-1] = '\0';
544
a5cf8262 545 return g_strdup(path);
1ca4d09a 546}
85ed303b 547
09e5ab63 548char *qdev_get_dev_path(DeviceState *dev)
85ed303b 549{
0d936928 550 BusClass *bc;
09e5ab63
AL
551
552 if (!dev || !dev->parent_bus) {
553 return NULL;
554 }
555
0d936928
AL
556 bc = BUS_GET_CLASS(dev->parent_bus);
557 if (bc->get_dev_path) {
558 return bc->get_dev_path(dev);
09e5ab63
AL
559 }
560
561 return NULL;
44677ded 562}
a5296ca9
AL
563
564/**
565 * Legacy property handling
566 */
567
57c9fafe 568static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
a5296ca9
AL
569 const char *name, Error **errp)
570{
57c9fafe 571 DeviceState *dev = DEVICE(obj);
a5296ca9
AL
572 Property *prop = opaque;
573
e3cb6ba6
PB
574 char buffer[1024];
575 char *ptr = buffer;
a5296ca9 576
e3cb6ba6
PB
577 prop->info->print(dev, prop, buffer, sizeof(buffer));
578 visit_type_str(v, &ptr, name, errp);
a5296ca9
AL
579}
580
a5296ca9
AL
581/**
582 * @qdev_add_legacy_property - adds a legacy property
583 *
584 * Do not use this is new code! Properties added through this interface will
ca2cc788 585 * be given names and types in the "legacy" namespace.
a5296ca9 586 *
68ee3569
PB
587 * Legacy properties are string versions of other OOM properties. The format
588 * of the string depends on the property type.
a5296ca9
AL
589 */
590void qdev_property_add_legacy(DeviceState *dev, Property *prop,
591 Error **errp)
592{
7ce7ffe0 593 gchar *name;
a5296ca9 594
f3be016d 595 /* Register pointer properties as legacy properties */
03ff7770 596 if (!prop->info->print && prop->info->get) {
68ee3569
PB
597 return;
598 }
f3be016d 599
ca2cc788 600 name = g_strdup_printf("legacy-%s", prop->name);
7ce7ffe0 601 object_property_add(OBJECT(dev), name, "str",
68ee3569 602 prop->info->print ? qdev_get_legacy_property : prop->info->get,
03ff7770 603 NULL,
57c9fafe
AL
604 NULL,
605 prop, errp);
a5296ca9 606
ca2cc788
PB
607 g_free(name);
608}
609
610/**
611 * @qdev_property_add_static - add a @Property to a device.
612 *
613 * Static properties access data in a struct. The actual type of the
614 * property and the field depends on the property type.
615 */
616void qdev_property_add_static(DeviceState *dev, Property *prop,
617 Error **errp)
618{
fdae245f
PB
619 Error *local_err = NULL;
620 Object *obj = OBJECT(dev);
621
d822979b
PB
622 /*
623 * TODO qdev_prop_ptr does not have getters or setters. It must
624 * go now that it can be replaced with links. The test should be
625 * removed along with it: all static properties are read/write.
626 */
627 if (!prop->info->get && !prop->info->set) {
628 return;
629 }
630
fdae245f 631 object_property_add(obj, prop->name, prop->info->name,
57c9fafe 632 prop->info->get, prop->info->set,
dd0ba250 633 prop->info->release,
fdae245f
PB
634 prop, &local_err);
635
636 if (local_err) {
637 error_propagate(errp, local_err);
638 return;
639 }
640 if (prop->qtype == QTYPE_NONE) {
641 return;
642 }
643
644 if (prop->qtype == QTYPE_QBOOL) {
5433a0a8 645 object_property_set_bool(obj, prop->defval, prop->name, &error_abort);
fdae245f
PB
646 } else if (prop->info->enum_table) {
647 object_property_set_str(obj, prop->info->enum_table[prop->defval],
5433a0a8 648 prop->name, &error_abort);
fdae245f 649 } else if (prop->qtype == QTYPE_QINT) {
5433a0a8 650 object_property_set_int(obj, prop->defval, prop->name, &error_abort);
fdae245f 651 }
6a146eba 652}
1de81d28 653
249d4172
AF
654static bool device_get_realized(Object *obj, Error **err)
655{
656 DeviceState *dev = DEVICE(obj);
657 return dev->realized;
658}
659
660static void device_set_realized(Object *obj, bool value, Error **err)
661{
662 DeviceState *dev = DEVICE(obj);
663 DeviceClass *dc = DEVICE_GET_CLASS(dev);
664 Error *local_err = NULL;
665
666 if (value && !dev->realized) {
249d4172
AF
667 if (!obj->parent && local_err == NULL) {
668 static int unattached_count;
669 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
670
671 object_property_add_child(container_get(qdev_get_machine(),
672 "/unattached"),
673 name, obj, &local_err);
674 g_free(name);
675 }
676
a7ddba52
IM
677 if (dc->realize) {
678 dc->realize(dev, &local_err);
679 }
680
249d4172
AF
681 if (qdev_get_vmsd(dev) && local_err == NULL) {
682 vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
683 dev->instance_id_alias,
684 dev->alias_required_for_version);
685 }
686 if (dev->hotplugged && local_err == NULL) {
687 device_reset(dev);
688 }
689 } else if (!value && dev->realized) {
fe6c2117
AF
690 if (qdev_get_vmsd(dev)) {
691 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
692 }
249d4172
AF
693 if (dc->unrealize) {
694 dc->unrealize(dev, &local_err);
695 }
696 }
697
698 if (local_err != NULL) {
699 error_propagate(err, local_err);
700 return;
701 }
702
703 dev->realized = value;
704}
705
9674bfe4
AL
706static void device_initfn(Object *obj)
707{
708 DeviceState *dev = DEVICE(obj);
bce54474 709 ObjectClass *class;
9674bfe4
AL
710 Property *prop;
711
712 if (qdev_hotplug) {
713 dev->hotplugged = 1;
714 qdev_hot_added = true;
715 }
716
717 dev->instance_id_alias = -1;
7983c8a3 718 dev->realized = false;
9674bfe4 719
249d4172
AF
720 object_property_add_bool(obj, "realized",
721 device_get_realized, device_set_realized, NULL);
722
bce54474
PB
723 class = object_get_class(OBJECT(dev));
724 do {
725 for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
5433a0a8
PC
726 qdev_property_add_legacy(dev, prop, &error_abort);
727 qdev_property_add_static(dev, prop, &error_abort);
bce54474 728 }
bce54474
PB
729 class = object_class_get_parent(class);
730 } while (class != object_class_by_name(TYPE_DEVICE));
9674bfe4 731
f968fc68 732 object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
5433a0a8 733 (Object **)&dev->parent_bus, &error_abort);
9674bfe4
AL
734}
735
99a0b036
EH
736static void device_post_init(Object *obj)
737{
5433a0a8 738 qdev_prop_set_globals(DEVICE(obj), &error_abort);
99a0b036
EH
739}
740
60adba37
AL
741/* Unlink device from bus and free the structure. */
742static void device_finalize(Object *obj)
743{
744 DeviceState *dev = DEVICE(obj);
06f7f2bb
PB
745 if (dev->opts) {
746 qemu_opts_del(dev->opts);
60adba37 747 }
60adba37
AL
748}
749
bce54474
PB
750static void device_class_base_init(ObjectClass *class, void *data)
751{
752 DeviceClass *klass = DEVICE_CLASS(class);
753
754 /* We explicitly look up properties in the superclasses,
755 * so do not propagate them to the subclasses.
756 */
757 klass->props = NULL;
60adba37
AL
758}
759
5d5b24d0 760static void device_unparent(Object *obj)
667d22d1
PB
761{
762 DeviceState *dev = DEVICE(obj);
06f7f2bb 763 BusState *bus;
0402a5d6 764 QObject *event_data;
b1ee5829 765 bool have_realized = dev->realized;
667d22d1 766
06f7f2bb
PB
767 while (dev->num_child_bus) {
768 bus = QLIST_FIRST(&dev->child_bus);
6780a22c 769 object_unparent(OBJECT(bus));
06f7f2bb
PB
770 }
771 if (dev->realized) {
fe6c2117 772 object_property_set_bool(obj, false, "realized", NULL);
06f7f2bb
PB
773 }
774 if (dev->parent_bus) {
5d5b24d0 775 bus_remove_child(dev->parent_bus, dev);
62d7ba66
PB
776 object_unref(OBJECT(dev->parent_bus));
777 dev->parent_bus = NULL;
5d5b24d0 778 }
0402a5d6 779
b1ee5829
AL
780 /* Only send event if the device had been completely realized */
781 if (have_realized) {
782 gchar *path = object_get_canonical_path(OBJECT(dev));
783
784 if (dev->id) {
785 event_data = qobject_from_jsonf("{ 'device': %s, 'path': %s }",
786 dev->id, path);
787 } else {
788 event_data = qobject_from_jsonf("{ 'path': %s }", path);
789 }
790 monitor_protocol_event(QEVENT_DEVICE_DELETED, event_data);
791 qobject_decref(event_data);
792 g_free(path);
0402a5d6 793 }
667d22d1
PB
794}
795
796static void device_class_init(ObjectClass *class, void *data)
797{
249d4172
AF
798 DeviceClass *dc = DEVICE_CLASS(class);
799
5d5b24d0 800 class->unparent = device_unparent;
249d4172 801 dc->realize = device_realize;
fe6c2117 802 dc->unrealize = device_unrealize;
667d22d1
PB
803}
804
94afdadc
AL
805void device_reset(DeviceState *dev)
806{
807 DeviceClass *klass = DEVICE_GET_CLASS(dev);
808
809 if (klass->reset) {
810 klass->reset(dev);
811 }
812}
813
f05f6b4a
PB
814Object *qdev_get_machine(void)
815{
816 static Object *dev;
817
818 if (dev == NULL) {
dfe47e70 819 dev = container_get(object_get_root(), "/machine");
f05f6b4a
PB
820 }
821
822 return dev;
823}
824
8c43a6f0 825static const TypeInfo device_type_info = {
32fea402
AL
826 .name = TYPE_DEVICE,
827 .parent = TYPE_OBJECT,
828 .instance_size = sizeof(DeviceState),
9674bfe4 829 .instance_init = device_initfn,
99a0b036 830 .instance_post_init = device_post_init,
60adba37 831 .instance_finalize = device_finalize,
bce54474 832 .class_base_init = device_class_base_init,
667d22d1 833 .class_init = device_class_init,
32fea402
AL
834 .abstract = true,
835 .class_size = sizeof(DeviceClass),
836};
837
ac7d1ba6
AL
838static void qbus_initfn(Object *obj)
839{
840 BusState *bus = BUS(obj);
841
842 QTAILQ_INIT(&bus->children);
843}
844
bbfa18fc
AK
845static char *default_bus_get_fw_dev_path(DeviceState *dev)
846{
847 return g_strdup(object_get_typename(OBJECT(dev)));
848}
849
6853d27a
PB
850static void bus_class_init(ObjectClass *class, void *data)
851{
bbfa18fc
AK
852 BusClass *bc = BUS_CLASS(class);
853
6853d27a 854 class->unparent = bus_unparent;
bbfa18fc 855 bc->get_fw_dev_path = default_bus_get_fw_dev_path;
6853d27a
PB
856}
857
ac7d1ba6
AL
858static void qbus_finalize(Object *obj)
859{
860 BusState *bus = BUS(obj);
ac7d1ba6 861
ac7d1ba6
AL
862 g_free((char *)bus->name);
863}
864
0d936928
AL
865static const TypeInfo bus_info = {
866 .name = TYPE_BUS,
867 .parent = TYPE_OBJECT,
868 .instance_size = sizeof(BusState),
869 .abstract = true,
870 .class_size = sizeof(BusClass),
ac7d1ba6
AL
871 .instance_init = qbus_initfn,
872 .instance_finalize = qbus_finalize,
6853d27a 873 .class_init = bus_class_init,
0d936928
AL
874};
875
83f7d43a 876static void qdev_register_types(void)
32fea402 877{
0d936928 878 type_register_static(&bus_info);
32fea402
AL
879 type_register_static(&device_type_info);
880}
881
83f7d43a 882type_init(qdev_register_types)