Statistics
| Branch: | Revision:

root / hw / qdev.c @ 721589dd

History | View | Annotate | Download (18.1 kB)

1 aae9460e Paul Brook
/*
2 aae9460e Paul Brook
 *  Dynamic device configuration and creation.
3 aae9460e Paul Brook
 *
4 aae9460e Paul Brook
 *  Copyright (c) 2009 CodeSourcery
5 aae9460e Paul Brook
 *
6 aae9460e Paul Brook
 * This library is free software; you can redistribute it and/or
7 aae9460e Paul Brook
 * modify it under the terms of the GNU Lesser General Public
8 aae9460e Paul Brook
 * License as published by the Free Software Foundation; either
9 aae9460e Paul Brook
 * version 2 of the License, or (at your option) any later version.
10 aae9460e Paul Brook
 *
11 aae9460e Paul Brook
 * This library is distributed in the hope that it will be useful,
12 aae9460e Paul Brook
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 aae9460e Paul Brook
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 aae9460e Paul Brook
 * Lesser General Public License for more details.
15 aae9460e Paul Brook
 *
16 aae9460e Paul Brook
 * You should have received a copy of the GNU Lesser General Public
17 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 aae9460e Paul Brook
 */
19 aae9460e Paul Brook
20 aae9460e Paul Brook
/* The theory here is that it should be possible to create a machine without
21 aae9460e Paul Brook
   knowledge of specific devices.  Historically board init routines have
22 aae9460e Paul Brook
   passed a bunch of arguments to each device, requiring the board know
23 aae9460e Paul Brook
   exactly which device it is dealing with.  This file provides an abstract
24 aae9460e Paul Brook
   API for device configuration and initialization.  Devices will generally
25 aae9460e Paul Brook
   inherit from a particular bus (e.g. PCI or I2C) rather than
26 aae9460e Paul Brook
   this API directly.  */
27 aae9460e Paul Brook
28 9d07d757 Paul Brook
#include "net.h"
29 aae9460e Paul Brook
#include "qdev.h"
30 aae9460e Paul Brook
#include "sysemu.h"
31 56f9107e Luiz Capitulino
#include "error.h"
32 aae9460e Paul Brook
33 ee46d8a5 Anthony Liguori
int qdev_hotplug = 0;
34 0ac8ef71 Alex Williamson
static bool qdev_hot_added = false;
35 0ac8ef71 Alex Williamson
static bool qdev_hot_removed = false;
36 3418bd25 Gerd Hoffmann
37 cdaed7c7 Gerd Hoffmann
/* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
38 b9aaf7f8 Blue Swirl
static BusState *main_system_bus;
39 2da8bb92 Isaku Yamahata
static void main_system_bus_create(void);
40 4d6ae674 Paul Brook
41 aae9460e Paul Brook
/* Register a new device type.  */
42 4be9f0d1 Anthony Liguori
const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
43 4be9f0d1 Anthony Liguori
{
44 6e008585 Anthony Liguori
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
45 6e008585 Anthony Liguori
    return dc->vmsd;
46 4be9f0d1 Anthony Liguori
}
47 4be9f0d1 Anthony Liguori
48 4be9f0d1 Anthony Liguori
BusInfo *qdev_get_bus_info(DeviceState *dev)
49 4be9f0d1 Anthony Liguori
{
50 6e008585 Anthony Liguori
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
51 6e008585 Anthony Liguori
    return dc->bus_info;
52 4be9f0d1 Anthony Liguori
}
53 4be9f0d1 Anthony Liguori
54 4be9f0d1 Anthony Liguori
Property *qdev_get_props(DeviceState *dev)
55 4be9f0d1 Anthony Liguori
{
56 6e008585 Anthony Liguori
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
57 6e008585 Anthony Liguori
    return dc->props;
58 4be9f0d1 Anthony Liguori
}
59 4be9f0d1 Anthony Liguori
60 4be9f0d1 Anthony Liguori
const char *qdev_fw_name(DeviceState *dev)
61 4be9f0d1 Anthony Liguori
{
62 6e008585 Anthony Liguori
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
63 4be9f0d1 Anthony Liguori
64 6e008585 Anthony Liguori
    if (dc->fw_name) {
65 6e008585 Anthony Liguori
        return dc->fw_name;
66 4be9f0d1 Anthony Liguori
    }
67 4be9f0d1 Anthony Liguori
68 4be9f0d1 Anthony Liguori
    return object_get_typename(OBJECT(dev));
69 4be9f0d1 Anthony Liguori
}
70 4be9f0d1 Anthony Liguori
71 a369da5f Blue Swirl
bool qdev_exists(const char *name)
72 a369da5f Blue Swirl
{
73 212ad111 Anthony Liguori
    return !!object_class_by_name(name);
74 a369da5f Blue Swirl
}
75 40021f08 Anthony Liguori
76 ca2cc788 Paolo Bonzini
static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
77 ca2cc788 Paolo Bonzini
                                     Error **errp);
78 ca2cc788 Paolo Bonzini
79 9fbe6127 Anthony Liguori
void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
80 0c17542d Markus Armbruster
{
81 a5296ca9 Anthony Liguori
    Property *prop;
82 0c17542d Markus Armbruster
83 0c17542d Markus Armbruster
    if (qdev_hotplug) {
84 0c17542d Markus Armbruster
        assert(bus->allow_hotplug);
85 0c17542d Markus Armbruster
    }
86 a5296ca9 Anthony Liguori
87 9fbe6127 Anthony Liguori
    dev->parent_bus = bus;
88 9674bfe4 Anthony Liguori
    QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
89 a5296ca9 Anthony Liguori
90 6e008585 Anthony Liguori
    for (prop = qdev_get_bus_info(dev)->props; prop && prop->name; prop++) {
91 a5296ca9 Anthony Liguori
        qdev_property_add_legacy(dev, prop, NULL);
92 ca2cc788 Paolo Bonzini
        qdev_property_add_static(dev, prop, NULL);
93 a5296ca9 Anthony Liguori
    }
94 4f2d3d70 Paolo Bonzini
    qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
95 0c17542d Markus Armbruster
}
96 0c17542d Markus Armbruster
97 aae9460e Paul Brook
/* Create a new device.  This only initializes the device state structure
98 aae9460e Paul Brook
   and allows properties to be set.  qdev_init should be called to
99 aae9460e Paul Brook
   initialize the actual device emulation.  */
