Statistics
| Branch: | Revision:

root / hw / qdev.c @ c9159fe9

History | View | Annotate | Download (20.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 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 aae9460e Paul Brook
/* Register a new device type.  */
38 4be9f0d1 Anthony Liguori
const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
39 4be9f0d1 Anthony Liguori
{
40 6e008585 Anthony Liguori
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
41 6e008585 Anthony Liguori
    return dc->vmsd;
42 4be9f0d1 Anthony Liguori
}
43 4be9f0d1 Anthony Liguori
44 4be9f0d1 Anthony Liguori
const char *qdev_fw_name(DeviceState *dev)
45 4be9f0d1 Anthony Liguori
{
46 6e008585 Anthony Liguori
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
47 4be9f0d1 Anthony Liguori
48 6e008585 Anthony Liguori
    if (dc->fw_name) {
49 6e008585 Anthony Liguori
        return dc->fw_name;
50 4be9f0d1 Anthony Liguori
    }
51 4be9f0d1 Anthony Liguori
52 4be9f0d1 Anthony Liguori
    return object_get_typename(OBJECT(dev));
53 4be9f0d1 Anthony Liguori
}
54 4be9f0d1 Anthony Liguori
55 a369da5f Blue Swirl
bool qdev_exists(const char *name)
56 a369da5f Blue Swirl
{
57 212ad111 Anthony Liguori
    return !!object_class_by_name(name);
58 a369da5f Blue Swirl
}
59 40021f08 Anthony Liguori
60 ca2cc788 Paolo Bonzini
static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
61 ca2cc788 Paolo Bonzini
                                     Error **errp);
62 ca2cc788 Paolo Bonzini
63 0866aca1 Anthony Liguori
static void bus_remove_child(BusState *bus, DeviceState *child)
64 0c17542d Markus Armbruster
{
65 0866aca1 Anthony Liguori
    BusChild *kid;
66 0866aca1 Anthony Liguori
67 0866aca1 Anthony Liguori
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
68 0866aca1 Anthony Liguori
        if (kid->child == child) {
69 0866aca1 Anthony Liguori
            char name[32];
70 0866aca1 Anthony Liguori
71 0866aca1 Anthony Liguori
            snprintf(name, sizeof(name), "child[%d]", kid->index);
72 0866aca1 Anthony Liguori
            QTAILQ_REMOVE(&bus->children, kid, sibling);
73 0866aca1 Anthony Liguori
            object_property_del(OBJECT(bus), name, NULL);
74 0866aca1 Anthony Liguori
            g_free(kid);
75 0866aca1 Anthony Liguori
            return;
76 0866aca1 Anthony Liguori
        }
77 0866aca1 Anthony Liguori
    }
78 0866aca1 Anthony Liguori
}
79 0866aca1 Anthony Liguori
80 0866aca1 Anthony Liguori
static void bus_add_child(BusState *bus, DeviceState *child)
81 0866aca1 Anthony Liguori
{
82 0866aca1 Anthony Liguori
    char name[32];
83 0866aca1 Anthony Liguori
    BusChild *kid = g_malloc0(sizeof(*kid));
84 0c17542d Markus Armbruster
85 0c17542d Markus Armbruster
    if (qdev_hotplug) {
86 0c17542d Markus Armbruster
        assert(bus->allow_hotplug);
87 0c17542d Markus Armbruster
    }
88 a5296ca9 Anthony Liguori
89 0866aca1 Anthony Liguori
    kid->index = bus->max_index++;
90 0866aca1 Anthony Liguori
    kid->child = child;
91 a5296ca9 Anthony Liguori
92 0866aca1 Anthony Liguori
    QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
93 0866aca1 Anthony Liguori
94 0866aca1 Anthony Liguori
    snprintf(name, sizeof(name), "child[%d]", kid->index);
95 0866aca1 Anthony Liguori
    object_property_add_link(OBJECT(bus), name,
96 0866aca1 Anthony Liguori
                             object_get_typename(OBJECT(child)),
97 0866aca1 Anthony Liguori
                             (Object **)&kid->child,
98 0866aca1 Anthony Liguori
                             NULL);
99 0866aca1 Anthony Liguori
}
100 0866aca1 Anthony Liguori
101 0866aca1 Anthony Liguori
void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
102 0866aca1 Anthony Liguori
{
103 9fbe6127 Anthony Liguori
    dev->parent_bus = bus;
104 0866aca1 Anthony Liguori
    bus_add_child(bus, dev);
105 0c17542d Markus Armbruster
}
106 0c17542d Markus Armbruster
107 aae9460e Paul Brook
/* Create a new device.  This only initializes the device state structure
108 aae9460e Paul Brook
   and allows properties to be set.  qdev_init should be called to
109 aae9460e Paul Brook
   initialize the actual device emulation.  */
