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