100 02e2da45 Paul Brook
DeviceState *qdev_create(BusState *bus, const char *name)
101 aae9460e Paul Brook
{
102 0bcdeda7 Blue Swirl
    DeviceState *dev;
103 0bcdeda7 Blue Swirl
104 0bcdeda7 Blue Swirl
    dev = qdev_try_create(bus, name);
105 0bcdeda7 Blue Swirl
    if (!dev) {
106 e92714c7 Peter Maydell
        if (bus) {
107 e92714c7 Peter Maydell
            hw_error("Unknown device '%s' for bus '%s'\n", name,
108 e92714c7 Peter Maydell
                     bus->info->name);
109 e92714c7 Peter Maydell
        } else {
110 e92714c7 Peter Maydell
            hw_error("Unknown device '%s' for default sysbus\n", name);
111 e92714c7 Peter Maydell
        }
112 0bcdeda7 Blue Swirl
    }
113 0bcdeda7 Blue Swirl
114 0bcdeda7 Blue Swirl
    return dev;
115 0bcdeda7 Blue Swirl
}
116 0bcdeda7 Blue Swirl
117 da57febf Paolo Bonzini
DeviceState *qdev_try_create(BusState *bus, const char *type)
118 0bcdeda7 Blue Swirl
{
119 9fbe6127 Anthony Liguori
    DeviceState *dev;
120 9fbe6127 Anthony Liguori
121 da57febf Paolo Bonzini
    if (object_class_by_name(type) == NULL) {
122 4ed658ca Andreas Färber
        return NULL;
123 4ed658ca Andreas Färber
    }
124 da57febf Paolo Bonzini
    dev = DEVICE(object_new(type));
125 9fbe6127 Anthony Liguori
    if (!dev) {
126 9fbe6127 Anthony Liguori
        return NULL;
127 9fbe6127 Anthony Liguori
    }
128 9fbe6127 Anthony Liguori
129 10c4c98a Gerd Hoffmann
    if (!bus) {
130 68694897 Stefan Weil
        bus = sysbus_get_default();
131 10c4c98a Gerd Hoffmann
    }
132 10c4c98a Gerd Hoffmann
133 9fbe6127 Anthony Liguori
    qdev_set_parent_bus(dev, bus);
134 9fbe6127 Anthony Liguori
    qdev_prop_set_globals(dev);
135 9fbe6127 Anthony Liguori
136 9fbe6127 Anthony Liguori
    return dev;
137 aae9460e Paul Brook
}
138 aae9460e Paul Brook
139 aae9460e Paul Brook
/* Initialize a device.  Device properties should be set before calling
140 aae9460e Paul Brook
   this function.  IRQs and MMIO regions should be connected/mapped after
141 18cfeb52 Markus Armbruster
   calling this function.
142 18cfeb52 Markus Armbruster
   On failure, destroy the device and return negative value.
143 18cfeb52 Markus Armbruster
   Return 0 on success.  */
144 81a322d4 Gerd Hoffmann
int qdev_init(DeviceState *dev)
145 aae9460e Paul Brook
{
146 6e008585 Anthony Liguori
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
147 959f733a Gerd Hoffmann
    int rc;
148 959f733a Gerd Hoffmann
149 131ec1bd Gerd Hoffmann
    assert(dev->state == DEV_STATE_CREATED);
150 6e008585 Anthony Liguori
151 d307af79 Anthony Liguori
    rc = dc->init(dev);
152 18cfeb52 Markus Armbruster
    if (rc < 0) {
153 18cfeb52 Markus Armbruster
        qdev_free(dev);
154 959f733a Gerd Hoffmann
        return rc;
155 18cfeb52 Markus Armbruster
    }
156 da57febf Paolo Bonzini
157 da57febf Paolo Bonzini
    if (!OBJECT(dev)->parent) {
158 da57febf Paolo Bonzini
        static int unattached_count = 0;
159 da57febf Paolo Bonzini
        gchar *name = g_strdup_printf("device[%d]", unattached_count++);
160 da57febf Paolo Bonzini
161 dfe47e70 Andreas Färber
        object_property_add_child(container_get(qdev_get_machine(),
162 dfe47e70 Andreas Färber
                                                "/unattached"),
163 dfe47e70 Andreas Färber
                                  name, OBJECT(dev), NULL);
164 da57febf Paolo Bonzini
        g_free(name);
165 da57febf Paolo Bonzini
    }
166 da57febf Paolo Bonzini
167 6e008585 Anthony Liguori
    if (qdev_get_vmsd(dev)) {
168 6e008585 Anthony Liguori
        vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
169 4d2ffa08 Jan Kiszka
                                       dev->instance_id_alias,
170 4d2ffa08 Jan Kiszka
                                       dev->alias_required_for_version);
171 4d2ffa08 Jan Kiszka
    }
172 131ec1bd Gerd Hoffmann
    dev->state = DEV_STATE_INITIALIZED;
173 94afdadc Anthony Liguori
    if (dev->hotplugged) {
174 94afdadc Anthony Liguori
        device_reset(dev);
175 5ab28c83 Jan Kiszka
    }
176 959f733a Gerd Hoffmann
    return 0;
