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