Statistics
| Branch: | Revision:

root / hw / qdev.c @ f05f6b4a

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