177 02e2da45 Paul Brook
}
178 02e2da45 Paul Brook
179 4d2ffa08 Jan Kiszka
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
180 4d2ffa08 Jan Kiszka
                                 int required_for_version)
181 4d2ffa08 Jan Kiszka
{
182 4d2ffa08 Jan Kiszka
    assert(dev->state == DEV_STATE_CREATED);
183 4d2ffa08 Jan Kiszka
    dev->instance_id_alias = alias_id;
184 4d2ffa08 Jan Kiszka
    dev->alias_required_for_version = required_for_version;
185 4d2ffa08 Jan Kiszka
}
186 4d2ffa08 Jan Kiszka
187 56f9107e Luiz Capitulino
void qdev_unplug(DeviceState *dev, Error **errp)
188 3418bd25 Gerd Hoffmann
{
189 6e008585 Anthony Liguori
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
190 6e008585 Anthony Liguori
191 3418bd25 Gerd Hoffmann
    if (!dev->parent_bus->allow_hotplug) {
192 56f9107e Luiz Capitulino
        error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
193 56f9107e Luiz Capitulino
        return;
194 3418bd25 Gerd Hoffmann
    }
195 6e008585 Anthony Liguori
    assert(dc->unplug != NULL);
196 593831de Amit Shah
197 0ac8ef71 Alex Williamson
    qdev_hot_removed = true;
198 0ac8ef71 Alex Williamson
199 56f9107e Luiz Capitulino
    if (dc->unplug(dev) < 0) {
200 56f9107e Luiz Capitulino
        error_set(errp, QERR_UNDEFINED_ERROR);
201 56f9107e Luiz Capitulino
        return;
202 56f9107e Luiz Capitulino
    }
203 3418bd25 Gerd Hoffmann
}
204 3418bd25 Gerd Hoffmann
205 ec990eb6 Anthony Liguori
static int qdev_reset_one(DeviceState *dev, void *opaque)
206 ec990eb6 Anthony Liguori
{
207 94afdadc Anthony Liguori
    device_reset(dev);
208 ec990eb6 Anthony Liguori
209 ec990eb6 Anthony Liguori
    return 0;
210 ec990eb6 Anthony Liguori
}
211 ec990eb6 Anthony Liguori
212 ec990eb6 Anthony Liguori
BusState *sysbus_get_default(void)
213 ec990eb6 Anthony Liguori
{
214 68694897 Stefan Weil
    if (!main_system_bus) {
215 2da8bb92 Isaku Yamahata
        main_system_bus_create();
216 68694897 Stefan Weil
    }
217 ec990eb6 Anthony Liguori
    return main_system_bus;
218 ec990eb6 Anthony Liguori
}
219 ec990eb6 Anthony Liguori
220 b4694b7c Isaku Yamahata
static int qbus_reset_one(BusState *bus, void *opaque)
221 b4694b7c Isaku Yamahata
{
222 b4694b7c Isaku Yamahata
    if (bus->info->reset) {
223 b4694b7c Isaku Yamahata
        return bus->info->reset(bus);
224 b4694b7c Isaku Yamahata
    }
225 b4694b7c Isaku Yamahata
    return 0;
226 b4694b7c Isaku Yamahata
}
227 b4694b7c Isaku Yamahata
228 5af0a04b Isaku Yamahata
void qdev_reset_all(DeviceState *dev)
229 5af0a04b Isaku Yamahata
{
230 5af0a04b Isaku Yamahata
    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
231 5af0a04b Isaku Yamahata
}
232 5af0a04b Isaku Yamahata
233 80376c3f Isaku Yamahata
void qbus_reset_all_fn(void *opaque)
234 80376c3f Isaku Yamahata
{
235 80376c3f Isaku Yamahata
    BusState *bus = opaque;
236 f530cce3 Michael S. Tsirkin
    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
237 80376c3f Isaku Yamahata
}
238 80376c3f Isaku Yamahata
239 3418bd25 Gerd Hoffmann
/* can be used as ->unplug() callback for the simple cases */
240 3418bd25 Gerd Hoffmann
int qdev_simple_unplug_cb(DeviceState *dev)
241 3418bd25 Gerd Hoffmann
{
242 3418bd25 Gerd Hoffmann
    /* just zap it */
243 57c9fafe Anthony Liguori
    object_unparent(OBJECT(dev));
244 3418bd25 Gerd Hoffmann
    qdev_free(dev);
245 3418bd25 Gerd Hoffmann
    return 0;
246 3418bd25 Gerd Hoffmann
}
247 3418bd25 Gerd Hoffmann
248 3b29a101 Michael Tokarev
249 3b29a101 Michael Tokarev
/* Like qdev_init(), but terminate program via error_report() instead of
250 e23a1b33 Markus Armbruster
   returning an error value.  This is okay during machine creation.
251 e23a1b33 Markus Armbruster
   Don't use for hotplug, because there callers need to recover from
252 e23a1b33 Markus Armbruster
   failure.  Exception: if you know the device's init() callback can't
253 e23a1b33 Markus Armbruster
   fail, then qdev_init_nofail() can't fail either, and is therefore
254 e23a1b33 Markus Armbruster
   usable even then.  But relying on the device implementation that
255 e23a1b33 Markus Armbruster
   way is somewhat unclean, and best avoided.  */