110 02e2da45 Paul Brook
DeviceState *qdev_create(BusState *bus, const char *name)
111 aae9460e Paul Brook
{
112 0bcdeda7 Blue Swirl
    DeviceState *dev;
113 0bcdeda7 Blue Swirl
114 0bcdeda7 Blue Swirl
    dev = qdev_try_create(bus, name);
115 0bcdeda7 Blue Swirl
    if (!dev) {
116 e92714c7 Peter Maydell
        if (bus) {
117 e92714c7 Peter Maydell
            hw_error("Unknown device '%s' for bus '%s'\n", name,
118 0d936928 Anthony Liguori
                     object_get_typename(OBJECT(bus)));
119 e92714c7 Peter Maydell
        } else {
120 e92714c7 Peter Maydell
            hw_error("Unknown device '%s' for default sysbus\n", name);
121 e92714c7 Peter Maydell
        }
122 0bcdeda7 Blue Swirl
    }
123 0bcdeda7 Blue Swirl
124 0bcdeda7 Blue Swirl
    return dev;
125 0bcdeda7 Blue Swirl
}
126 0bcdeda7 Blue Swirl
127 da57febf Paolo Bonzini
DeviceState *qdev_try_create(BusState *bus, const char *type)
128 0bcdeda7 Blue Swirl
{
129 9fbe6127 Anthony Liguori
    DeviceState *dev;
130 9fbe6127 Anthony Liguori
131 da57febf Paolo Bonzini
    if (object_class_by_name(type) == NULL) {
132 4ed658ca Andreas Färber
        return NULL;
133 4ed658ca Andreas Färber
    }
134 da57febf Paolo Bonzini
    dev = DEVICE(object_new(type));
135 9fbe6127 Anthony Liguori
    if (!dev) {
136 9fbe6127 Anthony Liguori
        return NULL;
137 9fbe6127 Anthony Liguori
    }
138 9fbe6127 Anthony Liguori
139 10c4c98a Gerd Hoffmann
    if (!bus) {
140 68694897 Stefan Weil
        bus = sysbus_get_default();
141 10c4c98a Gerd Hoffmann
    }
142 10c4c98a Gerd Hoffmann
143 9fbe6127 Anthony Liguori
    qdev_set_parent_bus(dev, bus);
144 9fbe6127 Anthony Liguori
145 9fbe6127 Anthony Liguori
    return dev;
146 aae9460e Paul Brook
}
147 aae9460e Paul Brook
148 aae9460e Paul Brook
/* Initialize a device.  Device properties should be set before calling
149 aae9460e Paul Brook
   this function.  IRQs and MMIO regions should be connected/mapped after
150 18cfeb52 Markus Armbruster
   calling this function.
151 18cfeb52 Markus Armbruster
   On failure, destroy the device and return negative value.
152 18cfeb52 Markus Armbruster
   Return 0 on success.  */
153 81a322d4 Gerd Hoffmann
int qdev_init(DeviceState *dev)
154 aae9460e Paul Brook
{
155 6e008585 Anthony Liguori
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
156 959f733a Gerd Hoffmann
    int rc;
157 959f733a Gerd Hoffmann
158 131ec1bd Gerd Hoffmann
    assert(dev->state == DEV_STATE_CREATED);
159 6e008585 Anthony Liguori
160 d307af79 Anthony Liguori
    rc = dc->init(dev);
161 18cfeb52 Markus Armbruster
    if (rc < 0) {
162 18cfeb52 Markus Armbruster
        qdev_free(dev);
163 959f733a Gerd Hoffmann
        return rc;
164 18cfeb52 Markus Armbruster
    }
165 da57febf Paolo Bonzini
166 da57febf Paolo Bonzini
    if (!OBJECT(dev)->parent) {
167 da57febf Paolo Bonzini
        static int unattached_count = 0;
168 da57febf Paolo Bonzini
        gchar *name = g_strdup_printf("device[%d]", unattached_count++);
169 da57febf Paolo Bonzini
170 dfe47e70 Andreas Färber
        object_property_add_child(container_get(qdev_get_machine(),
171 dfe47e70 Andreas Färber
                                                "/unattached"),
172 dfe47e70 Andreas Färber
                                  name, OBJECT(dev), NULL);
173 da57febf Paolo Bonzini
        g_free(name);
174 da57febf Paolo Bonzini
    }
175 da57febf Paolo Bonzini
176 6e008585 Anthony Liguori
    if (qdev_get_vmsd(dev)) {
177 6e008585 Anthony Liguori
        vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
178 4d2ffa08 Jan Kiszka
                                       dev->instance_id_alias,
179 4d2ffa08 Jan Kiszka
                                       dev->alias_required_for_version);
180 4d2ffa08 Jan Kiszka
    }
181 131ec1bd Gerd Hoffmann
    dev->state = DEV_STATE_INITIALIZED;
182 94afdadc Anthony Liguori
    if (dev->hotplugged) {
183 94afdadc Anthony Liguori
        device_reset(dev);
184 5ab28c83 Jan Kiszka
    }
185 959f733a Gerd Hoffmann
    return 0;
186 02e2da45 Paul Brook
}
187 02e2da45 Paul Brook
188 4d2ffa08 Jan Kiszka
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
189 4d2ffa08 Jan Kiszka
                                 int required_for_version)
