]> Git Repo - qemu.git/blame - hw/core/qdev.c
qom: Swap 'name' next to visitor in ObjectPropertyAccessor
[qemu.git] / hw / core / 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
18c86e2b 28#include "qemu/osdep.h"
83c9f4ca 29#include "hw/qdev.h"
6b1566cb 30#include "hw/fw-path-provider.h"
9c17d615 31#include "sysemu/sysemu.h"
b4a42f81 32#include "qapi/qmp/qerror.h"
7b1b5d19 33#include "qapi/visitor.h"
0402a5d6 34#include "qapi/qmp/qjson.h"
d49b6836 35#include "qemu/error-report.h"
0ee4de6c 36#include "hw/hotplug.h"
b7454548 37#include "hw/boards.h"
24b699fb 38#include "qapi-event.h"
aae9460e 39
ee46d8a5 40int qdev_hotplug = 0;
0ac8ef71
AW
41static bool qdev_hot_added = false;
42static bool qdev_hot_removed = false;
3418bd25 43
4be9f0d1
AL
44const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
45{
6e008585
AL
46 DeviceClass *dc = DEVICE_GET_CLASS(dev);
47 return dc->vmsd;
4be9f0d1
AL
48}
49
4be9f0d1
AL
50const char *qdev_fw_name(DeviceState *dev)
51{
6e008585 52 DeviceClass *dc = DEVICE_GET_CLASS(dev);
4be9f0d1 53
6e008585
AL
54 if (dc->fw_name) {
55 return dc->fw_name;
4be9f0d1
AL
56 }
57
58 return object_get_typename(OBJECT(dev));
59}
60
ca2cc788
PB
61static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
62 Error **errp);
63
0866aca1 64static void bus_remove_child(BusState *bus, DeviceState *child)
0c17542d 65{
0866aca1
AL
66 BusChild *kid;
67
68 QTAILQ_FOREACH(kid, &bus->children, sibling) {
69 if (kid->child == child) {
70 char name[32];
71
72 snprintf(name, sizeof(name), "child[%d]", kid->index);
73 QTAILQ_REMOVE(&bus->children, kid, sibling);
9d127820
PB
74
75 /* This gives back ownership of kid->child back to us. */
0866aca1 76 object_property_del(OBJECT(bus), name, NULL);
9d127820 77 object_unref(OBJECT(kid->child));
0866aca1
AL
78 g_free(kid);
79 return;
80 }
81 }
82}
83
84static void bus_add_child(BusState *bus, DeviceState *child)
85{
86 char name[32];
87 BusChild *kid = g_malloc0(sizeof(*kid));
0c17542d 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)),
39f72ef9
SH
99 (Object **)&kid->child,
100 NULL, /* read-only property */
101 0, /* return ownership on prop deletion */
102 NULL);
0866aca1
AL
103}
104
105void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
106{
9fbe6127 107 dev->parent_bus = bus;
62d7ba66 108 object_ref(OBJECT(bus));
0866aca1 109 bus_add_child(bus, dev);
0c17542d
MA
110}
111
431bbb26
IM
112static void qbus_set_hotplug_handler_internal(BusState *bus, Object *handler,
113 Error **errp)
114{
115
116 object_property_set_link(OBJECT(bus), OBJECT(handler),
117 QDEV_HOTPLUG_HANDLER_PROPERTY, errp);
431bbb26
IM
118}
119
120void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler, Error **errp)
121{
122 qbus_set_hotplug_handler_internal(bus, OBJECT(handler), errp);
123}
124
125void qbus_set_bus_hotplug_handler(BusState *bus, Error **errp)
126{
127 qbus_set_hotplug_handler_internal(bus, OBJECT(bus), errp);
128}
129
0210afe6
MA
130/* Create a new device. This only initializes the device state
131 structure and allows properties to be set. The device still needs
132 to be realized. See qdev-core.h. */
02e2da45 133DeviceState *qdev_create(BusState *bus, const char *name)
0bcdeda7
BS
134{
135 DeviceState *dev;
136
137 dev = qdev_try_create(bus, name);
138 if (!dev) {
e92714c7 139 if (bus) {
312fd5f2 140 error_report("Unknown device '%s' for bus '%s'", name,
23e3fbec 141 object_get_typename(OBJECT(bus)));
e92714c7 142 } else {
312fd5f2 143 error_report("Unknown device '%s' for default sysbus", name);
e92714c7 144 }
01ed1d52 145 abort();
0bcdeda7
BS
146 }
147
148 return dev;
149}
150
da57febf 151DeviceState *qdev_try_create(BusState *bus, const char *type)
aae9460e 152{
9fbe6127
AL
153 DeviceState *dev;
154
da57febf 155 if (object_class_by_name(type) == NULL) {
4ed658ca
AF
156 return NULL;
157 }
da57febf 158 dev = DEVICE(object_new(type));
9fbe6127
AL
159 if (!dev) {
160 return NULL;
161 }
162
10c4c98a 163 if (!bus) {
68694897 164 bus = sysbus_get_default();
10c4c98a
GH
165 }
166
9fbe6127 167 qdev_set_parent_bus(dev, bus);
b09995ae 168 object_unref(OBJECT(dev));
9fbe6127 169 return dev;
aae9460e
PB
170}
171
707ff800
PD
172static QTAILQ_HEAD(device_listeners, DeviceListener) device_listeners
173 = QTAILQ_HEAD_INITIALIZER(device_listeners);
174
175enum ListenerDirection { Forward, Reverse };
176
177#define DEVICE_LISTENER_CALL(_callback, _direction, _args...) \
178 do { \
179 DeviceListener *_listener; \
180 \
181 switch (_direction) { \
182 case Forward: \
183 QTAILQ_FOREACH(_listener, &device_listeners, link) { \
184 if (_listener->_callback) { \
185 _listener->_callback(_listener, ##_args); \
186 } \
187 } \
188 break; \
189 case Reverse: \
190 QTAILQ_FOREACH_REVERSE(_listener, &device_listeners, \
191 device_listeners, link) { \
192 if (_listener->_callback) { \
193 _listener->_callback(_listener, ##_args); \
194 } \
195 } \
196 break; \
197 default: \
198 abort(); \
199 } \
200 } while (0)
201
202static int device_listener_add(DeviceState *dev, void *opaque)
203{
204 DEVICE_LISTENER_CALL(realize, Forward, dev);
205
206 return 0;
207}
208
209void device_listener_register(DeviceListener *listener)
210{
211 QTAILQ_INSERT_TAIL(&device_listeners, listener, link);
212
213 qbus_walk_children(sysbus_get_default(), NULL, NULL, device_listener_add,
214 NULL, NULL);
215}
216
217void device_listener_unregister(DeviceListener *listener)
218{
219 QTAILQ_REMOVE(&device_listeners, listener, link);
220}
221
a7737e44 222static void device_realize(DeviceState *dev, Error **errp)
249d4172
AF
223{
224 DeviceClass *dc = DEVICE_GET_CLASS(dev);
da57febf 225
249d4172
AF
226 if (dc->init) {
227 int rc = dc->init(dev);
228 if (rc < 0) {
a7737e44 229 error_setg(errp, "Device initialization failed.");
249d4172
AF
230 return;
231 }
5ab28c83 232 }
02e2da45
PB
233}
234
fe6c2117
AF
235static void device_unrealize(DeviceState *dev, Error **errp)
236{
237 DeviceClass *dc = DEVICE_GET_CLASS(dev);
238
239 if (dc->exit) {
240 int rc = dc->exit(dev);
241 if (rc < 0) {
242 error_setg(errp, "Device exit failed.");
243 return;
244 }
245 }
246}
247
4d2ffa08
JK
248void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
249 int required_for_version)
250{
7983c8a3 251 assert(!dev->realized);
4d2ffa08
JK
252 dev->instance_id_alias = alias_id;
253 dev->alias_required_for_version = required_for_version;
254}
255
c06b2ffb 256HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
7716b8ca
IM
257{
258 HotplugHandler *hotplug_ctrl = NULL;
259
260 if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
261 hotplug_ctrl = dev->parent_bus->hotplug_handler;
262 } else if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
263 MachineState *machine = MACHINE(qdev_get_machine());
264 MachineClass *mc = MACHINE_GET_CLASS(machine);
265
266 if (mc->get_hotplug_handler) {
267 hotplug_ctrl = mc->get_hotplug_handler(machine, dev);
268 }
269 }
270 return hotplug_ctrl;
271}
272
56f9107e 273void qdev_unplug(DeviceState *dev, Error **errp)
3418bd25 274{
6e008585 275 DeviceClass *dc = DEVICE_GET_CLASS(dev);
7716b8ca
IM
276 HotplugHandler *hotplug_ctrl;
277 HotplugHandlerClass *hdc;
6e008585 278
39b888bd 279 if (dev->parent_bus && !qbus_is_hotpluggable(dev->parent_bus)) {
c6bd8c70 280 error_setg(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
56f9107e 281 return;
3418bd25 282 }
593831de 283
1a37eca1 284 if (!dc->hotpluggable) {
c6bd8c70
MA
285 error_setg(errp, QERR_DEVICE_NO_HOTPLUG,
286 object_get_typename(OBJECT(dev)));
1a37eca1
IM
287 return;
288 }
289
0ac8ef71
AW
290 qdev_hot_removed = true;
291
7716b8ca
IM
292 hotplug_ctrl = qdev_get_hotplug_handler(dev);
293 /* hotpluggable device MUST have HotplugHandler, if it doesn't
294 * then something is very wrong with it */
295 g_assert(hotplug_ctrl);
296
297 /* If device supports async unplug just request it to be done,
298 * otherwise just remove it synchronously */
299 hdc = HOTPLUG_HANDLER_GET_CLASS(hotplug_ctrl);
300 if (hdc->unplug_request) {
301 hotplug_handler_unplug_request(hotplug_ctrl, dev, errp);
5e954943 302 } else {
7716b8ca 303 hotplug_handler_unplug(hotplug_ctrl, dev, errp);
56f9107e 304 }
3418bd25
GH
305}
306
ec990eb6
AL
307static int qdev_reset_one(DeviceState *dev, void *opaque)
308{
94afdadc 309 device_reset(dev);
ec990eb6
AL
310
311 return 0;
312}
313
b4694b7c
IY
314static int qbus_reset_one(BusState *bus, void *opaque)
315{
0d936928
AL
316 BusClass *bc = BUS_GET_CLASS(bus);
317 if (bc->reset) {
dcc20931 318 bc->reset(bus);
b4694b7c
IY
319 }
320 return 0;
321}
322
5af0a04b
IY
323void qdev_reset_all(DeviceState *dev)
324{
dcc20931 325 qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
5af0a04b
IY
326}
327
ff8de075
DH
328void qdev_reset_all_fn(void *opaque)
329{
330 qdev_reset_all(DEVICE(opaque));
331}
332
d0508c36
PB
333void qbus_reset_all(BusState *bus)
334{
dcc20931 335 qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
d0508c36
PB
336}
337
80376c3f
IY
338void qbus_reset_all_fn(void *opaque)
339{
340 BusState *bus = opaque;
d0508c36 341 qbus_reset_all(bus);
80376c3f
IY
342}
343
3418bd25 344/* can be used as ->unplug() callback for the simple cases */
014176f9
IM
345void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
346 DeviceState *dev, Error **errp)
347{
2d9a982f
IM
348 /* just zap it */
349 object_unparent(OBJECT(dev));
014176f9 350}
3b29a101 351
0210afe6
MA
352/*
353 * Realize @dev.
354 * Device properties should be set before calling this function. IRQs
355 * and MMIO regions should be connected/mapped after calling this
356 * function.
357 * On failure, report an error with error_report() and terminate the
358 * program. This is okay during machine creation. Don't use for
359 * hotplug, because there callers need to recover from failure.
360 * Exception: if you know the device's init() callback can't fail,
361 * then qdev_init_nofail() can't fail either, and is therefore usable
362 * even then. But relying on the device implementation that way is
363 * somewhat unclean, and best avoided.
364 */
e23a1b33
MA
365void qdev_init_nofail(DeviceState *dev)
366{
c4bacafb 367 Error *err = NULL;
7de3abe5 368
c4bacafb
MA
369 assert(!dev->realized);
370
371 object_property_set_bool(OBJECT(dev), true, "realized", &err);
372 if (err) {
c29b77f9
MA
373 error_reportf_err(err, "Initialization of device %s failed: ",
374 object_get_typename(OBJECT(dev)));
bd6c9a61
MA
375 exit(1);
376 }
e23a1b33
MA
377}
378
3418bd25
GH
379void qdev_machine_creation_done(void)
380{
381 /*
382 * ok, initial machine setup is done, starting from now we can
383 * only create hotpluggable devices
384 */
385 qdev_hotplug = 1;
386}
387
0ac8ef71
AW
388bool qdev_machine_modified(void)
389{
390 return qdev_hot_added || qdev_hot_removed;
391}
392
02e2da45 393BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 394{
02e2da45 395 return dev->parent_bus;
aae9460e
PB
396}
397
a5f54290
PC
398static NamedGPIOList *qdev_get_named_gpio_list(DeviceState *dev,
399 const char *name)
400{
401 NamedGPIOList *ngl;
402
403 QLIST_FOREACH(ngl, &dev->gpios, node) {
404 /* NULL is a valid and matchable name, otherwise do a normal
405 * strcmp match.
406 */
407 if ((!ngl->name && !name) ||
408 (name && ngl->name && strcmp(name, ngl->name) == 0)) {
409 return ngl;
410 }
411 }
412
413 ngl = g_malloc0(sizeof(*ngl));
414 ngl->name = g_strdup(name);
415 QLIST_INSERT_HEAD(&dev->gpios, ngl, node);
416 return ngl;
417}
418
419void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler,
420 const char *name, int n)
421{
a69bef1c 422 int i;
a5f54290
PC
423 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
424
b235a71f 425 assert(gpio_list->num_out == 0 || !name);
a5f54290
PC
426 gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler,
427 dev, n);
a69bef1c 428
6c76b377
PF
429 if (!name) {
430 name = "unnamed-gpio-in";
431 }
a69bef1c 432 for (i = gpio_list->num_in; i < gpio_list->num_in + n; i++) {
6c76b377
PF
433 gchar *propname = g_strdup_printf("%s[%u]", name, i);
434
a69bef1c
PC
435 object_property_add_child(OBJECT(dev), propname,
436 OBJECT(gpio_list->in[i]), &error_abort);
6c76b377 437 g_free(propname);
a69bef1c 438 }
a69bef1c 439
a5f54290
PC
440 gpio_list->num_in += n;
441}
442
aae9460e
PB
443void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
444{
a5f54290
PC
445 qdev_init_gpio_in_named(dev, handler, NULL, n);
446}
447
448void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins,
449 const char *name, int n)
450{
688b057a 451 int i;
a5f54290
PC
452 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
453
b235a71f 454 assert(gpio_list->num_in == 0 || !name);
688b057a 455
6c76b377
PF
456 if (!name) {
457 name = "unnamed-gpio-out";
458 }
459 memset(pins, 0, sizeof(*pins) * n);
688b057a 460 for (i = 0; i < n; ++i) {
6c76b377
PF
461 gchar *propname = g_strdup_printf("%s[%u]", name,
462 gpio_list->num_out + i);
463
688b057a
PC
464 object_property_add_link(OBJECT(dev), propname, TYPE_IRQ,
465 (Object **)&pins[i],
466 object_property_allow_set_link,
467 OBJ_PROP_LINK_UNREF_ON_RELEASE,
468 &error_abort);
6c76b377 469 g_free(propname);
688b057a 470 }
6c76b377 471 gpio_list->num_out += n;
aae9460e
PB
472}
473
474void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
475{
a5f54290
PC
476 qdev_init_gpio_out_named(dev, pins, NULL, n);
477}
478
479qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n)
480{
481 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
482
483 assert(n >= 0 && n < gpio_list->num_in);
484 return gpio_list->in[n];
aae9460e
PB
485}
486
487qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
488{
a5f54290
PC
489 return qdev_get_gpio_in_named(dev, NULL, n);
490}
491
492void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
493 qemu_irq pin)
494{
02757df2
PC
495 char *propname = g_strdup_printf("%s[%d]",
496 name ? name : "unnamed-gpio-out", n);
497 if (pin) {
498 /* We need a name for object_property_set_link to work. If the
499 * object has a parent, object_property_add_child will come back
500 * with an error without doing anything. If it has none, it will
501 * never fail. So we can just call it with a NULL Error pointer.
502 */
88950eef
AF
503 object_property_add_child(container_get(qdev_get_machine(),
504 "/unattached"),
505 "non-qdev-gpio[*]", OBJECT(pin), NULL);
02757df2
PC
506 }
507 object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort);
508 g_free(propname);
aae9460e
PB
509}
510
b7973186
AG
511qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n)
512{
513 char *propname = g_strdup_printf("%s[%d]",
514 name ? name : "unnamed-gpio-out", n);
515
516 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
517 NULL);
518
519 return ret;
520}
521
67cc32eb 522/* disconnect a GPIO output, returning the disconnected input (if any) */
0c24db2b
PC
523
524static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev,
525 const char *name, int n)
526{
527 char *propname = g_strdup_printf("%s[%d]",
528 name ? name : "unnamed-gpio-out", n);
529
530 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
531 NULL);
532 if (ret) {
533 object_property_set_link(OBJECT(dev), NULL, propname, NULL);
534 }
535 g_free(propname);
536 return ret;
537}
a5f54290 538
0c24db2b
PC
539qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt,
540 const char *name, int n)
541{
542 qemu_irq disconnected = qdev_disconnect_gpio_out_named(dev, name, n);
543 qdev_connect_gpio_out_named(dev, name, n, icpt);
544 return disconnected;
aae9460e
PB
545}
546
547void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
548{
a5f54290 549 qdev_connect_gpio_out_named(dev, NULL, n, pin);
aae9460e
PB
550}
551
17a96a14
PC
552void qdev_pass_gpios(DeviceState *dev, DeviceState *container,
553 const char *name)
554{
555 int i;
556 NamedGPIOList *ngl = qdev_get_named_gpio_list(dev, name);
557
558 for (i = 0; i < ngl->num_in; i++) {
559 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-in";
560 char *propname = g_strdup_printf("%s[%d]", nm, i);
561
562 object_property_add_alias(OBJECT(container), propname,
563 OBJECT(dev), propname,
564 &error_abort);
6bc5cf92 565 g_free(propname);
17a96a14
PC
566 }
567 for (i = 0; i < ngl->num_out; i++) {
568 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-out";
569 char *propname = g_strdup_printf("%s[%d]", nm, i);
570
571 object_property_add_alias(OBJECT(container), propname,
572 OBJECT(dev), propname,
573 &error_abort);
6bc5cf92 574 g_free(propname);
17a96a14
PC
575 }
576 QLIST_REMOVE(ngl, node);
577 QLIST_INSERT_HEAD(&container->gpios, ngl, node);
578}
579
02e2da45 580BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 581{
02e2da45 582 BusState *bus;
f698c8ba
PC
583 Object *child = object_resolve_path_component(OBJECT(dev), name);
584
585 bus = (BusState *)object_dynamic_cast(child, TYPE_BUS);
586 if (bus) {
587 return bus;
588 }
4d6ae674 589
72cf2d4f 590 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 591 if (strcmp(name, bus->name) == 0) {
02e2da45 592 return bus;
4d6ae674
PB
593 }
594 }
595 return NULL;
596}
597
0293214b
PB
598int qbus_walk_children(BusState *bus,
599 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
600 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
601 void *opaque)
81699d8a 602{
0866aca1 603 BusChild *kid;
81699d8a
AL
604 int err;
605
0293214b
PB
606 if (pre_busfn) {
607 err = pre_busfn(bus, opaque);
81699d8a
AL
608 if (err) {
609 return err;
610 }
611 }
612
0866aca1 613 QTAILQ_FOREACH(kid, &bus->children, sibling) {
0293214b
PB
614 err = qdev_walk_children(kid->child,
615 pre_devfn, pre_busfn,
616 post_devfn, post_busfn, opaque);
81699d8a
AL
617 if (err < 0) {
618 return err;
619 }
620 }
621
0293214b
PB
622 if (post_busfn) {
623 err = post_busfn(bus, opaque);
624 if (err) {
625 return err;
626 }
627 }
628
81699d8a
AL
629 return 0;
630}
631
0293214b
PB
632int qdev_walk_children(DeviceState *dev,
633 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
634 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
635 void *opaque)
81699d8a
AL
636{
637 BusState *bus;
638 int err;
639
0293214b
PB
640 if (pre_devfn) {
641 err = pre_devfn(dev, opaque);
81699d8a
AL
642 if (err) {
643 return err;
644 }
645 }
646
647 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
0293214b
PB
648 err = qbus_walk_children(bus, pre_devfn, pre_busfn,
649 post_devfn, post_busfn, opaque);
81699d8a
AL
650 if (err < 0) {
651 return err;
652 }
653 }
654
0293214b
PB
655 if (post_devfn) {
656 err = post_devfn(dev, opaque);
657 if (err) {
658 return err;
659 }
660 }
661
81699d8a
AL
662 return 0;
663}
664
a2ee6b4f 665DeviceState *qdev_find_recursive(BusState *bus, const char *id)
3418bd25 666{
0866aca1
AL
667 BusChild *kid;
668 DeviceState *ret;
3418bd25
GH
669 BusState *child;
670
0866aca1
AL
671 QTAILQ_FOREACH(kid, &bus->children, sibling) {
672 DeviceState *dev = kid->child;
673
674 if (dev->id && strcmp(dev->id, id) == 0) {
3418bd25 675 return dev;
0866aca1
AL
676 }
677
3418bd25
GH
678 QLIST_FOREACH(child, &dev->child_bus, sibling) {
679 ret = qdev_find_recursive(child, id);
680 if (ret) {
681 return ret;
682 }
683 }
684 }
685 return NULL;
686}
687
013e1182 688static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
02e2da45 689{
ac7d1ba6 690 const char *typename = object_get_typename(OBJECT(bus));
61de3676 691 BusClass *bc;
d271de9f 692 char *buf;
61de3676 693 int i, len, bus_id;
02e2da45 694
013e1182
PB
695 bus->parent = parent;
696
697 if (name) {
698 bus->name = g_strdup(name);
ac7d1ba6 699 } else if (bus->parent && bus->parent->id) {
61de3676
AG
700 /* parent device has id -> use it plus parent-bus-id for bus name */
701 bus_id = bus->parent->num_child_bus;
702
ac7d1ba6 703 len = strlen(bus->parent->id) + 16;
7267c094 704 buf = g_malloc(len);
61de3676 705 snprintf(buf, len, "%s.%d", bus->parent->id, bus_id);
d271de9f
GH
706 bus->name = buf;
707 } else {
61de3676
AG
708 /* no id -> use lowercase bus type plus global bus-id for bus name */
709 bc = BUS_GET_CLASS(bus);
710 bus_id = bc->automatic_ids++;
711
0d936928 712 len = strlen(typename) + 16;
7267c094 713 buf = g_malloc(len);
61de3676
AG
714 len = snprintf(buf, len, "%s.%d", typename, bus_id);
715 for (i = 0; i < len; i++) {
bb87ece5 716 buf[i] = qemu_tolower(buf[i]);
61de3676 717 }
d271de9f
GH
718 bus->name = buf;
719 }
720
ac7d1ba6
AL
721 if (bus->parent) {
722 QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
723 bus->parent->num_child_bus++;
724 object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
b09995ae 725 object_unref(OBJECT(bus));
8185d216 726 } else if (bus != sysbus_get_default()) {
80376c3f
IY
727 /* TODO: once all bus devices are qdevified,
728 only reset handler for main_system_bus should be registered here. */
729 qemu_register_reset(qbus_reset_all_fn, bus);
02e2da45 730 }
cd739fb6
GH
731}
732
6853d27a
PB
733static void bus_unparent(Object *obj)
734{
735 BusState *bus = BUS(obj);
736 BusChild *kid;
737
738 while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
739 DeviceState *dev = kid->child;
02a5c4c9 740 object_unparent(OBJECT(dev));
6853d27a
PB
741 }
742 if (bus->parent) {
743 QLIST_REMOVE(bus, sibling);
744 bus->parent->num_child_bus--;
745 bus->parent = NULL;
746 } else {
747 assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
748 qemu_unregister_reset(qbus_reset_all_fn, bus);
749 }
750}
751
a7737e44 752static bool bus_get_realized(Object *obj, Error **errp)
02e7f85d
BD
753{
754 BusState *bus = BUS(obj);
755
756 return bus->realized;
757}
758
a7737e44 759static void bus_set_realized(Object *obj, bool value, Error **errp)
02e7f85d
BD
760{
761 BusState *bus = BUS(obj);
762 BusClass *bc = BUS_GET_CLASS(bus);
5942a190 763 BusChild *kid;
02e7f85d
BD
764 Error *local_err = NULL;
765
766 if (value && !bus->realized) {
767 if (bc->realize) {
768 bc->realize(bus, &local_err);
02e7f85d 769 }
5942a190
PB
770
771 /* TODO: recursive realization */
02e7f85d 772 } else if (!value && bus->realized) {
5942a190
PB
773 QTAILQ_FOREACH(kid, &bus->children, sibling) {
774 DeviceState *dev = kid->child;
775 object_property_set_bool(OBJECT(dev), false, "realized",
776 &local_err);
777 if (local_err != NULL) {
778 break;
779 }
780 }
781 if (bc->unrealize && local_err == NULL) {
02e7f85d 782 bc->unrealize(bus, &local_err);
02e7f85d
BD
783 }
784 }
785
b7b34d05
PB
786 if (local_err != NULL) {
787 error_propagate(errp, local_err);
788 return;
789 }
02e7f85d 790
b7b34d05 791 bus->realized = value;
02e7f85d
BD
792}
793
fb17dfe0 794void qbus_create_inplace(void *bus, size_t size, const char *typename,
0d936928 795 DeviceState *parent, const char *name)
cd739fb6 796{
213f0c4f 797 object_initialize(bus, size, typename);
013e1182 798 qbus_realize(bus, parent, name);
02e2da45 799}
cae4956e 800
0d936928 801BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
2da8bb92 802{
cd739fb6
GH
803 BusState *bus;
804
0d936928 805 bus = BUS(object_new(typename));
013e1182 806 qbus_realize(bus, parent, name);
ac7d1ba6 807
02e2da45 808 return bus;
2da8bb92
IY
809}
810
0d936928
AL
811static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
812{
813 BusClass *bc = BUS_GET_CLASS(bus);
814
815 if (bc->get_fw_dev_path) {
816 return bc->get_fw_dev_path(dev);
131ec1bd 817 }
0d936928
AL
818
819 return NULL;
131ec1bd
GH
820}
821
6b1566cb
PB
822static char *qdev_get_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
823{
824 Object *obj = OBJECT(dev);
825 char *d = NULL;
826
827 while (!d && obj->parent) {
828 obj = obj->parent;
829 d = fw_path_provider_try_get_dev_path(obj, bus, dev);
830 }
831 return d;
832}
833
0be63901
GA
834char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
835{
836 Object *obj = OBJECT(dev);
837
838 return fw_path_provider_try_get_dev_path(obj, bus, dev);
839}
840
1ca4d09a
GN
841static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
842{
843 int l = 0;
844
845 if (dev && dev->parent_bus) {
846 char *d;
847 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
6b1566cb
PB
848 d = qdev_get_fw_dev_path_from_handler(dev->parent_bus, dev);
849 if (!d) {
850 d = bus_get_fw_dev_path(dev->parent_bus, dev);
851 }
0d936928 852 if (d) {
1ca4d09a 853 l += snprintf(p + l, size - l, "%s", d);
7267c094 854 g_free(d);
1ca4d09a 855 } else {
bbfa18fc 856 return l;
1ca4d09a
GN
857 }
858 }
859 l += snprintf(p + l , size - l, "/");
860
861 return l;
862}
863
864char* qdev_get_fw_dev_path(DeviceState *dev)
865{
866 char path[128];
867 int l;
868
869 l = qdev_get_fw_dev_path_helper(dev, path, 128);
870
871 path[l-1] = '\0';
872
a5cf8262 873 return g_strdup(path);
1ca4d09a 874}
85ed303b 875
09e5ab63 876char *qdev_get_dev_path(DeviceState *dev)
85ed303b 877{
0d936928 878 BusClass *bc;
09e5ab63
AL
879
880 if (!dev || !dev->parent_bus) {
881 return NULL;
882 }
883
0d936928
AL
884 bc = BUS_GET_CLASS(dev->parent_bus);
885 if (bc->get_dev_path) {
886 return bc->get_dev_path(dev);
09e5ab63
AL
887 }
888
889 return NULL;
44677ded 890}
a5296ca9
AL
891
892/**
893 * Legacy property handling
894 */
895
d7bce999
EB
896static void qdev_get_legacy_property(Object *obj, Visitor *v,
897 const char *name, void *opaque,
898 Error **errp)
a5296ca9 899{
57c9fafe 900 DeviceState *dev = DEVICE(obj);
a5296ca9
AL
901 Property *prop = opaque;
902
e3cb6ba6
PB
903 char buffer[1024];
904 char *ptr = buffer;
a5296ca9 905
e3cb6ba6 906 prop->info->print(dev, prop, buffer, sizeof(buffer));
51e72bc1 907 visit_type_str(v, name, &ptr, errp);
a5296ca9
AL
908}
909
a5296ca9
AL
910/**
911 * @qdev_add_legacy_property - adds a legacy property
912 *
913 * Do not use this is new code! Properties added through this interface will
ca2cc788 914 * be given names and types in the "legacy" namespace.
a5296ca9 915 *
68ee3569
PB
916 * Legacy properties are string versions of other OOM properties. The format
917 * of the string depends on the property type.
a5296ca9 918 */
f5a014d2
SW
919static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
920 Error **errp)
a5296ca9 921{
7ce7ffe0 922 gchar *name;
a5296ca9 923
f3be016d 924 /* Register pointer properties as legacy properties */
03ff7770 925 if (!prop->info->print && prop->info->get) {
68ee3569
PB
926 return;
927 }
f3be016d 928
ca2cc788 929 name = g_strdup_printf("legacy-%s", prop->name);
7ce7ffe0 930 object_property_add(OBJECT(dev), name, "str",
68ee3569 931 prop->info->print ? qdev_get_legacy_property : prop->info->get,
03ff7770 932 NULL,
57c9fafe
AL
933 NULL,
934 prop, errp);
a5296ca9 935
ca2cc788
PB
936 g_free(name);
937}
938
939/**
940 * @qdev_property_add_static - add a @Property to a device.
941 *
942 * Static properties access data in a struct. The actual type of the
943 * property and the field depends on the property type.
944 */
945void qdev_property_add_static(DeviceState *dev, Property *prop,
946 Error **errp)
947{
fdae245f
PB
948 Error *local_err = NULL;
949 Object *obj = OBJECT(dev);
950
d822979b
PB
951 /*
952 * TODO qdev_prop_ptr does not have getters or setters. It must
953 * go now that it can be replaced with links. The test should be
954 * removed along with it: all static properties are read/write.
955 */
956 if (!prop->info->get && !prop->info->set) {
957 return;
958 }
959
fdae245f 960 object_property_add(obj, prop->name, prop->info->name,
57c9fafe 961 prop->info->get, prop->info->set,
dd0ba250 962 prop->info->release,
fdae245f
PB
963 prop, &local_err);
964
965 if (local_err) {
966 error_propagate(errp, local_err);
967 return;
968 }
b8c9cd5c
GA
969
970 object_property_set_description(obj, prop->name,
971 prop->info->description,
972 &error_abort);
973
fdae245f
PB
974 if (prop->qtype == QTYPE_NONE) {
975 return;
976 }
977
978 if (prop->qtype == QTYPE_QBOOL) {
5433a0a8 979 object_property_set_bool(obj, prop->defval, prop->name, &error_abort);
fdae245f
PB
980 } else if (prop->info->enum_table) {
981 object_property_set_str(obj, prop->info->enum_table[prop->defval],
5433a0a8 982 prop->name, &error_abort);
fdae245f 983 } else if (prop->qtype == QTYPE_QINT) {
5433a0a8 984 object_property_set_int(obj, prop->defval, prop->name, &error_abort);
fdae245f 985 }
6a146eba 986}
1de81d28 987
67cc7e0a
SH
988/* @qdev_alias_all_properties - Add alias properties to the source object for
989 * all qdev properties on the target DeviceState.
990 */
991void qdev_alias_all_properties(DeviceState *target, Object *source)
992{
993 ObjectClass *class;
994 Property *prop;
995
996 class = object_get_class(OBJECT(target));
997 do {
998 DeviceClass *dc = DEVICE_CLASS(class);
999
1000 for (prop = dc->props; prop && prop->name; prop++) {
1001 object_property_add_alias(source, prop->name,
1002 OBJECT(target), prop->name,
1003 &error_abort);
1004 }
1005 class = object_class_get_parent(class);
1006 } while (class != object_class_by_name(TYPE_DEVICE));
1007}
1008
4cae4d5a 1009static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
66e56b13
ZG
1010{
1011 GSList **list = opaque;
09d56017
JL
1012 DeviceState *dev = (DeviceState *)object_dynamic_cast(OBJECT(obj),
1013 TYPE_DEVICE);
1014
1015 if (dev == NULL) {
1016 return 0;
1017 }
66e56b13
ZG
1018
1019 if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) {
1020 *list = g_slist_append(*list, dev);
1021 }
1022
66e56b13
ZG
1023 return 0;
1024}
1025
4cae4d5a
MA
1026GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
1027{
1028 GSList *list = NULL;
1029
1030 object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);
1031
1032 return list;
1033}
1034
a7737e44 1035static bool device_get_realized(Object *obj, Error **errp)
249d4172
AF
1036{
1037 DeviceState *dev = DEVICE(obj);
1038 return dev->realized;
1039}
1040
a7737e44 1041static void device_set_realized(Object *obj, bool value, Error **errp)
249d4172
AF
1042{
1043 DeviceState *dev = DEVICE(obj);
1044 DeviceClass *dc = DEVICE_GET_CLASS(dev);
7716b8ca 1045 HotplugHandler *hotplug_ctrl;
5c21ce77 1046 BusState *bus;
249d4172
AF
1047 Error *local_err = NULL;
1048
1a37eca1 1049 if (dev->hotplugged && !dc->hotpluggable) {
c6bd8c70 1050 error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
1a37eca1
IM
1051 return;
1052 }
1053
249d4172 1054 if (value && !dev->realized) {
d578029e 1055 if (!obj->parent) {
249d4172
AF
1056 static int unattached_count;
1057 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
1058
1059 object_property_add_child(container_get(qdev_get_machine(),
1060 "/unattached"),
d578029e 1061 name, obj, &error_abort);
249d4172
AF
1062 g_free(name);
1063 }
1064
a7ddba52
IM
1065 if (dc->realize) {
1066 dc->realize(dev, &local_err);
1067 }
1068
1d45a705
GA
1069 if (local_err != NULL) {
1070 goto fail;
1071 }
1072
707ff800
PD
1073 DEVICE_LISTENER_CALL(realize, Forward, dev);
1074
7716b8ca
IM
1075 hotplug_ctrl = qdev_get_hotplug_handler(dev);
1076 if (hotplug_ctrl) {
1077 hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
5e954943
IM
1078 }
1079
1d45a705
GA
1080 if (local_err != NULL) {
1081 goto post_realize_fail;
1082 }
1083
1084 if (qdev_get_vmsd(dev)) {
249d4172
AF
1085 vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
1086 dev->instance_id_alias,
1087 dev->alias_required_for_version);
1088 }
1d45a705
GA
1089
1090 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
1091 object_property_set_bool(OBJECT(bus), true, "realized",
5c21ce77 1092 &local_err);
1d45a705
GA
1093 if (local_err != NULL) {
1094 goto child_realize_fail;
5c21ce77
BD
1095 }
1096 }
1d45a705 1097 if (dev->hotplugged) {
249d4172
AF
1098 device_reset(dev);
1099 }
352e8da7 1100 dev->pending_deleted_event = false;
249d4172 1101 } else if (!value && dev->realized) {
cd4520ad 1102 Error **local_errp = NULL;
5c21ce77 1103 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
cd4520ad 1104 local_errp = local_err ? NULL : &local_err;
5c21ce77 1105 object_property_set_bool(OBJECT(bus), false, "realized",
cd4520ad 1106 local_errp);
5c21ce77 1107 }
cd4520ad 1108 if (qdev_get_vmsd(dev)) {
fe6c2117
AF
1109 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
1110 }
cd4520ad
GA
1111 if (dc->unrealize) {
1112 local_errp = local_err ? NULL : &local_err;
1113 dc->unrealize(dev, local_errp);
249d4172 1114 }
352e8da7 1115 dev->pending_deleted_event = true;
707ff800 1116 DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
249d4172
AF
1117 }
1118
1119 if (local_err != NULL) {
1d45a705 1120 goto fail;
249d4172
AF
1121 }
1122
1123 dev->realized = value;
1d45a705
GA
1124 return;
1125
1126child_realize_fail:
1127 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
1128 object_property_set_bool(OBJECT(bus), false, "realized",
1129 NULL);
1130 }
1131
1132 if (qdev_get_vmsd(dev)) {
1133 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
1134 }
1135
1136post_realize_fail:
1137 if (dc->unrealize) {
1138 dc->unrealize(dev, NULL);
1139 }
1140
1141fail:
1142 error_propagate(errp, local_err);
249d4172
AF
1143}
1144
a7737e44 1145static bool device_get_hotpluggable(Object *obj, Error **errp)
1a37eca1
IM
1146{
1147 DeviceClass *dc = DEVICE_GET_CLASS(obj);
1148 DeviceState *dev = DEVICE(obj);
1149
2b81b35f 1150 return dc->hotpluggable && (dev->parent_bus == NULL ||
39b888bd 1151 qbus_is_hotpluggable(dev->parent_bus));
1a37eca1
IM
1152}
1153
d012ffc1
IM
1154static bool device_get_hotplugged(Object *obj, Error **err)
1155{
1156 DeviceState *dev = DEVICE(obj);
1157
1158 return dev->hotplugged;
1159}
1160
1161static void device_set_hotplugged(Object *obj, bool value, Error **err)
1162{
1163 DeviceState *dev = DEVICE(obj);
1164
1165 dev->hotplugged = value;
1166}
1167
9674bfe4
AL
1168static void device_initfn(Object *obj)
1169{
1170 DeviceState *dev = DEVICE(obj);
bce54474 1171 ObjectClass *class;
9674bfe4
AL
1172 Property *prop;
1173
1174 if (qdev_hotplug) {
1175 dev->hotplugged = 1;
1176 qdev_hot_added = true;
1177 }
1178
1179 dev->instance_id_alias = -1;
7983c8a3 1180 dev->realized = false;
9674bfe4 1181
249d4172
AF
1182 object_property_add_bool(obj, "realized",
1183 device_get_realized, device_set_realized, NULL);
1a37eca1
IM
1184 object_property_add_bool(obj, "hotpluggable",
1185 device_get_hotpluggable, NULL, NULL);
d012ffc1
IM
1186 object_property_add_bool(obj, "hotplugged",
1187 device_get_hotplugged, device_set_hotplugged,
1188 &error_abort);
249d4172 1189
bce54474
PB
1190 class = object_get_class(OBJECT(dev));
1191 do {
1192 for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
5433a0a8
PC
1193 qdev_property_add_legacy(dev, prop, &error_abort);
1194 qdev_property_add_static(dev, prop, &error_abort);
bce54474 1195 }
bce54474
PB
1196 class = object_class_get_parent(class);
1197 } while (class != object_class_by_name(TYPE_DEVICE));
9674bfe4 1198
f968fc68 1199 object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
39f72ef9 1200 (Object **)&dev->parent_bus, NULL, 0,
9561fda8 1201 &error_abort);
a5f54290 1202 QLIST_INIT(&dev->gpios);
9674bfe4
AL
1203}
1204
99a0b036
EH
1205static void device_post_init(Object *obj)
1206{
25f8dd96 1207 qdev_prop_set_globals(DEVICE(obj));
99a0b036
EH
1208}
1209
60adba37
AL
1210/* Unlink device from bus and free the structure. */
1211static void device_finalize(Object *obj)
1212{
a5f54290
PC
1213 NamedGPIOList *ngl, *next;
1214
60adba37 1215 DeviceState *dev = DEVICE(obj);
a5f54290
PC
1216
1217 QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
1218 QLIST_REMOVE(ngl, node);
f173d57a 1219 qemu_free_irqs(ngl->in, ngl->num_in);
a5f54290
PC
1220 g_free(ngl->name);
1221 g_free(ngl);
1222 /* ngl->out irqs are owned by the other end and should not be freed
1223 * here
1224 */
1225 }
60adba37
AL
1226}
1227
bce54474
PB
1228static void device_class_base_init(ObjectClass *class, void *data)
1229{
1230 DeviceClass *klass = DEVICE_CLASS(class);
1231
1232 /* We explicitly look up properties in the superclasses,
1233 * so do not propagate them to the subclasses.
1234 */
1235 klass->props = NULL;
60adba37
AL
1236}
1237
5d5b24d0 1238static void device_unparent(Object *obj)
667d22d1
PB
1239{
1240 DeviceState *dev = DEVICE(obj);
06f7f2bb 1241 BusState *bus;
667d22d1 1242
5c21ce77
BD
1243 if (dev->realized) {
1244 object_property_set_bool(obj, false, "realized", NULL);
1245 }
06f7f2bb
PB
1246 while (dev->num_child_bus) {
1247 bus = QLIST_FIRST(&dev->child_bus);
6780a22c 1248 object_unparent(OBJECT(bus));
06f7f2bb 1249 }
06f7f2bb 1250 if (dev->parent_bus) {
5d5b24d0 1251 bus_remove_child(dev->parent_bus, dev);
62d7ba66
PB
1252 object_unref(OBJECT(dev->parent_bus));
1253 dev->parent_bus = NULL;
5d5b24d0 1254 }
0402a5d6 1255
b1ee5829 1256 /* Only send event if the device had been completely realized */
352e8da7 1257 if (dev->pending_deleted_event) {
b1ee5829
AL
1258 gchar *path = object_get_canonical_path(OBJECT(dev));
1259
24b699fb 1260 qapi_event_send_device_deleted(!!dev->id, dev->id, path, &error_abort);
b1ee5829 1261 g_free(path);
0402a5d6 1262 }
abed886e
PB
1263
1264 qemu_opts_del(dev->opts);
1265 dev->opts = NULL;
667d22d1
PB
1266}
1267
1268static void device_class_init(ObjectClass *class, void *data)
1269{
249d4172
AF
1270 DeviceClass *dc = DEVICE_CLASS(class);
1271
5d5b24d0 1272 class->unparent = device_unparent;
249d4172 1273 dc->realize = device_realize;
fe6c2117 1274 dc->unrealize = device_unrealize;
267a3264
IM
1275
1276 /* by default all devices were considered as hotpluggable,
1277 * so with intent to check it in generic qdev_unplug() /
1278 * device_set_realized() functions make every device
1279 * hotpluggable. Devices that shouldn't be hotpluggable,
1280 * should override it in their class_init()
1281 */
1282 dc->hotpluggable = true;
667d22d1
PB
1283}
1284
94afdadc
AL
1285void device_reset(DeviceState *dev)
1286{
1287 DeviceClass *klass = DEVICE_GET_CLASS(dev);
1288
1289 if (klass->reset) {
1290 klass->reset(dev);
1291 }
1292}
1293
f05f6b4a
PB
1294Object *qdev_get_machine(void)
1295{
1296 static Object *dev;
1297
1298 if (dev == NULL) {
dfe47e70 1299 dev = container_get(object_get_root(), "/machine");
f05f6b4a
PB
1300 }
1301
1302 return dev;
1303}
1304
8c43a6f0 1305static const TypeInfo device_type_info = {
32fea402
AL
1306 .name = TYPE_DEVICE,
1307 .parent = TYPE_OBJECT,
1308 .instance_size = sizeof(DeviceState),
9674bfe4 1309 .instance_init = device_initfn,
99a0b036 1310 .instance_post_init = device_post_init,
60adba37 1311 .instance_finalize = device_finalize,
bce54474 1312 .class_base_init = device_class_base_init,
667d22d1 1313 .class_init = device_class_init,
32fea402
AL
1314 .abstract = true,
1315 .class_size = sizeof(DeviceClass),
1316};
1317
ac7d1ba6
AL
1318static void qbus_initfn(Object *obj)
1319{
1320 BusState *bus = BUS(obj);
1321
1322 QTAILQ_INIT(&bus->children);
0ee4de6c
IM
1323 object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY,
1324 TYPE_HOTPLUG_HANDLER,
9561fda8 1325 (Object **)&bus->hotplug_handler,
39f72ef9 1326 object_property_allow_set_link,
9561fda8
SH
1327 OBJ_PROP_LINK_UNREF_ON_RELEASE,
1328 NULL);
02e7f85d
BD
1329 object_property_add_bool(obj, "realized",
1330 bus_get_realized, bus_set_realized, NULL);
ac7d1ba6
AL
1331}
1332
bbfa18fc
AK
1333static char *default_bus_get_fw_dev_path(DeviceState *dev)
1334{
1335 return g_strdup(object_get_typename(OBJECT(dev)));
1336}
1337
6853d27a
PB
1338static void bus_class_init(ObjectClass *class, void *data)
1339{
bbfa18fc
AK
1340 BusClass *bc = BUS_CLASS(class);
1341
6853d27a 1342 class->unparent = bus_unparent;
bbfa18fc 1343 bc->get_fw_dev_path = default_bus_get_fw_dev_path;
6853d27a
PB
1344}
1345
ac7d1ba6
AL
1346static void qbus_finalize(Object *obj)
1347{
1348 BusState *bus = BUS(obj);
ac7d1ba6 1349
ac7d1ba6
AL
1350 g_free((char *)bus->name);
1351}
1352
0d936928
AL
1353static const TypeInfo bus_info = {
1354 .name = TYPE_BUS,
1355 .parent = TYPE_OBJECT,
1356 .instance_size = sizeof(BusState),
1357 .abstract = true,
1358 .class_size = sizeof(BusClass),
ac7d1ba6
AL
1359 .instance_init = qbus_initfn,
1360 .instance_finalize = qbus_finalize,
6853d27a 1361 .class_init = bus_class_init,
0d936928
AL
1362};
1363
83f7d43a 1364static void qdev_register_types(void)
32fea402 1365{
0d936928 1366 type_register_static(&bus_info);
32fea402
AL
1367 type_register_static(&device_type_info);
1368}
1369
83f7d43a 1370type_init(qdev_register_types)
This page took 0.940807 seconds and 4 git commands to generate.