256 e23a1b33 Markus Armbruster
void qdev_init_nofail(DeviceState *dev)
257 e23a1b33 Markus Armbruster
{
258 bd6c9a61 Markus Armbruster
    if (qdev_init(dev) < 0) {
259 6e008585 Anthony Liguori
        error_report("Initialization of device %s failed",
260 6e008585 Anthony Liguori
                     object_get_typename(OBJECT(dev)));
261 bd6c9a61 Markus Armbruster
        exit(1);
262 bd6c9a61 Markus Armbruster
    }
263 e23a1b33 Markus Armbruster
}
264 e23a1b33 Markus Armbruster
265 02e2da45 Paul Brook
/* Unlink device from bus and free the structure.  */
266 02e2da45 Paul Brook
void qdev_free(DeviceState *dev)
267 02e2da45 Paul Brook
{
268 32fea402 Anthony Liguori
    object_delete(OBJECT(dev));
269 aae9460e Paul Brook
}
270 aae9460e Paul Brook
271 3418bd25 Gerd Hoffmann
void qdev_machine_creation_done(void)
272 3418bd25 Gerd Hoffmann
{
273 3418bd25 Gerd Hoffmann
    /*
274 3418bd25 Gerd Hoffmann
     * ok, initial machine setup is done, starting from now we can
275 3418bd25 Gerd Hoffmann
     * only create hotpluggable devices
276 3418bd25 Gerd Hoffmann
     */
277 3418bd25 Gerd Hoffmann
    qdev_hotplug = 1;
278 3418bd25 Gerd Hoffmann
}
279 3418bd25 Gerd Hoffmann
280 0ac8ef71 Alex Williamson
bool qdev_machine_modified(void)
281 0ac8ef71 Alex Williamson
{
282 0ac8ef71 Alex Williamson
    return qdev_hot_added || qdev_hot_removed;
283 0ac8ef71 Alex Williamson
}
284 0ac8ef71 Alex Williamson
285 02e2da45 Paul Brook
BusState *qdev_get_parent_bus(DeviceState *dev)
286 aae9460e Paul Brook
{
287 02e2da45 Paul Brook
    return dev->parent_bus;
288 aae9460e Paul Brook
}
289 aae9460e Paul Brook
290 aae9460e Paul Brook
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
291 aae9460e Paul Brook
{
292 aae9460e Paul Brook
    assert(dev->num_gpio_in == 0);
293 aae9460e Paul Brook
    dev->num_gpio_in = n;
294 aae9460e Paul Brook
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
295 aae9460e Paul Brook
}
296 aae9460e Paul Brook
297 aae9460e Paul Brook
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
298 aae9460e Paul Brook
{
299 aae9460e Paul Brook
    assert(dev->num_gpio_out == 0);
300 aae9460e Paul Brook
    dev->num_gpio_out = n;
301 aae9460e Paul Brook
    dev->gpio_out = pins;
302 aae9460e Paul Brook
}
303 aae9460e Paul Brook
304 aae9460e Paul Brook
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
305 aae9460e Paul Brook
{
306 aae9460e Paul Brook
    assert(n >= 0 && n < dev->num_gpio_in);
307 aae9460e Paul Brook
    return dev->gpio_in[n];
308 aae9460e Paul Brook
}
309 aae9460e Paul Brook
310 aae9460e Paul Brook
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
311 aae9460e Paul Brook
{
312 aae9460e Paul Brook
    assert(n >= 0 && n < dev->num_gpio_out);
313 aae9460e Paul Brook
    dev->gpio_out[n] = pin;
314 aae9460e Paul Brook
}
315 aae9460e Paul Brook
316 ed16ab5a Gerd Hoffmann
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
317 ed16ab5a Gerd Hoffmann
{
318 6eed1856 Jan Kiszka
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
319 ed16ab5a Gerd Hoffmann
    if (nd->vlan)
320 ed16ab5a Gerd Hoffmann
        qdev_prop_set_vlan(dev, "vlan", nd->vlan);
321 ed16ab5a Gerd Hoffmann
    if (nd->netdev)
322 ed16ab5a Gerd Hoffmann
        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
323 75422b0d Amit Shah
    if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
324 97b15621 Gerd Hoffmann
        qdev_prop_exists(dev, "vectors")) {
325 97b15621 Gerd Hoffmann
        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
326 97b15621 Gerd Hoffmann
    }
327 48e2faf2 Peter Maydell
    nd->instantiated = 1;
328 ed16ab5a Gerd Hoffmann
}
329 ed16ab5a Gerd Hoffmann
330 02e2da45 Paul Brook
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
331 4d6ae674 Paul Brook
{
332 02e2da45 Paul Brook
    BusState *bus;
333 4d6ae674 Paul Brook
334 72cf2d4f Blue Swirl
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
335 4d6ae674 Paul Brook
        if (strcmp(name, bus->name) == 0) {
336 02e2da45 Paul Brook
            return bus;
337 4d6ae674 Paul Brook
        }
338 4d6ae674 Paul Brook
    }
339 4d6ae674 Paul Brook
    return NULL;
340 4d6ae674 Paul Brook
}
341 4d6ae674 Paul Brook
342 81699d8a Anthony Liguori
int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
343 81699d8a Anthony Liguori
                       qbus_walkerfn *busfn, void *opaque)
344 81699d8a Anthony Liguori
{
345 81699d8a Anthony Liguori
    DeviceState *dev;
346 81699d8a Anthony Liguori
    int err;
347 81699d8a Anthony Liguori
348 81699d8a Anthony Liguori
    if (busfn) {
349 81699d8a Anthony Liguori
        err = busfn(bus, opaque);
350 81699d8a Anthony Liguori
        if (err) {
351 81699d8a Anthony Liguori
            return err;
352 81699d8a Anthony Liguori
        }
353 81699d8a Anthony Liguori
    }
354 81699d8a Anthony Liguori
355 d8bb00d6 Paolo Bonzini
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
356 81699d8a Anthony Liguori
        err = qdev_walk_children(dev, devfn, busfn, opaque);
357 81699d8a Anthony Liguori
        if (err < 0) {
358 81699d8a Anthony Liguori
            return err;
359 81699d8a Anthony Liguori
        }
360 81699d8a Anthony Liguori
    }
361 81699d8a Anthony Liguori
362 81699d8a Anthony Liguori
    return 0;
