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