Statistics
| Branch: | Revision:

root / hw / qdev.c @ 2850ca9e

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