363 81699d8a Anthony Liguori
}
364 81699d8a Anthony Liguori
365 81699d8a Anthony Liguori
int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
366 81699d8a Anthony Liguori
                       qbus_walkerfn *busfn, void *opaque)
367 81699d8a Anthony Liguori
{
368 81699d8a Anthony Liguori
    BusState *bus;
369 81699d8a Anthony Liguori
    int err;
370 81699d8a Anthony Liguori
371 81699d8a Anthony Liguori
    if (devfn) {
372 81699d8a Anthony Liguori
        err = devfn(dev, opaque);
373 81699d8a Anthony Liguori
        if (err) {
374 81699d8a Anthony Liguori
            return err;
375 81699d8a Anthony Liguori
        }
376 81699d8a Anthony Liguori
    }
377 81699d8a Anthony Liguori
378 81699d8a Anthony Liguori
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
379 81699d8a Anthony Liguori
        err = qbus_walk_children(bus, devfn, busfn, opaque);
380 81699d8a Anthony Liguori
        if (err < 0) {
381 81699d8a Anthony Liguori
            return err;
382 81699d8a Anthony Liguori
        }
383 81699d8a Anthony Liguori
    }
384 81699d8a Anthony Liguori
385 81699d8a Anthony Liguori
    return 0;
386 81699d8a Anthony Liguori
}
387 81699d8a Anthony Liguori
388 a2ee6b4f Isaku Yamahata
DeviceState *qdev_find_recursive(BusState *bus, const char *id)
389 3418bd25 Gerd Hoffmann
{
390 3418bd25 Gerd Hoffmann
    DeviceState *dev, *ret;
391 3418bd25 Gerd Hoffmann
    BusState *child;
392 3418bd25 Gerd Hoffmann
393 d8bb00d6 Paolo Bonzini
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
394 3418bd25 Gerd Hoffmann
        if (dev->id && strcmp(dev->id, id) == 0)
395 3418bd25 Gerd Hoffmann
            return dev;
396 3418bd25 Gerd Hoffmann
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
397 3418bd25 Gerd Hoffmann
            ret = qdev_find_recursive(child, id);
398 3418bd25 Gerd Hoffmann
            if (ret) {
399 3418bd25 Gerd Hoffmann
                return ret;
400 3418bd25 Gerd Hoffmann
            }
401 3418bd25 Gerd Hoffmann
        }
402 3418bd25 Gerd Hoffmann
    }
403 3418bd25 Gerd Hoffmann
    return NULL;
404 3418bd25 Gerd Hoffmann
}
405 3418bd25 Gerd Hoffmann
406 cd739fb6 Gerd Hoffmann
void qbus_create_inplace(BusState *bus, BusInfo *info,
407 cd739fb6 Gerd Hoffmann
                         DeviceState *parent, const char *name)
408 02e2da45 Paul Brook
{
409 d271de9f Gerd Hoffmann
    char *buf;
410 d271de9f Gerd Hoffmann
    int i,len;
411 02e2da45 Paul Brook
412 10c4c98a Gerd Hoffmann
    bus->info = info;
413 02e2da45 Paul Brook
    bus->parent = parent;
414 d271de9f Gerd Hoffmann
415 d271de9f Gerd Hoffmann
    if (name) {
416 d271de9f Gerd Hoffmann
        /* use supplied name */
417 7267c094 Anthony Liguori
        bus->name = g_strdup(name);
418 d271de9f Gerd Hoffmann
    } else if (parent && parent->id) {
419 d271de9f Gerd Hoffmann
        /* parent device has id -> use it for bus name */
420 d271de9f Gerd Hoffmann
        len = strlen(parent->id) + 16;
421 7267c094 Anthony Liguori
        buf = g_malloc(len);
422 d271de9f Gerd Hoffmann
        snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
423 d271de9f Gerd Hoffmann
        bus->name = buf;
424 d271de9f Gerd Hoffmann
    } else {
425 d271de9f Gerd Hoffmann
        /* no id -> use lowercase bus type for bus name */
426 d271de9f Gerd Hoffmann
        len = strlen(info->name) + 16;
427 7267c094 Anthony Liguori
        buf = g_malloc(len);
428 d271de9f Gerd Hoffmann
        len = snprintf(buf, len, "%s.%d", info->name,
429 d271de9f Gerd Hoffmann
                       parent ? parent->num_child_bus : 0);
430 d271de9f Gerd Hoffmann
        for (i = 0; i < len; i++)
431 bb87ece5 Christoph Egger
            buf[i] = qemu_tolower(buf[i]);
432 d271de9f Gerd Hoffmann
        bus->name = buf;
433 d271de9f Gerd Hoffmann
    }
434 d271de9f Gerd Hoffmann
435 d8bb00d6 Paolo Bonzini
    QTAILQ_INIT(&bus->children);
436 02e2da45 Paul Brook
    if (parent) {
437 72cf2d4f Blue Swirl
        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
438 d271de9f Gerd Hoffmann
        parent->num_child_bus++;
439 80376c3f Isaku Yamahata
    } else if (bus != main_system_bus) {
440 80376c3f Isaku Yamahata
        /* TODO: once all bus devices are qdevified,
441 80376c3f Isaku Yamahata
           only reset handler for main_system_bus should be registered here. */
442 80376c3f Isaku Yamahata
        qemu_register_reset(qbus_reset_all_fn, bus);
443 02e2da45 Paul Brook
    }
444 cd739fb6 Gerd Hoffmann
}
445 cd739fb6 Gerd Hoffmann
446 cd739fb6 Gerd Hoffmann
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
447 cd739fb6 Gerd Hoffmann
{
448 cd739fb6 Gerd Hoffmann
    BusState *bus;
449 cd739fb6 Gerd Hoffmann
450 7267c094 Anthony Liguori
    bus = g_malloc0(info->size);
451 cd739fb6 Gerd Hoffmann
    bus->qdev_allocated = 1;
452 cd739fb6 Gerd Hoffmann
    qbus_create_inplace(bus, info, parent, name);
453 02e2da45 Paul Brook
    return bus;
454 02e2da45 Paul Brook
}
455 cae4956e Gerd Hoffmann
456 2da8bb92 Isaku Yamahata
static void main_system_bus_create(void)
457 2da8bb92 Isaku Yamahata
{
458 2da8bb92 Isaku Yamahata
    /* assign main_system_bus before qbus_create_inplace()
459 2da8bb92 Isaku Yamahata
     * in order to make "if (bus != main_system_bus)" work */
460 7267c094 Anthony Liguori
    main_system_bus = g_malloc0(system_bus_info.size);
461 2da8bb92 Isaku Yamahata
    main_system_bus->qdev_allocated = 1;
462 2da8bb92 Isaku Yamahata
    qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
463 2da8bb92 Isaku Yamahata
                        "main-system-bus");