190 4d2ffa08 Jan Kiszka
{
191 4d2ffa08 Jan Kiszka
    assert(dev->state == DEV_STATE_CREATED);
192 4d2ffa08 Jan Kiszka
    dev->instance_id_alias = alias_id;
193 4d2ffa08 Jan Kiszka
    dev->alias_required_for_version = required_for_version;
194 4d2ffa08 Jan Kiszka
}
195 4d2ffa08 Jan Kiszka
196 56f9107e Luiz Capitulino
void qdev_unplug(DeviceState *dev, Error **errp)
197 3418bd25 Gerd Hoffmann
{
198 6e008585 Anthony Liguori
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
199 6e008585 Anthony Liguori
200 3418bd25 Gerd Hoffmann
    if (!dev->parent_bus->allow_hotplug) {
201 56f9107e Luiz Capitulino
        error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
202 56f9107e Luiz Capitulino
        return;
203 3418bd25 Gerd Hoffmann
    }
204 6e008585 Anthony Liguori
    assert(dc->unplug != NULL);
205 593831de Amit Shah
206 0ac8ef71 Alex Williamson
    qdev_hot_removed = true;
207 0ac8ef71 Alex Williamson
208 56f9107e Luiz Capitulino
    if (dc->unplug(dev) < 0) {
209 56f9107e Luiz Capitulino
        error_set(errp, QERR_UNDEFINED_ERROR);
210 56f9107e Luiz Capitulino
        return;
211 56f9107e Luiz Capitulino
    }
212 3418bd25 Gerd Hoffmann
}
213 3418bd25 Gerd Hoffmann
214 ec990eb6 Anthony Liguori
static int qdev_reset_one(DeviceState *dev, void *opaque)
215 ec990eb6 Anthony Liguori
{
216 94afdadc Anthony Liguori
    device_reset(dev);
217 ec990eb6 Anthony Liguori
218 ec990eb6 Anthony Liguori
    return 0;
219 ec990eb6 Anthony Liguori
}
220 ec990eb6 Anthony Liguori
221 b4694b7c Isaku Yamahata
static int qbus_reset_one(BusState *bus, void *opaque)
222 b4694b7c Isaku Yamahata
{
223 0d936928 Anthony Liguori
    BusClass *bc = BUS_GET_CLASS(bus);
224 0d936928 Anthony Liguori
    if (bc->reset) {
225 0d936928 Anthony Liguori
        return bc->reset(bus);
226 b4694b7c Isaku Yamahata
    }
227 b4694b7c Isaku Yamahata
    return 0;
228 b4694b7c Isaku Yamahata
}
229 b4694b7c Isaku Yamahata
230 5af0a04b Isaku Yamahata
void qdev_reset_all(DeviceState *dev)
231 5af0a04b Isaku Yamahata
{
232 5af0a04b Isaku Yamahata
    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
233 5af0a04b Isaku Yamahata
}
234 5af0a04b Isaku Yamahata
235 80376c3f Isaku Yamahata
void qbus_reset_all_fn(void *opaque)
236 80376c3f Isaku Yamahata
{
237 80376c3f Isaku Yamahata
    BusState *bus = opaque;
238 f530cce3 Michael S. Tsirkin
    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
239 80376c3f Isaku Yamahata
}
240 80376c3f Isaku Yamahata
241 3418bd25 Gerd Hoffmann
/* can be used as ->unplug() callback for the simple cases */
242 3418bd25 Gerd Hoffmann
int qdev_simple_unplug_cb(DeviceState *dev)
243 3418bd25 Gerd Hoffmann
{
244 3418bd25 Gerd Hoffmann
    /* just zap it */
245 3418bd25 Gerd Hoffmann
    qdev_free(dev);
246 3418bd25 Gerd Hoffmann
    return 0;
247 3418bd25 Gerd Hoffmann
}
248 3418bd25 Gerd Hoffmann
249 3b29a101 Michael Tokarev
250 3b29a101 Michael Tokarev
/* Like qdev_init(), but terminate program via error_report() instead of
251 e23a1b33 Markus Armbruster
   returning an error value.  This is okay during machine creation.
252 e23a1b33 Markus Armbruster
   Don't use for hotplug, because there callers need to recover from
253 e23a1b33 Markus Armbruster
   failure.  Exception: if you know the device's init() callback can't
254 e23a1b33 Markus Armbruster
   fail, then qdev_init_nofail() can't fail either, and is therefore
255 e23a1b33 Markus Armbruster
   usable even then.  But relying on the device implementation that
256 e23a1b33 Markus Armbruster
   way is somewhat unclean, and best avoided.  */
257 e23a1b33 Markus Armbruster
void qdev_init_nofail(DeviceState *dev)
258 e23a1b33 Markus Armbruster
{
259 7de3abe5 Anthony Liguori
    const char *typename = object_get_typename(OBJECT(dev));
260 7de3abe5 Anthony Liguori
261 bd6c9a61 Markus Armbruster
    if (qdev_init(dev) < 0) {
262 7de3abe5 Anthony Liguori
        error_report("Initialization of device %s failed", typename);
263 bd6c9a61 Markus Armbruster
        exit(1);
264 bd6c9a61 Markus Armbruster
    }
265 e23a1b33 Markus Armbruster
}
266 e23a1b33 Markus Armbruster
267 02e2da45 Paul Brook
/* Unlink device from bus and free the structure.  */
268 02e2da45 Paul Brook
void qdev_free(DeviceState *dev)
269 02e2da45 Paul Brook
{
270 32fea402 Anthony Liguori
    object_delete(OBJECT(dev));
271 aae9460e Paul Brook
}
272 aae9460e Paul Brook
273 3418bd25 Gerd Hoffmann
void qdev_machine_creation_done(void)
274 3418bd25 Gerd Hoffmann
{
275 3418bd25 Gerd Hoffmann
    /*
276 3418bd25 Gerd Hoffmann
     * ok, initial machine setup is done, starting from now we can
277 3418bd25 Gerd Hoffmann
     * only create hotpluggable devices
278 3418bd25 Gerd Hoffmann
     */
279 3418bd25 Gerd Hoffmann
    qdev_hotplug = 1;
280 3418bd25 Gerd Hoffmann
}
281 3418bd25 Gerd Hoffmann
282 0ac8ef71 Alex Williamson
bool qdev_machine_modified(void)
283 0ac8ef71 Alex Williamson
{
284 0ac8ef71 Alex Williamson
    return qdev_hot_added || qdev_hot_removed;
285 0ac8ef71 Alex Williamson
}
286 0ac8ef71 Alex Williamson
287 02e2da45 Paul Brook
BusState *qdev_get_parent_bus(DeviceState *dev)
288 aae9460e Paul Brook
{
289 02e2da45 Paul Brook
    return dev->parent_bus;
290 aae9460e Paul Brook
}
291 aae9460e Paul Brook
292 aae9460e Paul Brook
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
293 aae9460e Paul Brook
{
294 aae9460e Paul Brook
    assert(dev->num_gpio_in == 0);
295 aae9460e Paul Brook
    dev->num_gpio_in = n;
296 aae9460e Paul Brook
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
297 aae9460e Paul Brook
}
298 aae9460e Paul Brook
299 aae9460e Paul Brook
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
300 aae9460e Paul Brook
{
301 aae9460e Paul Brook
    assert(dev->num_gpio_out == 0);
302 aae9460e Paul Brook
    dev->num_gpio_out = n;
303 aae9460e Paul Brook
    dev->gpio_out = pins;
304 aae9460e Paul Brook
}
305 aae9460e Paul Brook
306 aae9460e Paul Brook
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
307 aae9460e Paul Brook
{
308 aae9460e Paul Brook
    assert(n >= 0 && n < dev->num_gpio_in);
309 aae9460e Paul Brook
    return dev->gpio_in[n];
310 aae9460e Paul Brook
}
311 aae9460e Paul Brook
312 aae9460e Paul Brook
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
313 aae9460e Paul Brook
{
314 aae9460e Paul Brook
    assert(n >= 0 && n < dev->num_gpio_out);
315 aae9460e Paul Brook
    dev->gpio_out[n] = pin;
316 aae9460e Paul Brook
}
317 aae9460e Paul Brook
318 ed16ab5a Gerd Hoffmann
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
319 ed16ab5a Gerd Hoffmann
{
320 6eed1856 Jan Kiszka
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
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 89bfe000 Paolo Bonzini
        object_property_find(OBJECT(dev), "vectors", NULL)) {
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 0866aca1 Anthony Liguori
    BusChild *kid;
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 0866aca1 Anthony Liguori
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
356 0866aca1 Anthony Liguori
        err = qdev_walk_children(kid->child, 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 0866aca1 Anthony Liguori
    BusChild *kid;
391 0866aca1 Anthony Liguori
    DeviceState *ret;
392 3418bd25 Gerd Hoffmann
    BusState *child;
393 3418bd25 Gerd Hoffmann
394 0866aca1 Anthony Liguori
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
395 0866aca1 Anthony Liguori
        DeviceState *dev = kid->child;
396 0866aca1 Anthony Liguori
397 0866aca1 Anthony Liguori
        if (dev->id && strcmp(dev->id, id) == 0) {
398 3418bd25 Gerd Hoffmann
            return dev;
399 0866aca1 Anthony Liguori
        }
400 0866aca1 Anthony Liguori
401 3418bd25 Gerd Hoffmann
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
402 3418bd25 Gerd Hoffmann
            ret = qdev_find_recursive(child, id);
403 3418bd25 Gerd Hoffmann
            if (ret) {
404 3418bd25 Gerd Hoffmann
                return ret;
405 3418bd25 Gerd Hoffmann
            }
406 3418bd25 Gerd Hoffmann
        }
407 3418bd25 Gerd Hoffmann
    }
