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