464 2da8bb92 Isaku Yamahata
}
465 2da8bb92 Isaku Yamahata
466 131ec1bd Gerd Hoffmann
void qbus_free(BusState *bus)
467 131ec1bd Gerd Hoffmann
{
468 131ec1bd Gerd Hoffmann
    DeviceState *dev;
469 131ec1bd Gerd Hoffmann
470 d8bb00d6 Paolo Bonzini
    while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
471 131ec1bd Gerd Hoffmann
        qdev_free(dev);
472 131ec1bd Gerd Hoffmann
    }
473 131ec1bd Gerd Hoffmann
    if (bus->parent) {
474 131ec1bd Gerd Hoffmann
        QLIST_REMOVE(bus, sibling);
475 131ec1bd Gerd Hoffmann
        bus->parent->num_child_bus--;
476 80376c3f Isaku Yamahata
    } else {
477 80376c3f Isaku Yamahata
        assert(bus != main_system_bus); /* main_system_bus is never freed */
478 80376c3f Isaku Yamahata
        qemu_unregister_reset(qbus_reset_all_fn, bus);
479 131ec1bd Gerd Hoffmann
    }
480 7267c094 Anthony Liguori
    g_free((void*)bus->name);
481 131ec1bd Gerd Hoffmann
    if (bus->qdev_allocated) {
482 7267c094 Anthony Liguori
        g_free(bus);
483 131ec1bd Gerd Hoffmann
    }
484 131ec1bd Gerd Hoffmann
}
485 131ec1bd Gerd Hoffmann
486 1ca4d09a Gleb Natapov
static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
487 1ca4d09a Gleb Natapov
{
488 1ca4d09a Gleb Natapov
    int l = 0;
489 1ca4d09a Gleb Natapov
490 1ca4d09a Gleb Natapov
    if (dev && dev->parent_bus) {
491 1ca4d09a Gleb Natapov
        char *d;
492 1ca4d09a Gleb Natapov
        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
493 1ca4d09a Gleb Natapov
        if (dev->parent_bus->info->get_fw_dev_path) {
494 1ca4d09a Gleb Natapov
            d = dev->parent_bus->info->get_fw_dev_path(dev);
495 1ca4d09a Gleb Natapov
            l += snprintf(p + l, size - l, "%s", d);
496 7267c094 Anthony Liguori
            g_free(d);
497 1ca4d09a Gleb Natapov
        } else {
498 f79f2bfc Anthony Liguori
            l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
499 1ca4d09a Gleb Natapov
        }
500 1ca4d09a Gleb Natapov
    }
501 1ca4d09a Gleb Natapov
    l += snprintf(p + l , size - l, "/");
502 1ca4d09a Gleb Natapov
503 1ca4d09a Gleb Natapov
    return l;
504 1ca4d09a Gleb Natapov
}
505 1ca4d09a Gleb Natapov
506 1ca4d09a Gleb Natapov
char* qdev_get_fw_dev_path(DeviceState *dev)
507 1ca4d09a Gleb Natapov
{
508 1ca4d09a Gleb Natapov
    char path[128];
509 1ca4d09a Gleb Natapov
    int l;
510 1ca4d09a Gleb Natapov
511 1ca4d09a Gleb Natapov
    l = qdev_get_fw_dev_path_helper(dev, path, 128);
512 1ca4d09a Gleb Natapov
513 1ca4d09a Gleb Natapov
    path[l-1] = '\0';
514 1ca4d09a Gleb Natapov
515 1ca4d09a Gleb Natapov
    return strdup(path);
516 1ca4d09a Gleb Natapov
}
517 85ed303b Anthony Liguori
518 57c9fafe Anthony Liguori
static char *qdev_get_type(Object *obj, Error **errp)
519 85ed303b Anthony Liguori
{
520 57c9fafe Anthony Liguori
    return g_strdup(object_get_typename(obj));
521 44677ded Anthony Liguori
}
522 a5296ca9 Anthony Liguori
523 a5296ca9 Anthony Liguori
/**
524 a5296ca9 Anthony Liguori
 * Legacy property handling
525 a5296ca9 Anthony Liguori
 */
526 a5296ca9 Anthony Liguori
527 57c9fafe Anthony Liguori
static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
528 a5296ca9 Anthony Liguori
                                     const char *name, Error **errp)
529 a5296ca9 Anthony Liguori
{
530 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
531 a5296ca9 Anthony Liguori
    Property *prop = opaque;
532 a5296ca9 Anthony Liguori
533 e3cb6ba6 Paolo Bonzini
    char buffer[1024];
534 e3cb6ba6 Paolo Bonzini
    char *ptr = buffer;
535 a5296ca9 Anthony Liguori
536 e3cb6ba6 Paolo Bonzini
    prop->info->print(dev, prop, buffer, sizeof(buffer));
537 e3cb6ba6 Paolo Bonzini
    visit_type_str(v, &ptr, name, errp);
538 a5296ca9 Anthony Liguori
}
539 a5296ca9 Anthony Liguori
540 57c9fafe Anthony Liguori
static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
541 a5296ca9 Anthony Liguori
                                     const char *name, Error **errp)
