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