blob: dc46e7bd10925c9126ff8135413eda2de8ed5d13 [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++;
Anthony Liguorif968fc62012-05-02 10:39:01 +0200407 object_property_add_child(OBJECT(parent), bus->name, OBJECT(bus), NULL);
Paolo Bonzini8185d212012-05-02 12:06:55 +0200408 } else if (bus != sysbus_get_default()) {
Isaku Yamahata80376c32010-12-20 14:33:35 +0900409 /* TODO: once all bus devices are qdevified,
410 only reset handler for main_system_bus should be registered here. */
411 qemu_register_reset(qbus_reset_all_fn, bus);
Paul Brook02e2da42009-05-23 00:05:19 +0100412 }
Gerd Hoffmanncd739fb2009-09-16 22:25:27 +0200413}
414
Anthony Liguori0d936922012-05-02 09:00:20 +0200415void qbus_create_inplace(BusState *bus, const char *typename,
416 DeviceState *parent, const char *name)
417{
418 object_initialize(bus, typename);
419 do_qbus_create_inplace(bus, typename, parent, name);
420}
421
422BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
Gerd Hoffmanncd739fb2009-09-16 22:25:27 +0200423{
424 BusState *bus;
425
Anthony Liguori0d936922012-05-02 09:00:20 +0200426 bus = BUS(object_new(typename));
427 bus->qom_allocated = true;
428 do_qbus_create_inplace(bus, typename, parent, name);
Paul Brook02e2da42009-05-23 00:05:19 +0100429 return bus;
430}
Gerd Hoffmanncae49562009-06-05 15:53:17 +0100431
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200432void qbus_free(BusState *bus)
433{
434 DeviceState *dev;
435
Paolo Bonzinid8bb00d2011-09-14 09:28:06 +0200436 while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200437 qdev_free(dev);
438 }
439 if (bus->parent) {
440 QLIST_REMOVE(bus, sibling);
441 bus->parent->num_child_bus--;
Isaku Yamahata80376c32010-12-20 14:33:35 +0900442 } else {
Paolo Bonzini8185d212012-05-02 12:06:55 +0200443 assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
Isaku Yamahata80376c32010-12-20 14:33:35 +0900444 qemu_unregister_reset(qbus_reset_all_fn, bus);
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200445 }
Anthony Liguori7267c092011-08-20 22:09:37 -0500446 g_free((void*)bus->name);
Anthony Liguori0d936922012-05-02 09:00:20 +0200447 if (bus->qom_allocated) {
448 object_delete(OBJECT(bus));
449 } else {
450 object_finalize(OBJECT(bus));
451 if (bus->glib_allocated) {
452 g_free(bus);
453 }
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200454 }
455}
456
Anthony Liguori0d936922012-05-02 09:00:20 +0200457static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
458{
459 BusClass *bc = BUS_GET_CLASS(bus);
460
461 if (bc->get_fw_dev_path) {
462 return bc->get_fw_dev_path(dev);
463 }
464
465 return NULL;
466}
467
Gleb Natapov1ca4d092010-12-08 13:35:05 +0200468static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
469{
470 int l = 0;
471
472 if (dev && dev->parent_bus) {
473 char *d;
474 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
Anthony Liguori0d936922012-05-02 09:00:20 +0200475 d = bus_get_fw_dev_path(dev->parent_bus, dev);
476 if (d) {
Gleb Natapov1ca4d092010-12-08 13:35:05 +0200477 l += snprintf(p + l, size - l, "%s", d);
Anthony Liguori7267c092011-08-20 22:09:37 -0500478 g_free(d);
Gleb Natapov1ca4d092010-12-08 13:35:05 +0200479 } else {
Anthony Liguorif79f2bf2011-12-04 11:17:51 -0600480 l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
Gleb Natapov1ca4d092010-12-08 13:35:05 +0200481 }
482 }
483 l += snprintf(p + l , size - l, "/");
484
485 return l;
486}
487
488char* qdev_get_fw_dev_path(DeviceState *dev)
489{
490 char path[128];
491 int l;
492
493 l = qdev_get_fw_dev_path_helper(dev, path, 128);
494
495 path[l-1] = '\0';
496
497 return strdup(path);
498}
Anthony Liguori85ed3032011-12-12 14:29:25 -0600499
Anthony Liguori09e5ab62012-02-03 12:28:43 -0600500char *qdev_get_dev_path(DeviceState *dev)
501{
Anthony Liguori0d936922012-05-02 09:00:20 +0200502 BusClass *bc;
Anthony Liguori09e5ab62012-02-03 12:28:43 -0600503
504 if (!dev || !dev->parent_bus) {
505 return NULL;
506 }
507
Anthony Liguori0d936922012-05-02 09:00:20 +0200508 bc = BUS_GET_CLASS(dev->parent_bus);
509 if (bc->get_dev_path) {
510 return bc->get_dev_path(dev);
Anthony Liguori09e5ab62012-02-03 12:28:43 -0600511 }
512
513 return NULL;
514}
515
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600516/**
517 * Legacy property handling
518 */
519
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600520static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600521 const char *name, Error **errp)
522{
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600523 DeviceState *dev = DEVICE(obj);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600524 Property *prop = opaque;
525
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100526 char buffer[1024];
527 char *ptr = buffer;
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600528
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100529 prop->info->print(dev, prop, buffer, sizeof(buffer));
530 visit_type_str(v, &ptr, name, errp);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600531}
532
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600533static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600534 const char *name, Error **errp)
535{
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600536 DeviceState *dev = DEVICE(obj);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600537 Property *prop = opaque;
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100538 Error *local_err = NULL;
539 char *ptr = NULL;
540 int ret;
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600541
542 if (dev->state != DEV_STATE_CREATED) {
543 error_set(errp, QERR_PERMISSION_DENIED);
544 return;
545 }
546
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100547 visit_type_str(v, &ptr, name, &local_err);
548 if (local_err) {
549 error_propagate(errp, local_err);
550 return;
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600551 }
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100552
553 ret = prop->info->parse(dev, prop, ptr);
Paolo Bonzini7db4c4e2011-12-18 17:05:07 +0100554 error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100555 g_free(ptr);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600556}
557
558/**
559 * @qdev_add_legacy_property - adds a legacy property
560 *
561 * Do not use this is new code! Properties added through this interface will
Paolo Bonzinica2cc782011-12-18 17:05:11 +0100562 * be given names and types in the "legacy" namespace.
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600563 *
Paolo Bonzini68ee3562012-02-02 10:17:19 +0100564 * Legacy properties are string versions of other OOM properties. The format
565 * of the string depends on the property type.
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600566 */
567void qdev_property_add_legacy(DeviceState *dev, Property *prop,
568 Error **errp)
569{
Paolo Bonzinica2cc782011-12-18 17:05:11 +0100570 gchar *name, *type;
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600571
Anthony Liguorif3be0162012-05-02 13:31:07 +0200572 /* Register pointer properties as legacy properties */
573 if (!prop->info->print && !prop->info->parse &&
574 (prop->info->set || prop->info->get)) {
Paolo Bonzini68ee3562012-02-02 10:17:19 +0100575 return;
576 }
Anthony Liguorif3be0162012-05-02 13:31:07 +0200577
Paolo Bonzinica2cc782011-12-18 17:05:11 +0100578 name = g_strdup_printf("legacy-%s", prop->name);
Paolo Bonzinicafe5bd2011-12-18 17:05:10 +0100579 type = g_strdup_printf("legacy<%s>",
580 prop->info->legacy_name ?: prop->info->name);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600581
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600582 object_property_add(OBJECT(dev), name, type,
Paolo Bonzini68ee3562012-02-02 10:17:19 +0100583 prop->info->print ? qdev_get_legacy_property : prop->info->get,
584 prop->info->parse ? qdev_set_legacy_property : prop->info->set,
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600585 NULL,
586 prop, errp);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600587
588 g_free(type);
Paolo Bonzinica2cc782011-12-18 17:05:11 +0100589 g_free(name);
590}
591
592/**
593 * @qdev_property_add_static - add a @Property to a device.
594 *
595 * Static properties access data in a struct. The actual type of the
596 * property and the field depends on the property type.
597 */
598void qdev_property_add_static(DeviceState *dev, Property *prop,
599 Error **errp)
600{
Paolo Bonzinifdae2452012-04-02 22:40:26 +0200601 Error *local_err = NULL;
602 Object *obj = OBJECT(dev);
603
Paolo Bonzinid8229792012-02-02 09:47:13 +0100604 /*
605 * TODO qdev_prop_ptr does not have getters or setters. It must
606 * go now that it can be replaced with links. The test should be
607 * removed along with it: all static properties are read/write.
608 */
609 if (!prop->info->get && !prop->info->set) {
610 return;
611 }
612
Paolo Bonzinifdae2452012-04-02 22:40:26 +0200613 object_property_add(obj, prop->name, prop->info->name,
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600614 prop->info->get, prop->info->set,
Paolo Bonzinidd0ba252012-02-02 13:08:48 +0100615 prop->info->release,
Paolo Bonzinifdae2452012-04-02 22:40:26 +0200616 prop, &local_err);
617
618 if (local_err) {
619 error_propagate(errp, local_err);
620 return;
621 }
622 if (prop->qtype == QTYPE_NONE) {
623 return;
624 }
625
626 if (prop->qtype == QTYPE_QBOOL) {
627 object_property_set_bool(obj, prop->defval, prop->name, &local_err);
628 } else if (prop->info->enum_table) {
629 object_property_set_str(obj, prop->info->enum_table[prop->defval],
630 prop->name, &local_err);
631 } else if (prop->qtype == QTYPE_QINT) {
632 object_property_set_int(obj, prop->defval, prop->name, &local_err);
633 }
634 assert_no_error(local_err);
Anthony Liguori6a146eb2011-12-12 14:29:42 -0600635}
Anthony Liguori1de81d22011-12-19 16:37:46 -0600636
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600637static void device_initfn(Object *obj)
638{
639 DeviceState *dev = DEVICE(obj);
Paolo Bonzinibce54472012-03-28 18:12:47 +0200640 ObjectClass *class;
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600641 Property *prop;
642
643 if (qdev_hotplug) {
644 dev->hotplugged = 1;
645 qdev_hot_added = true;
646 }
647
648 dev->instance_id_alias = -1;
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600649 dev->state = DEV_STATE_CREATED;
650
Paolo Bonzinibce54472012-03-28 18:12:47 +0200651 class = object_get_class(OBJECT(dev));
652 do {
653 for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
654 qdev_property_add_legacy(dev, prop, NULL);
655 qdev_property_add_static(dev, prop, NULL);
656 }
Paolo Bonzinibce54472012-03-28 18:12:47 +0200657 class = object_class_get_parent(class);
658 } while (class != object_class_by_name(TYPE_DEVICE));
Paolo Bonzini4b3582b2012-04-03 10:05:07 +0200659 qdev_prop_set_globals(dev);
Anthony Liguorif968fc62012-05-02 10:39:01 +0200660
661 object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
662 (Object **)&dev->parent_bus, NULL);
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600663}
664
Anthony Liguori60adba32011-12-23 08:38:56 -0600665/* Unlink device from bus and free the structure. */
666static void device_finalize(Object *obj)
667{
668 DeviceState *dev = DEVICE(obj);
669 BusState *bus;
Anthony Liguori60adba32011-12-23 08:38:56 -0600670 DeviceClass *dc = DEVICE_GET_CLASS(dev);
671
672 if (dev->state == DEV_STATE_INITIALIZED) {
673 while (dev->num_child_bus) {
674 bus = QLIST_FIRST(&dev->child_bus);
675 qbus_free(bus);
676 }
677 if (qdev_get_vmsd(dev)) {
678 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
679 }
680 if (dc->exit) {
681 dc->exit(dev);
682 }
683 if (dev->opts) {
684 qemu_opts_del(dev->opts);
685 }
686 }
687 QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
Anthony Liguori60adba32011-12-23 08:38:56 -0600688}
689
Paolo Bonzinibce54472012-03-28 18:12:47 +0200690static void device_class_base_init(ObjectClass *class, void *data)
691{
692 DeviceClass *klass = DEVICE_CLASS(class);
693
694 /* We explicitly look up properties in the superclasses,
695 * so do not propagate them to the subclasses.
696 */
697 klass->props = NULL;
698}
699
Anthony Liguori94afdad2011-12-04 11:36:01 -0600700void device_reset(DeviceState *dev)
701{
702 DeviceClass *klass = DEVICE_GET_CLASS(dev);
703
704 if (klass->reset) {
705 klass->reset(dev);
706 }
707}
708
Paolo Bonzinif05f6b42012-03-28 16:34:12 +0200709Object *qdev_get_machine(void)
710{
711 static Object *dev;
712
713 if (dev == NULL) {
Andreas Färberdfe47e72012-04-05 13:21:46 +0200714 dev = container_get(object_get_root(), "/machine");
Paolo Bonzinif05f6b42012-03-28 16:34:12 +0200715 }
716
717 return dev;
718}
719
Anthony Liguori32fea402011-12-16 14:34:46 -0600720static TypeInfo device_type_info = {
721 .name = TYPE_DEVICE,
722 .parent = TYPE_OBJECT,
723 .instance_size = sizeof(DeviceState),
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600724 .instance_init = device_initfn,
Anthony Liguori60adba32011-12-23 08:38:56 -0600725 .instance_finalize = device_finalize,
Paolo Bonzinibce54472012-03-28 18:12:47 +0200726 .class_base_init = device_class_base_init,
Anthony Liguori32fea402011-12-16 14:34:46 -0600727 .abstract = true,
728 .class_size = sizeof(DeviceClass),
729};
730
Anthony Liguori0d936922012-05-02 09:00:20 +0200731static const TypeInfo bus_info = {
732 .name = TYPE_BUS,
733 .parent = TYPE_OBJECT,
734 .instance_size = sizeof(BusState),
735 .abstract = true,
736 .class_size = sizeof(BusClass),
737};
738
Andreas Färber83f7d432012-02-09 15:20:55 +0100739static void qdev_register_types(void)
Anthony Liguori32fea402011-12-16 14:34:46 -0600740{
Anthony Liguori0d936922012-05-02 09:00:20 +0200741 type_register_static(&bus_info);
Anthony Liguori32fea402011-12-16 14:34:46 -0600742 type_register_static(&device_type_info);
743}
744
Andreas Färber83f7d432012-02-09 15:20:55 +0100745type_init(qdev_register_types)