408 3418bd25 Gerd Hoffmann
    return NULL;
409 3418bd25 Gerd Hoffmann
}
410 3418bd25 Gerd Hoffmann
411 ac7d1ba6 Anthony Liguori
static void qbus_realize(BusState *bus)
412 02e2da45 Paul Brook
{
413 ac7d1ba6 Anthony Liguori
    const char *typename = object_get_typename(OBJECT(bus));
414 d271de9f Gerd Hoffmann
    char *buf;
415 d271de9f Gerd Hoffmann
    int i,len;
416 02e2da45 Paul Brook
417 ac7d1ba6 Anthony Liguori
    if (bus->name) {
418 d271de9f Gerd Hoffmann
        /* use supplied name */
419 ac7d1ba6 Anthony Liguori
    } else if (bus->parent && bus->parent->id) {
420 d271de9f Gerd Hoffmann
        /* parent device has id -> use it for bus name */
421 ac7d1ba6 Anthony Liguori
        len = strlen(bus->parent->id) + 16;
422 7267c094 Anthony Liguori
        buf = g_malloc(len);
423 ac7d1ba6 Anthony Liguori
        snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
424 d271de9f Gerd Hoffmann
        bus->name = buf;
425 d271de9f Gerd Hoffmann
    } else {
426 d271de9f Gerd Hoffmann
        /* no id -> use lowercase bus type for bus name */
427 0d936928 Anthony Liguori
        len = strlen(typename) + 16;
428 7267c094 Anthony Liguori
        buf = g_malloc(len);
429 0d936928 Anthony Liguori
        len = snprintf(buf, len, "%s.%d", typename,
430 ac7d1ba6 Anthony Liguori
                       bus->parent ? bus->parent->num_child_bus : 0);
431 d271de9f Gerd Hoffmann
        for (i = 0; i < len; i++)
432 bb87ece5 Christoph Egger
            buf[i] = qemu_tolower(buf[i]);
433 d271de9f Gerd Hoffmann
        bus->name = buf;
434 d271de9f Gerd Hoffmann
    }
435 d271de9f Gerd Hoffmann
436 ac7d1ba6 Anthony Liguori
    if (bus->parent) {
437 ac7d1ba6 Anthony Liguori
        QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
438 ac7d1ba6 Anthony Liguori
        bus->parent->num_child_bus++;
439 ac7d1ba6 Anthony Liguori
        object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
440 8185d216 Paolo Bonzini
    } else if (bus != sysbus_get_default()) {
441 80376c3f Isaku Yamahata
        /* TODO: once all bus devices are qdevified,
442 80376c3f Isaku Yamahata
           only reset handler for main_system_bus should be registered here. */
443 80376c3f Isaku Yamahata
        qemu_register_reset(qbus_reset_all_fn, bus);
444 02e2da45 Paul Brook
    }
445 cd739fb6 Gerd Hoffmann
}
446 cd739fb6 Gerd Hoffmann
447 0d936928 Anthony Liguori
void qbus_create_inplace(BusState *bus, const char *typename,
448 0d936928 Anthony Liguori
                         DeviceState *parent, const char *name)