542 a5296ca9 Anthony Liguori
{
543 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
544 a5296ca9 Anthony Liguori
    Property *prop = opaque;
545 e3cb6ba6 Paolo Bonzini
    Error *local_err = NULL;
546 e3cb6ba6 Paolo Bonzini
    char *ptr = NULL;
547 e3cb6ba6 Paolo Bonzini
    int ret;
548 a5296ca9 Anthony Liguori
549 a5296ca9 Anthony Liguori
    if (dev->state != DEV_STATE_CREATED) {
550 a5296ca9 Anthony Liguori
        error_set(errp, QERR_PERMISSION_DENIED);
551 a5296ca9 Anthony Liguori
        return;
552 a5296ca9 Anthony Liguori
    }
553 a5296ca9 Anthony Liguori
554 e3cb6ba6 Paolo Bonzini
    visit_type_str(v, &ptr, name, &local_err);
555 e3cb6ba6 Paolo Bonzini
    if (local_err) {
556 e3cb6ba6 Paolo Bonzini
        error_propagate(errp, local_err);
557 e3cb6ba6 Paolo Bonzini
        return;
558 e3cb6ba6 Paolo Bonzini
    }
559 a5296ca9 Anthony Liguori
560 e3cb6ba6 Paolo Bonzini
    ret = prop->info->parse(dev, prop, ptr);
561 7db4c4e8 Paolo Bonzini
    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
562 e3cb6ba6 Paolo Bonzini
    g_free(ptr);
563 a5296ca9 Anthony Liguori
}
564 a5296ca9 Anthony Liguori
565 a5296ca9 Anthony Liguori
/**
566 a5296ca9 Anthony Liguori
 * @qdev_add_legacy_property - adds a legacy property
567 a5296ca9 Anthony Liguori
 *
568 a5296ca9 Anthony Liguori
 * Do not use this is new code!  Properties added through this interface will
569 ca2cc788 Paolo Bonzini
 * be given names and types in the "legacy" namespace.
570 a5296ca9 Anthony Liguori
 *
571 68ee3569 Paolo Bonzini
 * Legacy properties are string versions of other OOM properties.  The format
572 68ee3569 Paolo Bonzini
 * of the string depends on the property type.
573 a5296ca9 Anthony Liguori
 */
574 a5296ca9 Anthony Liguori
void qdev_property_add_legacy(DeviceState *dev, Property *prop,
575 a5296ca9 Anthony Liguori
                              Error **errp)
576 a5296ca9 Anthony Liguori
{
577 ca2cc788 Paolo Bonzini
    gchar *name, *type;
578 a5296ca9 Anthony Liguori
579 f3be016d Anthony Liguori
    /* Register pointer properties as legacy properties */
580 f3be016d Anthony Liguori
    if (!prop->info->print && !prop->info->parse &&
581 f3be016d Anthony Liguori
        (prop->info->set || prop->info->get)) {
582 68ee3569 Paolo Bonzini
        return;
583 68ee3569 Paolo Bonzini
    }
584 f3be016d Anthony Liguori
585 ca2cc788 Paolo Bonzini
    name = g_strdup_printf("legacy-%s", prop->name);
586 cafe5bdb Paolo Bonzini
    type = g_strdup_printf("legacy<%s>",
587 cafe5bdb Paolo Bonzini
                           prop->info->legacy_name ?: prop->info->name);
588 a5296ca9 Anthony Liguori
589 57c9fafe Anthony Liguori
    object_property_add(OBJECT(dev), name, type,
590 68ee3569 Paolo Bonzini
                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
591 68ee3569 Paolo Bonzini
                        prop->info->parse ? qdev_set_legacy_property : prop->info->set,
592 57c9fafe Anthony Liguori
                        NULL,
593 57c9fafe Anthony Liguori
                        prop, errp);
594 a5296ca9 Anthony Liguori
595 a5296ca9 Anthony Liguori
    g_free(type);
596 ca2cc788 Paolo Bonzini
    g_free(name);
597 ca2cc788 Paolo Bonzini
}
598 ca2cc788 Paolo Bonzini
599 ca2cc788 Paolo Bonzini
/**
600 ca2cc788 Paolo Bonzini
 * @qdev_property_add_static - add a @Property to a device.
601 ca2cc788 Paolo Bonzini
 *
602 ca2cc788 Paolo Bonzini
 * Static properties access data in a struct.  The actual type of the
603 ca2cc788 Paolo Bonzini
 * property and the field depends on the property type.
604 ca2cc788 Paolo Bonzini
 */
605 ca2cc788 Paolo Bonzini
void qdev_property_add_static(DeviceState *dev, Property *prop,
606 ca2cc788 Paolo Bonzini
                              Error **errp)
