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