]> git.proxmox.com Git - mirror_qemu.git/blame - hw/core/qdev.c
Merge remote-tracking branch 'remotes/kraxel/tags/ui-20200515-pull-request' into...
[mirror_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"
e688df6b 29#include "qapi/error.h"
c577ff62 30#include "qapi/qapi-events-qdev.h"
b4a42f81 31#include "qapi/qmp/qerror.h"
7b1b5d19 32#include "qapi/visitor.h"
d49b6836 33#include "qemu/error-report.h"
922a01a0 34#include "qemu/option.h"
0ee4de6c 35#include "hw/hotplug.h"
64552b6b 36#include "hw/irq.h"
a27bd6c7 37#include "hw/qdev-properties.h"
b7454548 38#include "hw/boards.h"
7474f1be 39#include "hw/sysbus.h"
0e6934f2 40#include "hw/qdev-clock.h"
d6454270 41#include "migration/vmstate.h"
70804c83 42#include "trace.h"
aae9460e 43
9bed84c1 44bool qdev_hotplug = false;
0ac8ef71 45static bool qdev_hot_added = false;
21def24a 46bool qdev_hot_removed = false;
3418bd25 47
4be9f0d1
AL
48const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
49{
6e008585
AL
50 DeviceClass *dc = DEVICE_GET_CLASS(dev);
51 return dc->vmsd;
4be9f0d1
AL
52}
53
0866aca1 54static void bus_remove_child(BusState *bus, DeviceState *child)
0c17542d 55{
0866aca1
AL
56 BusChild *kid;
57
58 QTAILQ_FOREACH(kid, &bus->children, sibling) {
59 if (kid->child == child) {
60 char name[32];
61
62 snprintf(name, sizeof(name), "child[%d]", kid->index);
63 QTAILQ_REMOVE(&bus->children, kid, sibling);
9d127820 64
12b2e9f3
TK
65 bus->num_children--;
66
9d127820 67 /* This gives back ownership of kid->child back to us. */
df4fe0b2 68 object_property_del(OBJECT(bus), name);
9d127820 69 object_unref(OBJECT(kid->child));
0866aca1
AL
70 g_free(kid);
71 return;
72 }
73 }
74}
75
76static void bus_add_child(BusState *bus, DeviceState *child)
77{
78 char name[32];
79 BusChild *kid = g_malloc0(sizeof(*kid));
0c17542d 80
12b2e9f3 81 bus->num_children++;
0866aca1
AL
82 kid->index = bus->max_index++;
83 kid->child = child;
9d127820 84 object_ref(OBJECT(kid->child));
a5296ca9 85
0866aca1
AL
86 QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
87
9d127820 88 /* This transfers ownership of kid->child to the property. */
0866aca1
AL
89 snprintf(name, sizeof(name), "child[%d]", kid->index);
90 object_property_add_link(OBJECT(bus), name,
91 object_get_typename(OBJECT(child)),
39f72ef9
SH
92 (Object **)&kid->child,
93 NULL, /* read-only property */
d2623129 94 0);
0866aca1
AL
95}
96
97void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
98{
a7c3a4f9 99 BusState *old_parent_bus = dev->parent_bus;
91c968ac 100
a7c3a4f9 101 if (old_parent_bus) {
70804c83 102 trace_qdev_update_parent_bus(dev, object_get_typename(OBJECT(dev)),
a7c3a4f9 103 old_parent_bus, object_get_typename(OBJECT(old_parent_bus)),
70804c83
DH
104 OBJECT(bus), object_get_typename(OBJECT(bus)));
105 /*
106 * Keep a reference to the device while it's not plugged into
91c968ac
PM
107 * any bus, to avoid it potentially evaporating when it is
108 * dereffed in bus_remove_child().
a7c3a4f9
DH
109 * Also keep the ref of the parent bus until the end, so that
110 * we can safely call resettable_change_parent() below.
91c968ac
PM
111 */
112 object_ref(OBJECT(dev));
113 bus_remove_child(dev->parent_bus, dev);
91c968ac 114 }
9fbe6127 115 dev->parent_bus = bus;
62d7ba66 116 object_ref(OBJECT(bus));
0866aca1 117 bus_add_child(bus, dev);
a7c3a4f9
DH
118 if (dev->realized) {
119 resettable_change_parent(OBJECT(dev), OBJECT(bus),
120 OBJECT(old_parent_bus));
121 }
122 if (old_parent_bus) {
123 object_unref(OBJECT(old_parent_bus));
91c968ac
PM
124 object_unref(OBJECT(dev));
125 }
0c17542d
MA
126}
127
0210afe6
MA
128/* Create a new device. This only initializes the device state
129 structure and allows properties to be set. The device still needs
130 to be realized. See qdev-core.h. */
02e2da45 131DeviceState *qdev_create(BusState *bus, const char *name)
0bcdeda7
BS
132{
133 DeviceState *dev;
134
135 dev = qdev_try_create(bus, name);
136 if (!dev) {
e92714c7 137 if (bus) {
312fd5f2 138 error_report("Unknown device '%s' for bus '%s'", name,
23e3fbec 139 object_get_typename(OBJECT(bus)));
e92714c7 140 } else {
312fd5f2 141 error_report("Unknown device '%s' for default sysbus", name);
e92714c7 142 }
01ed1d52 143 abort();
0bcdeda7
BS
144 }
145
146 return dev;
147}
148
da57febf 149DeviceState *qdev_try_create(BusState *bus, const char *type)
aae9460e 150{
9fbe6127
AL
151 DeviceState *dev;
152
da57febf 153 if (object_class_by_name(type) == NULL) {
4ed658ca
AF
154 return NULL;
155 }
da57febf 156 dev = DEVICE(object_new(type));
9fbe6127
AL
157 if (!dev) {
158 return NULL;
159 }
160
10c4c98a 161 if (!bus) {
7474f1be
PM
162 /* Assert that the device really is a SysBusDevice before
163 * we put it onto the sysbus. Non-sysbus devices which aren't
164 * being put onto a bus should be created with object_new(TYPE_FOO),
165 * not qdev_create(NULL, TYPE_FOO).
166 */
167 g_assert(object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE));
68694897 168 bus = sysbus_get_default();
10c4c98a
GH
169 }
170
9fbe6127 171 qdev_set_parent_bus(dev, bus);
b09995ae 172 object_unref(OBJECT(dev));
9fbe6127 173 return dev;
aae9460e
PB
174}
175
eae3eb3e 176static QTAILQ_HEAD(, DeviceListener) device_listeners
707ff800
PD
177 = QTAILQ_HEAD_INITIALIZER(device_listeners);
178
179enum ListenerDirection { Forward, Reverse };
180
181#define DEVICE_LISTENER_CALL(_callback, _direction, _args...) \
182 do { \
183 DeviceListener *_listener; \
184 \
185 switch (_direction) { \
186 case Forward: \
187 QTAILQ_FOREACH(_listener, &device_listeners, link) { \
188 if (_listener->_callback) { \
189 _listener->_callback(_listener, ##_args); \
190 } \
191 } \
192 break; \
193 case Reverse: \
194 QTAILQ_FOREACH_REVERSE(_listener, &device_listeners, \
eae3eb3e 195 link) { \
707ff800
PD
196 if (_listener->_callback) { \
197 _listener->_callback(_listener, ##_args); \
198 } \
199 } \
200 break; \
201 default: \
202 abort(); \
203 } \
204 } while (0)
205
206static int device_listener_add(DeviceState *dev, void *opaque)
207{
208 DEVICE_LISTENER_CALL(realize, Forward, dev);
209
210 return 0;
211}
212
213void device_listener_register(DeviceListener *listener)
214{
215 QTAILQ_INSERT_TAIL(&device_listeners, listener, link);
216
217 qbus_walk_children(sysbus_get_default(), NULL, NULL, device_listener_add,
218 NULL, NULL);
219}
220
221void device_listener_unregister(DeviceListener *listener)
222{
223 QTAILQ_REMOVE(&device_listeners, listener, link);
224}
225
f3a85056
JF
226bool qdev_should_hide_device(QemuOpts *opts)
227{
228 int rc = -1;
229 DeviceListener *listener;
230
231 QTAILQ_FOREACH(listener, &device_listeners, link) {
232 if (listener->should_be_hidden) {
233 /*
234 * should_be_hidden_will return
235 * 1 if device matches opts and it should be hidden
236 * 0 if device matches opts and should not be hidden
237 * -1 if device doesn't match ops
238 */
239 rc = listener->should_be_hidden(listener, opts);
240 }
241
242 if (rc > 0) {
243 break;
244 }
245 }
246
247 return rc > 0;
248}
249
4d2ffa08
JK
250void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
251 int required_for_version)
252{
7983c8a3 253 assert(!dev->realized);
4d2ffa08
JK
254 dev->instance_id_alias = alias_id;
255 dev->alias_required_for_version = required_for_version;
256}
257
03fcbd9d
TH
258HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
259{
260 MachineState *machine;
261 MachineClass *mc;
262 Object *m_obj = qdev_get_machine();
263
264 if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
265 machine = MACHINE(m_obj);
266 mc = MACHINE_GET_CLASS(machine);
267 if (mc->get_hotplug_handler) {
268 return mc->get_hotplug_handler(machine, dev);
269 }
270 }
271
272 return NULL;
273}
274
d2321d31
PX
275bool qdev_hotplug_allowed(DeviceState *dev, Error **errp)
276{
277 MachineState *machine;
278 MachineClass *mc;
279 Object *m_obj = qdev_get_machine();
280
281 if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
282 machine = MACHINE(m_obj);
283 mc = MACHINE_GET_CLASS(machine);
284 if (mc->hotplug_allowed) {
285 return mc->hotplug_allowed(machine, dev, errp);
286 }
287 }
288
289 return true;
290}
291
14405c27
DH
292HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev)
293{
294 if (dev->parent_bus) {
295 return dev->parent_bus->hotplug_handler;
296 }
297 return NULL;
298}
299
c06b2ffb 300HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
7716b8ca 301{
17cc0128 302 HotplugHandler *hotplug_ctrl = qdev_get_machine_hotplug_handler(dev);
7716b8ca 303
17cc0128 304 if (hotplug_ctrl == NULL && dev->parent_bus) {
14405c27 305 hotplug_ctrl = qdev_get_bus_hotplug_handler(dev);
7716b8ca
IM
306 }
307 return hotplug_ctrl;
308}
309
70804c83
DH
310static int qdev_prereset(DeviceState *dev, void *opaque)
311{
312 trace_qdev_reset_tree(dev, object_get_typename(OBJECT(dev)));
313 return 0;
314}
315
316static int qbus_prereset(BusState *bus, void *opaque)
317{
318 trace_qbus_reset_tree(bus, object_get_typename(OBJECT(bus)));
319 return 0;
320}
321
ec990eb6
AL
322static int qdev_reset_one(DeviceState *dev, void *opaque)
323{
f703a04c 324 device_legacy_reset(dev);
ec990eb6
AL
325
326 return 0;
327}
328
b4694b7c
IY
329static int qbus_reset_one(BusState *bus, void *opaque)
330{
0d936928 331 BusClass *bc = BUS_GET_CLASS(bus);
70804c83 332 trace_qbus_reset(bus, object_get_typename(OBJECT(bus)));
0d936928 333 if (bc->reset) {
dcc20931 334 bc->reset(bus);
b4694b7c
IY
335 }
336 return 0;
337}
338
5af0a04b
IY
339void qdev_reset_all(DeviceState *dev)
340{
70804c83
DH
341 trace_qdev_reset_all(dev, object_get_typename(OBJECT(dev)));
342 qdev_walk_children(dev, qdev_prereset, qbus_prereset,
343 qdev_reset_one, qbus_reset_one, NULL);
5af0a04b
IY
344}
345
ff8de075
DH
346void qdev_reset_all_fn(void *opaque)
347{
348 qdev_reset_all(DEVICE(opaque));
349}
350
d0508c36
PB
351void qbus_reset_all(BusState *bus)
352{
70804c83
DH
353 trace_qbus_reset_all(bus, object_get_typename(OBJECT(bus)));
354 qbus_walk_children(bus, qdev_prereset, qbus_prereset,
355 qdev_reset_one, qbus_reset_one, NULL);
d0508c36
PB
356}
357
80376c3f
IY
358void qbus_reset_all_fn(void *opaque)
359{
360 BusState *bus = opaque;
d0508c36 361 qbus_reset_all(bus);
80376c3f
IY
362}
363
abb89dbf
DH
364void device_cold_reset(DeviceState *dev)
365{
366 resettable_reset(OBJECT(dev), RESET_TYPE_COLD);
367}
368
c11256aa
DH
369bool device_is_in_reset(DeviceState *dev)
370{
371 return resettable_is_in_reset(OBJECT(dev));
372}
373
374static ResettableState *device_get_reset_state(Object *obj)
375{
376 DeviceState *dev = DEVICE(obj);
377 return &dev->reset;
378}
379
380static void device_reset_child_foreach(Object *obj, ResettableChildCallback cb,
381 void *opaque, ResetType type)
382{
383 DeviceState *dev = DEVICE(obj);
384 BusState *bus;
385
386 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
387 cb(OBJECT(bus), opaque, type);
388 }
389}
390
3418bd25 391/* can be used as ->unplug() callback for the simple cases */
014176f9
IM
392void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
393 DeviceState *dev, Error **errp)
394{
b69c3c21 395 object_property_set_bool(OBJECT(dev), false, "realized", &error_abort);
014176f9 396}
3b29a101 397
0210afe6
MA
398/*
399 * Realize @dev.
400 * Device properties should be set before calling this function. IRQs
401 * and MMIO regions should be connected/mapped after calling this
402 * function.
403 * On failure, report an error with error_report() and terminate the
404 * program. This is okay during machine creation. Don't use for
405 * hotplug, because there callers need to recover from failure.
406 * Exception: if you know the device's init() callback can't fail,
407 * then qdev_init_nofail() can't fail either, and is therefore usable
408 * even then. But relying on the device implementation that way is
409 * somewhat unclean, and best avoided.
410 */
e23a1b33
MA
411void qdev_init_nofail(DeviceState *dev)
412{
c4bacafb 413 Error *err = NULL;
7de3abe5 414
c4bacafb
MA
415 assert(!dev->realized);
416
0d4104e5 417 object_ref(OBJECT(dev));
c4bacafb
MA
418 object_property_set_bool(OBJECT(dev), true, "realized", &err);
419 if (err) {
c29b77f9
MA
420 error_reportf_err(err, "Initialization of device %s failed: ",
421 object_get_typename(OBJECT(dev)));
bd6c9a61
MA
422 exit(1);
423 }
0d4104e5 424 object_unref(OBJECT(dev));
e23a1b33
MA
425}
426
3418bd25
GH
427void qdev_machine_creation_done(void)
428{
429 /*
430 * ok, initial machine setup is done, starting from now we can
431 * only create hotpluggable devices
432 */
9bed84c1 433 qdev_hotplug = true;
3418bd25
GH
434}
435
0ac8ef71
AW
436bool qdev_machine_modified(void)
437{
438 return qdev_hot_added || qdev_hot_removed;
439}
440
02e2da45 441BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 442{
02e2da45 443 return dev->parent_bus;
aae9460e
PB
444}
445
a5f54290
PC
446static NamedGPIOList *qdev_get_named_gpio_list(DeviceState *dev,
447 const char *name)
448{
449 NamedGPIOList *ngl;
450
451 QLIST_FOREACH(ngl, &dev->gpios, node) {
3a87dde8
MAL
452 /* NULL is a valid and matchable name. */
453 if (g_strcmp0(name, ngl->name) == 0) {
a5f54290
PC
454 return ngl;
455 }
456 }
457
458 ngl = g_malloc0(sizeof(*ngl));
459 ngl->name = g_strdup(name);
460 QLIST_INSERT_HEAD(&dev->gpios, ngl, node);
461 return ngl;
462}
463
4a151677
PM
464void qdev_init_gpio_in_named_with_opaque(DeviceState *dev,
465 qemu_irq_handler handler,
466 void *opaque,
467 const char *name, int n)
a5f54290 468{
a69bef1c 469 int i;
a5f54290
PC
470 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
471
b235a71f 472 assert(gpio_list->num_out == 0 || !name);
a5f54290 473 gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler,
4a151677 474 opaque, n);
a69bef1c 475
6c76b377
PF
476 if (!name) {
477 name = "unnamed-gpio-in";
478 }
a69bef1c 479 for (i = gpio_list->num_in; i < gpio_list->num_in + n; i++) {
6c76b377
PF
480 gchar *propname = g_strdup_printf("%s[%u]", name, i);
481
a69bef1c 482 object_property_add_child(OBJECT(dev), propname,
d2623129 483 OBJECT(gpio_list->in[i]));
6c76b377 484 g_free(propname);
a69bef1c 485 }
a69bef1c 486
a5f54290
PC
487 gpio_list->num_in += n;
488}
489
aae9460e
PB
490void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
491{
a5f54290
PC
492 qdev_init_gpio_in_named(dev, handler, NULL, n);
493}
494
495void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins,
496 const char *name, int n)
497{
688b057a 498 int i;
a5f54290
PC
499 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
500
b235a71f 501 assert(gpio_list->num_in == 0 || !name);
688b057a 502
6c76b377
PF
503 if (!name) {
504 name = "unnamed-gpio-out";
505 }
506 memset(pins, 0, sizeof(*pins) * n);
688b057a 507 for (i = 0; i < n; ++i) {
6c76b377
PF
508 gchar *propname = g_strdup_printf("%s[%u]", name,
509 gpio_list->num_out + i);
510
688b057a
PC
511 object_property_add_link(OBJECT(dev), propname, TYPE_IRQ,
512 (Object **)&pins[i],
513 object_property_allow_set_link,
d2623129 514 OBJ_PROP_LINK_STRONG);
6c76b377 515 g_free(propname);
688b057a 516 }
6c76b377 517 gpio_list->num_out += n;
aae9460e
PB
518}
519
520void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
521{
a5f54290
PC
522 qdev_init_gpio_out_named(dev, pins, NULL, n);
523}
524
525qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n)
526{
527 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
528
529 assert(n >= 0 && n < gpio_list->num_in);
530 return gpio_list->in[n];
aae9460e
PB
531}
532
533qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
534{
a5f54290
PC
535 return qdev_get_gpio_in_named(dev, NULL, n);
536}
537
538void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
539 qemu_irq pin)
540{
02757df2
PC
541 char *propname = g_strdup_printf("%s[%d]",
542 name ? name : "unnamed-gpio-out", n);
9f742c28
MA
543 if (pin && !OBJECT(pin)->parent) {
544 /* We need a name for object_property_set_link to work */
88950eef
AF
545 object_property_add_child(container_get(qdev_get_machine(),
546 "/unattached"),
d2623129 547 "non-qdev-gpio[*]", OBJECT(pin));
02757df2
PC
548 }
549 object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort);
550 g_free(propname);
aae9460e
PB
551}
552
b7973186
AG
553qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n)
554{
2244f233 555 g_autofree char *propname = g_strdup_printf("%s[%d]",
b7973186
AG
556 name ? name : "unnamed-gpio-out", n);
557
558 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
559 NULL);
560
561 return ret;
562}
563
67cc32eb 564/* disconnect a GPIO output, returning the disconnected input (if any) */
0c24db2b
PC
565
566static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev,
567 const char *name, int n)
568{
569 char *propname = g_strdup_printf("%s[%d]",
570 name ? name : "unnamed-gpio-out", n);
571
572 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
573 NULL);
574 if (ret) {
575 object_property_set_link(OBJECT(dev), NULL, propname, NULL);
576 }
577 g_free(propname);
578 return ret;
579}
a5f54290 580
0c24db2b
PC
581qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt,
582 const char *name, int n)
583{
584 qemu_irq disconnected = qdev_disconnect_gpio_out_named(dev, name, n);
585 qdev_connect_gpio_out_named(dev, name, n, icpt);
586 return disconnected;
aae9460e
PB
587}
588
589void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
590{
a5f54290 591 qdev_connect_gpio_out_named(dev, NULL, n, pin);
aae9460e
PB
592}
593
17a96a14
PC
594void qdev_pass_gpios(DeviceState *dev, DeviceState *container,
595 const char *name)
596{
597 int i;
598 NamedGPIOList *ngl = qdev_get_named_gpio_list(dev, name);
599
600 for (i = 0; i < ngl->num_in; i++) {
601 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-in";
602 char *propname = g_strdup_printf("%s[%d]", nm, i);
603
604 object_property_add_alias(OBJECT(container), propname,
d2623129 605 OBJECT(dev), propname);
6bc5cf92 606 g_free(propname);
17a96a14
PC
607 }
608 for (i = 0; i < ngl->num_out; i++) {
609 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-out";
610 char *propname = g_strdup_printf("%s[%d]", nm, i);
611
612 object_property_add_alias(OBJECT(container), propname,
d2623129 613 OBJECT(dev), propname);
6bc5cf92 614 g_free(propname);
17a96a14
PC
615 }
616 QLIST_REMOVE(ngl, node);
617 QLIST_INSERT_HEAD(&container->gpios, ngl, node);
618}
619
02e2da45 620BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 621{
02e2da45 622 BusState *bus;
f698c8ba
PC
623 Object *child = object_resolve_path_component(OBJECT(dev), name);
624
625 bus = (BusState *)object_dynamic_cast(child, TYPE_BUS);
626 if (bus) {
627 return bus;
628 }
4d6ae674 629
72cf2d4f 630 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 631 if (strcmp(name, bus->name) == 0) {
02e2da45 632 return bus;
4d6ae674
PB
633 }
634 }
635 return NULL;
636}
637
0293214b
PB
638int qdev_walk_children(DeviceState *dev,
639 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
640 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
641 void *opaque)
81699d8a
AL
642{
643 BusState *bus;
644 int err;
645
0293214b
PB
646 if (pre_devfn) {
647 err = pre_devfn(dev, opaque);
81699d8a
AL
648 if (err) {
649 return err;
650 }
651 }
652
653 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
0293214b
PB
654 err = qbus_walk_children(bus, pre_devfn, pre_busfn,
655 post_devfn, post_busfn, opaque);
81699d8a
AL
656 if (err < 0) {
657 return err;
658 }
659 }
660
0293214b
PB
661 if (post_devfn) {
662 err = post_devfn(dev, opaque);
663 if (err) {
664 return err;
665 }
666 }
667
81699d8a
AL
668 return 0;
669}
670
a2ee6b4f 671DeviceState *qdev_find_recursive(BusState *bus, const char *id)
3418bd25 672{
0866aca1
AL
673 BusChild *kid;
674 DeviceState *ret;
3418bd25
GH
675 BusState *child;
676
0866aca1
AL
677 QTAILQ_FOREACH(kid, &bus->children, sibling) {
678 DeviceState *dev = kid->child;
679
680 if (dev->id && strcmp(dev->id, id) == 0) {
3418bd25 681 return dev;
0866aca1
AL
682 }
683
3418bd25
GH
684 QLIST_FOREACH(child, &dev->child_bus, sibling) {
685 ret = qdev_find_recursive(child, id);
686 if (ret) {
687 return ret;
688 }
689 }
690 }
691 return NULL;
692}
693
09e5ab63 694char *qdev_get_dev_path(DeviceState *dev)
85ed303b 695{
0d936928 696 BusClass *bc;
09e5ab63
AL
697
698 if (!dev || !dev->parent_bus) {
699 return NULL;
700 }
701
0d936928
AL
702 bc = BUS_GET_CLASS(dev->parent_bus);
703 if (bc->get_dev_path) {
704 return bc->get_dev_path(dev);
09e5ab63
AL
705 }
706
707 return NULL;
44677ded 708}
a5296ca9
AL
709
710/**
711 * Legacy property handling
712 */
713
d7bce999
EB
714static void qdev_get_legacy_property(Object *obj, Visitor *v,
715 const char *name, void *opaque,
716 Error **errp)
a5296ca9 717{
57c9fafe 718 DeviceState *dev = DEVICE(obj);
a5296ca9
AL
719 Property *prop = opaque;
720
e3cb6ba6
PB
721 char buffer[1024];
722 char *ptr = buffer;
a5296ca9 723
e3cb6ba6 724 prop->info->print(dev, prop, buffer, sizeof(buffer));
51e72bc1 725 visit_type_str(v, name, &ptr, errp);
a5296ca9
AL
726}
727
a5296ca9 728/**
77b06bba 729 * qdev_class_add_legacy_property:
d9d8d452
C
730 * @dev: Device to add the property to.
731 * @prop: The qdev property definition.
d9d8d452
C
732 *
733 * Add a legacy QOM property to @dev for qdev property @prop.
a5296ca9 734 *
d9d8d452
C
735 * Legacy properties are string versions of QOM properties. The format of
736 * the string depends on the property type. Legacy properties are only
737 * needed for "info qtree".
a5296ca9 738 *
6871a0d0 739 * Do not use this in new code! QOM Properties added through this interface
d9d8d452 740 * will be given names in the "legacy" namespace.
a5296ca9 741 */
77b06bba 742static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop)
a5296ca9 743{
77b06bba 744 g_autofree char *name = NULL;
a5296ca9 745
f3be016d 746 /* Register pointer properties as legacy properties */
03ff7770 747 if (!prop->info->print && prop->info->get) {
68ee3569
PB
748 return;
749 }
f3be016d 750
ca2cc788 751 name = g_strdup_printf("legacy-%s", prop->name);
77b06bba
MAL
752 object_class_property_add(OBJECT_CLASS(dc), name, "str",
753 prop->info->print ? qdev_get_legacy_property : prop->info->get,
d2623129 754 NULL, NULL, prop);
ca2cc788
PB
755}
756
94d912d1 757void qdev_property_add_static(DeviceState *dev, Property *prop)
ca2cc788 758{
fdae245f 759 Object *obj = OBJECT(dev);
77b06bba 760 ObjectProperty *op;
fdae245f 761
77b06bba
MAL
762 assert(!prop->info->create);
763
764 op = object_property_add(obj, prop->name, prop->info->name,
765 prop->info->get, prop->info->set,
766 prop->info->release,
d2623129 767 prop);
b8c9cd5c
GA
768
769 object_property_set_description(obj, prop->name,
7eecec7d 770 prop->info->description);
b8c9cd5c 771
5cc56cc6 772 if (prop->set_default) {
77b06bba
MAL
773 prop->info->set_default_value(op, prop);
774 if (op->init) {
775 op->init(obj, op);
776 }
fdae245f 777 }
6a146eba 778}
1de81d28 779
77b06bba
MAL
780static void qdev_class_add_property(DeviceClass *klass, Property *prop)
781{
782 ObjectClass *oc = OBJECT_CLASS(klass);
783
784 if (prop->info->create) {
40c2281c 785 prop->info->create(oc, prop);
77b06bba
MAL
786 } else {
787 ObjectProperty *op;
788
789 op = object_class_property_add(oc,
790 prop->name, prop->info->name,
791 prop->info->get, prop->info->set,
792 prop->info->release,
d2623129 793 prop);
77b06bba
MAL
794 if (prop->set_default) {
795 prop->info->set_default_value(op, prop);
796 }
797 }
798 object_class_property_set_description(oc, prop->name,
7eecec7d 799 prop->info->description);
77b06bba
MAL
800}
801
67cc7e0a
SH
802/* @qdev_alias_all_properties - Add alias properties to the source object for
803 * all qdev properties on the target DeviceState.
804 */
805void qdev_alias_all_properties(DeviceState *target, Object *source)
806{
807 ObjectClass *class;
808 Property *prop;
809
810 class = object_get_class(OBJECT(target));
811 do {
812 DeviceClass *dc = DEVICE_CLASS(class);
813
385d8f22 814 for (prop = dc->props_; prop && prop->name; prop++) {
67cc7e0a 815 object_property_add_alias(source, prop->name,
d2623129 816 OBJECT(target), prop->name);
67cc7e0a
SH
817 }
818 class = object_class_get_parent(class);
819 } while (class != object_class_by_name(TYPE_DEVICE));
820}
821
a7737e44 822static bool device_get_realized(Object *obj, Error **errp)
249d4172
AF
823{
824 DeviceState *dev = DEVICE(obj);
825 return dev->realized;
826}
827
40f03bd5 828static bool check_only_migratable(Object *obj, Error **errp)
1bfe5f05
JQ
829{
830 DeviceClass *dc = DEVICE_GET_CLASS(obj);
831
832 if (!vmstate_check_only_migratable(dc->vmsd)) {
40f03bd5 833 error_setg(errp, "Device %s is not migratable, but "
1bfe5f05
JQ
834 "--only-migratable was specified",
835 object_get_typename(obj));
836 return false;
837 }
838
839 return true;
840}
841
a7737e44 842static void device_set_realized(Object *obj, bool value, Error **errp)
249d4172
AF
843{
844 DeviceState *dev = DEVICE(obj);
845 DeviceClass *dc = DEVICE_GET_CLASS(dev);
7716b8ca 846 HotplugHandler *hotplug_ctrl;
5c21ce77 847 BusState *bus;
0e6934f2 848 NamedClockList *ncl;
249d4172 849 Error *local_err = NULL;
69382d8b
IM
850 bool unattached_parent = false;
851 static int unattached_count;
249d4172 852
1a37eca1 853 if (dev->hotplugged && !dc->hotpluggable) {
c6bd8c70 854 error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
1a37eca1
IM
855 return;
856 }
857
249d4172 858 if (value && !dev->realized) {
1bfe5f05 859 if (!check_only_migratable(obj, &local_err)) {
7562f907
AA
860 goto fail;
861 }
862
d578029e 863 if (!obj->parent) {
249d4172
AF
864 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
865
866 object_property_add_child(container_get(qdev_get_machine(),
867 "/unattached"),
d2623129 868 name, obj);
69382d8b 869 unattached_parent = true;
249d4172
AF
870 g_free(name);
871 }
872
41346263
IM
873 hotplug_ctrl = qdev_get_hotplug_handler(dev);
874 if (hotplug_ctrl) {
875 hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err);
876 if (local_err != NULL) {
877 goto fail;
878 }
879 }
880
a7ddba52
IM
881 if (dc->realize) {
882 dc->realize(dev, &local_err);
40f03bd5
VSO
883 if (local_err != NULL) {
884 goto fail;
885 }
1d45a705
GA
886 }
887
707ff800
PD
888 DEVICE_LISTENER_CALL(realize, Forward, dev);
889
04162f8f
MR
890 /*
891 * always free/re-initialize here since the value cannot be cleaned up
892 * in device_unrealize due to its usage later on in the unplug path
893 */
894 g_free(dev->canonical_path);
895 dev->canonical_path = object_get_canonical_path(OBJECT(dev));
0e6934f2
DH
896 QLIST_FOREACH(ncl, &dev->clocks, node) {
897 if (ncl->alias) {
898 continue;
899 } else {
900 clock_setup_canonical_path(ncl->clock);
901 }
902 }
04162f8f 903
1d45a705 904 if (qdev_get_vmsd(dev)) {
3cad405b 905 if (vmstate_register_with_alias_id(VMSTATE_IF(dev),
1df2c9a2
PX
906 VMSTATE_INSTANCE_ID_ANY,
907 qdev_get_vmsd(dev), dev,
67980031
DDAG
908 dev->instance_id_alias,
909 dev->alias_required_for_version,
910 &local_err) < 0) {
911 goto post_realize_fail;
912 }
249d4172 913 }
1d45a705 914
e755e127
DH
915 /*
916 * Clear the reset state, in case the object was previously unrealized
917 * with a dirty state.
918 */
919 resettable_state_clear(&dev->reset);
920
1d45a705
GA
921 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
922 object_property_set_bool(OBJECT(bus), true, "realized",
5c21ce77 923 &local_err);
1d45a705
GA
924 if (local_err != NULL) {
925 goto child_realize_fail;
5c21ce77
BD
926 }
927 }
1d45a705 928 if (dev->hotplugged) {
e755e127
DH
929 /*
930 * Reset the device, as well as its subtree which, at this point,
931 * should be realized too.
932 */
933 resettable_assert_reset(OBJECT(dev), RESET_TYPE_COLD);
934 resettable_change_parent(OBJECT(dev), OBJECT(dev->parent_bus),
935 NULL);
936 resettable_release_reset(OBJECT(dev), RESET_TYPE_COLD);
249d4172 937 }
352e8da7 938 dev->pending_deleted_event = false;
25e89788
SH
939
940 if (hotplug_ctrl) {
8b5e6caf
IM
941 hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
942 if (local_err != NULL) {
943 goto child_realize_fail;
944 }
945 }
946
249d4172 947 } else if (!value && dev->realized) {
5c21ce77
BD
948 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
949 object_property_set_bool(OBJECT(bus), false, "realized",
b69c3c21 950 &error_abort);
5c21ce77 951 }
cd4520ad 952 if (qdev_get_vmsd(dev)) {
3cad405b 953 vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev);
fe6c2117 954 }
cd4520ad 955 if (dc->unrealize) {
b69c3c21 956 dc->unrealize(dev);
249d4172 957 }
352e8da7 958 dev->pending_deleted_event = true;
707ff800 959 DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
249d4172
AF
960 }
961
40f03bd5 962 assert(local_err == NULL);
c7f8d0f3 963 dev->realized = value;
1d45a705
GA
964 return;
965
966child_realize_fail:
967 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
968 object_property_set_bool(OBJECT(bus), false, "realized",
b69c3c21 969 &error_abort);
1d45a705
GA
970 }
971
972 if (qdev_get_vmsd(dev)) {
3cad405b 973 vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev);
1d45a705
GA
974 }
975
976post_realize_fail:
04162f8f
MR
977 g_free(dev->canonical_path);
978 dev->canonical_path = NULL;
1d45a705 979 if (dc->unrealize) {
b69c3c21 980 dc->unrealize(dev);
1d45a705
GA
981 }
982
983fail:
984 error_propagate(errp, local_err);
69382d8b
IM
985 if (unattached_parent) {
986 object_unparent(OBJECT(dev));
987 unattached_count--;
988 }
249d4172
AF
989}
990
a7737e44 991static bool device_get_hotpluggable(Object *obj, Error **errp)
1a37eca1
IM
992{
993 DeviceClass *dc = DEVICE_GET_CLASS(obj);
994 DeviceState *dev = DEVICE(obj);
995
2b81b35f 996 return dc->hotpluggable && (dev->parent_bus == NULL ||
39b888bd 997 qbus_is_hotpluggable(dev->parent_bus));
1a37eca1
IM
998}
999
40f03bd5 1000static bool device_get_hotplugged(Object *obj, Error **errp)
d012ffc1
IM
1001{
1002 DeviceState *dev = DEVICE(obj);
1003
1004 return dev->hotplugged;
1005}
1006
9674bfe4
AL
1007static void device_initfn(Object *obj)
1008{
1009 DeviceState *dev = DEVICE(obj);
9674bfe4
AL
1010
1011 if (qdev_hotplug) {
1012 dev->hotplugged = 1;
1013 qdev_hot_added = true;
1014 }
1015
1016 dev->instance_id_alias = -1;
7983c8a3 1017 dev->realized = false;
a1190ab6 1018 dev->allow_unplug_during_migration = false;
9674bfe4 1019
a5f54290 1020 QLIST_INIT(&dev->gpios);
0e6934f2 1021 QLIST_INIT(&dev->clocks);
9674bfe4
AL
1022}
1023
1c3994f6
MAL
1024static void device_post_init(Object *obj)
1025{
1a3ec8c1
MA
1026 /*
1027 * Note: ordered so that the user's global properties take
1028 * precedence.
1029 */
1c3994f6 1030 object_apply_compat_props(obj);
25f8dd96 1031 qdev_prop_set_globals(DEVICE(obj));
99a0b036
EH
1032}
1033
60adba37
AL
1034/* Unlink device from bus and free the structure. */
1035static void device_finalize(Object *obj)
1036{
a5f54290
PC
1037 NamedGPIOList *ngl, *next;
1038
60adba37 1039 DeviceState *dev = DEVICE(obj);
a5f54290
PC
1040
1041 QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
1042 QLIST_REMOVE(ngl, node);
f173d57a 1043 qemu_free_irqs(ngl->in, ngl->num_in);
a5f54290
PC
1044 g_free(ngl->name);
1045 g_free(ngl);
1046 /* ngl->out irqs are owned by the other end and should not be freed
1047 * here
1048 */
1049 }
f7b879e0 1050
0e6934f2
DH
1051 qdev_finalize_clocklist(dev);
1052
f7b879e0
MR
1053 /* Only send event if the device had been completely realized */
1054 if (dev->pending_deleted_event) {
1055 g_assert(dev->canonical_path);
1056
3ab72385 1057 qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path);
f7b879e0
MR
1058 g_free(dev->canonical_path);
1059 dev->canonical_path = NULL;
1060 }
1061
1062 qemu_opts_del(dev->opts);
60adba37
AL
1063}
1064
bce54474
PB
1065static void device_class_base_init(ObjectClass *class, void *data)
1066{
1067 DeviceClass *klass = DEVICE_CLASS(class);
1068
1069 /* We explicitly look up properties in the superclasses,
1070 * so do not propagate them to the subclasses.
1071 */
385d8f22 1072 klass->props_ = NULL;
60adba37
AL
1073}
1074
5d5b24d0 1075static void device_unparent(Object *obj)
667d22d1
PB
1076{
1077 DeviceState *dev = DEVICE(obj);
06f7f2bb 1078 BusState *bus;
667d22d1 1079
5c21ce77 1080 if (dev->realized) {
b69c3c21 1081 object_property_set_bool(obj, false, "realized", &error_abort);
5c21ce77 1082 }
06f7f2bb
PB
1083 while (dev->num_child_bus) {
1084 bus = QLIST_FIRST(&dev->child_bus);
6780a22c 1085 object_unparent(OBJECT(bus));
06f7f2bb 1086 }
06f7f2bb 1087 if (dev->parent_bus) {
5d5b24d0 1088 bus_remove_child(dev->parent_bus, dev);
62d7ba66
PB
1089 object_unref(OBJECT(dev->parent_bus));
1090 dev->parent_bus = NULL;
5d5b24d0 1091 }
667d22d1
PB
1092}
1093
107b5969
MAL
1094static char *
1095device_vmstate_if_get_id(VMStateIf *obj)
1096{
1097 DeviceState *dev = DEVICE(obj);
1098
1099 return qdev_get_dev_path(dev);
1100}
1101
c11256aa
DH
1102/**
1103 * device_phases_reset:
1104 * Transition reset method for devices to allow moving
1105 * smoothly from legacy reset method to multi-phases
1106 */
1107static void device_phases_reset(DeviceState *dev)
1108{
1109 ResettableClass *rc = RESETTABLE_GET_CLASS(dev);
1110
1111 if (rc->phases.enter) {
1112 rc->phases.enter(OBJECT(dev), RESET_TYPE_COLD);
1113 }
1114 if (rc->phases.hold) {
1115 rc->phases.hold(OBJECT(dev));
1116 }
1117 if (rc->phases.exit) {
1118 rc->phases.exit(OBJECT(dev));
1119 }
1120}
1121
1122static void device_transitional_reset(Object *obj)
1123{
1124 DeviceClass *dc = DEVICE_GET_CLASS(obj);
1125
1126 /*
1127 * This will call either @device_phases_reset (for multi-phases transitioned
1128 * devices) or a device's specific method for not-yet transitioned devices.
1129 * In both case, it does not reset children.
1130 */
1131 if (dc->reset) {
1132 dc->reset(DEVICE(obj));
1133 }
1134}
1135
1136/**
1137 * device_get_transitional_reset:
1138 * check if the device's class is ready for multi-phase
1139 */
1140static ResettableTrFunction device_get_transitional_reset(Object *obj)
1141{
1142 DeviceClass *dc = DEVICE_GET_CLASS(obj);
1143 if (dc->reset != device_phases_reset) {
1144 /*
1145 * dc->reset has been overridden by a subclass,
1146 * the device is not ready for multi phase yet.
1147 */
1148 return device_transitional_reset;
1149 }
1150 return NULL;
1151}
1152
667d22d1
PB
1153static void device_class_init(ObjectClass *class, void *data)
1154{
249d4172 1155 DeviceClass *dc = DEVICE_CLASS(class);
107b5969 1156 VMStateIfClass *vc = VMSTATE_IF_CLASS(class);
c11256aa 1157 ResettableClass *rc = RESETTABLE_CLASS(class);
249d4172 1158
5d5b24d0 1159 class->unparent = device_unparent;
267a3264
IM
1160
1161 /* by default all devices were considered as hotpluggable,
1162 * so with intent to check it in generic qdev_unplug() /
1163 * device_set_realized() functions make every device
1164 * hotpluggable. Devices that shouldn't be hotpluggable,
1165 * should override it in their class_init()
1166 */
1167 dc->hotpluggable = true;
e90f2a8c 1168 dc->user_creatable = true;
107b5969 1169 vc->get_id = device_vmstate_if_get_id;
c11256aa
DH
1170 rc->get_state = device_get_reset_state;
1171 rc->child_foreach = device_reset_child_foreach;
1172
1173 /*
1174 * @device_phases_reset is put as the default reset method below, allowing
1175 * to do the multi-phase transition from base classes to leaf classes. It
1176 * allows a legacy-reset Device class to extend a multi-phases-reset
1177 * Device class for the following reason:
1178 * + If a base class B has been moved to multi-phase, then it does not
1179 * override this default reset method and may have defined phase methods.
1180 * + A child class C (extending class B) which uses
1181 * device_class_set_parent_reset() (or similar means) to override the
1182 * reset method will still work as expected. @device_phases_reset function
1183 * will be registered as the parent reset method and effectively call
1184 * parent reset phases.
1185 */
1186 dc->reset = device_phases_reset;
1187 rc->get_transitional_function = device_get_transitional_reset;
c68fc935
MAL
1188
1189 object_class_property_add_bool(class, "realized",
d2623129 1190 device_get_realized, device_set_realized);
c68fc935 1191 object_class_property_add_bool(class, "hotpluggable",
d2623129 1192 device_get_hotpluggable, NULL);
c68fc935 1193 object_class_property_add_bool(class, "hotplugged",
d2623129 1194 device_get_hotplugged, NULL);
c68fc935 1195 object_class_property_add_link(class, "parent_bus", TYPE_BUS,
d2623129 1196 offsetof(DeviceState, parent_bus), NULL, 0);
667d22d1
PB
1197}
1198
4f67d30b
MAL
1199void device_class_set_props(DeviceClass *dc, Property *props)
1200{
77b06bba
MAL
1201 Property *prop;
1202
385d8f22 1203 dc->props_ = props;
77b06bba
MAL
1204 for (prop = props; prop && prop->name; prop++) {
1205 qdev_class_add_legacy_property(dc, prop);
1206 qdev_class_add_property(dc, prop);
1207 }
4f67d30b
MAL
1208}
1209
46795cf2
PMD
1210void device_class_set_parent_reset(DeviceClass *dc,
1211 DeviceReset dev_reset,
1212 DeviceReset *parent_reset)
1213{
1214 *parent_reset = dc->reset;
1215 dc->reset = dev_reset;
1216}
1217
1218void device_class_set_parent_realize(DeviceClass *dc,
1219 DeviceRealize dev_realize,
1220 DeviceRealize *parent_realize)
1221{
1222 *parent_realize = dc->realize;
1223 dc->realize = dev_realize;
1224}
1225
1226void device_class_set_parent_unrealize(DeviceClass *dc,
1227 DeviceUnrealize dev_unrealize,
1228 DeviceUnrealize *parent_unrealize)
1229{
1230 *parent_unrealize = dc->unrealize;
1231 dc->unrealize = dev_unrealize;
1232}
1233
f703a04c 1234void device_legacy_reset(DeviceState *dev)
94afdadc
AL
1235{
1236 DeviceClass *klass = DEVICE_GET_CLASS(dev);
1237
70804c83 1238 trace_qdev_reset(dev, object_get_typename(OBJECT(dev)));
94afdadc
AL
1239 if (klass->reset) {
1240 klass->reset(dev);
1241 }
1242}
1243
f05f6b4a
PB
1244Object *qdev_get_machine(void)
1245{
1246 static Object *dev;
1247
1248 if (dev == NULL) {
dfe47e70 1249 dev = container_get(object_get_root(), "/machine");
f05f6b4a
PB
1250 }
1251
1252 return dev;
1253}
1254
8c43a6f0 1255static const TypeInfo device_type_info = {
32fea402
AL
1256 .name = TYPE_DEVICE,
1257 .parent = TYPE_OBJECT,
1258 .instance_size = sizeof(DeviceState),
9674bfe4 1259 .instance_init = device_initfn,
99a0b036 1260 .instance_post_init = device_post_init,
60adba37 1261 .instance_finalize = device_finalize,
bce54474 1262 .class_base_init = device_class_base_init,
667d22d1 1263 .class_init = device_class_init,
32fea402
AL
1264 .abstract = true,
1265 .class_size = sizeof(DeviceClass),
107b5969
MAL
1266 .interfaces = (InterfaceInfo[]) {
1267 { TYPE_VMSTATE_IF },
c11256aa 1268 { TYPE_RESETTABLE_INTERFACE },
107b5969
MAL
1269 { }
1270 }
32fea402
AL
1271};
1272
83f7d43a 1273static void qdev_register_types(void)
32fea402
AL
1274{
1275 type_register_static(&device_type_info);
1276}
1277
83f7d43a 1278type_init(qdev_register_types)