607 ca2cc788 Paolo Bonzini
{
608 d822979b Paolo Bonzini
    /*
609 d822979b Paolo Bonzini
     * TODO qdev_prop_ptr does not have getters or setters.  It must
610 d822979b Paolo Bonzini
     * go now that it can be replaced with links.  The test should be
611 d822979b Paolo Bonzini
     * removed along with it: all static properties are read/write.
612 d822979b Paolo Bonzini
     */
613 d822979b Paolo Bonzini
    if (!prop->info->get && !prop->info->set) {
614 d822979b Paolo Bonzini
        return;
615 d822979b Paolo Bonzini
    }
616 d822979b Paolo Bonzini
617 57c9fafe Anthony Liguori
    object_property_add(OBJECT(dev), prop->name, prop->info->name,
618 57c9fafe Anthony Liguori
                        prop->info->get, prop->info->set,
619 dd0ba250 Paolo Bonzini
                        prop->info->release,
620 57c9fafe Anthony Liguori
                        prop, errp);
621 6a146eba Anthony Liguori
}
622 1de81d28 Anthony Liguori
623 9674bfe4 Anthony Liguori
static void device_initfn(Object *obj)
624 9674bfe4 Anthony Liguori
{
625 9674bfe4 Anthony Liguori
    DeviceState *dev = DEVICE(obj);
626 9674bfe4 Anthony Liguori
    Property *prop;
627 9674bfe4 Anthony Liguori
628 9674bfe4 Anthony Liguori
    if (qdev_hotplug) {
629 9674bfe4 Anthony Liguori
        dev->hotplugged = 1;
630 9674bfe4 Anthony Liguori
        qdev_hot_added = true;
631 9674bfe4 Anthony Liguori
    }
632 9674bfe4 Anthony Liguori
633 9674bfe4 Anthony Liguori
    dev->instance_id_alias = -1;
634 9674bfe4 Anthony Liguori
    dev->state = DEV_STATE_CREATED;
635 9674bfe4 Anthony Liguori
636 9674bfe4 Anthony Liguori
    for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
637 9674bfe4 Anthony Liguori
        qdev_property_add_legacy(dev, prop, NULL);
638 9674bfe4 Anthony Liguori
        qdev_property_add_static(dev, prop, NULL);
639 9674bfe4 Anthony Liguori
    }
640 9674bfe4 Anthony Liguori
641 57c9fafe Anthony Liguori
    object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL);
642 4f2d3d70 Paolo Bonzini
    qdev_prop_set_defaults(dev, qdev_get_props(dev));
643 9674bfe4 Anthony Liguori
}
644 9674bfe4 Anthony Liguori
645 60adba37 Anthony Liguori
/* Unlink device from bus and free the structure.  */
646 60adba37 Anthony Liguori
static void device_finalize(Object *obj)
647 60adba37 Anthony Liguori
{
648 60adba37 Anthony Liguori
    DeviceState *dev = DEVICE(obj);
649 60adba37 Anthony Liguori
    BusState *bus;
650 60adba37 Anthony Liguori
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
651 60adba37 Anthony Liguori
652 60adba37 Anthony Liguori
    if (dev->state == DEV_STATE_INITIALIZED) {
653 60adba37 Anthony Liguori
        while (dev->num_child_bus) {
654 60adba37 Anthony Liguori
            bus = QLIST_FIRST(&dev->child_bus);
655 60adba37 Anthony Liguori
            qbus_free(bus);
656 60adba37 Anthony Liguori
        }
657 60adba37 Anthony Liguori
        if (qdev_get_vmsd(dev)) {
658 60adba37 Anthony Liguori
            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
659 60adba37 Anthony Liguori
        }
660 60adba37 Anthony Liguori
        if (dc->exit) {
661 60adba37 Anthony Liguori
            dc->exit(dev);
662 60adba37 Anthony Liguori
        }
663 60adba37 Anthony Liguori
        if (dev->opts) {
664 60adba37 Anthony Liguori
            qemu_opts_del(dev->opts);
665 60adba37 Anthony Liguori
        }
666 60adba37 Anthony Liguori
    }
667 60adba37 Anthony Liguori
    QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
668 60adba37 Anthony Liguori
}
669 60adba37 Anthony Liguori
670 94afdadc Anthony Liguori
void device_reset(DeviceState *dev)
671 94afdadc Anthony Liguori
{
672 94afdadc Anthony Liguori
    DeviceClass *klass = DEVICE_GET_CLASS(dev);
673 94afdadc Anthony Liguori
674 94afdadc Anthony Liguori
    if (klass->reset) {
675 94afdadc Anthony Liguori
        klass->reset(dev);
676 94afdadc Anthony Liguori
    }
677 94afdadc Anthony Liguori
}
678 94afdadc Anthony Liguori
679 f05f6b4a Paolo Bonzini
Object *qdev_get_machine(void)
680 f05f6b4a Paolo Bonzini
{
681 f05f6b4a Paolo Bonzini
    static Object *dev;
682 f05f6b4a Paolo Bonzini
683 f05f6b4a Paolo Bonzini
    if (dev == NULL) {
684 dfe47e70 Andreas Färber
        dev = container_get(object_get_root(), "/machine");
685 f05f6b4a Paolo Bonzini
    }
686 f05f6b4a Paolo Bonzini
687 f05f6b4a Paolo Bonzini
    return dev;
688 f05f6b4a Paolo Bonzini
}
689 f05f6b4a Paolo Bonzini
690 32fea402 Anthony Liguori
static TypeInfo device_type_info = {
691 32fea402 Anthony Liguori
    .name = TYPE_DEVICE,
692 32fea402 Anthony Liguori
    .parent = TYPE_OBJECT,
693 32fea402 Anthony Liguori
    .instance_size = sizeof(DeviceState),
694 9674bfe4 Anthony Liguori
    .instance_init = device_initfn,
695 60adba37 Anthony Liguori
    .instance_finalize = device_finalize,
696 32fea402 Anthony Liguori
    .abstract = true,
697 32fea402 Anthony Liguori
    .class_size = sizeof(DeviceClass),
698 32fea402 Anthony Liguori
};
699 32fea402 Anthony Liguori
700 83f7d43a Andreas Färber
static void qdev_register_types(void)
701 32fea402 Anthony Liguori
{
702 32fea402 Anthony Liguori
    type_register_static(&device_type_info);
703 32fea402 Anthony Liguori
}
704 32fea402 Anthony Liguori
705 83f7d43a Andreas Färber
type_init(qdev_register_types)