blob: 63012b5252ceff73bd2e36c3b8f26a9e4cec58fb [file] [log] [blame]
Paul Brookaae94602009-05-14 22:35:06 +01001/*
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
Blue Swirl8167ee82009-07-16 20:47:01 +000017 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Paul Brookaae94602009-05-14 22:35:06 +010018 */
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
Paul Brook9d07d752009-05-14 22:35:07 +010028#include "net.h"
Paul Brookaae94602009-05-14 22:35:06 +010029#include "qdev.h"
30#include "sysemu.h"
Luiz Capitulino56f91072012-03-14 17:37:38 -030031#include "error.h"
Paul Brookaae94602009-05-14 22:35:06 +010032
Anthony Liguoriee46d8a2011-12-22 15:24:20 -060033int qdev_hotplug = 0;
Alex Williamson0ac8ef72011-01-04 12:37:50 -070034static bool qdev_hot_added = false;
35static bool qdev_hot_removed = false;
Gerd Hoffmann3418bd22009-09-25 21:42:41 +020036
Paul Brookaae94602009-05-14 22:35:06 +010037/* Register a new device type. */
Anthony Liguori4be9f0d2011-12-09 10:51:49 -060038const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
39{
Anthony Liguori6e008582011-12-09 11:06:57 -060040 DeviceClass *dc = DEVICE_GET_CLASS(dev);
41 return dc->vmsd;
Anthony Liguori4be9f0d2011-12-09 10:51:49 -060042}
43
Anthony Liguori4be9f0d2011-12-09 10:51:49 -060044const char *qdev_fw_name(DeviceState *dev)
45{
Anthony Liguori6e008582011-12-09 11:06:57 -060046 DeviceClass *dc = DEVICE_GET_CLASS(dev);
Anthony Liguori4be9f0d2011-12-09 10:51:49 -060047
Anthony Liguori6e008582011-12-09 11:06:57 -060048 if (dc->fw_name) {
49 return dc->fw_name;
Anthony Liguori4be9f0d2011-12-09 10:51:49 -060050 }
51
52 return object_get_typename(OBJECT(dev));
53}
54
Blue Swirla369da52011-09-27 19:15:42 +000055bool qdev_exists(const char *name)
56{
Anthony Liguori212ad112012-02-01 09:34:28 -060057 return !!object_class_by_name(name);
Blue Swirla369da52011-09-27 19:15:42 +000058}
Anthony Liguori40021f02011-12-04 12:22:06 -060059
Paolo Bonzinica2cc782011-12-18 17:05:11 +010060static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
61 Error **errp);
62
Anthony Liguori9fbe6122011-12-22 15:14:27 -060063void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
Paul Brookaae94602009-05-14 22:35:06 +010064{
Gerd Hoffmann3418bd22009-09-25 21:42:41 +020065 if (qdev_hotplug) {
66 assert(bus->allow_hotplug);
Gerd Hoffmann3418bd22009-09-25 21:42:41 +020067 }
Anthony Liguoria5296ca2011-12-12 14:29:27 -060068
Anthony Liguori9fbe6122011-12-22 15:14:27 -060069 dev->parent_bus = bus;
Anthony Liguori9674bfe2011-12-22 15:06:37 -060070 QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
Paul Brookaae94602009-05-14 22:35:06 +010071}
72
Markus Armbruster0c175422010-02-19 19:12:18 +010073/* Create a new device. This only initializes the device state structure
74 and allows properties to be set. qdev_init should be called to
75 initialize the actual device emulation. */
76DeviceState *qdev_create(BusState *bus, const char *name)
77{
Blue Swirl0bcdeda2011-02-05 14:34:25 +000078 DeviceState *dev;
79
80 dev = qdev_try_create(bus, name);
81 if (!dev) {
Peter Maydelle92714c2011-08-03 23:49:04 +010082 if (bus) {
83 hw_error("Unknown device '%s' for bus '%s'\n", name,
Anthony Liguori0d936922012-05-02 09:00:20 +020084 object_get_typename(OBJECT(bus)));
Peter Maydelle92714c2011-08-03 23:49:04 +010085 } else {
86 hw_error("Unknown device '%s' for default sysbus\n", name);
87 }
Blue Swirl0bcdeda2011-02-05 14:34:25 +000088 }
89
90 return dev;
91}
92
Paolo Bonzinida57feb2012-03-27 18:38:47 +020093DeviceState *qdev_try_create(BusState *bus, const char *type)
Blue Swirl0bcdeda2011-02-05 14:34:25 +000094{
Anthony Liguori9fbe6122011-12-22 15:14:27 -060095 DeviceState *dev;
96
Paolo Bonzinida57feb2012-03-27 18:38:47 +020097 if (object_class_by_name(type) == NULL) {
Andreas Färber4ed658c2012-02-17 02:47:44 +010098 return NULL;
99 }
Paolo Bonzinida57feb2012-03-27 18:38:47 +0200100 dev = DEVICE(object_new(type));
Anthony Liguori9fbe6122011-12-22 15:14:27 -0600101 if (!dev) {
102 return NULL;
103 }
104
Markus Armbruster0c175422010-02-19 19:12:18 +0100105 if (!bus) {
Stefan Weil68694892010-12-16 19:33:22 +0100106 bus = sysbus_get_default();
Markus Armbruster0c175422010-02-19 19:12:18 +0100107 }
108
Anthony Liguori9fbe6122011-12-22 15:14:27 -0600109 qdev_set_parent_bus(dev, bus);
Anthony Liguori9fbe6122011-12-22 15:14:27 -0600110
111 return dev;
Markus Armbruster0c175422010-02-19 19:12:18 +0100112}
113
Paul Brookaae94602009-05-14 22:35:06 +0100114/* Initialize a device. Device properties should be set before calling
115 this function. IRQs and MMIO regions should be connected/mapped after
Markus Armbruster18cfeb52009-10-07 01:15:56 +0200116 calling this function.
117 On failure, destroy the device and return negative value.
118 Return 0 on success. */
Gerd Hoffmann81a322d2009-08-14 10:36:05 +0200119int qdev_init(DeviceState *dev)
Paul Brookaae94602009-05-14 22:35:06 +0100120{
Anthony Liguori6e008582011-12-09 11:06:57 -0600121 DeviceClass *dc = DEVICE_GET_CLASS(dev);
Gerd Hoffmann959f7332009-09-01 09:56:12 +0200122 int rc;
123
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200124 assert(dev->state == DEV_STATE_CREATED);
Anthony Liguori6e008582011-12-09 11:06:57 -0600125
Anthony Liguorid307af72011-12-09 15:02:56 -0600126 rc = dc->init(dev);
Markus Armbruster18cfeb52009-10-07 01:15:56 +0200127 if (rc < 0) {
128 qdev_free(dev);
Gerd Hoffmann959f7332009-09-01 09:56:12 +0200129 return rc;
Markus Armbruster18cfeb52009-10-07 01:15:56 +0200130 }
Paolo Bonzinida57feb2012-03-27 18:38:47 +0200131
132 if (!OBJECT(dev)->parent) {
133 static int unattached_count = 0;
134 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
135
Andreas Färberdfe47e72012-04-05 13:21:46 +0200136 object_property_add_child(container_get(qdev_get_machine(),
137 "/unattached"),
138 name, OBJECT(dev), NULL);
Paolo Bonzinida57feb2012-03-27 18:38:47 +0200139 g_free(name);
140 }
141
Anthony Liguori6e008582011-12-09 11:06:57 -0600142 if (qdev_get_vmsd(dev)) {
143 vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
Jan Kiszka4d2ffa02010-05-15 13:32:40 +0200144 dev->instance_id_alias,
145 dev->alias_required_for_version);
146 }
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200147 dev->state = DEV_STATE_INITIALIZED;
Anthony Liguori94afdad2011-12-04 11:36:01 -0600148 if (dev->hotplugged) {
149 device_reset(dev);
Jan Kiszka5ab28c82011-07-24 19:38:36 +0200150 }
Gerd Hoffmann959f7332009-09-01 09:56:12 +0200151 return 0;
Paul Brook02e2da42009-05-23 00:05:19 +0100152}
153
Jan Kiszka4d2ffa02010-05-15 13:32:40 +0200154void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
155 int required_for_version)
156{
157 assert(dev->state == DEV_STATE_CREATED);
158 dev->instance_id_alias = alias_id;
159 dev->alias_required_for_version = required_for_version;
160}
161
Luiz Capitulino56f91072012-03-14 17:37:38 -0300162void qdev_unplug(DeviceState *dev, Error **errp)
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200163{
Anthony Liguori6e008582011-12-09 11:06:57 -0600164 DeviceClass *dc = DEVICE_GET_CLASS(dev);
165
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200166 if (!dev->parent_bus->allow_hotplug) {
Luiz Capitulino56f91072012-03-14 17:37:38 -0300167 error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
168 return;
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200169 }
Anthony Liguori6e008582011-12-09 11:06:57 -0600170 assert(dc->unplug != NULL);
Amit Shah593831d2009-11-02 14:56:41 +0530171
Alex Williamson0ac8ef72011-01-04 12:37:50 -0700172 qdev_hot_removed = true;
173
Luiz Capitulino56f91072012-03-14 17:37:38 -0300174 if (dc->unplug(dev) < 0) {
175 error_set(errp, QERR_UNDEFINED_ERROR);
176 return;
177 }
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200178}
179
Anthony Liguoriec990eb2010-11-19 18:55:59 +0900180static int qdev_reset_one(DeviceState *dev, void *opaque)
181{
Anthony Liguori94afdad2011-12-04 11:36:01 -0600182 device_reset(dev);
Anthony Liguoriec990eb2010-11-19 18:55:59 +0900183
184 return 0;
185}
186
Isaku Yamahatab4694b72010-11-19 18:56:00 +0900187static int qbus_reset_one(BusState *bus, void *opaque)
188{
Anthony Liguori0d936922012-05-02 09:00:20 +0200189 BusClass *bc = BUS_GET_CLASS(bus);
190 if (bc->reset) {
191 return bc->reset(bus);
Isaku Yamahatab4694b72010-11-19 18:56:00 +0900192 }
193 return 0;
194}
195
Isaku Yamahata5af0a042010-11-19 18:56:01 +0900196void qdev_reset_all(DeviceState *dev)
197{
198 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
199}
200
Isaku Yamahata80376c32010-12-20 14:33:35 +0900201void qbus_reset_all_fn(void *opaque)
202{
203 BusState *bus = opaque;
Michael S. Tsirkinf530cce2010-12-20 15:17:10 +0200204 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
Isaku Yamahata80376c32010-12-20 14:33:35 +0900205}
206
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200207/* can be used as ->unplug() callback for the simple cases */
208int qdev_simple_unplug_cb(DeviceState *dev)
209{
210 /* just zap it */
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600211 object_unparent(OBJECT(dev));
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200212 qdev_free(dev);
213 return 0;
214}
215
Michael Tokarev3b29a102011-04-06 17:51:59 +0400216
217/* Like qdev_init(), but terminate program via error_report() instead of
Markus Armbrustere23a1b32009-10-07 01:15:58 +0200218 returning an error value. This is okay during machine creation.
219 Don't use for hotplug, because there callers need to recover from
220 failure. Exception: if you know the device's init() callback can't
221 fail, then qdev_init_nofail() can't fail either, and is therefore
222 usable even then. But relying on the device implementation that
223 way is somewhat unclean, and best avoided. */
224void qdev_init_nofail(DeviceState *dev)
225{
Markus Armbrusterbd6c9a62010-05-27 21:23:08 +0200226 if (qdev_init(dev) < 0) {
Anthony Liguori6e008582011-12-09 11:06:57 -0600227 error_report("Initialization of device %s failed",
228 object_get_typename(OBJECT(dev)));
Markus Armbrusterbd6c9a62010-05-27 21:23:08 +0200229 exit(1);
230 }
Markus Armbrustere23a1b32009-10-07 01:15:58 +0200231}
232
Paul Brook02e2da42009-05-23 00:05:19 +0100233/* Unlink device from bus and free the structure. */
234void qdev_free(DeviceState *dev)
235{
Anthony Liguori32fea402011-12-16 14:34:46 -0600236 object_delete(OBJECT(dev));
Paul Brookaae94602009-05-14 22:35:06 +0100237}
238
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200239void qdev_machine_creation_done(void)
240{
241 /*
242 * ok, initial machine setup is done, starting from now we can
243 * only create hotpluggable devices
244 */
245 qdev_hotplug = 1;
246}
247
Alex Williamson0ac8ef72011-01-04 12:37:50 -0700248bool qdev_machine_modified(void)
249{
250 return qdev_hot_added || qdev_hot_removed;
251}
252
Paul Brook02e2da42009-05-23 00:05:19 +0100253BusState *qdev_get_parent_bus(DeviceState *dev)
Paul Brookaae94602009-05-14 22:35:06 +0100254{
Paul Brook02e2da42009-05-23 00:05:19 +0100255 return dev->parent_bus;
Paul Brookaae94602009-05-14 22:35:06 +0100256}
257
Paul Brookaae94602009-05-14 22:35:06 +0100258void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
259{
260 assert(dev->num_gpio_in == 0);
261 dev->num_gpio_in = n;
262 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
263}
264
265void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
266{
267 assert(dev->num_gpio_out == 0);
268 dev->num_gpio_out = n;
269 dev->gpio_out = pins;
270}
271
272qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
273{
274 assert(n >= 0 && n < dev->num_gpio_in);
275 return dev->gpio_in[n];
276}
277
278void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
279{
280 assert(n >= 0 && n < dev->num_gpio_out);
281 dev->gpio_out[n] = pin;
282}
283
Gerd Hoffmanned16ab52009-10-21 15:25:26 +0200284void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
285{
Jan Kiszka6eed1852011-07-20 12:20:22 +0200286 qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
Gerd Hoffmanned16ab52009-10-21 15:25:26 +0200287 if (nd->vlan)
288 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
289 if (nd->netdev)
290 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
Amit Shah75422b02010-02-25 17:24:43 +0530291 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
Gerd Hoffmann97b15622009-10-21 15:25:35 +0200292 qdev_prop_exists(dev, "vectors")) {
293 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
294 }
Peter Maydell48e2faf2011-05-20 16:50:01 +0100295 nd->instantiated = 1;
Gerd Hoffmanned16ab52009-10-21 15:25:26 +0200296}
297
Paul Brook02e2da42009-05-23 00:05:19 +0100298BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
Paul Brook4d6ae672009-05-14 22:35:06 +0100299{
Paul Brook02e2da42009-05-23 00:05:19 +0100300 BusState *bus;
Paul Brook4d6ae672009-05-14 22:35:06 +0100301
Blue Swirl72cf2d42009-09-12 07:36:22 +0000302 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
Paul Brook4d6ae672009-05-14 22:35:06 +0100303 if (strcmp(name, bus->name) == 0) {
Paul Brook02e2da42009-05-23 00:05:19 +0100304 return bus;
Paul Brook4d6ae672009-05-14 22:35:06 +0100305 }
306 }
307 return NULL;
308}
309
Anthony Liguori81699d82010-11-19 18:55:58 +0900310int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
311 qbus_walkerfn *busfn, void *opaque)
312{
313 DeviceState *dev;
314 int err;
315
316 if (busfn) {
317 err = busfn(bus, opaque);
318 if (err) {
319 return err;
320 }
321 }
322
Paolo Bonzinid8bb00d2011-09-14 09:28:06 +0200323 QTAILQ_FOREACH(dev, &bus->children, sibling) {
Anthony Liguori81699d82010-11-19 18:55:58 +0900324 err = qdev_walk_children(dev, devfn, busfn, opaque);
325 if (err < 0) {
326 return err;
327 }
328 }
329
330 return 0;
331}
332
333int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
334 qbus_walkerfn *busfn, void *opaque)
335{
336 BusState *bus;
337 int err;
338
339 if (devfn) {
340 err = devfn(dev, opaque);
341 if (err) {
342 return err;
343 }
344 }
345
346 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
347 err = qbus_walk_children(bus, devfn, busfn, opaque);
348 if (err < 0) {
349 return err;
350 }
351 }
352
353 return 0;
354}
355
Isaku Yamahataa2ee6b42010-12-24 12:14:12 +0900356DeviceState *qdev_find_recursive(BusState *bus, const char *id)
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200357{
358 DeviceState *dev, *ret;
359 BusState *child;
360
Paolo Bonzinid8bb00d2011-09-14 09:28:06 +0200361 QTAILQ_FOREACH(dev, &bus->children, sibling) {
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200362 if (dev->id && strcmp(dev->id, id) == 0)
363 return dev;
364 QLIST_FOREACH(child, &dev->child_bus, sibling) {
365 ret = qdev_find_recursive(child, id);
366 if (ret) {
367 return ret;
368 }
369 }
370 }
371 return NULL;
372}
373
Anthony Liguori0d936922012-05-02 09:00:20 +0200374/* FIXME move this logic into instance_init */
375static void do_qbus_create_inplace(BusState *bus, const char *typename,
376 DeviceState *parent, const char *name)
Paul Brook02e2da42009-05-23 00:05:19 +0100377{
Gerd Hoffmannd271de92009-07-15 13:59:24 +0200378 char *buf;
379 int i,len;
Paul Brook02e2da42009-05-23 00:05:19 +0100380
Paul Brook02e2da42009-05-23 00:05:19 +0100381 bus->parent = parent;
Gerd Hoffmannd271de92009-07-15 13:59:24 +0200382
383 if (name) {
384 /* use supplied name */
Anthony Liguori7267c092011-08-20 22:09:37 -0500385 bus->name = g_strdup(name);
Gerd Hoffmannd271de92009-07-15 13:59:24 +0200386 } else if (parent && parent->id) {
387 /* parent device has id -> use it for bus name */
388 len = strlen(parent->id) + 16;
Anthony Liguori7267c092011-08-20 22:09:37 -0500389 buf = g_malloc(len);
Gerd Hoffmannd271de92009-07-15 13:59:24 +0200390 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
391 bus->name = buf;
392 } else {
393 /* no id -> use lowercase bus type for bus name */
Anthony Liguori0d936922012-05-02 09:00:20 +0200394 len = strlen(typename) + 16;
Anthony Liguori7267c092011-08-20 22:09:37 -0500395 buf = g_malloc(len);
Anthony Liguori0d936922012-05-02 09:00:20 +0200396 len = snprintf(buf, len, "%s.%d", typename,
Gerd Hoffmannd271de92009-07-15 13:59:24 +0200397 parent ? parent->num_child_bus : 0);
398 for (i = 0; i < len; i++)
Christoph Eggerbb87ece2009-07-30 15:28:45 +0200399 buf[i] = qemu_tolower(buf[i]);
Gerd Hoffmannd271de92009-07-15 13:59:24 +0200400 bus->name = buf;
401 }
402
Paolo Bonzinid8bb00d2011-09-14 09:28:06 +0200403 QTAILQ_INIT(&bus->children);
Paul Brook02e2da42009-05-23 00:05:19 +0100404 if (parent) {
Blue Swirl72cf2d42009-09-12 07:36:22 +0000405 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
Gerd Hoffmannd271de92009-07-15 13:59:24 +0200406 parent->num_child_bus++;
Paolo Bonzini8185d212012-05-02 12:06:55 +0200407 } else if (bus != sysbus_get_default()) {
Isaku Yamahata80376c32010-12-20 14:33:35 +0900408 /* TODO: once all bus devices are qdevified,
409 only reset handler for main_system_bus should be registered here. */
410 qemu_register_reset(qbus_reset_all_fn, bus);
Paul Brook02e2da42009-05-23 00:05:19 +0100411 }
Gerd Hoffmanncd739fb2009-09-16 22:25:27 +0200412}
413
Anthony Liguori0d936922012-05-02 09:00:20 +0200414void qbus_create_inplace(BusState *bus, const char *typename,
415 DeviceState *parent, const char *name)
416{
417 object_initialize(bus, typename);
418 do_qbus_create_inplace(bus, typename, parent, name);
419}
420
421BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
Gerd Hoffmanncd739fb2009-09-16 22:25:27 +0200422{
423 BusState *bus;
424
Anthony Liguori0d936922012-05-02 09:00:20 +0200425 bus = BUS(object_new(typename));
426 bus->qom_allocated = true;
427 do_qbus_create_inplace(bus, typename, parent, name);
Paul Brook02e2da42009-05-23 00:05:19 +0100428 return bus;
429}
Gerd Hoffmanncae49562009-06-05 15:53:17 +0100430
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200431void qbus_free(BusState *bus)
432{
433 DeviceState *dev;
434
Paolo Bonzinid8bb00d2011-09-14 09:28:06 +0200435 while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200436 qdev_free(dev);
437 }
438 if (bus->parent) {
439 QLIST_REMOVE(bus, sibling);
440 bus->parent->num_child_bus--;
Isaku Yamahata80376c32010-12-20 14:33:35 +0900441 } else {
Paolo Bonzini8185d212012-05-02 12:06:55 +0200442 assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
Isaku Yamahata80376c32010-12-20 14:33:35 +0900443 qemu_unregister_reset(qbus_reset_all_fn, bus);
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200444 }
Anthony Liguori7267c092011-08-20 22:09:37 -0500445 g_free((void*)bus->name);
Anthony Liguori0d936922012-05-02 09:00:20 +0200446 if (bus->qom_allocated) {
447 object_delete(OBJECT(bus));
448 } else {
449 object_finalize(OBJECT(bus));
450 if (bus->glib_allocated) {
451 g_free(bus);
452 }
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200453 }
454}
455
Anthony Liguori0d936922012-05-02 09:00:20 +0200456static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
457{
458 BusClass *bc = BUS_GET_CLASS(bus);
459
460 if (bc->get_fw_dev_path) {
461 return bc->get_fw_dev_path(dev);
462 }
463
464 return NULL;
465}
466
Gleb Natapov1ca4d092010-12-08 13:35:05 +0200467static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
468{
469 int l = 0;
470
471 if (dev && dev->parent_bus) {
472 char *d;
473 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
Anthony Liguori0d936922012-05-02 09:00:20 +0200474 d = bus_get_fw_dev_path(dev->parent_bus, dev);
475 if (d) {
Gleb Natapov1ca4d092010-12-08 13:35:05 +0200476 l += snprintf(p + l, size - l, "%s", d);
Anthony Liguori7267c092011-08-20 22:09:37 -0500477 g_free(d);
Gleb Natapov1ca4d092010-12-08 13:35:05 +0200478 } else {
Anthony Liguorif79f2bf2011-12-04 11:17:51 -0600479 l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
Gleb Natapov1ca4d092010-12-08 13:35:05 +0200480 }
481 }
482 l += snprintf(p + l , size - l, "/");
483
484 return l;
485}
486
487char* qdev_get_fw_dev_path(DeviceState *dev)
488{
489 char path[128];
490 int l;
491
492 l = qdev_get_fw_dev_path_helper(dev, path, 128);
493
494 path[l-1] = '\0';
495
496 return strdup(path);
497}
Anthony Liguori85ed3032011-12-12 14:29:25 -0600498
Anthony Liguori09e5ab62012-02-03 12:28:43 -0600499char *qdev_get_dev_path(DeviceState *dev)
500{
Anthony Liguori0d936922012-05-02 09:00:20 +0200501 BusClass *bc;
Anthony Liguori09e5ab62012-02-03 12:28:43 -0600502
503 if (!dev || !dev->parent_bus) {
504 return NULL;
505 }
506
Anthony Liguori0d936922012-05-02 09:00:20 +0200507 bc = BUS_GET_CLASS(dev->parent_bus);
508 if (bc->get_dev_path) {
509 return bc->get_dev_path(dev);
Anthony Liguori09e5ab62012-02-03 12:28:43 -0600510 }
511
512 return NULL;
513}
514
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600515/**
516 * Legacy property handling
517 */
518
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600519static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600520 const char *name, Error **errp)
521{
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600522 DeviceState *dev = DEVICE(obj);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600523 Property *prop = opaque;
524
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100525 char buffer[1024];
526 char *ptr = buffer;
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600527
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100528 prop->info->print(dev, prop, buffer, sizeof(buffer));
529 visit_type_str(v, &ptr, name, errp);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600530}
531
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600532static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600533 const char *name, Error **errp)
534{
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600535 DeviceState *dev = DEVICE(obj);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600536 Property *prop = opaque;
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100537 Error *local_err = NULL;
538 char *ptr = NULL;
539 int ret;
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600540
541 if (dev->state != DEV_STATE_CREATED) {
542 error_set(errp, QERR_PERMISSION_DENIED);
543 return;
544 }
545
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100546 visit_type_str(v, &ptr, name, &local_err);
547 if (local_err) {
548 error_propagate(errp, local_err);
549 return;
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600550 }
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100551
552 ret = prop->info->parse(dev, prop, ptr);
Paolo Bonzini7db4c4e2011-12-18 17:05:07 +0100553 error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100554 g_free(ptr);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600555}
556
557/**
558 * @qdev_add_legacy_property - adds a legacy property
559 *
560 * Do not use this is new code! Properties added through this interface will
Paolo Bonzinica2cc782011-12-18 17:05:11 +0100561 * be given names and types in the "legacy" namespace.
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600562 *
Paolo Bonzini68ee3562012-02-02 10:17:19 +0100563 * Legacy properties are string versions of other OOM properties. The format
564 * of the string depends on the property type.
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600565 */
566void qdev_property_add_legacy(DeviceState *dev, Property *prop,
567 Error **errp)
568{
Paolo Bonzinica2cc782011-12-18 17:05:11 +0100569 gchar *name, *type;
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600570
Anthony Liguorif3be0162012-05-02 13:31:07 +0200571 /* Register pointer properties as legacy properties */
572 if (!prop->info->print && !prop->info->parse &&
573 (prop->info->set || prop->info->get)) {
Paolo Bonzini68ee3562012-02-02 10:17:19 +0100574 return;
575 }
Anthony Liguorif3be0162012-05-02 13:31:07 +0200576
Paolo Bonzinica2cc782011-12-18 17:05:11 +0100577 name = g_strdup_printf("legacy-%s", prop->name);
Paolo Bonzinicafe5bd2011-12-18 17:05:10 +0100578 type = g_strdup_printf("legacy<%s>",
579 prop->info->legacy_name ?: prop->info->name);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600580
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600581 object_property_add(OBJECT(dev), name, type,
Paolo Bonzini68ee3562012-02-02 10:17:19 +0100582 prop->info->print ? qdev_get_legacy_property : prop->info->get,
583 prop->info->parse ? qdev_set_legacy_property : prop->info->set,
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600584 NULL,
585 prop, errp);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600586
587 g_free(type);
Paolo Bonzinica2cc782011-12-18 17:05:11 +0100588 g_free(name);
589}
590
591/**
592 * @qdev_property_add_static - add a @Property to a device.
593 *
594 * Static properties access data in a struct. The actual type of the
595 * property and the field depends on the property type.
596 */
597void qdev_property_add_static(DeviceState *dev, Property *prop,
598 Error **errp)
599{
Paolo Bonzinifdae2452012-04-02 22:40:26 +0200600 Error *local_err = NULL;
601 Object *obj = OBJECT(dev);
602
Paolo Bonzinid8229792012-02-02 09:47:13 +0100603 /*
604 * TODO qdev_prop_ptr does not have getters or setters. It must
605 * go now that it can be replaced with links. The test should be
606 * removed along with it: all static properties are read/write.
607 */
608 if (!prop->info->get && !prop->info->set) {
609 return;
610 }
611
Paolo Bonzinifdae2452012-04-02 22:40:26 +0200612 object_property_add(obj, prop->name, prop->info->name,
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600613 prop->info->get, prop->info->set,
Paolo Bonzinidd0ba252012-02-02 13:08:48 +0100614 prop->info->release,
Paolo Bonzinifdae2452012-04-02 22:40:26 +0200615 prop, &local_err);
616
617 if (local_err) {
618 error_propagate(errp, local_err);
619 return;
620 }
621 if (prop->qtype == QTYPE_NONE) {
622 return;
623 }
624
625 if (prop->qtype == QTYPE_QBOOL) {
626 object_property_set_bool(obj, prop->defval, prop->name, &local_err);
627 } else if (prop->info->enum_table) {
628 object_property_set_str(obj, prop->info->enum_table[prop->defval],
629 prop->name, &local_err);
630 } else if (prop->qtype == QTYPE_QINT) {
631 object_property_set_int(obj, prop->defval, prop->name, &local_err);
632 }
633 assert_no_error(local_err);
Anthony Liguori6a146eb2011-12-12 14:29:42 -0600634}
Anthony Liguori1de81d22011-12-19 16:37:46 -0600635
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600636static void device_initfn(Object *obj)
637{
638 DeviceState *dev = DEVICE(obj);
Paolo Bonzinibce54472012-03-28 18:12:47 +0200639 ObjectClass *class;
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600640 Property *prop;
641
642 if (qdev_hotplug) {
643 dev->hotplugged = 1;
644 qdev_hot_added = true;
645 }
646
647 dev->instance_id_alias = -1;
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600648 dev->state = DEV_STATE_CREATED;
649
Paolo Bonzinibce54472012-03-28 18:12:47 +0200650 class = object_get_class(OBJECT(dev));
651 do {
652 for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
653 qdev_property_add_legacy(dev, prop, NULL);
654 qdev_property_add_static(dev, prop, NULL);
655 }
Paolo Bonzinibce54472012-03-28 18:12:47 +0200656 class = object_class_get_parent(class);
657 } while (class != object_class_by_name(TYPE_DEVICE));
Paolo Bonzini4b3582b2012-04-03 10:05:07 +0200658 qdev_prop_set_globals(dev);
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600659}
660
Anthony Liguori60adba32011-12-23 08:38:56 -0600661/* Unlink device from bus and free the structure. */
662static void device_finalize(Object *obj)
663{
664 DeviceState *dev = DEVICE(obj);
665 BusState *bus;
Anthony Liguori60adba32011-12-23 08:38:56 -0600666 DeviceClass *dc = DEVICE_GET_CLASS(dev);
667
668 if (dev->state == DEV_STATE_INITIALIZED) {
669 while (dev->num_child_bus) {
670 bus = QLIST_FIRST(&dev->child_bus);
671 qbus_free(bus);
672 }
673 if (qdev_get_vmsd(dev)) {
674 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
675 }
676 if (dc->exit) {
677 dc->exit(dev);
678 }
679 if (dev->opts) {
680 qemu_opts_del(dev->opts);
681 }
682 }
683 QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
Anthony Liguori60adba32011-12-23 08:38:56 -0600684}
685
Paolo Bonzinibce54472012-03-28 18:12:47 +0200686static void device_class_base_init(ObjectClass *class, void *data)
687{
688 DeviceClass *klass = DEVICE_CLASS(class);
689
690 /* We explicitly look up properties in the superclasses,
691 * so do not propagate them to the subclasses.
692 */
693 klass->props = NULL;
694}
695
Anthony Liguori94afdad2011-12-04 11:36:01 -0600696void device_reset(DeviceState *dev)
697{
698 DeviceClass *klass = DEVICE_GET_CLASS(dev);
699
700 if (klass->reset) {
701 klass->reset(dev);
702 }
703}
704
Paolo Bonzinif05f6b42012-03-28 16:34:12 +0200705Object *qdev_get_machine(void)
706{
707 static Object *dev;
708
709 if (dev == NULL) {
Andreas Färberdfe47e72012-04-05 13:21:46 +0200710 dev = container_get(object_get_root(), "/machine");
Paolo Bonzinif05f6b42012-03-28 16:34:12 +0200711 }
712
713 return dev;
714}
715
Anthony Liguori32fea402011-12-16 14:34:46 -0600716static TypeInfo device_type_info = {
717 .name = TYPE_DEVICE,
718 .parent = TYPE_OBJECT,
719 .instance_size = sizeof(DeviceState),
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600720 .instance_init = device_initfn,
Anthony Liguori60adba32011-12-23 08:38:56 -0600721 .instance_finalize = device_finalize,
Paolo Bonzinibce54472012-03-28 18:12:47 +0200722 .class_base_init = device_class_base_init,
Anthony Liguori32fea402011-12-16 14:34:46 -0600723 .abstract = true,
724 .class_size = sizeof(DeviceClass),
725};
726
Anthony Liguori0d936922012-05-02 09:00:20 +0200727static const TypeInfo bus_info = {
728 .name = TYPE_BUS,
729 .parent = TYPE_OBJECT,
730 .instance_size = sizeof(BusState),
731 .abstract = true,
732 .class_size = sizeof(BusClass),
733};
734
Andreas Färber83f7d432012-02-09 15:20:55 +0100735static void qdev_register_types(void)
Anthony Liguori32fea402011-12-16 14:34:46 -0600736{
Anthony Liguori0d936922012-05-02 09:00:20 +0200737 type_register_static(&bus_info);
Anthony Liguori32fea402011-12-16 14:34:46 -0600738 type_register_static(&device_type_info);
739}
740
Andreas Färber83f7d432012-02-09 15:20:55 +0100741type_init(qdev_register_types)