449 cd739fb6 Gerd Hoffmann
{
450 0d936928 Anthony Liguori
    object_initialize(bus, typename);
451 cd739fb6 Gerd Hoffmann
452 ac7d1ba6 Anthony Liguori
    bus->parent = parent;
453 ac7d1ba6 Anthony Liguori
    bus->name = name ? g_strdup(name) : NULL;
454 ac7d1ba6 Anthony Liguori
    qbus_realize(bus);
455 02e2da45 Paul Brook
}
456 cae4956e Gerd Hoffmann
457 0d936928 Anthony Liguori
BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
458 2da8bb92 Isaku Yamahata
{
459 cd739fb6 Gerd Hoffmann
    BusState *bus;
460 cd739fb6 Gerd Hoffmann
461 0d936928 Anthony Liguori
    bus = BUS(object_new(typename));
462 0d936928 Anthony Liguori
    bus->qom_allocated = true;
463 ac7d1ba6 Anthony Liguori
464 ac7d1ba6 Anthony Liguori
    bus->parent = parent;
465 ac7d1ba6 Anthony Liguori
    bus->name = name ? g_strdup(name) : NULL;
466 ac7d1ba6 Anthony Liguori
    qbus_realize(bus);
467 ac7d1ba6 Anthony Liguori
468 02e2da45 Paul Brook
    return bus;
469 2da8bb92 Isaku Yamahata
}
470 2da8bb92 Isaku Yamahata
471 131ec1bd Gerd Hoffmann
void qbus_free(BusState *bus)
472 131ec1bd Gerd Hoffmann
{
473 0d936928 Anthony Liguori
    if (bus->qom_allocated) {
474 0d936928 Anthony Liguori
        object_delete(OBJECT(bus));
475 80376c3f Isaku Yamahata
    } else {
476 0d936928 Anthony Liguori
        object_finalize(OBJECT(bus));
477 0d936928 Anthony Liguori
        if (bus->glib_allocated) {
478 0d936928 Anthony Liguori
            g_free(bus);
479 0d936928 Anthony Liguori
        }
480 131ec1bd Gerd Hoffmann
    }
481 0d936928 Anthony Liguori
}
482 0d936928 Anthony Liguori
483 0d936928 Anthony Liguori
static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
484 0d936928 Anthony Liguori
{
485 0d936928 Anthony Liguori
    BusClass *bc = BUS_GET_CLASS(bus);
486 0d936928 Anthony Liguori
487 0d936928 Anthony Liguori
    if (bc->get_fw_dev_path) {
488 0d936928 Anthony Liguori
        return bc->get_fw_dev_path(dev);
489 131ec1bd Gerd Hoffmann
    }
490 0d936928 Anthony Liguori
491 0d936928 Anthony Liguori
    return NULL;
492 131ec1bd Gerd Hoffmann
}
493 131ec1bd Gerd Hoffmann
494 1ca4d09a Gleb Natapov
static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
495 1ca4d09a Gleb Natapov
{
496 1ca4d09a Gleb Natapov
    int l = 0;
497 1ca4d09a Gleb Natapov
498 1ca4d09a Gleb Natapov
    if (dev && dev->parent_bus) {
499 1ca4d09a Gleb Natapov
        char *d;
500 1ca4d09a Gleb Natapov
        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
501 0d936928 Anthony Liguori
        d = bus_get_fw_dev_path(dev->parent_bus, dev);
502 0d936928 Anthony Liguori
        if (d) {
503 1ca4d09a Gleb Natapov
            l += snprintf(p + l, size - l, "%s", d);
504 7267c094 Anthony Liguori
            g_free(d);
505 1ca4d09a Gleb Natapov
        } else {
506 f79f2bfc Anthony Liguori
            l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
507 1ca4d09a Gleb Natapov
        }
508 1ca4d09a Gleb Natapov
    }
509 1ca4d09a Gleb Natapov
    l += snprintf(p + l , size - l, "/");
510 1ca4d09a Gleb Natapov
511 1ca4d09a Gleb Natapov
    return l;
512 1ca4d09a Gleb Natapov
}
513 1ca4d09a Gleb Natapov
514 1ca4d09a Gleb Natapov
char* qdev_get_fw_dev_path(DeviceState *dev)
515 1ca4d09a Gleb Natapov
{
516 1ca4d09a Gleb Natapov
    char path[128];
517 1ca4d09a Gleb Natapov
    int l;
518 1ca4d09a Gleb Natapov
519 1ca4d09a Gleb Natapov
    l = qdev_get_fw_dev_path_helper(dev, path, 128);
520 1ca4d09a Gleb Natapov
521 1ca4d09a Gleb Natapov
    path[l-1] = '\0';
522 1ca4d09a Gleb Natapov
523 a5cf8262 Jim Meyering
    return g_strdup(path);
524 1ca4d09a Gleb Natapov
}
525 85ed303b Anthony Liguori
526 09e5ab63 Anthony Liguori
char *qdev_get_dev_path(DeviceState *dev)
527 85ed303b Anthony Liguori
{
528 0d936928 Anthony Liguori
    BusClass *bc;
529 09e5ab63 Anthony Liguori
530 09e5ab63 Anthony Liguori
    if (!dev || !dev->parent_bus) {
531 09e5ab63 Anthony Liguori
        return NULL;
532 09e5ab63 Anthony Liguori
    }
533 09e5ab63 Anthony Liguori
534 0d936928 Anthony Liguori
    bc = BUS_GET_CLASS(dev->parent_bus);
535 0d936928 Anthony Liguori
    if (bc->get_dev_path) {
536 0d936928 Anthony Liguori
        return bc->get_dev_path(dev);
537 09e5ab63 Anthony Liguori
    }
538 09e5ab63 Anthony Liguori
539 09e5ab63 Anthony Liguori
    return NULL;
540 44677ded Anthony Liguori
}
541 a5296ca9 Anthony Liguori
542 a5296ca9 Anthony Liguori
/**
543 a5296ca9 Anthony Liguori
 * Legacy property handling
544 a5296ca9 Anthony Liguori
 */
545 a5296ca9 Anthony Liguori
546 57c9fafe Anthony Liguori
static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
547 a5296ca9 Anthony Liguori
                                     const char *name, Error **errp)
