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