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