548 a5296ca9 Anthony Liguori
{
549 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
550 a5296ca9 Anthony Liguori
    Property *prop = opaque;
551 a5296ca9 Anthony Liguori
552 e3cb6ba6 Paolo Bonzini
    char buffer[1024];
553 e3cb6ba6 Paolo Bonzini
    char *ptr = buffer;
554 a5296ca9 Anthony Liguori
555 e3cb6ba6 Paolo Bonzini
    prop->info->print(dev, prop, buffer, sizeof(buffer));
556 e3cb6ba6 Paolo Bonzini
    visit_type_str(v, &ptr, name, errp);
557 a5296ca9 Anthony Liguori
}
558 a5296ca9 Anthony Liguori
559 57c9fafe Anthony Liguori
static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
560 a5296ca9 Anthony Liguori
                                     const char *name, Error **errp)
561 a5296ca9 Anthony Liguori
{
562 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
563 a5296ca9 Anthony Liguori
    Property *prop = opaque;
564 e3cb6ba6 Paolo Bonzini
    Error *local_err = NULL;
565 e3cb6ba6 Paolo Bonzini
    char *ptr = NULL;
566 e3cb6ba6 Paolo Bonzini
    int ret;
567 a5296ca9 Anthony Liguori
568 a5296ca9 Anthony Liguori
    if (dev->state != DEV_STATE_CREATED) {
569 a5296ca9 Anthony Liguori
        error_set(errp, QERR_PERMISSION_DENIED);
570 a5296ca9 Anthony Liguori
        return;
571 a5296ca9 Anthony Liguori
    }
572 a5296ca9 Anthony Liguori
573 e3cb6ba6 Paolo Bonzini
    visit_type_str(v, &ptr, name, &local_err);
574 e3cb6ba6 Paolo Bonzini
    if (local_err) {
575 e3cb6ba6 Paolo Bonzini
        error_propagate(errp, local_err);
576 e3cb6ba6 Paolo Bonzini
        return;
577 e3cb6ba6 Paolo Bonzini
    }
578 a5296ca9 Anthony Liguori
579 e3cb6ba6 Paolo Bonzini
    ret = prop->info->parse(dev, prop, ptr);
580 7db4c4e8 Paolo Bonzini
    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
581 e3cb6ba6 Paolo Bonzini
    g_free(ptr);
582 a5296ca9 Anthony Liguori
}
583 a5296ca9 Anthony Liguori
584 a5296ca9 Anthony Liguori
/**
585 a5296ca9 Anthony Liguori
 * @qdev_add_legacy_property - adds a legacy property
586 a5296ca9 Anthony Liguori
 *
587 a5296ca9 Anthony Liguori
 * Do not use this is new code!  Properties added through this interface will
588 ca2cc788 Paolo Bonzini
 * be given names and types in the "legacy" namespace.
589 a5296ca9 Anthony Liguori
 *
590 68ee3569 Paolo Bonzini
 * Legacy properties are string versions of other OOM properties.  The format
591 68ee3569 Paolo Bonzini
 * of the string depends on the property type.
592 a5296ca9 Anthony Liguori
 */
593 a5296ca9 Anthony Liguori
void qdev_property_add_legacy(DeviceState *dev, Property *prop,
594 a5296ca9 Anthony Liguori
                              Error **errp)
595 a5296ca9 Anthony Liguori
{
596 ca2cc788 Paolo Bonzini
    gchar *name, *type;
597 a5296ca9 Anthony Liguori
598 f3be016d Anthony Liguori
    /* Register pointer properties as legacy properties */
599 f3be016d Anthony Liguori
    if (!prop->info->print && !prop->info->parse &&
600 f3be016d Anthony Liguori
        (prop->info->set || prop->info->get)) {
601 68ee3569 Paolo Bonzini
        return;
602 68ee3569 Paolo Bonzini
    }
603 f3be016d Anthony Liguori
604 ca2cc788 Paolo Bonzini
    name = g_strdup_printf("legacy-%s", prop->name);
605 cafe5bdb Paolo Bonzini
    type = g_strdup_printf("legacy<%s>",
606 cafe5bdb Paolo Bonzini
                           prop->info->legacy_name ?: prop->info->name);
607 a5296ca9 Anthony Liguori
608 57c9fafe Anthony Liguori
    object_property_add(OBJECT(dev), name, type,
609 68ee3569 Paolo Bonzini
                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
610 68ee3569 Paolo Bonzini
                        prop->info->parse ? qdev_set_legacy_property : prop->info->set,
611 57c9fafe Anthony Liguori
                        NULL,
612 57c9fafe Anthony Liguori
                        prop, errp);
613 a5296ca9 Anthony Liguori
614 a5296ca9 Anthony Liguori
    g_free(type);
615 ca2cc788 Paolo Bonzini
    g_free(name);
616 ca2cc788 Paolo Bonzini
}
617 ca2cc788 Paolo Bonzini
618 ca2cc788 Paolo Bonzini
/**
619 ca2cc788 Paolo Bonzini
 * @qdev_property_add_static - add a @Property to a device.
620 ca2cc788 Paolo Bonzini
 *
621 ca2cc788 Paolo Bonzini
 * Static properties access data in a struct.  The actual type of the
622 ca2cc788 Paolo Bonzini
 * property and the field depends on the property type.
623 ca2cc788 Paolo Bonzini
 */
624 ca2cc788 Paolo Bonzini
void qdev_property_add_static(DeviceState *dev, Property *prop,
625 ca2cc788 Paolo Bonzini
                              Error **errp)
