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