blob: afbc975b8f32a10fae3025df2a7e16d90afd7e0f [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
Gerd Hoffmanncdaed7c2009-10-06 21:17:52 +020037/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
Blue Swirlb9aaf7f2009-06-09 18:38:51 +000038static BusState *main_system_bus;
Isaku Yamahata2da8bb92011-08-02 10:59:13 +090039static void main_system_bus_create(void);
Paul Brook4d6ae672009-05-14 22:35:06 +010040
Paul Brookaae94602009-05-14 22:35:06 +010041/* Register a new device type. */
Anthony Liguori4be9f0d2011-12-09 10:51:49 -060042const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
43{
Anthony Liguori6e008582011-12-09 11:06:57 -060044 DeviceClass *dc = DEVICE_GET_CLASS(dev);
45 return dc->vmsd;
Anthony Liguori4be9f0d2011-12-09 10:51:49 -060046}
47
48BusInfo *qdev_get_bus_info(DeviceState *dev)
49{
Anthony Liguori6e008582011-12-09 11:06:57 -060050 DeviceClass *dc = DEVICE_GET_CLASS(dev);
51 return dc->bus_info;
Anthony Liguori4be9f0d2011-12-09 10:51:49 -060052}
53
54Property *qdev_get_props(DeviceState *dev)
55{
Anthony Liguori6e008582011-12-09 11:06:57 -060056 DeviceClass *dc = DEVICE_GET_CLASS(dev);
57 return dc->props;
Anthony Liguori4be9f0d2011-12-09 10:51:49 -060058}
59
60const char *qdev_fw_name(DeviceState *dev)
61{
Anthony Liguori6e008582011-12-09 11:06:57 -060062 DeviceClass *dc = DEVICE_GET_CLASS(dev);
Anthony Liguori4be9f0d2011-12-09 10:51:49 -060063
Anthony Liguori6e008582011-12-09 11:06:57 -060064 if (dc->fw_name) {
65 return dc->fw_name;
Anthony Liguori4be9f0d2011-12-09 10:51:49 -060066 }
67
68 return object_get_typename(OBJECT(dev));
69}
70
Blue Swirla369da52011-09-27 19:15:42 +000071bool qdev_exists(const char *name)
72{
Anthony Liguori212ad112012-02-01 09:34:28 -060073 return !!object_class_by_name(name);
Blue Swirla369da52011-09-27 19:15:42 +000074}
Anthony Liguori40021f02011-12-04 12:22:06 -060075
Paolo Bonzinica2cc782011-12-18 17:05:11 +010076static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
77 Error **errp);
78
Anthony Liguori9fbe6122011-12-22 15:14:27 -060079void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
Paul Brookaae94602009-05-14 22:35:06 +010080{
Anthony Liguoria5296ca2011-12-12 14:29:27 -060081 Property *prop;
Paul Brookaae94602009-05-14 22:35:06 +010082
Gerd Hoffmann3418bd22009-09-25 21:42:41 +020083 if (qdev_hotplug) {
84 assert(bus->allow_hotplug);
Gerd Hoffmann3418bd22009-09-25 21:42:41 +020085 }
Anthony Liguoria5296ca2011-12-12 14:29:27 -060086
Anthony Liguori9fbe6122011-12-22 15:14:27 -060087 dev->parent_bus = bus;
Anthony Liguori9674bfe2011-12-22 15:06:37 -060088 QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
Anthony Liguoria5296ca2011-12-12 14:29:27 -060089
Anthony Liguori6e008582011-12-09 11:06:57 -060090 for (prop = qdev_get_bus_info(dev)->props; prop && prop->name; prop++) {
Anthony Liguoria5296ca2011-12-12 14:29:27 -060091 qdev_property_add_legacy(dev, prop, NULL);
Paolo Bonzinica2cc782011-12-18 17:05:11 +010092 qdev_property_add_static(dev, prop, NULL);
Anthony Liguoria5296ca2011-12-12 14:29:27 -060093 }
Paolo Bonzini4f2d3d72012-02-02 09:43:02 +010094 qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
Paul Brookaae94602009-05-14 22:35:06 +010095}
96
Markus Armbruster0c175422010-02-19 19:12:18 +010097/* Create a new device. This only initializes the device state structure
98 and allows properties to be set. qdev_init should be called to
99 initialize the actual device emulation. */
100DeviceState *qdev_create(BusState *bus, const char *name)
101{
Blue Swirl0bcdeda2011-02-05 14:34:25 +0000102 DeviceState *dev;
103
104 dev = qdev_try_create(bus, name);
105 if (!dev) {
Peter Maydelle92714c2011-08-03 23:49:04 +0100106 if (bus) {
107 hw_error("Unknown device '%s' for bus '%s'\n", name,
108 bus->info->name);
109 } else {
110 hw_error("Unknown device '%s' for default sysbus\n", name);
111 }
Blue Swirl0bcdeda2011-02-05 14:34:25 +0000112 }
113
114 return dev;
115}
116
Paolo Bonzinida57feb2012-03-27 18:38:47 +0200117DeviceState *qdev_try_create(BusState *bus, const char *type)
Blue Swirl0bcdeda2011-02-05 14:34:25 +0000118{
Anthony Liguori9fbe6122011-12-22 15:14:27 -0600119 DeviceState *dev;
120
Paolo Bonzinida57feb2012-03-27 18:38:47 +0200121 if (object_class_by_name(type) == NULL) {
Andreas Färber4ed658c2012-02-17 02:47:44 +0100122 return NULL;
123 }
Paolo Bonzinida57feb2012-03-27 18:38:47 +0200124 dev = DEVICE(object_new(type));
Anthony Liguori9fbe6122011-12-22 15:14:27 -0600125 if (!dev) {
126 return NULL;
127 }
128
Markus Armbruster0c175422010-02-19 19:12:18 +0100129 if (!bus) {
Stefan Weil68694892010-12-16 19:33:22 +0100130 bus = sysbus_get_default();
Markus Armbruster0c175422010-02-19 19:12:18 +0100131 }
132
Anthony Liguori9fbe6122011-12-22 15:14:27 -0600133 qdev_set_parent_bus(dev, bus);
134 qdev_prop_set_globals(dev);
135
136 return dev;
Markus Armbruster0c175422010-02-19 19:12:18 +0100137}
138
Paul Brookaae94602009-05-14 22:35:06 +0100139/* Initialize a device. Device properties should be set before calling
140 this function. IRQs and MMIO regions should be connected/mapped after
Markus Armbruster18cfeb52009-10-07 01:15:56 +0200141 calling this function.
142 On failure, destroy the device and return negative value.
143 Return 0 on success. */
Gerd Hoffmann81a322d2009-08-14 10:36:05 +0200144int qdev_init(DeviceState *dev)
Paul Brookaae94602009-05-14 22:35:06 +0100145{
Anthony Liguori6e008582011-12-09 11:06:57 -0600146 DeviceClass *dc = DEVICE_GET_CLASS(dev);
Gerd Hoffmann959f7332009-09-01 09:56:12 +0200147 int rc;
148
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200149 assert(dev->state == DEV_STATE_CREATED);
Anthony Liguori6e008582011-12-09 11:06:57 -0600150
Anthony Liguorid307af72011-12-09 15:02:56 -0600151 rc = dc->init(dev);
Markus Armbruster18cfeb52009-10-07 01:15:56 +0200152 if (rc < 0) {
153 qdev_free(dev);
Gerd Hoffmann959f7332009-09-01 09:56:12 +0200154 return rc;
Markus Armbruster18cfeb52009-10-07 01:15:56 +0200155 }
Paolo Bonzinida57feb2012-03-27 18:38:47 +0200156
157 if (!OBJECT(dev)->parent) {
158 static int unattached_count = 0;
159 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
160
Paolo Bonzinif05f6b42012-03-28 16:34:12 +0200161 object_property_add_child(container_get("/machine/unattached"), name,
Paolo Bonzinida57feb2012-03-27 18:38:47 +0200162 OBJECT(dev), NULL);
163 g_free(name);
164 }
165
Anthony Liguori6e008582011-12-09 11:06:57 -0600166 if (qdev_get_vmsd(dev)) {
167 vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
Jan Kiszka4d2ffa02010-05-15 13:32:40 +0200168 dev->instance_id_alias,
169 dev->alias_required_for_version);
170 }
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200171 dev->state = DEV_STATE_INITIALIZED;
Anthony Liguori94afdad2011-12-04 11:36:01 -0600172 if (dev->hotplugged) {
173 device_reset(dev);
Jan Kiszka5ab28c82011-07-24 19:38:36 +0200174 }
Gerd Hoffmann959f7332009-09-01 09:56:12 +0200175 return 0;
Paul Brook02e2da42009-05-23 00:05:19 +0100176}
177
Jan Kiszka4d2ffa02010-05-15 13:32:40 +0200178void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
179 int required_for_version)
180{
181 assert(dev->state == DEV_STATE_CREATED);
182 dev->instance_id_alias = alias_id;
183 dev->alias_required_for_version = required_for_version;
184}
185
Luiz Capitulino56f91072012-03-14 17:37:38 -0300186void qdev_unplug(DeviceState *dev, Error **errp)
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200187{
Anthony Liguori6e008582011-12-09 11:06:57 -0600188 DeviceClass *dc = DEVICE_GET_CLASS(dev);
189
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200190 if (!dev->parent_bus->allow_hotplug) {
Luiz Capitulino56f91072012-03-14 17:37:38 -0300191 error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
192 return;
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200193 }
Anthony Liguori6e008582011-12-09 11:06:57 -0600194 assert(dc->unplug != NULL);
Amit Shah593831d2009-11-02 14:56:41 +0530195
Alex Williamson0ac8ef72011-01-04 12:37:50 -0700196 qdev_hot_removed = true;
197
Luiz Capitulino56f91072012-03-14 17:37:38 -0300198 if (dc->unplug(dev) < 0) {
199 error_set(errp, QERR_UNDEFINED_ERROR);
200 return;
201 }
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200202}
203
Anthony Liguoriec990eb2010-11-19 18:55:59 +0900204static int qdev_reset_one(DeviceState *dev, void *opaque)
205{
Anthony Liguori94afdad2011-12-04 11:36:01 -0600206 device_reset(dev);
Anthony Liguoriec990eb2010-11-19 18:55:59 +0900207
208 return 0;
209}
210
211BusState *sysbus_get_default(void)
212{
Stefan Weil68694892010-12-16 19:33:22 +0100213 if (!main_system_bus) {
Isaku Yamahata2da8bb92011-08-02 10:59:13 +0900214 main_system_bus_create();
Stefan Weil68694892010-12-16 19:33:22 +0100215 }
Anthony Liguoriec990eb2010-11-19 18:55:59 +0900216 return main_system_bus;
217}
218
Isaku Yamahatab4694b72010-11-19 18:56:00 +0900219static int qbus_reset_one(BusState *bus, void *opaque)
220{
221 if (bus->info->reset) {
222 return bus->info->reset(bus);
223 }
224 return 0;
225}
226
Isaku Yamahata5af0a042010-11-19 18:56:01 +0900227void qdev_reset_all(DeviceState *dev)
228{
229 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
230}
231
Isaku Yamahata80376c32010-12-20 14:33:35 +0900232void qbus_reset_all_fn(void *opaque)
233{
234 BusState *bus = opaque;
Michael S. Tsirkinf530cce2010-12-20 15:17:10 +0200235 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
Isaku Yamahata80376c32010-12-20 14:33:35 +0900236}
237
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200238/* can be used as ->unplug() callback for the simple cases */
239int qdev_simple_unplug_cb(DeviceState *dev)
240{
241 /* just zap it */
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600242 object_unparent(OBJECT(dev));
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200243 qdev_free(dev);
244 return 0;
245}
246
Michael Tokarev3b29a102011-04-06 17:51:59 +0400247
248/* Like qdev_init(), but terminate program via error_report() instead of
Markus Armbrustere23a1b32009-10-07 01:15:58 +0200249 returning an error value. This is okay during machine creation.
250 Don't use for hotplug, because there callers need to recover from
251 failure. Exception: if you know the device's init() callback can't
252 fail, then qdev_init_nofail() can't fail either, and is therefore
253 usable even then. But relying on the device implementation that
254 way is somewhat unclean, and best avoided. */
255void qdev_init_nofail(DeviceState *dev)
256{
Markus Armbrusterbd6c9a62010-05-27 21:23:08 +0200257 if (qdev_init(dev) < 0) {
Anthony Liguori6e008582011-12-09 11:06:57 -0600258 error_report("Initialization of device %s failed",
259 object_get_typename(OBJECT(dev)));
Markus Armbrusterbd6c9a62010-05-27 21:23:08 +0200260 exit(1);
261 }
Markus Armbrustere23a1b32009-10-07 01:15:58 +0200262}
263
Paul Brook02e2da42009-05-23 00:05:19 +0100264/* Unlink device from bus and free the structure. */
265void qdev_free(DeviceState *dev)
266{
Anthony Liguori32fea402011-12-16 14:34:46 -0600267 object_delete(OBJECT(dev));
Paul Brookaae94602009-05-14 22:35:06 +0100268}
269
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200270void qdev_machine_creation_done(void)
271{
272 /*
273 * ok, initial machine setup is done, starting from now we can
274 * only create hotpluggable devices
275 */
276 qdev_hotplug = 1;
277}
278
Alex Williamson0ac8ef72011-01-04 12:37:50 -0700279bool qdev_machine_modified(void)
280{
281 return qdev_hot_added || qdev_hot_removed;
282}
283
Paul Brook02e2da42009-05-23 00:05:19 +0100284BusState *qdev_get_parent_bus(DeviceState *dev)
Paul Brookaae94602009-05-14 22:35:06 +0100285{
Paul Brook02e2da42009-05-23 00:05:19 +0100286 return dev->parent_bus;
Paul Brookaae94602009-05-14 22:35:06 +0100287}
288
Paul Brookaae94602009-05-14 22:35:06 +0100289void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
290{
291 assert(dev->num_gpio_in == 0);
292 dev->num_gpio_in = n;
293 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
294}
295
296void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
297{
298 assert(dev->num_gpio_out == 0);
299 dev->num_gpio_out = n;
300 dev->gpio_out = pins;
301}
302
303qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
304{
305 assert(n >= 0 && n < dev->num_gpio_in);
306 return dev->gpio_in[n];
307}
308
309void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
310{
311 assert(n >= 0 && n < dev->num_gpio_out);
312 dev->gpio_out[n] = pin;
313}
314
Gerd Hoffmanned16ab52009-10-21 15:25:26 +0200315void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
316{
Jan Kiszka6eed1852011-07-20 12:20:22 +0200317 qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
Gerd Hoffmanned16ab52009-10-21 15:25:26 +0200318 if (nd->vlan)
319 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
320 if (nd->netdev)
321 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
Amit Shah75422b02010-02-25 17:24:43 +0530322 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
Gerd Hoffmann97b15622009-10-21 15:25:35 +0200323 qdev_prop_exists(dev, "vectors")) {
324 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
325 }
Peter Maydell48e2faf2011-05-20 16:50:01 +0100326 nd->instantiated = 1;
Gerd Hoffmanned16ab52009-10-21 15:25:26 +0200327}
328
Paul Brook02e2da42009-05-23 00:05:19 +0100329BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
Paul Brook4d6ae672009-05-14 22:35:06 +0100330{
Paul Brook02e2da42009-05-23 00:05:19 +0100331 BusState *bus;
Paul Brook4d6ae672009-05-14 22:35:06 +0100332
Blue Swirl72cf2d42009-09-12 07:36:22 +0000333 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
Paul Brook4d6ae672009-05-14 22:35:06 +0100334 if (strcmp(name, bus->name) == 0) {
Paul Brook02e2da42009-05-23 00:05:19 +0100335 return bus;
Paul Brook4d6ae672009-05-14 22:35:06 +0100336 }
337 }
338 return NULL;
339}
340
Anthony Liguori81699d82010-11-19 18:55:58 +0900341int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
342 qbus_walkerfn *busfn, void *opaque)
343{
344 DeviceState *dev;
345 int err;
346
347 if (busfn) {
348 err = busfn(bus, opaque);
349 if (err) {
350 return err;
351 }
352 }
353
Paolo Bonzinid8bb00d2011-09-14 09:28:06 +0200354 QTAILQ_FOREACH(dev, &bus->children, sibling) {
Anthony Liguori81699d82010-11-19 18:55:58 +0900355 err = qdev_walk_children(dev, devfn, busfn, opaque);
356 if (err < 0) {
357 return err;
358 }
359 }
360
361 return 0;
362}
363
364int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
365 qbus_walkerfn *busfn, void *opaque)
366{
367 BusState *bus;
368 int err;
369
370 if (devfn) {
371 err = devfn(dev, opaque);
372 if (err) {
373 return err;
374 }
375 }
376
377 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
378 err = qbus_walk_children(bus, devfn, busfn, opaque);
379 if (err < 0) {
380 return err;
381 }
382 }
383
384 return 0;
385}
386
Isaku Yamahataa2ee6b42010-12-24 12:14:12 +0900387DeviceState *qdev_find_recursive(BusState *bus, const char *id)
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200388{
389 DeviceState *dev, *ret;
390 BusState *child;
391
Paolo Bonzinid8bb00d2011-09-14 09:28:06 +0200392 QTAILQ_FOREACH(dev, &bus->children, sibling) {
Gerd Hoffmann3418bd22009-09-25 21:42:41 +0200393 if (dev->id && strcmp(dev->id, id) == 0)
394 return dev;
395 QLIST_FOREACH(child, &dev->child_bus, sibling) {
396 ret = qdev_find_recursive(child, id);
397 if (ret) {
398 return ret;
399 }
400 }
401 }
402 return NULL;
403}
404
Gerd Hoffmanncd739fb2009-09-16 22:25:27 +0200405void qbus_create_inplace(BusState *bus, BusInfo *info,
406 DeviceState *parent, const char *name)
Paul Brook02e2da42009-05-23 00:05:19 +0100407{
Gerd Hoffmannd271de92009-07-15 13:59:24 +0200408 char *buf;
409 int i,len;
Paul Brook02e2da42009-05-23 00:05:19 +0100410
Gerd Hoffmann10c4c982009-06-30 14:12:08 +0200411 bus->info = info;
Paul Brook02e2da42009-05-23 00:05:19 +0100412 bus->parent = parent;
Gerd Hoffmannd271de92009-07-15 13:59:24 +0200413
414 if (name) {
415 /* use supplied name */
Anthony Liguori7267c092011-08-20 22:09:37 -0500416 bus->name = g_strdup(name);
Gerd Hoffmannd271de92009-07-15 13:59:24 +0200417 } else if (parent && parent->id) {
418 /* parent device has id -> use it for bus name */
419 len = strlen(parent->id) + 16;
Anthony Liguori7267c092011-08-20 22:09:37 -0500420 buf = g_malloc(len);
Gerd Hoffmannd271de92009-07-15 13:59:24 +0200421 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
422 bus->name = buf;
423 } else {
424 /* no id -> use lowercase bus type for bus name */
425 len = strlen(info->name) + 16;
Anthony Liguori7267c092011-08-20 22:09:37 -0500426 buf = g_malloc(len);
Gerd Hoffmannd271de92009-07-15 13:59:24 +0200427 len = snprintf(buf, len, "%s.%d", info->name,
428 parent ? parent->num_child_bus : 0);
429 for (i = 0; i < len; i++)
Christoph Eggerbb87ece2009-07-30 15:28:45 +0200430 buf[i] = qemu_tolower(buf[i]);
Gerd Hoffmannd271de92009-07-15 13:59:24 +0200431 bus->name = buf;
432 }
433
Paolo Bonzinid8bb00d2011-09-14 09:28:06 +0200434 QTAILQ_INIT(&bus->children);
Paul Brook02e2da42009-05-23 00:05:19 +0100435 if (parent) {
Blue Swirl72cf2d42009-09-12 07:36:22 +0000436 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
Gerd Hoffmannd271de92009-07-15 13:59:24 +0200437 parent->num_child_bus++;
Isaku Yamahata80376c32010-12-20 14:33:35 +0900438 } else if (bus != main_system_bus) {
439 /* TODO: once all bus devices are qdevified,
440 only reset handler for main_system_bus should be registered here. */
441 qemu_register_reset(qbus_reset_all_fn, bus);
Paul Brook02e2da42009-05-23 00:05:19 +0100442 }
Gerd Hoffmanncd739fb2009-09-16 22:25:27 +0200443}
444
445BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
446{
447 BusState *bus;
448
Anthony Liguori7267c092011-08-20 22:09:37 -0500449 bus = g_malloc0(info->size);
Gerd Hoffmanncd739fb2009-09-16 22:25:27 +0200450 bus->qdev_allocated = 1;
451 qbus_create_inplace(bus, info, parent, name);
Paul Brook02e2da42009-05-23 00:05:19 +0100452 return bus;
453}
Gerd Hoffmanncae49562009-06-05 15:53:17 +0100454
Isaku Yamahata2da8bb92011-08-02 10:59:13 +0900455static void main_system_bus_create(void)
456{
457 /* assign main_system_bus before qbus_create_inplace()
458 * in order to make "if (bus != main_system_bus)" work */
Anthony Liguori7267c092011-08-20 22:09:37 -0500459 main_system_bus = g_malloc0(system_bus_info.size);
Isaku Yamahata2da8bb92011-08-02 10:59:13 +0900460 main_system_bus->qdev_allocated = 1;
461 qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
462 "main-system-bus");
463}
464
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200465void qbus_free(BusState *bus)
466{
467 DeviceState *dev;
468
Paolo Bonzinid8bb00d2011-09-14 09:28:06 +0200469 while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200470 qdev_free(dev);
471 }
472 if (bus->parent) {
473 QLIST_REMOVE(bus, sibling);
474 bus->parent->num_child_bus--;
Isaku Yamahata80376c32010-12-20 14:33:35 +0900475 } else {
476 assert(bus != main_system_bus); /* main_system_bus is never freed */
477 qemu_unregister_reset(qbus_reset_all_fn, bus);
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200478 }
Anthony Liguori7267c092011-08-20 22:09:37 -0500479 g_free((void*)bus->name);
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200480 if (bus->qdev_allocated) {
Anthony Liguori7267c092011-08-20 22:09:37 -0500481 g_free(bus);
Gerd Hoffmann131ec1b2009-09-25 21:42:34 +0200482 }
483}
484
Gleb Natapov1ca4d092010-12-08 13:35:05 +0200485static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
486{
487 int l = 0;
488
489 if (dev && dev->parent_bus) {
490 char *d;
491 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
492 if (dev->parent_bus->info->get_fw_dev_path) {
493 d = dev->parent_bus->info->get_fw_dev_path(dev);
494 l += snprintf(p + l, size - l, "%s", d);
Anthony Liguori7267c092011-08-20 22:09:37 -0500495 g_free(d);
Gleb Natapov1ca4d092010-12-08 13:35:05 +0200496 } else {
Anthony Liguorif79f2bf2011-12-04 11:17:51 -0600497 l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
Gleb Natapov1ca4d092010-12-08 13:35:05 +0200498 }
499 }
500 l += snprintf(p + l , size - l, "/");
501
502 return l;
503}
504
505char* qdev_get_fw_dev_path(DeviceState *dev)
506{
507 char path[128];
508 int l;
509
510 l = qdev_get_fw_dev_path_helper(dev, path, 128);
511
512 path[l-1] = '\0';
513
514 return strdup(path);
515}
Anthony Liguori85ed3032011-12-12 14:29:25 -0600516
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600517static char *qdev_get_type(Object *obj, Error **errp)
Anthony Liguoricd34d662011-12-12 14:29:43 -0600518{
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600519 return g_strdup(object_get_typename(obj));
Anthony Liguori44677de2011-12-12 14:29:26 -0600520}
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600521
522/**
523 * Legacy property handling
524 */
525
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600526static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600527 const char *name, Error **errp)
528{
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600529 DeviceState *dev = DEVICE(obj);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600530 Property *prop = opaque;
531
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100532 char buffer[1024];
533 char *ptr = buffer;
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600534
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100535 prop->info->print(dev, prop, buffer, sizeof(buffer));
536 visit_type_str(v, &ptr, name, errp);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600537}
538
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600539static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600540 const char *name, Error **errp)
541{
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600542 DeviceState *dev = DEVICE(obj);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600543 Property *prop = opaque;
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100544 Error *local_err = NULL;
545 char *ptr = NULL;
546 int ret;
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600547
548 if (dev->state != DEV_STATE_CREATED) {
549 error_set(errp, QERR_PERMISSION_DENIED);
550 return;
551 }
552
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100553 visit_type_str(v, &ptr, name, &local_err);
554 if (local_err) {
555 error_propagate(errp, local_err);
556 return;
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600557 }
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100558
559 ret = prop->info->parse(dev, prop, ptr);
Paolo Bonzini7db4c4e2011-12-18 17:05:07 +0100560 error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
Paolo Bonzinie3cb6ba2011-12-18 17:05:06 +0100561 g_free(ptr);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600562}
563
564/**
565 * @qdev_add_legacy_property - adds a legacy property
566 *
567 * Do not use this is new code! Properties added through this interface will
Paolo Bonzinica2cc782011-12-18 17:05:11 +0100568 * be given names and types in the "legacy" namespace.
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600569 *
Paolo Bonzini68ee3562012-02-02 10:17:19 +0100570 * Legacy properties are string versions of other OOM properties. The format
571 * of the string depends on the property type.
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600572 */
573void qdev_property_add_legacy(DeviceState *dev, Property *prop,
574 Error **errp)
575{
Paolo Bonzinica2cc782011-12-18 17:05:11 +0100576 gchar *name, *type;
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600577
Paolo Bonzini68ee3562012-02-02 10:17:19 +0100578 if (!prop->info->print && !prop->info->parse) {
579 return;
580 }
Paolo Bonzinica2cc782011-12-18 17:05:11 +0100581 name = g_strdup_printf("legacy-%s", prop->name);
Paolo Bonzinicafe5bd2011-12-18 17:05:10 +0100582 type = g_strdup_printf("legacy<%s>",
583 prop->info->legacy_name ?: prop->info->name);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600584
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600585 object_property_add(OBJECT(dev), name, type,
Paolo Bonzini68ee3562012-02-02 10:17:19 +0100586 prop->info->print ? qdev_get_legacy_property : prop->info->get,
587 prop->info->parse ? qdev_set_legacy_property : prop->info->set,
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600588 NULL,
589 prop, errp);
Anthony Liguoria5296ca2011-12-12 14:29:27 -0600590
591 g_free(type);
Paolo Bonzinica2cc782011-12-18 17:05:11 +0100592 g_free(name);
593}
594
595/**
596 * @qdev_property_add_static - add a @Property to a device.
597 *
598 * Static properties access data in a struct. The actual type of the
599 * property and the field depends on the property type.
600 */
601void qdev_property_add_static(DeviceState *dev, Property *prop,
602 Error **errp)
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
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600613 object_property_add(OBJECT(dev), prop->name, prop->info->name,
614 prop->info->get, prop->info->set,
Paolo Bonzinidd0ba252012-02-02 13:08:48 +0100615 prop->info->release,
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600616 prop, errp);
Anthony Liguori6a146eb2011-12-12 14:29:42 -0600617}
Anthony Liguori1de81d22011-12-19 16:37:46 -0600618
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600619static void device_initfn(Object *obj)
620{
621 DeviceState *dev = DEVICE(obj);
622 Property *prop;
623
624 if (qdev_hotplug) {
625 dev->hotplugged = 1;
626 qdev_hot_added = true;
627 }
628
629 dev->instance_id_alias = -1;
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600630 dev->state = DEV_STATE_CREATED;
631
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600632 for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
633 qdev_property_add_legacy(dev, prop, NULL);
634 qdev_property_add_static(dev, prop, NULL);
635 }
636
Anthony Liguori57c9faf2012-01-30 08:55:55 -0600637 object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL);
Paolo Bonzini4f2d3d72012-02-02 09:43:02 +0100638 qdev_prop_set_defaults(dev, qdev_get_props(dev));
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600639}
640
Anthony Liguori60adba32011-12-23 08:38:56 -0600641/* Unlink device from bus and free the structure. */
642static void device_finalize(Object *obj)
643{
644 DeviceState *dev = DEVICE(obj);
645 BusState *bus;
Anthony Liguori60adba32011-12-23 08:38:56 -0600646 DeviceClass *dc = DEVICE_GET_CLASS(dev);
647
648 if (dev->state == DEV_STATE_INITIALIZED) {
649 while (dev->num_child_bus) {
650 bus = QLIST_FIRST(&dev->child_bus);
651 qbus_free(bus);
652 }
653 if (qdev_get_vmsd(dev)) {
654 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
655 }
656 if (dc->exit) {
657 dc->exit(dev);
658 }
659 if (dev->opts) {
660 qemu_opts_del(dev->opts);
661 }
662 }
663 QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
Anthony Liguori60adba32011-12-23 08:38:56 -0600664}
665
Anthony Liguori94afdad2011-12-04 11:36:01 -0600666void device_reset(DeviceState *dev)
667{
668 DeviceClass *klass = DEVICE_GET_CLASS(dev);
669
670 if (klass->reset) {
671 klass->reset(dev);
672 }
673}
674
Paolo Bonzinif05f6b42012-03-28 16:34:12 +0200675Object *qdev_get_machine(void)
676{
677 static Object *dev;
678
679 if (dev == NULL) {
680 dev = container_get("/machine");
681 }
682
683 return dev;
684}
685
Anthony Liguori32fea402011-12-16 14:34:46 -0600686static TypeInfo device_type_info = {
687 .name = TYPE_DEVICE,
688 .parent = TYPE_OBJECT,
689 .instance_size = sizeof(DeviceState),
Anthony Liguori9674bfe2011-12-22 15:06:37 -0600690 .instance_init = device_initfn,
Anthony Liguori60adba32011-12-23 08:38:56 -0600691 .instance_finalize = device_finalize,
Anthony Liguori32fea402011-12-16 14:34:46 -0600692 .abstract = true,
693 .class_size = sizeof(DeviceClass),
694};
695
Andreas Färber83f7d432012-02-09 15:20:55 +0100696static void qdev_register_types(void)
Anthony Liguori32fea402011-12-16 14:34:46 -0600697{
698 type_register_static(&device_type_info);
699}
700
Andreas Färber83f7d432012-02-09 15:20:55 +0100701type_init(qdev_register_types)