626 ca2cc788 Paolo Bonzini
{
627 fdae245f Paolo Bonzini
    Error *local_err = NULL;
628 fdae245f Paolo Bonzini
    Object *obj = OBJECT(dev);
629 fdae245f Paolo Bonzini
630 d822979b Paolo Bonzini
    /*
631 d822979b Paolo Bonzini
     * TODO qdev_prop_ptr does not have getters or setters.  It must
632 d822979b Paolo Bonzini
     * go now that it can be replaced with links.  The test should be
633 d822979b Paolo Bonzini
     * removed along with it: all static properties are read/write.
634 d822979b Paolo Bonzini
     */
635 d822979b Paolo Bonzini
    if (!prop->info->get && !prop->info->set) {
636 d822979b Paolo Bonzini
        return;
637 d822979b Paolo Bonzini
    }
638 d822979b Paolo Bonzini
639 fdae245f Paolo Bonzini
    object_property_add(obj, prop->name, prop->info->name,
640 57c9fafe Anthony Liguori
                        prop->info->get, prop->info->set,
641 dd0ba250 Paolo Bonzini
                        prop->info->release,
642 fdae245f Paolo Bonzini
                        prop, &local_err);
643 fdae245f Paolo Bonzini
644 fdae245f Paolo Bonzini
    if (local_err) {
645 fdae245f Paolo Bonzini
        error_propagate(errp, local_err);
646 fdae245f Paolo Bonzini
        return;
647 fdae245f Paolo Bonzini
    }
648 fdae245f Paolo Bonzini
    if (prop->qtype == QTYPE_NONE) {
649 fdae245f Paolo Bonzini
        return;
650 fdae245f Paolo Bonzini
    }
651 fdae245f Paolo Bonzini
652 fdae245f Paolo Bonzini
    if (prop->qtype == QTYPE_QBOOL) {
653 fdae245f Paolo Bonzini
        object_property_set_bool(obj, prop->defval, prop->name, &local_err);
654 fdae245f Paolo Bonzini
    } else if (prop->info->enum_table) {
655 fdae245f Paolo Bonzini
        object_property_set_str(obj, prop->info->enum_table[prop->defval],
656 fdae245f Paolo Bonzini
                                prop->name, &local_err);
657 fdae245f Paolo Bonzini
    } else if (prop->qtype == QTYPE_QINT) {
658 fdae245f Paolo Bonzini
        object_property_set_int(obj, prop->defval, prop->name, &local_err);
659 fdae245f Paolo Bonzini
    }
660 fdae245f Paolo Bonzini
    assert_no_error(local_err);
661 6a146eba Anthony Liguori
}
662 1de81d28 Anthony Liguori
663 9674bfe4 Anthony Liguori
static void device_initfn(Object *obj)
664 9674bfe4 Anthony Liguori
{
665 9674bfe4 Anthony Liguori
    DeviceState *dev = DEVICE(obj);
666 bce54474 Paolo Bonzini
    ObjectClass *class;
667 9674bfe4 Anthony Liguori
    Property *prop;
668 9674bfe4 Anthony Liguori
669 9674bfe4 Anthony Liguori
    if (qdev_hotplug) {
670 9674bfe4 Anthony Liguori
        dev->hotplugged = 1;
671 9674bfe4 Anthony Liguori
        qdev_hot_added = true;
672 9674bfe4 Anthony Liguori
    }
673 9674bfe4 Anthony Liguori
674 9674bfe4 Anthony Liguori
    dev->instance_id_alias = -1;
675 9674bfe4 Anthony Liguori
    dev->state = DEV_STATE_CREATED;
676 9674bfe4 Anthony Liguori
677 bce54474 Paolo Bonzini
    class = object_get_class(OBJECT(dev));
678 bce54474 Paolo Bonzini
    do {
679 bce54474 Paolo Bonzini
        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
680 bce54474 Paolo Bonzini
            qdev_property_add_legacy(dev, prop, NULL);
681 bce54474 Paolo Bonzini
            qdev_property_add_static(dev, prop, NULL);
682 bce54474 Paolo Bonzini
        }
683 bce54474 Paolo Bonzini
        class = object_class_get_parent(class);
684 bce54474 Paolo Bonzini
    } while (class != object_class_by_name(TYPE_DEVICE));
685 4b3582b0 Paolo Bonzini
    qdev_prop_set_globals(dev);
686 9674bfe4 Anthony Liguori
687 f968fc68 Anthony Liguori
    object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
688 f968fc68 Anthony Liguori
                             (Object **)&dev->parent_bus, NULL);
