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