]> Git Repo - qemu.git/blame - hw/qdev.c
fix Xen compilation
[qemu.git] / hw / 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
9d07d757 28#include "net.h"
aae9460e
PB
29#include "qdev.h"
30#include "sysemu.h"
56f9107e 31#include "error.h"
aae9460e 32
ee46d8a5 33int qdev_hotplug = 0;
0ac8ef71
AW
34static bool qdev_hot_added = false;
35static bool qdev_hot_removed = false;
3418bd25 36
aae9460e 37/* Register a new device type. */
4be9f0d1
AL
38const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
39{
6e008585
AL
40 DeviceClass *dc = DEVICE_GET_CLASS(dev);
41 return dc->vmsd;
4be9f0d1
AL
42}
43
4be9f0d1
AL
44const char *qdev_fw_name(DeviceState *dev)
45{
6e008585 46 DeviceClass *dc = DEVICE_GET_CLASS(dev);
4be9f0d1 47
6e008585
AL
48 if (dc->fw_name) {
49 return dc->fw_name;
4be9f0d1
AL
50 }
51
52 return object_get_typename(OBJECT(dev));
53}
54
a369da5f
BS
55bool qdev_exists(const char *name)
56{
212ad111 57 return !!object_class_by_name(name);
a369da5f 58}
40021f08 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);
73 object_property_del(OBJECT(bus), name, NULL);
74 g_free(kid);
75 return;
76 }
77 }
78}
79
80static void bus_add_child(BusState *bus, DeviceState *child)
81{
82 char name[32];
83 BusChild *kid = g_malloc0(sizeof(*kid));
0c17542d 84
0c17542d
MA
85 if (qdev_hotplug) {
86 assert(bus->allow_hotplug);
0c17542d 87 }
a5296ca9 88
0866aca1
AL
89 kid->index = bus->max_index++;
90 kid->child = child;
a5296ca9 91
0866aca1
AL
92 QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
93
94 snprintf(name, sizeof(name), "child[%d]", kid->index);
95 object_property_add_link(OBJECT(bus), name,
96 object_get_typename(OBJECT(child)),
97 (Object **)&kid->child,
98 NULL);
99}
100
101void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
102{
9fbe6127 103 dev->parent_bus = bus;
0866aca1 104 bus_add_child(bus, dev);
0c17542d
MA
105}
106
aae9460e
PB
107/* Create a new device. This only initializes the device state structure
108 and allows properties to be set. qdev_init should be called to
109 initialize the actual device emulation. */
02e2da45 110DeviceState *qdev_create(BusState *bus, const char *name)
0bcdeda7
BS
111{
112 DeviceState *dev;
113
114 dev = qdev_try_create(bus, name);
115 if (!dev) {
e92714c7
PM
116 if (bus) {
117 hw_error("Unknown device '%s' for bus '%s'\n", name,
0d936928 118 object_get_typename(OBJECT(bus)));
e92714c7
PM
119 } else {
120 hw_error("Unknown device '%s' for default sysbus\n", name);
121 }
0bcdeda7
BS
122 }
123
124 return dev;
125}
126
da57febf 127DeviceState *qdev_try_create(BusState *bus, const char *type)
aae9460e 128{
9fbe6127
AL
129 DeviceState *dev;
130
da57febf 131 if (object_class_by_name(type) == NULL) {
4ed658ca
AF
132 return NULL;
133 }
da57febf 134 dev = DEVICE(object_new(type));
9fbe6127
AL
135 if (!dev) {
136 return NULL;
137 }
138
10c4c98a 139 if (!bus) {
68694897 140 bus = sysbus_get_default();
10c4c98a
GH
141 }
142
9fbe6127 143 qdev_set_parent_bus(dev, bus);
9fbe6127
AL
144
145 return dev;
aae9460e
PB
146}
147
148/* Initialize a device. Device properties should be set before calling
149 this function. IRQs and MMIO regions should be connected/mapped after
18cfeb52
MA
150 calling this function.
151 On failure, destroy the device and return negative value.
152 Return 0 on success. */
81a322d4 153int qdev_init(DeviceState *dev)
aae9460e 154{
6e008585 155 DeviceClass *dc = DEVICE_GET_CLASS(dev);
959f733a
GH
156 int rc;
157
131ec1bd 158 assert(dev->state == DEV_STATE_CREATED);
6e008585 159
d307af79 160 rc = dc->init(dev);
18cfeb52 161 if (rc < 0) {
266ca11a 162 object_unparent(OBJECT(dev));
18cfeb52 163 qdev_free(dev);
959f733a 164 return rc;
18cfeb52 165 }
da57febf
PB
166
167 if (!OBJECT(dev)->parent) {
168 static int unattached_count = 0;
169 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
170
dfe47e70
AF
171 object_property_add_child(container_get(qdev_get_machine(),
172 "/unattached"),
173 name, OBJECT(dev), NULL);
da57febf
PB
174 g_free(name);
175 }
176
6e008585
AL
177 if (qdev_get_vmsd(dev)) {
178 vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
4d2ffa08
JK
179 dev->instance_id_alias,
180 dev->alias_required_for_version);
181 }
131ec1bd 182 dev->state = DEV_STATE_INITIALIZED;
94afdadc
AL
183 if (dev->hotplugged) {
184 device_reset(dev);
5ab28c83 185 }
959f733a 186 return 0;
02e2da45
PB
187}
188
4d2ffa08
JK
189void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
190 int required_for_version)
191{
192 assert(dev->state == DEV_STATE_CREATED);
193 dev->instance_id_alias = alias_id;
194 dev->alias_required_for_version = required_for_version;
195}
196
56f9107e 197void qdev_unplug(DeviceState *dev, Error **errp)
3418bd25 198{
6e008585
AL
199 DeviceClass *dc = DEVICE_GET_CLASS(dev);
200
3418bd25 201 if (!dev->parent_bus->allow_hotplug) {
56f9107e
LC
202 error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
203 return;
3418bd25 204 }
6e008585 205 assert(dc->unplug != NULL);
593831de 206
0ac8ef71
AW
207 qdev_hot_removed = true;
208
56f9107e
LC
209 if (dc->unplug(dev) < 0) {
210 error_set(errp, QERR_UNDEFINED_ERROR);
211 return;
212 }
3418bd25
GH
213}
214
ec990eb6
AL
215static int qdev_reset_one(DeviceState *dev, void *opaque)
216{
94afdadc 217 device_reset(dev);
ec990eb6
AL
218
219 return 0;
220}
221
b4694b7c
IY
222static int qbus_reset_one(BusState *bus, void *opaque)
223{
0d936928
AL
224 BusClass *bc = BUS_GET_CLASS(bus);
225 if (bc->reset) {
226 return bc->reset(bus);
b4694b7c
IY
227 }
228 return 0;
229}
230
5af0a04b
IY
231void qdev_reset_all(DeviceState *dev)
232{
233 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
234}
235
80376c3f
IY
236void qbus_reset_all_fn(void *opaque)
237{
238 BusState *bus = opaque;
f530cce3 239 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
80376c3f
IY
240}
241
3418bd25
GH
242/* can be used as ->unplug() callback for the simple cases */
243int qdev_simple_unplug_cb(DeviceState *dev)
244{
245 /* just zap it */
57c9fafe 246 object_unparent(OBJECT(dev));
3418bd25
GH
247 qdev_free(dev);
248 return 0;
249}
250
3b29a101
MT
251
252/* Like qdev_init(), but terminate program via error_report() instead of
e23a1b33
MA
253 returning an error value. This is okay during machine creation.
254 Don't use for hotplug, because there callers need to recover from
255 failure. Exception: if you know the device's init() callback can't
256 fail, then qdev_init_nofail() can't fail either, and is therefore
257 usable even then. But relying on the device implementation that
258 way is somewhat unclean, and best avoided. */
259void qdev_init_nofail(DeviceState *dev)
260{
7de3abe5
AL
261 const char *typename = object_get_typename(OBJECT(dev));
262
bd6c9a61 263 if (qdev_init(dev) < 0) {
7de3abe5 264 error_report("Initialization of device %s failed", typename);
bd6c9a61
MA
265 exit(1);
266 }
e23a1b33
MA
267}
268
02e2da45
PB
269/* Unlink device from bus and free the structure. */
270void qdev_free(DeviceState *dev)
271{
32fea402 272 object_delete(OBJECT(dev));
aae9460e
PB
273}
274
3418bd25
GH
275void qdev_machine_creation_done(void)
276{
277 /*
278 * ok, initial machine setup is done, starting from now we can
279 * only create hotpluggable devices
280 */
281 qdev_hotplug = 1;
282}
283
0ac8ef71
AW
284bool qdev_machine_modified(void)
285{
286 return qdev_hot_added || qdev_hot_removed;
287}
288
02e2da45 289BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 290{
02e2da45 291 return dev->parent_bus;
aae9460e
PB
292}
293
aae9460e
PB
294void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
295{
296 assert(dev->num_gpio_in == 0);
297 dev->num_gpio_in = n;
298 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
299}
300
301void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
302{
303 assert(dev->num_gpio_out == 0);
304 dev->num_gpio_out = n;
305 dev->gpio_out = pins;
306}
307
308qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
309{
310 assert(n >= 0 && n < dev->num_gpio_in);
311 return dev->gpio_in[n];
312}
313
314void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
315{
316 assert(n >= 0 && n < dev->num_gpio_out);
317 dev->gpio_out[n] = pin;
318}
319
ed16ab5a
GH
320void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
321{
6eed1856 322 qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
ed16ab5a
GH
323 if (nd->vlan)
324 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
325 if (nd->netdev)
326 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
75422b0d 327 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
89bfe000 328 object_property_find(OBJECT(dev), "vectors", NULL)) {
97b15621
GH
329 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
330 }
48e2faf2 331 nd->instantiated = 1;
ed16ab5a
GH
332}
333
02e2da45 334BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 335{
02e2da45 336 BusState *bus;
4d6ae674 337
72cf2d4f 338 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 339 if (strcmp(name, bus->name) == 0) {
02e2da45 340 return bus;
4d6ae674
PB
341 }
342 }
343 return NULL;
344}
345
81699d8a
AL
346int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
347 qbus_walkerfn *busfn, void *opaque)
348{
0866aca1 349 BusChild *kid;
81699d8a
AL
350 int err;
351
352 if (busfn) {
353 err = busfn(bus, opaque);
354 if (err) {
355 return err;
356 }
357 }
358
0866aca1
AL
359 QTAILQ_FOREACH(kid, &bus->children, sibling) {
360 err = qdev_walk_children(kid->child, devfn, busfn, opaque);
81699d8a
AL
361 if (err < 0) {
362 return err;
363 }
364 }
365
366 return 0;
367}
368
369int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
370 qbus_walkerfn *busfn, void *opaque)
371{
372 BusState *bus;
373 int err;
374
375 if (devfn) {
376 err = devfn(dev, opaque);
377 if (err) {
378 return err;
379 }
380 }
381
382 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
383 err = qbus_walk_children(bus, devfn, busfn, opaque);
384 if (err < 0) {
385 return err;
386 }
387 }
388
389 return 0;
390}
391
a2ee6b4f 392DeviceState *qdev_find_recursive(BusState *bus, const char *id)
3418bd25 393{
0866aca1
AL
394 BusChild *kid;
395 DeviceState *ret;
3418bd25
GH
396 BusState *child;
397
0866aca1
AL
398 QTAILQ_FOREACH(kid, &bus->children, sibling) {
399 DeviceState *dev = kid->child;
400
401 if (dev->id && strcmp(dev->id, id) == 0) {
3418bd25 402 return dev;
0866aca1
AL
403 }
404
3418bd25
GH
405 QLIST_FOREACH(child, &dev->child_bus, sibling) {
406 ret = qdev_find_recursive(child, id);
407 if (ret) {
408 return ret;
409 }
410 }
411 }
412 return NULL;
413}
414
ac7d1ba6 415static void qbus_realize(BusState *bus)
02e2da45 416{
ac7d1ba6 417 const char *typename = object_get_typename(OBJECT(bus));
d271de9f
GH
418 char *buf;
419 int i,len;
02e2da45 420
ac7d1ba6 421 if (bus->name) {
d271de9f 422 /* use supplied name */
ac7d1ba6 423 } else if (bus->parent && bus->parent->id) {
d271de9f 424 /* parent device has id -> use it for bus name */
ac7d1ba6 425 len = strlen(bus->parent->id) + 16;
7267c094 426 buf = g_malloc(len);
ac7d1ba6 427 snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
d271de9f
GH
428 bus->name = buf;
429 } else {
430 /* no id -> use lowercase bus type for bus name */
0d936928 431 len = strlen(typename) + 16;
7267c094 432 buf = g_malloc(len);
0d936928 433 len = snprintf(buf, len, "%s.%d", typename,
ac7d1ba6 434 bus->parent ? bus->parent->num_child_bus : 0);
d271de9f 435 for (i = 0; i < len; i++)
bb87ece5 436 buf[i] = qemu_tolower(buf[i]);
d271de9f
GH
437 bus->name = buf;
438 }
439
ac7d1ba6
AL
440 if (bus->parent) {
441 QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
442 bus->parent->num_child_bus++;
443 object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
8185d216 444 } else if (bus != sysbus_get_default()) {
80376c3f
IY
445 /* TODO: once all bus devices are qdevified,
446 only reset handler for main_system_bus should be registered here. */
447 qemu_register_reset(qbus_reset_all_fn, bus);
02e2da45 448 }
cd739fb6
GH
449}
450
0d936928
AL
451void qbus_create_inplace(BusState *bus, const char *typename,
452 DeviceState *parent, const char *name)
cd739fb6 453{
0d936928 454 object_initialize(bus, typename);
cd739fb6 455
ac7d1ba6
AL
456 bus->parent = parent;
457 bus->name = name ? g_strdup(name) : NULL;
458 qbus_realize(bus);
02e2da45 459}
cae4956e 460
0d936928 461BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
2da8bb92 462{
cd739fb6
GH
463 BusState *bus;
464
0d936928
AL
465 bus = BUS(object_new(typename));
466 bus->qom_allocated = true;
ac7d1ba6
AL
467
468 bus->parent = parent;
469 bus->name = name ? g_strdup(name) : NULL;
470 qbus_realize(bus);
471
02e2da45 472 return bus;
2da8bb92
IY
473}
474
131ec1bd
GH
475void qbus_free(BusState *bus)
476{
0d936928
AL
477 if (bus->qom_allocated) {
478 object_delete(OBJECT(bus));
80376c3f 479 } else {
0d936928
AL
480 object_finalize(OBJECT(bus));
481 if (bus->glib_allocated) {
482 g_free(bus);
483 }
131ec1bd 484 }
0d936928
AL
485}
486
487static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
488{
489 BusClass *bc = BUS_GET_CLASS(bus);
490
491 if (bc->get_fw_dev_path) {
492 return bc->get_fw_dev_path(dev);
131ec1bd 493 }
0d936928
AL
494
495 return NULL;
131ec1bd
GH
496}
497
1ca4d09a
GN
498static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
499{
500 int l = 0;
501
502 if (dev && dev->parent_bus) {
503 char *d;
504 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
0d936928
AL
505 d = bus_get_fw_dev_path(dev->parent_bus, dev);
506 if (d) {
1ca4d09a 507 l += snprintf(p + l, size - l, "%s", d);
7267c094 508 g_free(d);
1ca4d09a 509 } else {
f79f2bfc 510 l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
1ca4d09a
GN
511 }
512 }
513 l += snprintf(p + l , size - l, "/");
514
515 return l;
516}
517
518char* qdev_get_fw_dev_path(DeviceState *dev)
519{
520 char path[128];
521 int l;
522
523 l = qdev_get_fw_dev_path_helper(dev, path, 128);
524
525 path[l-1] = '\0';
526
527 return strdup(path);
528}
85ed303b 529
09e5ab63 530char *qdev_get_dev_path(DeviceState *dev)
85ed303b 531{
0d936928 532 BusClass *bc;
09e5ab63
AL
533
534 if (!dev || !dev->parent_bus) {
535 return NULL;
536 }
537
0d936928
AL
538 bc = BUS_GET_CLASS(dev->parent_bus);
539 if (bc->get_dev_path) {
540 return bc->get_dev_path(dev);
09e5ab63
AL
541 }
542
543 return NULL;
44677ded 544}
a5296ca9
AL
545
546/**
547 * Legacy property handling
548 */
549
57c9fafe 550static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
a5296ca9
AL
551 const char *name, Error **errp)
552{
57c9fafe 553 DeviceState *dev = DEVICE(obj);
a5296ca9
AL
554 Property *prop = opaque;
555
e3cb6ba6
PB
556 char buffer[1024];
557 char *ptr = buffer;
a5296ca9 558
e3cb6ba6
PB
559 prop->info->print(dev, prop, buffer, sizeof(buffer));
560 visit_type_str(v, &ptr, name, errp);
a5296ca9
AL
561}
562
57c9fafe 563static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
a5296ca9
AL
564 const char *name, Error **errp)
565{
57c9fafe 566 DeviceState *dev = DEVICE(obj);
a5296ca9 567 Property *prop = opaque;
e3cb6ba6
PB
568 Error *local_err = NULL;
569 char *ptr = NULL;
570 int ret;
a5296ca9
AL
571
572 if (dev->state != DEV_STATE_CREATED) {
573 error_set(errp, QERR_PERMISSION_DENIED);
574 return;
575 }
576
e3cb6ba6
PB
577 visit_type_str(v, &ptr, name, &local_err);
578 if (local_err) {
579 error_propagate(errp, local_err);
580 return;
581 }
a5296ca9 582
e3cb6ba6 583 ret = prop->info->parse(dev, prop, ptr);
7db4c4e8 584 error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
e3cb6ba6 585 g_free(ptr);
a5296ca9
AL
586}
587
588/**
589 * @qdev_add_legacy_property - adds a legacy property
590 *
591 * Do not use this is new code! Properties added through this interface will
ca2cc788 592 * be given names and types in the "legacy" namespace.
a5296ca9 593 *
68ee3569
PB
594 * Legacy properties are string versions of other OOM properties. The format
595 * of the string depends on the property type.
a5296ca9
AL
596 */
597void qdev_property_add_legacy(DeviceState *dev, Property *prop,
598 Error **errp)
599{
ca2cc788 600 gchar *name, *type;
a5296ca9 601
f3be016d
AL
602 /* Register pointer properties as legacy properties */
603 if (!prop->info->print && !prop->info->parse &&
604 (prop->info->set || prop->info->get)) {
68ee3569
PB
605 return;
606 }
f3be016d 607
ca2cc788 608 name = g_strdup_printf("legacy-%s", prop->name);
cafe5bdb
PB
609 type = g_strdup_printf("legacy<%s>",
610 prop->info->legacy_name ?: prop->info->name);
a5296ca9 611
57c9fafe 612 object_property_add(OBJECT(dev), name, type,
68ee3569
PB
613 prop->info->print ? qdev_get_legacy_property : prop->info->get,
614 prop->info->parse ? qdev_set_legacy_property : prop->info->set,
57c9fafe
AL
615 NULL,
616 prop, errp);
a5296ca9
AL
617
618 g_free(type);
ca2cc788
PB
619 g_free(name);
620}
621
622/**
623 * @qdev_property_add_static - add a @Property to a device.
624 *
625 * Static properties access data in a struct. The actual type of the
626 * property and the field depends on the property type.
627 */
628void qdev_property_add_static(DeviceState *dev, Property *prop,
629 Error **errp)
630{
fdae245f
PB
631 Error *local_err = NULL;
632 Object *obj = OBJECT(dev);
633
d822979b
PB
634 /*
635 * TODO qdev_prop_ptr does not have getters or setters. It must
636 * go now that it can be replaced with links. The test should be
637 * removed along with it: all static properties are read/write.
638 */
639 if (!prop->info->get && !prop->info->set) {
640 return;
641 }
642
fdae245f 643 object_property_add(obj, prop->name, prop->info->name,
57c9fafe 644 prop->info->get, prop->info->set,
dd0ba250 645 prop->info->release,
fdae245f
PB
646 prop, &local_err);
647
648 if (local_err) {
649 error_propagate(errp, local_err);
650 return;
651 }
652 if (prop->qtype == QTYPE_NONE) {
653 return;
654 }
655
656 if (prop->qtype == QTYPE_QBOOL) {
657 object_property_set_bool(obj, prop->defval, prop->name, &local_err);
658 } else if (prop->info->enum_table) {
659 object_property_set_str(obj, prop->info->enum_table[prop->defval],
660 prop->name, &local_err);
661 } else if (prop->qtype == QTYPE_QINT) {
662 object_property_set_int(obj, prop->defval, prop->name, &local_err);
663 }
664 assert_no_error(local_err);
6a146eba 665}
1de81d28 666
9674bfe4
AL
667static void device_initfn(Object *obj)
668{
669 DeviceState *dev = DEVICE(obj);
bce54474 670 ObjectClass *class;
9674bfe4
AL
671 Property *prop;
672
673 if (qdev_hotplug) {
674 dev->hotplugged = 1;
675 qdev_hot_added = true;
676 }
677
678 dev->instance_id_alias = -1;
9674bfe4
AL
679 dev->state = DEV_STATE_CREATED;
680
bce54474
PB
681 class = object_get_class(OBJECT(dev));
682 do {
683 for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
684 qdev_property_add_legacy(dev, prop, NULL);
685 qdev_property_add_static(dev, prop, NULL);
686 }
bce54474
PB
687 class = object_class_get_parent(class);
688 } while (class != object_class_by_name(TYPE_DEVICE));
4b3582b0 689 qdev_prop_set_globals(dev);
9674bfe4 690
f968fc68
AL
691 object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
692 (Object **)&dev->parent_bus, NULL);
9674bfe4
AL
693}
694
60adba37
AL
695/* Unlink device from bus and free the structure. */
696static void device_finalize(Object *obj)
697{
698 DeviceState *dev = DEVICE(obj);
699 BusState *bus;
60adba37
AL
700 DeviceClass *dc = DEVICE_GET_CLASS(dev);
701
702 if (dev->state == DEV_STATE_INITIALIZED) {
703 while (dev->num_child_bus) {
704 bus = QLIST_FIRST(&dev->child_bus);
705 qbus_free(bus);
706 }
707 if (qdev_get_vmsd(dev)) {
708 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
709 }
710 if (dc->exit) {
711 dc->exit(dev);
712 }
713 if (dev->opts) {
714 qemu_opts_del(dev->opts);
715 }
716 }
0866aca1
AL
717 if (dev->parent_bus) {
718 bus_remove_child(dev->parent_bus, dev);
719 }
60adba37
AL
720}
721
bce54474
PB
722static void device_class_base_init(ObjectClass *class, void *data)
723{
724 DeviceClass *klass = DEVICE_CLASS(class);
725
726 /* We explicitly look up properties in the superclasses,
727 * so do not propagate them to the subclasses.
728 */
729 klass->props = NULL;
60adba37
AL
730}
731
94afdadc
AL
732void device_reset(DeviceState *dev)
733{
734 DeviceClass *klass = DEVICE_GET_CLASS(dev);
735
736 if (klass->reset) {
737 klass->reset(dev);
738 }
739}
740
f05f6b4a
PB
741Object *qdev_get_machine(void)
742{
743 static Object *dev;
744
745 if (dev == NULL) {
dfe47e70 746 dev = container_get(object_get_root(), "/machine");
f05f6b4a
PB
747 }
748
749 return dev;
750}
751
32fea402
AL
752static TypeInfo device_type_info = {
753 .name = TYPE_DEVICE,
754 .parent = TYPE_OBJECT,
755 .instance_size = sizeof(DeviceState),
9674bfe4 756 .instance_init = device_initfn,
60adba37 757 .instance_finalize = device_finalize,
bce54474 758 .class_base_init = device_class_base_init,
32fea402
AL
759 .abstract = true,
760 .class_size = sizeof(DeviceClass),
761};
762
ac7d1ba6
AL
763static void qbus_initfn(Object *obj)
764{
765 BusState *bus = BUS(obj);
766
767 QTAILQ_INIT(&bus->children);
768}
769
770static void qbus_finalize(Object *obj)
771{
772 BusState *bus = BUS(obj);
773 BusChild *kid;
774
775 while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
776 DeviceState *dev = kid->child;
777 qdev_free(dev);
778 }
779 if (bus->parent) {
780 QLIST_REMOVE(bus, sibling);
781 bus->parent->num_child_bus--;
782 } else {
783 assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
784 qemu_unregister_reset(qbus_reset_all_fn, bus);
785 }
786 g_free((char *)bus->name);
787}
788
0d936928
AL
789static const TypeInfo bus_info = {
790 .name = TYPE_BUS,
791 .parent = TYPE_OBJECT,
792 .instance_size = sizeof(BusState),
793 .abstract = true,
794 .class_size = sizeof(BusClass),
ac7d1ba6
AL
795 .instance_init = qbus_initfn,
796 .instance_finalize = qbus_finalize,
0d936928
AL
797};
798
83f7d43a 799static void qdev_register_types(void)
32fea402 800{
0d936928 801 type_register_static(&bus_info);
32fea402
AL
802 type_register_static(&device_type_info);
803}
804
83f7d43a 805type_init(qdev_register_types)
This page took 0.634338 seconds and 4 git commands to generate.