689 9674bfe4 Anthony Liguori
}
690 9674bfe4 Anthony Liguori
691 60adba37 Anthony Liguori
/* Unlink device from bus and free the structure.  */
692 60adba37 Anthony Liguori
static void device_finalize(Object *obj)
693 60adba37 Anthony Liguori
{
694 60adba37 Anthony Liguori
    DeviceState *dev = DEVICE(obj);
695 60adba37 Anthony Liguori
    BusState *bus;
696 60adba37 Anthony Liguori
    DeviceClass *dc = DEVICE_GET_CLASS(dev);
697 60adba37 Anthony Liguori
698 60adba37 Anthony Liguori
    if (dev->state == DEV_STATE_INITIALIZED) {
699 60adba37 Anthony Liguori
        while (dev->num_child_bus) {
700 60adba37 Anthony Liguori
            bus = QLIST_FIRST(&dev->child_bus);
701 60adba37 Anthony Liguori
            qbus_free(bus);
702 60adba37 Anthony Liguori
        }
703 60adba37 Anthony Liguori
        if (qdev_get_vmsd(dev)) {
704 60adba37 Anthony Liguori
            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
705 60adba37 Anthony Liguori
        }
706 60adba37 Anthony Liguori
        if (dc->exit) {
707 60adba37 Anthony Liguori
            dc->exit(dev);
708 60adba37 Anthony Liguori
        }
709 60adba37 Anthony Liguori
        if (dev->opts) {
710 60adba37 Anthony Liguori
            qemu_opts_del(dev->opts);
711 60adba37 Anthony Liguori
        }
712 60adba37 Anthony Liguori
    }
713 0866aca1 Anthony Liguori
    if (dev->parent_bus) {
714 0866aca1 Anthony Liguori
        bus_remove_child(dev->parent_bus, dev);
715 0866aca1 Anthony Liguori
    }
716 60adba37 Anthony Liguori
}
717 60adba37 Anthony Liguori
718 bce54474 Paolo Bonzini
static void device_class_base_init(ObjectClass *class, void *data)
719 bce54474 Paolo Bonzini
{
720 bce54474 Paolo Bonzini
    DeviceClass *klass = DEVICE_CLASS(class);
721 bce54474 Paolo Bonzini
722 bce54474 Paolo Bonzini
    /* We explicitly look up properties in the superclasses,
723 bce54474 Paolo Bonzini
     * so do not propagate them to the subclasses.
724 bce54474 Paolo Bonzini
     */
725 bce54474 Paolo Bonzini
    klass->props = NULL;
726 60adba37 Anthony Liguori
}
727 60adba37 Anthony Liguori
728 94afdadc Anthony Liguori
void device_reset(DeviceState *dev)
729 94afdadc Anthony Liguori
{
730 94afdadc Anthony Liguori
    DeviceClass *klass = DEVICE_GET_CLASS(dev);
731 94afdadc Anthony Liguori
732 94afdadc Anthony Liguori
    if (klass->reset) {
733 94afdadc Anthony Liguori
        klass->reset(dev);
734 94afdadc Anthony Liguori
    }
735 94afdadc Anthony Liguori
}
736 94afdadc Anthony Liguori
737 f05f6b4a Paolo Bonzini
Object *qdev_get_machine(void)
738 f05f6b4a Paolo Bonzini
{
739 f05f6b4a Paolo Bonzini
    static Object *dev;
740 f05f6b4a Paolo Bonzini
741 f05f6b4a Paolo Bonzini
    if (dev == NULL) {
742 dfe47e70 Andreas Färber
        dev = container_get(object_get_root(), "/machine");
743 f05f6b4a Paolo Bonzini
    }
744 f05f6b4a Paolo Bonzini
745 f05f6b4a Paolo Bonzini
    return dev;
746 f05f6b4a Paolo Bonzini
}
747 f05f6b4a Paolo Bonzini
748 32fea402 Anthony Liguori
static TypeInfo device_type_info = {
749 32fea402 Anthony Liguori
    .name = TYPE_DEVICE,
750 32fea402 Anthony Liguori
    .parent = TYPE_OBJECT,
751 32fea402 Anthony Liguori
    .instance_size = sizeof(DeviceState),
752 9674bfe4 Anthony Liguori
    .instance_init = device_initfn,
753 60adba37 Anthony Liguori
    .instance_finalize = device_finalize,
754 bce54474 Paolo Bonzini
    .class_base_init = device_class_base_init,
755 32fea402 Anthony Liguori
    .abstract = true,
756 32fea402 Anthony Liguori
    .class_size = sizeof(DeviceClass),
757 32fea402 Anthony Liguori
};
758 32fea402 Anthony Liguori
759 ac7d1ba6 Anthony Liguori
static void qbus_initfn(Object *obj)
760 ac7d1ba6 Anthony Liguori
{
761 ac7d1ba6 Anthony Liguori
    BusState *bus = BUS(obj);
762 ac7d1ba6 Anthony Liguori
763 ac7d1ba6 Anthony Liguori
    QTAILQ_INIT(&bus->children);
764 ac7d1ba6 Anthony Liguori
}
765 ac7d1ba6 Anthony Liguori
766 ac7d1ba6 Anthony Liguori
static void qbus_finalize(Object *obj)
767 ac7d1ba6 Anthony Liguori
{
768 ac7d1ba6 Anthony Liguori
    BusState *bus = BUS(obj);
769 ac7d1ba6 Anthony Liguori
    BusChild *kid;
770 ac7d1ba6 Anthony Liguori
771 ac7d1ba6 Anthony Liguori
    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
772 ac7d1ba6 Anthony Liguori
        DeviceState *dev = kid->child;
773 ac7d1ba6 Anthony Liguori
        qdev_free(dev);
774 ac7d1ba6 Anthony Liguori
    }
775 ac7d1ba6 Anthony Liguori
    if (bus->parent) {
776 ac7d1ba6 Anthony Liguori
        QLIST_REMOVE(bus, sibling);
777 ac7d1ba6 Anthony Liguori
        bus->parent->num_child_bus--;
778 ac7d1ba6 Anthony Liguori
    } else {
779 ac7d1ba6 Anthony Liguori
        assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
780 ac7d1ba6 Anthony Liguori
        qemu_unregister_reset(qbus_reset_all_fn, bus);
781 ac7d1ba6 Anthony Liguori
    }
782 ac7d1ba6 Anthony Liguori
    g_free((char *)bus->name);
783 ac7d1ba6 Anthony Liguori
}
784 ac7d1ba6 Anthony Liguori
785 0d936928 Anthony Liguori
static const TypeInfo bus_info = {
786 0d936928 Anthony Liguori
    .name = TYPE_BUS,
787 0d936928 Anthony Liguori
    .parent = TYPE_OBJECT,
788 0d936928 Anthony Liguori
    .instance_size = sizeof(BusState),
789 0d936928 Anthony Liguori
    .abstract = true,
790 0d936928 Anthony Liguori
    .class_size = sizeof(BusClass),
791 ac7d1ba6 Anthony Liguori
    .instance_init = qbus_initfn,
792 ac7d1ba6 Anthony Liguori
    .instance_finalize = qbus_finalize,
793 0d936928 Anthony Liguori
};
794 0d936928 Anthony Liguori
795 83f7d43a Andreas Färber
static void qdev_register_types(void)
796 32fea402 Anthony Liguori
{
797 0d936928 Anthony Liguori
    type_register_static(&bus_info);
798 32fea402 Anthony Liguori
    type_register_static(&device_type_info);
799 32fea402 Anthony Liguori
}
800 32fea402 Anthony Liguori
801 83f7d43a Andreas Färber
type_init(qdev_register_types)