Statistics
| Branch: | Revision:

root / hw / qdev.c @ 15d7dc4f

History | View | Annotate | Download (24.2 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 cae4956e Gerd Hoffmann
#include "monitor.h"
32 aae9460e Paul Brook
33 3418bd25 Gerd Hoffmann
static int qdev_hotplug = 0;
34 0ac8ef71 Alex Williamson
static bool qdev_hot_added = false;
35 0ac8ef71 Alex Williamson
static bool qdev_hot_removed = false;
36 3418bd25 Gerd Hoffmann
37 cdaed7c7 Gerd Hoffmann
/* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
38 b9aaf7f8 Blue Swirl
static BusState *main_system_bus;
39 4d6ae674 Paul Brook
40 0958b4cc Gerd Hoffmann
DeviceInfo *device_info_list;
41 aae9460e Paul Brook
42 8ffb1bcf Gerd Hoffmann
static BusState *qbus_find_recursive(BusState *bus, const char *name,
43 8ffb1bcf Gerd Hoffmann
                                     const BusInfo *info);
44 8ffb1bcf Gerd Hoffmann
static BusState *qbus_find(const char *path);
45 8ffb1bcf Gerd Hoffmann
46 aae9460e Paul Brook
/* Register a new device type.  */
47 074f2fff Gerd Hoffmann
void qdev_register(DeviceInfo *info)
48 aae9460e Paul Brook
{
49 074f2fff Gerd Hoffmann
    assert(info->size >= sizeof(DeviceState));
50 042f84d0 Gerd Hoffmann
    assert(!info->next);
51 aae9460e Paul Brook
52 042f84d0 Gerd Hoffmann
    info->next = device_info_list;
53 042f84d0 Gerd Hoffmann
    device_info_list = info;
54 aae9460e Paul Brook
}
55 aae9460e Paul Brook
56 81ebb98b Gerd Hoffmann
static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
57 81ebb98b Gerd Hoffmann
{
58 81ebb98b Gerd Hoffmann
    DeviceInfo *info;
59 81ebb98b Gerd Hoffmann
60 3320e56e Gerd Hoffmann
    /* first check device names */
61 81ebb98b Gerd Hoffmann
    for (info = device_info_list; info != NULL; info = info->next) {
62 81ebb98b Gerd Hoffmann
        if (bus_info && info->bus_info != bus_info)
63 81ebb98b Gerd Hoffmann
            continue;
64 81ebb98b Gerd Hoffmann
        if (strcmp(info->name, name) != 0)
65 81ebb98b Gerd Hoffmann
            continue;
66 81ebb98b Gerd Hoffmann
        return info;
67 81ebb98b Gerd Hoffmann
    }
68 3320e56e Gerd Hoffmann
69 3320e56e Gerd Hoffmann
    /* failing that check the aliases */
70 3320e56e Gerd Hoffmann
    for (info = device_info_list; info != NULL; info = info->next) {
71 3320e56e Gerd Hoffmann
        if (bus_info && info->bus_info != bus_info)
72 3320e56e Gerd Hoffmann
            continue;
73 3320e56e Gerd Hoffmann
        if (!info->alias)
74 3320e56e Gerd Hoffmann
            continue;
75 3320e56e Gerd Hoffmann
        if (strcmp(info->alias, name) != 0)
76 3320e56e Gerd Hoffmann
            continue;
77 3320e56e Gerd Hoffmann
        return info;
78 3320e56e Gerd Hoffmann
    }
79 81ebb98b Gerd Hoffmann
    return NULL;
80 81ebb98b Gerd Hoffmann
}
81 81ebb98b Gerd Hoffmann
82 0c17542d Markus Armbruster
static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
83 0c17542d Markus Armbruster
{
84 0c17542d Markus Armbruster
    DeviceState *dev;
85 0c17542d Markus Armbruster
86 0c17542d Markus Armbruster
    assert(bus->info == info->bus_info);
87 0c17542d Markus Armbruster
    dev = qemu_mallocz(info->size);
88 0c17542d Markus Armbruster
    dev->info = info;
89 0c17542d Markus Armbruster
    dev->parent_bus = bus;
90 0c17542d Markus Armbruster
    qdev_prop_set_defaults(dev, dev->info->props);
91 0c17542d Markus Armbruster
    qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
92 0c17542d Markus Armbruster
    qdev_prop_set_globals(dev);
93 0c17542d Markus Armbruster
    QLIST_INSERT_HEAD(&bus->children, dev, sibling);
94 0c17542d Markus Armbruster
    if (qdev_hotplug) {
95 0c17542d Markus Armbruster
        assert(bus->allow_hotplug);
96 0c17542d Markus Armbruster
        dev->hotplugged = 1;
97 0ac8ef71 Alex Williamson
        qdev_hot_added = true;
98 0c17542d Markus Armbruster
    }
99 4d2ffa08 Jan Kiszka
    dev->instance_id_alias = -1;
100 0c17542d Markus Armbruster
    dev->state = DEV_STATE_CREATED;
101 0c17542d Markus Armbruster
    return dev;
102 0c17542d Markus Armbruster
}
103 0c17542d Markus Armbruster
104 aae9460e Paul Brook
/* Create a new device.  This only initializes the device state structure
105 aae9460e Paul Brook
   and allows properties to be set.  qdev_init should be called to
106 aae9460e Paul Brook
   initialize the actual device emulation.  */
107 02e2da45 Paul Brook
DeviceState *qdev_create(BusState *bus, const char *name)
108 aae9460e Paul Brook
{
109 0bcdeda7 Blue Swirl
    DeviceState *dev;
110 0bcdeda7 Blue Swirl
111 0bcdeda7 Blue Swirl
    dev = qdev_try_create(bus, name);
112 0bcdeda7 Blue Swirl
    if (!dev) {
113 0bcdeda7 Blue Swirl
        hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
114 0bcdeda7 Blue Swirl
    }
115 0bcdeda7 Blue Swirl
116 0bcdeda7 Blue Swirl
    return dev;
117 0bcdeda7 Blue Swirl
}
118 0bcdeda7 Blue Swirl
119 0bcdeda7 Blue Swirl
DeviceState *qdev_try_create(BusState *bus, const char *name)
120 0bcdeda7 Blue Swirl
{
121 042f84d0 Gerd Hoffmann
    DeviceInfo *info;
122 aae9460e Paul Brook
123 10c4c98a Gerd Hoffmann
    if (!bus) {
124 68694897 Stefan Weil
        bus = sysbus_get_default();
125 10c4c98a Gerd Hoffmann
    }
126 10c4c98a Gerd Hoffmann
127 81ebb98b Gerd Hoffmann
    info = qdev_find_info(bus->info, name);
128 042f84d0 Gerd Hoffmann
    if (!info) {
129 0bcdeda7 Blue Swirl
        return NULL;
130 aae9460e Paul Brook
    }
131 aae9460e Paul Brook
132 0c17542d Markus Armbruster
    return qdev_create_from_info(bus, info);
133 aae9460e Paul Brook
}
134 aae9460e Paul Brook
135 8a9662ca Markus Armbruster
static void qdev_print_devinfo(DeviceInfo *info)
136 1b524b04 Gerd Hoffmann
{
137 8a9662ca Markus Armbruster
    error_printf("name \"%s\", bus %s",
138 8a9662ca Markus Armbruster
                 info->name, info->bus_info->name);
139 22f2e344 Gerd Hoffmann
    if (info->alias) {
140 8a9662ca Markus Armbruster
        error_printf(", alias \"%s\"", info->alias);
141 22f2e344 Gerd Hoffmann
    }
142 22f2e344 Gerd Hoffmann
    if (info->desc) {
143 8a9662ca Markus Armbruster
        error_printf(", desc \"%s\"", info->desc);
144 22f2e344 Gerd Hoffmann
    }
145 22f2e344 Gerd Hoffmann
    if (info->no_user) {
146 8a9662ca Markus Armbruster
        error_printf(", no-user");
147 22f2e344 Gerd Hoffmann
    }
148 8a9662ca Markus Armbruster
    error_printf("\n");
149 1b524b04 Gerd Hoffmann
}
150 1b524b04 Gerd Hoffmann
151 f31d07d1 Gerd Hoffmann
static int set_property(const char *name, const char *value, void *opaque)
152 8ffb1bcf Gerd Hoffmann
{
153 f31d07d1 Gerd Hoffmann
    DeviceState *dev = opaque;
154 f31d07d1 Gerd Hoffmann
155 f31d07d1 Gerd Hoffmann
    if (strcmp(name, "driver") == 0)
156 f31d07d1 Gerd Hoffmann
        return 0;
157 f31d07d1 Gerd Hoffmann
    if (strcmp(name, "bus") == 0)
158 f31d07d1 Gerd Hoffmann
        return 0;
159 f31d07d1 Gerd Hoffmann
160 3df04ac3 Mark McLoughlin
    if (qdev_prop_parse(dev, name, value) == -1) {
161 f31d07d1 Gerd Hoffmann
        return -1;
162 f31d07d1 Gerd Hoffmann
    }
163 f31d07d1 Gerd Hoffmann
    return 0;
164 f31d07d1 Gerd Hoffmann
}
165 f31d07d1 Gerd Hoffmann
166 ff952ba2 Markus Armbruster
int qdev_device_help(QemuOpts *opts)
167 ff952ba2 Markus Armbruster
{
168 ff952ba2 Markus Armbruster
    const char *driver;
169 ff952ba2 Markus Armbruster
    DeviceInfo *info;
170 08350cf0 Markus Armbruster
    Property *prop;
171 ff952ba2 Markus Armbruster
172 ff952ba2 Markus Armbruster
    driver = qemu_opt_get(opts, "driver");
173 ff952ba2 Markus Armbruster
    if (driver && !strcmp(driver, "?")) {
174 ff952ba2 Markus Armbruster
        for (info = device_info_list; info != NULL; info = info->next) {
175 c64eafaf Markus Armbruster
            if (info->no_user) {
176 c64eafaf Markus Armbruster
                continue;       /* not available, don't show */
177 c64eafaf Markus Armbruster
            }
178 8a9662ca Markus Armbruster
            qdev_print_devinfo(info);
179 ff952ba2 Markus Armbruster
        }
180 ff952ba2 Markus Armbruster
        return 1;
181 ff952ba2 Markus Armbruster
    }
182 ff952ba2 Markus Armbruster
183 08350cf0 Markus Armbruster
    if (!qemu_opt_get(opts, "?")) {
184 08350cf0 Markus Armbruster
        return 0;
185 08350cf0 Markus Armbruster
    }
186 08350cf0 Markus Armbruster
187 08350cf0 Markus Armbruster
    info = qdev_find_info(NULL, driver);
188 08350cf0 Markus Armbruster
    if (!info) {
189 08350cf0 Markus Armbruster
        return 0;
190 08350cf0 Markus Armbruster
    }
191 08350cf0 Markus Armbruster
192 08350cf0 Markus Armbruster
    for (prop = info->props; prop && prop->name; prop++) {
193 036f7166 Markus Armbruster
        /*
194 036f7166 Markus Armbruster
         * TODO Properties without a parser are just for dirty hacks.
195 036f7166 Markus Armbruster
         * qdev_prop_ptr is the only such PropertyInfo.  It's marked
196 036f7166 Markus Armbruster
         * for removal.  This conditional should be removed along with
197 036f7166 Markus Armbruster
         * it.
198 036f7166 Markus Armbruster
         */
199 036f7166 Markus Armbruster
        if (!prop->info->parse) {
200 036f7166 Markus Armbruster
            continue;           /* no way to set it, don't show */
201 036f7166 Markus Armbruster
        }
202 8a9662ca Markus Armbruster
        error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
203 08350cf0 Markus Armbruster
    }
204 08350cf0 Markus Armbruster
    return 1;
205 ff952ba2 Markus Armbruster
}
206 ff952ba2 Markus Armbruster
207 f31d07d1 Gerd Hoffmann
DeviceState *qdev_device_add(QemuOpts *opts)
208 f31d07d1 Gerd Hoffmann
{
209 f31d07d1 Gerd Hoffmann
    const char *driver, *path, *id;
210 8ffb1bcf Gerd Hoffmann
    DeviceInfo *info;
211 8ffb1bcf Gerd Hoffmann
    DeviceState *qdev;
212 8ffb1bcf Gerd Hoffmann
    BusState *bus;
213 8ffb1bcf Gerd Hoffmann
214 f31d07d1 Gerd Hoffmann
    driver = qemu_opt_get(opts, "driver");
215 f31d07d1 Gerd Hoffmann
    if (!driver) {
216 0204276b Markus Armbruster
        qerror_report(QERR_MISSING_PARAMETER, "driver");
217 8ffb1bcf Gerd Hoffmann
        return NULL;
218 8ffb1bcf Gerd Hoffmann
    }
219 f31d07d1 Gerd Hoffmann
220 f31d07d1 Gerd Hoffmann
    /* find driver */
221 8ffb1bcf Gerd Hoffmann
    info = qdev_find_info(NULL, driver);
222 c64eafaf Markus Armbruster
    if (!info || info->no_user) {
223 e17ba87c Markus Armbruster
        qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
224 0204276b Markus Armbruster
        error_printf_unless_qmp("Try with argument '?' for a list.\n");
225 8ffb1bcf Gerd Hoffmann
        return NULL;
226 8ffb1bcf Gerd Hoffmann
    }
227 8ffb1bcf Gerd Hoffmann
228 f31d07d1 Gerd Hoffmann
    /* find bus */
229 f31d07d1 Gerd Hoffmann
    path = qemu_opt_get(opts, "bus");
230 f31d07d1 Gerd Hoffmann
    if (path != NULL) {
231 8ffb1bcf Gerd Hoffmann
        bus = qbus_find(path);
232 ac8dae67 Markus Armbruster
        if (!bus) {
233 ac8dae67 Markus Armbruster
            return NULL;
234 ac8dae67 Markus Armbruster
        }
235 ac8dae67 Markus Armbruster
        if (bus->info != info->bus_info) {
236 0204276b Markus Armbruster
            qerror_report(QERR_BAD_BUS_FOR_DEVICE,
237 0204276b Markus Armbruster
                           driver, bus->info->name);
238 327867b6 Markus Armbruster
            return NULL;
239 327867b6 Markus Armbruster
        }
240 8ffb1bcf Gerd Hoffmann
    } else {
241 8ffb1bcf Gerd Hoffmann
        bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
242 ac8dae67 Markus Armbruster
        if (!bus) {
243 0204276b Markus Armbruster
            qerror_report(QERR_NO_BUS_FOR_DEVICE,
244 0204276b Markus Armbruster
                           info->name, info->bus_info->name);
245 ac8dae67 Markus Armbruster
            return NULL;
246 ac8dae67 Markus Armbruster
        }
247 75570088 Gerd Hoffmann
    }
248 3418bd25 Gerd Hoffmann
    if (qdev_hotplug && !bus->allow_hotplug) {
249 0204276b Markus Armbruster
        qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
250 3418bd25 Gerd Hoffmann
        return NULL;
251 3418bd25 Gerd Hoffmann
    }
252 8ffb1bcf Gerd Hoffmann
253 f31d07d1 Gerd Hoffmann
    /* create device, set properties */
254 0c17542d Markus Armbruster
    qdev = qdev_create_from_info(bus, info);
255 f31d07d1 Gerd Hoffmann
    id = qemu_opts_id(opts);
256 f31d07d1 Gerd Hoffmann
    if (id) {
257 f31d07d1 Gerd Hoffmann
        qdev->id = id;
258 f31d07d1 Gerd Hoffmann
    }
259 f31d07d1 Gerd Hoffmann
    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
260 f31d07d1 Gerd Hoffmann
        qdev_free(qdev);
261 f31d07d1 Gerd Hoffmann
        return NULL;
262 8ffb1bcf Gerd Hoffmann
    }
263 5c17ca25 Markus Armbruster
    if (qdev_init(qdev) < 0) {
264 0204276b Markus Armbruster
        qerror_report(QERR_DEVICE_INIT_FAILED, driver);
265 81a322d4 Gerd Hoffmann
        return NULL;
266 81a322d4 Gerd Hoffmann
    }
267 ef80b466 Gerd Hoffmann
    qdev->opts = opts;
268 8ffb1bcf Gerd Hoffmann
    return qdev;
269 8ffb1bcf Gerd Hoffmann
}
270 8ffb1bcf Gerd Hoffmann
271 aae9460e Paul Brook
/* Initialize a device.  Device properties should be set before calling
272 aae9460e Paul Brook
   this function.  IRQs and MMIO regions should be connected/mapped after
273 18cfeb52 Markus Armbruster
   calling this function.
274 18cfeb52 Markus Armbruster
   On failure, destroy the device and return negative value.
275 18cfeb52 Markus Armbruster
   Return 0 on success.  */
276 81a322d4 Gerd Hoffmann
int qdev_init(DeviceState *dev)
277 aae9460e Paul Brook
{
278 959f733a Gerd Hoffmann
    int rc;
279 959f733a Gerd Hoffmann
280 131ec1bd Gerd Hoffmann
    assert(dev->state == DEV_STATE_CREATED);
281 959f733a Gerd Hoffmann
    rc = dev->info->init(dev, dev->info);
282 18cfeb52 Markus Armbruster
    if (rc < 0) {
283 18cfeb52 Markus Armbruster
        qdev_free(dev);
284 959f733a Gerd Hoffmann
        return rc;
285 18cfeb52 Markus Armbruster
    }
286 4d2ffa08 Jan Kiszka
    if (dev->info->vmsd) {
287 0be71e32 Alex Williamson
        vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
288 4d2ffa08 Jan Kiszka
                                       dev->instance_id_alias,
289 4d2ffa08 Jan Kiszka
                                       dev->alias_required_for_version);
290 4d2ffa08 Jan Kiszka
    }
291 131ec1bd Gerd Hoffmann
    dev->state = DEV_STATE_INITIALIZED;
292 959f733a Gerd Hoffmann
    return 0;
293 02e2da45 Paul Brook
}
294 02e2da45 Paul Brook
295 4d2ffa08 Jan Kiszka
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
296 4d2ffa08 Jan Kiszka
                                 int required_for_version)
297 4d2ffa08 Jan Kiszka
{
298 4d2ffa08 Jan Kiszka
    assert(dev->state == DEV_STATE_CREATED);
299 4d2ffa08 Jan Kiszka
    dev->instance_id_alias = alias_id;
300 4d2ffa08 Jan Kiszka
    dev->alias_required_for_version = required_for_version;
301 4d2ffa08 Jan Kiszka
}
302 4d2ffa08 Jan Kiszka
303 3418bd25 Gerd Hoffmann
int qdev_unplug(DeviceState *dev)
304 3418bd25 Gerd Hoffmann
{
305 3418bd25 Gerd Hoffmann
    if (!dev->parent_bus->allow_hotplug) {
306 cc601cb7 Markus Armbruster
        qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
307 3418bd25 Gerd Hoffmann
        return -1;
308 3418bd25 Gerd Hoffmann
    }
309 593831de Amit Shah
    assert(dev->info->unplug != NULL);
310 593831de Amit Shah
311 0ac8ef71 Alex Williamson
    qdev_hot_removed = true;
312 0ac8ef71 Alex Williamson
313 3418bd25 Gerd Hoffmann
    return dev->info->unplug(dev);
314 3418bd25 Gerd Hoffmann
}
315 3418bd25 Gerd Hoffmann
316 ec990eb6 Anthony Liguori
static int qdev_reset_one(DeviceState *dev, void *opaque)
317 ec990eb6 Anthony Liguori
{
318 ec990eb6 Anthony Liguori
    if (dev->info->reset) {
319 ec990eb6 Anthony Liguori
        dev->info->reset(dev);
320 ec990eb6 Anthony Liguori
    }
321 ec990eb6 Anthony Liguori
322 ec990eb6 Anthony Liguori
    return 0;
323 ec990eb6 Anthony Liguori
}
324 ec990eb6 Anthony Liguori
325 ec990eb6 Anthony Liguori
BusState *sysbus_get_default(void)
326 ec990eb6 Anthony Liguori
{
327 68694897 Stefan Weil
    if (!main_system_bus) {
328 68694897 Stefan Weil
        main_system_bus = qbus_create(&system_bus_info, NULL,
329 68694897 Stefan Weil
                                      "main-system-bus");
330 68694897 Stefan Weil
    }
331 ec990eb6 Anthony Liguori
    return main_system_bus;
332 ec990eb6 Anthony Liguori
}
333 ec990eb6 Anthony Liguori
334 b4694b7c Isaku Yamahata
static int qbus_reset_one(BusState *bus, void *opaque)
335 b4694b7c Isaku Yamahata
{
336 b4694b7c Isaku Yamahata
    if (bus->info->reset) {
337 b4694b7c Isaku Yamahata
        return bus->info->reset(bus);
338 b4694b7c Isaku Yamahata
    }
339 b4694b7c Isaku Yamahata
    return 0;
340 b4694b7c Isaku Yamahata
}
341 b4694b7c Isaku Yamahata
342 5af0a04b Isaku Yamahata
void qdev_reset_all(DeviceState *dev)
343 5af0a04b Isaku Yamahata
{
344 5af0a04b Isaku Yamahata
    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
345 5af0a04b Isaku Yamahata
}
346 5af0a04b Isaku Yamahata
347 80376c3f Isaku Yamahata
void qbus_reset_all_fn(void *opaque)
348 80376c3f Isaku Yamahata
{
349 80376c3f Isaku Yamahata
    BusState *bus = opaque;
350 f530cce3 Michael S. Tsirkin
    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
351 80376c3f Isaku Yamahata
}
352 80376c3f Isaku Yamahata
353 3418bd25 Gerd Hoffmann
/* can be used as ->unplug() callback for the simple cases */
354 3418bd25 Gerd Hoffmann
int qdev_simple_unplug_cb(DeviceState *dev)
355 3418bd25 Gerd Hoffmann
{
356 3418bd25 Gerd Hoffmann
    /* just zap it */
357 3418bd25 Gerd Hoffmann
    qdev_free(dev);
358 3418bd25 Gerd Hoffmann
    return 0;
359 3418bd25 Gerd Hoffmann
}
360 3418bd25 Gerd Hoffmann
361 e23a1b33 Markus Armbruster
/* Like qdev_init(), but terminate program via hw_error() instead of
362 e23a1b33 Markus Armbruster
   returning an error value.  This is okay during machine creation.
363 e23a1b33 Markus Armbruster
   Don't use for hotplug, because there callers need to recover from
364 e23a1b33 Markus Armbruster
   failure.  Exception: if you know the device's init() callback can't
365 e23a1b33 Markus Armbruster
   fail, then qdev_init_nofail() can't fail either, and is therefore
366 e23a1b33 Markus Armbruster
   usable even then.  But relying on the device implementation that
367 e23a1b33 Markus Armbruster
   way is somewhat unclean, and best avoided.  */
368 e23a1b33 Markus Armbruster
void qdev_init_nofail(DeviceState *dev)
369 e23a1b33 Markus Armbruster
{
370 e23a1b33 Markus Armbruster
    DeviceInfo *info = dev->info;
371 e23a1b33 Markus Armbruster
372 bd6c9a61 Markus Armbruster
    if (qdev_init(dev) < 0) {
373 bd6c9a61 Markus Armbruster
        error_report("Initialization of device %s failed\n", info->name);
374 bd6c9a61 Markus Armbruster
        exit(1);
375 bd6c9a61 Markus Armbruster
    }
376 e23a1b33 Markus Armbruster
}
377 e23a1b33 Markus Armbruster
378 02e2da45 Paul Brook
/* Unlink device from bus and free the structure.  */
379 02e2da45 Paul Brook
void qdev_free(DeviceState *dev)
380 02e2da45 Paul Brook
{
381 131ec1bd Gerd Hoffmann
    BusState *bus;
382 d21357df Markus Armbruster
    Property *prop;
383 131ec1bd Gerd Hoffmann
384 131ec1bd Gerd Hoffmann
    if (dev->state == DEV_STATE_INITIALIZED) {
385 131ec1bd Gerd Hoffmann
        while (dev->num_child_bus) {
386 131ec1bd Gerd Hoffmann
            bus = QLIST_FIRST(&dev->child_bus);
387 131ec1bd Gerd Hoffmann
            qbus_free(bus);
388 131ec1bd Gerd Hoffmann
        }
389 131ec1bd Gerd Hoffmann
        if (dev->info->vmsd)
390 0be71e32 Alex Williamson
            vmstate_unregister(dev, dev->info->vmsd, dev);
391 d29275f1 Gerd Hoffmann
        if (dev->info->exit)
392 d29275f1 Gerd Hoffmann
            dev->info->exit(dev);
393 ef80b466 Gerd Hoffmann
        if (dev->opts)
394 ef80b466 Gerd Hoffmann
            qemu_opts_del(dev->opts);
395 131ec1bd Gerd Hoffmann
    }
396 72cf2d4f Blue Swirl
    QLIST_REMOVE(dev, sibling);
397 d21357df Markus Armbruster
    for (prop = dev->info->props; prop && prop->name; prop++) {
398 d21357df Markus Armbruster
        if (prop->info->free) {
399 d21357df Markus Armbruster
            prop->info->free(dev, prop);
400 d21357df Markus Armbruster
        }
401 d21357df Markus Armbruster
    }
402 ccb63de3 Gerd Hoffmann
    qemu_free(dev);
403 aae9460e Paul Brook
}
404 aae9460e Paul Brook
405 3418bd25 Gerd Hoffmann
void qdev_machine_creation_done(void)
406 3418bd25 Gerd Hoffmann
{
407 3418bd25 Gerd Hoffmann
    /*
408 3418bd25 Gerd Hoffmann
     * ok, initial machine setup is done, starting from now we can
409 3418bd25 Gerd Hoffmann
     * only create hotpluggable devices
410 3418bd25 Gerd Hoffmann
     */
411 3418bd25 Gerd Hoffmann
    qdev_hotplug = 1;
412 3418bd25 Gerd Hoffmann
}
413 3418bd25 Gerd Hoffmann
414 0ac8ef71 Alex Williamson
bool qdev_machine_modified(void)
415 0ac8ef71 Alex Williamson
{
416 0ac8ef71 Alex Williamson
    return qdev_hot_added || qdev_hot_removed;
417 0ac8ef71 Alex Williamson
}
418 0ac8ef71 Alex Williamson
419 aae9460e Paul Brook
/* Get a character (serial) device interface.  */
420 aae9460e Paul Brook
CharDriverState *qdev_init_chardev(DeviceState *dev)
421 aae9460e Paul Brook
{
422 aae9460e Paul Brook
    static int next_serial;
423 98b19252 Amit Shah
424 98b19252 Amit Shah
    /* FIXME: This function needs to go away: use chardev properties!  */
425 98b19252 Amit Shah
    return serial_hds[next_serial++];
426 aae9460e Paul Brook
}
427 aae9460e Paul Brook
428 02e2da45 Paul Brook
BusState *qdev_get_parent_bus(DeviceState *dev)
429 aae9460e Paul Brook
{
430 02e2da45 Paul Brook
    return dev->parent_bus;
431 aae9460e Paul Brook
}
432 aae9460e Paul Brook
433 aae9460e Paul Brook
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
434 aae9460e Paul Brook
{
435 aae9460e Paul Brook
    assert(dev->num_gpio_in == 0);
436 aae9460e Paul Brook
    dev->num_gpio_in = n;
437 aae9460e Paul Brook
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
438 aae9460e Paul Brook
}
439 aae9460e Paul Brook
440 aae9460e Paul Brook
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
441 aae9460e Paul Brook
{
442 aae9460e Paul Brook
    assert(dev->num_gpio_out == 0);
443 aae9460e Paul Brook
    dev->num_gpio_out = n;
444 aae9460e Paul Brook
    dev->gpio_out = pins;
445 aae9460e Paul Brook
}
446 aae9460e Paul Brook
447 aae9460e Paul Brook
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
448 aae9460e Paul Brook
{
449 aae9460e Paul Brook
    assert(n >= 0 && n < dev->num_gpio_in);
450 aae9460e Paul Brook
    return dev->gpio_in[n];
451 aae9460e Paul Brook
}
452 aae9460e Paul Brook
453 aae9460e Paul Brook
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
454 aae9460e Paul Brook
{
455 aae9460e Paul Brook
    assert(n >= 0 && n < dev->num_gpio_out);
456 aae9460e Paul Brook
    dev->gpio_out[n] = pin;
457 aae9460e Paul Brook
}
458 aae9460e Paul Brook
459 ed16ab5a Gerd Hoffmann
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
460 ed16ab5a Gerd Hoffmann
{
461 ed16ab5a Gerd Hoffmann
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
462 ed16ab5a Gerd Hoffmann
    if (nd->vlan)
463 ed16ab5a Gerd Hoffmann
        qdev_prop_set_vlan(dev, "vlan", nd->vlan);
464 ed16ab5a Gerd Hoffmann
    if (nd->netdev)
465 ed16ab5a Gerd Hoffmann
        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
466 75422b0d Amit Shah
    if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
467 97b15621 Gerd Hoffmann
        qdev_prop_exists(dev, "vectors")) {
468 97b15621 Gerd Hoffmann
        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
469 97b15621 Gerd Hoffmann
    }
470 ed16ab5a Gerd Hoffmann
}
471 ed16ab5a Gerd Hoffmann
472 02e2da45 Paul Brook
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
473 4d6ae674 Paul Brook
{
474 02e2da45 Paul Brook
    BusState *bus;
475 4d6ae674 Paul Brook
476 72cf2d4f Blue Swirl
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
477 4d6ae674 Paul Brook
        if (strcmp(name, bus->name) == 0) {
478 02e2da45 Paul Brook
            return bus;
479 4d6ae674 Paul Brook
        }
480 4d6ae674 Paul Brook
    }
481 4d6ae674 Paul Brook
    return NULL;
482 4d6ae674 Paul Brook
}
483 4d6ae674 Paul Brook
484 81699d8a Anthony Liguori
int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
485 81699d8a Anthony Liguori
                       qbus_walkerfn *busfn, void *opaque)
486 81699d8a Anthony Liguori
{
487 81699d8a Anthony Liguori
    DeviceState *dev;
488 81699d8a Anthony Liguori
    int err;
489 81699d8a Anthony Liguori
490 81699d8a Anthony Liguori
    if (busfn) {
491 81699d8a Anthony Liguori
        err = busfn(bus, opaque);
492 81699d8a Anthony Liguori
        if (err) {
493 81699d8a Anthony Liguori
            return err;
494 81699d8a Anthony Liguori
        }
495 81699d8a Anthony Liguori
    }
496 81699d8a Anthony Liguori
497 81699d8a Anthony Liguori
    QLIST_FOREACH(dev, &bus->children, sibling) {
498 81699d8a Anthony Liguori
        err = qdev_walk_children(dev, devfn, busfn, opaque);
499 81699d8a Anthony Liguori
        if (err < 0) {
500 81699d8a Anthony Liguori
            return err;
501 81699d8a Anthony Liguori
        }
502 81699d8a Anthony Liguori
    }
503 81699d8a Anthony Liguori
504 81699d8a Anthony Liguori
    return 0;
505 81699d8a Anthony Liguori
}
506 81699d8a Anthony Liguori
507 81699d8a Anthony Liguori
int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
508 81699d8a Anthony Liguori
                       qbus_walkerfn *busfn, void *opaque)
509 81699d8a Anthony Liguori
{
510 81699d8a Anthony Liguori
    BusState *bus;
511 81699d8a Anthony Liguori
    int err;
512 81699d8a Anthony Liguori
513 81699d8a Anthony Liguori
    if (devfn) {
514 81699d8a Anthony Liguori
        err = devfn(dev, opaque);
515 81699d8a Anthony Liguori
        if (err) {
516 81699d8a Anthony Liguori
            return err;
517 81699d8a Anthony Liguori
        }
518 81699d8a Anthony Liguori
    }
519 81699d8a Anthony Liguori
520 81699d8a Anthony Liguori
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
521 81699d8a Anthony Liguori
        err = qbus_walk_children(bus, devfn, busfn, opaque);
522 81699d8a Anthony Liguori
        if (err < 0) {
523 81699d8a Anthony Liguori
            return err;
524 81699d8a Anthony Liguori
        }
525 81699d8a Anthony Liguori
    }
526 81699d8a Anthony Liguori
527 81699d8a Anthony Liguori
    return 0;
528 81699d8a Anthony Liguori
}
529 81699d8a Anthony Liguori
530 8ffb1bcf Gerd Hoffmann
static BusState *qbus_find_recursive(BusState *bus, const char *name,
531 8ffb1bcf Gerd Hoffmann
                                     const BusInfo *info)
532 8ffb1bcf Gerd Hoffmann
{
533 8ffb1bcf Gerd Hoffmann
    DeviceState *dev;
534 8ffb1bcf Gerd Hoffmann
    BusState *child, *ret;
535 8ffb1bcf Gerd Hoffmann
    int match = 1;
536 8ffb1bcf Gerd Hoffmann
537 8ffb1bcf Gerd Hoffmann
    if (name && (strcmp(bus->name, name) != 0)) {
538 8ffb1bcf Gerd Hoffmann
        match = 0;
539 8ffb1bcf Gerd Hoffmann
    }
540 8ffb1bcf Gerd Hoffmann
    if (info && (bus->info != info)) {
541 8ffb1bcf Gerd Hoffmann
        match = 0;
542 8ffb1bcf Gerd Hoffmann
    }
543 8ffb1bcf Gerd Hoffmann
    if (match) {
544 8ffb1bcf Gerd Hoffmann
        return bus;
545 8ffb1bcf Gerd Hoffmann
    }
546 8ffb1bcf Gerd Hoffmann
547 72cf2d4f Blue Swirl
    QLIST_FOREACH(dev, &bus->children, sibling) {
548 72cf2d4f Blue Swirl
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
549 8ffb1bcf Gerd Hoffmann
            ret = qbus_find_recursive(child, name, info);
550 8ffb1bcf Gerd Hoffmann
            if (ret) {
551 8ffb1bcf Gerd Hoffmann
                return ret;
552 8ffb1bcf Gerd Hoffmann
            }
553 8ffb1bcf Gerd Hoffmann
        }
554 8ffb1bcf Gerd Hoffmann
    }
555 8ffb1bcf Gerd Hoffmann
    return NULL;
556 8ffb1bcf Gerd Hoffmann
}
557 8ffb1bcf Gerd Hoffmann
558 a2ee6b4f Isaku Yamahata
DeviceState *qdev_find_recursive(BusState *bus, const char *id)
559 3418bd25 Gerd Hoffmann
{
560 3418bd25 Gerd Hoffmann
    DeviceState *dev, *ret;
561 3418bd25 Gerd Hoffmann
    BusState *child;
562 3418bd25 Gerd Hoffmann
563 3418bd25 Gerd Hoffmann
    QLIST_FOREACH(dev, &bus->children, sibling) {
564 3418bd25 Gerd Hoffmann
        if (dev->id && strcmp(dev->id, id) == 0)
565 3418bd25 Gerd Hoffmann
            return dev;
566 3418bd25 Gerd Hoffmann
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
567 3418bd25 Gerd Hoffmann
            ret = qdev_find_recursive(child, id);
568 3418bd25 Gerd Hoffmann
            if (ret) {
569 3418bd25 Gerd Hoffmann
                return ret;
570 3418bd25 Gerd Hoffmann
            }
571 3418bd25 Gerd Hoffmann
        }
572 3418bd25 Gerd Hoffmann
    }
573 3418bd25 Gerd Hoffmann
    return NULL;
574 3418bd25 Gerd Hoffmann
}
575 3418bd25 Gerd Hoffmann
576 53db16b5 Markus Armbruster
static void qbus_list_bus(DeviceState *dev)
577 8ffb1bcf Gerd Hoffmann
{
578 8ffb1bcf Gerd Hoffmann
    BusState *child;
579 8ffb1bcf Gerd Hoffmann
    const char *sep = " ";
580 8ffb1bcf Gerd Hoffmann
581 53db16b5 Markus Armbruster
    error_printf("child busses at \"%s\":",
582 53db16b5 Markus Armbruster
                 dev->id ? dev->id : dev->info->name);
583 72cf2d4f Blue Swirl
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
584 53db16b5 Markus Armbruster
        error_printf("%s\"%s\"", sep, child->name);
585 8ffb1bcf Gerd Hoffmann
        sep = ", ";
586 8ffb1bcf Gerd Hoffmann
    }
587 53db16b5 Markus Armbruster
    error_printf("\n");
588 8ffb1bcf Gerd Hoffmann
}
589 8ffb1bcf Gerd Hoffmann
590 53db16b5 Markus Armbruster
static void qbus_list_dev(BusState *bus)
591 8ffb1bcf Gerd Hoffmann
{
592 8ffb1bcf Gerd Hoffmann
    DeviceState *dev;
593 8ffb1bcf Gerd Hoffmann
    const char *sep = " ";
594 8ffb1bcf Gerd Hoffmann
595 53db16b5 Markus Armbruster
    error_printf("devices at \"%s\":", bus->name);
596 72cf2d4f Blue Swirl
    QLIST_FOREACH(dev, &bus->children, sibling) {
597 53db16b5 Markus Armbruster
        error_printf("%s\"%s\"", sep, dev->info->name);
598 8ffb1bcf Gerd Hoffmann
        if (dev->id)
599 53db16b5 Markus Armbruster
            error_printf("/\"%s\"", dev->id);
600 8ffb1bcf Gerd Hoffmann
        sep = ", ";
601 8ffb1bcf Gerd Hoffmann
    }
602 53db16b5 Markus Armbruster
    error_printf("\n");
603 8ffb1bcf Gerd Hoffmann
}
604 8ffb1bcf Gerd Hoffmann
605 8ffb1bcf Gerd Hoffmann
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
606 8ffb1bcf Gerd Hoffmann
{
607 8ffb1bcf Gerd Hoffmann
    BusState *child;
608 8ffb1bcf Gerd Hoffmann
609 72cf2d4f Blue Swirl
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
610 8ffb1bcf Gerd Hoffmann
        if (strcmp(child->name, elem) == 0) {
611 8ffb1bcf Gerd Hoffmann
            return child;
612 8ffb1bcf Gerd Hoffmann
        }
613 8ffb1bcf Gerd Hoffmann
    }
614 8ffb1bcf Gerd Hoffmann
    return NULL;
615 8ffb1bcf Gerd Hoffmann
}
616 8ffb1bcf Gerd Hoffmann
617 8ffb1bcf Gerd Hoffmann
static DeviceState *qbus_find_dev(BusState *bus, char *elem)
618 8ffb1bcf Gerd Hoffmann
{
619 8ffb1bcf Gerd Hoffmann
    DeviceState *dev;
620 8ffb1bcf Gerd Hoffmann
621 8ffb1bcf Gerd Hoffmann
    /*
622 8ffb1bcf Gerd Hoffmann
     * try to match in order:
623 8ffb1bcf Gerd Hoffmann
     *   (1) instance id, if present
624 8ffb1bcf Gerd Hoffmann
     *   (2) driver name
625 8ffb1bcf Gerd Hoffmann
     *   (3) driver alias, if present
626 8ffb1bcf Gerd Hoffmann
     */
627 72cf2d4f Blue Swirl
    QLIST_FOREACH(dev, &bus->children, sibling) {
628 8ffb1bcf Gerd Hoffmann
        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
629 8ffb1bcf Gerd Hoffmann
            return dev;
630 8ffb1bcf Gerd Hoffmann
        }
631 8ffb1bcf Gerd Hoffmann
    }
632 72cf2d4f Blue Swirl
    QLIST_FOREACH(dev, &bus->children, sibling) {
633 8ffb1bcf Gerd Hoffmann
        if (strcmp(dev->info->name, elem) == 0) {
634 8ffb1bcf Gerd Hoffmann
            return dev;
635 8ffb1bcf Gerd Hoffmann
        }
636 8ffb1bcf Gerd Hoffmann
    }
637 72cf2d4f Blue Swirl
    QLIST_FOREACH(dev, &bus->children, sibling) {
638 8ffb1bcf Gerd Hoffmann
        if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
639 8ffb1bcf Gerd Hoffmann
            return dev;
640 8ffb1bcf Gerd Hoffmann
        }
641 8ffb1bcf Gerd Hoffmann
    }
642 8ffb1bcf Gerd Hoffmann
    return NULL;
643 8ffb1bcf Gerd Hoffmann
}
644 8ffb1bcf Gerd Hoffmann
645 8ffb1bcf Gerd Hoffmann
static BusState *qbus_find(const char *path)
646 8ffb1bcf Gerd Hoffmann
{
647 8ffb1bcf Gerd Hoffmann
    DeviceState *dev;
648 8ffb1bcf Gerd Hoffmann
    BusState *bus;
649 53db16b5 Markus Armbruster
    char elem[128];
650 8ffb1bcf Gerd Hoffmann
    int pos, len;
651 8ffb1bcf Gerd Hoffmann
652 8ffb1bcf Gerd Hoffmann
    /* find start element */
653 8ffb1bcf Gerd Hoffmann
    if (path[0] == '/') {
654 8ffb1bcf Gerd Hoffmann
        bus = main_system_bus;
655 8ffb1bcf Gerd Hoffmann
        pos = 0;
656 8ffb1bcf Gerd Hoffmann
    } else {
657 8ffb1bcf Gerd Hoffmann
        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
658 fc98eb43 Markus Armbruster
            assert(!path[0]);
659 fc98eb43 Markus Armbruster
            elem[0] = len = 0;
660 8ffb1bcf Gerd Hoffmann
        }
661 8ffb1bcf Gerd Hoffmann
        bus = qbus_find_recursive(main_system_bus, elem, NULL);
662 8ffb1bcf Gerd Hoffmann
        if (!bus) {
663 ac8dae67 Markus Armbruster
            qerror_report(QERR_BUS_NOT_FOUND, elem);
664 8ffb1bcf Gerd Hoffmann
            return NULL;
665 8ffb1bcf Gerd Hoffmann
        }
666 8ffb1bcf Gerd Hoffmann
        pos = len;
667 8ffb1bcf Gerd Hoffmann
    }
668 8ffb1bcf Gerd Hoffmann
669 8ffb1bcf Gerd Hoffmann
    for (;;) {
670 fc98eb43 Markus Armbruster
        assert(path[pos] == '/' || !path[pos]);
671 fc98eb43 Markus Armbruster
        while (path[pos] == '/') {
672 fc98eb43 Markus Armbruster
            pos++;
673 fc98eb43 Markus Armbruster
        }
674 8ffb1bcf Gerd Hoffmann
        if (path[pos] == '\0') {
675 8ffb1bcf Gerd Hoffmann
            return bus;
676 8ffb1bcf Gerd Hoffmann
        }
677 8ffb1bcf Gerd Hoffmann
678 8ffb1bcf Gerd Hoffmann
        /* find device */
679 fc98eb43 Markus Armbruster
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
680 fc98eb43 Markus Armbruster
            assert(0);
681 fc98eb43 Markus Armbruster
            elem[0] = len = 0;
682 8ffb1bcf Gerd Hoffmann
        }
683 8ffb1bcf Gerd Hoffmann
        pos += len;
684 8ffb1bcf Gerd Hoffmann
        dev = qbus_find_dev(bus, elem);
685 8ffb1bcf Gerd Hoffmann
        if (!dev) {
686 ac8dae67 Markus Armbruster
            qerror_report(QERR_DEVICE_NOT_FOUND, elem);
687 8bc27249 Markus Armbruster
            if (!monitor_cur_is_qmp()) {
688 8bc27249 Markus Armbruster
                qbus_list_dev(bus);
689 8bc27249 Markus Armbruster
            }
690 8ffb1bcf Gerd Hoffmann
            return NULL;
691 8ffb1bcf Gerd Hoffmann
        }
692 fc98eb43 Markus Armbruster
693 fc98eb43 Markus Armbruster
        assert(path[pos] == '/' || !path[pos]);
694 fc98eb43 Markus Armbruster
        while (path[pos] == '/') {
695 fc98eb43 Markus Armbruster
            pos++;
696 fc98eb43 Markus Armbruster
        }
697 8ffb1bcf Gerd Hoffmann
        if (path[pos] == '\0') {
698 8ffb1bcf Gerd Hoffmann
            /* last specified element is a device.  If it has exactly
699 8ffb1bcf Gerd Hoffmann
             * one child bus accept it nevertheless */
700 8ffb1bcf Gerd Hoffmann
            switch (dev->num_child_bus) {
701 8ffb1bcf Gerd Hoffmann
            case 0:
702 ac8dae67 Markus Armbruster
                qerror_report(QERR_DEVICE_NO_BUS, elem);
703 8ffb1bcf Gerd Hoffmann
                return NULL;
704 8ffb1bcf Gerd Hoffmann
            case 1:
705 72cf2d4f Blue Swirl
                return QLIST_FIRST(&dev->child_bus);
706 8ffb1bcf Gerd Hoffmann
            default:
707 ac8dae67 Markus Armbruster
                qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
708 8bc27249 Markus Armbruster
                if (!monitor_cur_is_qmp()) {
709 8bc27249 Markus Armbruster
                    qbus_list_bus(dev);
710 8bc27249 Markus Armbruster
                }
711 8ffb1bcf Gerd Hoffmann
                return NULL;
712 8ffb1bcf Gerd Hoffmann
            }
713 8ffb1bcf Gerd Hoffmann
        }
714 8ffb1bcf Gerd Hoffmann
715 8ffb1bcf Gerd Hoffmann
        /* find bus */
716 fc98eb43 Markus Armbruster
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
717 fc98eb43 Markus Armbruster
            assert(0);
718 fc98eb43 Markus Armbruster
            elem[0] = len = 0;
719 8ffb1bcf Gerd Hoffmann
        }
720 8ffb1bcf Gerd Hoffmann
        pos += len;
721 8ffb1bcf Gerd Hoffmann
        bus = qbus_find_bus(dev, elem);
722 8ffb1bcf Gerd Hoffmann
        if (!bus) {
723 ac8dae67 Markus Armbruster
            qerror_report(QERR_BUS_NOT_FOUND, elem);
724 8bc27249 Markus Armbruster
            if (!monitor_cur_is_qmp()) {
725 8bc27249 Markus Armbruster
                qbus_list_bus(dev);
726 8bc27249 Markus Armbruster
            }
727 8ffb1bcf Gerd Hoffmann
            return NULL;
728 8ffb1bcf Gerd Hoffmann
        }
729 8ffb1bcf Gerd Hoffmann
    }
730 8ffb1bcf Gerd Hoffmann
}
731 8ffb1bcf Gerd Hoffmann
732 cd739fb6 Gerd Hoffmann
void qbus_create_inplace(BusState *bus, BusInfo *info,
733 cd739fb6 Gerd Hoffmann
                         DeviceState *parent, const char *name)
734 02e2da45 Paul Brook
{
735 d271de9f Gerd Hoffmann
    char *buf;
736 d271de9f Gerd Hoffmann
    int i,len;
737 02e2da45 Paul Brook
738 10c4c98a Gerd Hoffmann
    bus->info = info;
739 02e2da45 Paul Brook
    bus->parent = parent;
740 d271de9f Gerd Hoffmann
741 d271de9f Gerd Hoffmann
    if (name) {
742 d271de9f Gerd Hoffmann
        /* use supplied name */
743 d271de9f Gerd Hoffmann
        bus->name = qemu_strdup(name);
744 d271de9f Gerd Hoffmann
    } else if (parent && parent->id) {
745 d271de9f Gerd Hoffmann
        /* parent device has id -> use it for bus name */
746 d271de9f Gerd Hoffmann
        len = strlen(parent->id) + 16;
747 d271de9f Gerd Hoffmann
        buf = qemu_malloc(len);
748 d271de9f Gerd Hoffmann
        snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
749 d271de9f Gerd Hoffmann
        bus->name = buf;
750 d271de9f Gerd Hoffmann
    } else {
751 d271de9f Gerd Hoffmann
        /* no id -> use lowercase bus type for bus name */
752 d271de9f Gerd Hoffmann
        len = strlen(info->name) + 16;
753 d271de9f Gerd Hoffmann
        buf = qemu_malloc(len);
754 d271de9f Gerd Hoffmann
        len = snprintf(buf, len, "%s.%d", info->name,
755 d271de9f Gerd Hoffmann
                       parent ? parent->num_child_bus : 0);
756 d271de9f Gerd Hoffmann
        for (i = 0; i < len; i++)
757 bb87ece5 Christoph Egger
            buf[i] = qemu_tolower(buf[i]);
758 d271de9f Gerd Hoffmann
        bus->name = buf;
759 d271de9f Gerd Hoffmann
    }
760 d271de9f Gerd Hoffmann
761 72cf2d4f Blue Swirl
    QLIST_INIT(&bus->children);
762 02e2da45 Paul Brook
    if (parent) {
763 72cf2d4f Blue Swirl
        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
764 d271de9f Gerd Hoffmann
        parent->num_child_bus++;
765 80376c3f Isaku Yamahata
    } else if (bus != main_system_bus) {
766 80376c3f Isaku Yamahata
        /* TODO: once all bus devices are qdevified,
767 80376c3f Isaku Yamahata
           only reset handler for main_system_bus should be registered here. */
768 80376c3f Isaku Yamahata
        qemu_register_reset(qbus_reset_all_fn, bus);
769 02e2da45 Paul Brook
    }
770 cd739fb6 Gerd Hoffmann
}
771 cd739fb6 Gerd Hoffmann
772 cd739fb6 Gerd Hoffmann
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
773 cd739fb6 Gerd Hoffmann
{
774 cd739fb6 Gerd Hoffmann
    BusState *bus;
775 cd739fb6 Gerd Hoffmann
776 cd739fb6 Gerd Hoffmann
    bus = qemu_mallocz(info->size);
777 cd739fb6 Gerd Hoffmann
    bus->qdev_allocated = 1;
778 cd739fb6 Gerd Hoffmann
    qbus_create_inplace(bus, info, parent, name);
779 02e2da45 Paul Brook
    return bus;
780 02e2da45 Paul Brook
}
781 cae4956e Gerd Hoffmann
782 131ec1bd Gerd Hoffmann
void qbus_free(BusState *bus)
783 131ec1bd Gerd Hoffmann
{
784 131ec1bd Gerd Hoffmann
    DeviceState *dev;
785 131ec1bd Gerd Hoffmann
786 131ec1bd Gerd Hoffmann
    while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
787 131ec1bd Gerd Hoffmann
        qdev_free(dev);
788 131ec1bd Gerd Hoffmann
    }
789 131ec1bd Gerd Hoffmann
    if (bus->parent) {
790 131ec1bd Gerd Hoffmann
        QLIST_REMOVE(bus, sibling);
791 131ec1bd Gerd Hoffmann
        bus->parent->num_child_bus--;
792 80376c3f Isaku Yamahata
    } else {
793 80376c3f Isaku Yamahata
        assert(bus != main_system_bus); /* main_system_bus is never freed */
794 80376c3f Isaku Yamahata
        qemu_unregister_reset(qbus_reset_all_fn, bus);
795 131ec1bd Gerd Hoffmann
    }
796 e163ae7b Isaku Yamahata
    qemu_free((void*)bus->name);
797 131ec1bd Gerd Hoffmann
    if (bus->qdev_allocated) {
798 131ec1bd Gerd Hoffmann
        qemu_free(bus);
799 131ec1bd Gerd Hoffmann
    }
800 131ec1bd Gerd Hoffmann
}
801 131ec1bd Gerd Hoffmann
802 cae4956e Gerd Hoffmann
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
803 cae4956e Gerd Hoffmann
static void qbus_print(Monitor *mon, BusState *bus, int indent);
804 cae4956e Gerd Hoffmann
805 ee6847d1 Gerd Hoffmann
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
806 ee6847d1 Gerd Hoffmann
                             const char *prefix, int indent)
807 ee6847d1 Gerd Hoffmann
{
808 ee6847d1 Gerd Hoffmann
    char buf[64];
809 ee6847d1 Gerd Hoffmann
810 ee6847d1 Gerd Hoffmann
    if (!props)
811 ee6847d1 Gerd Hoffmann
        return;
812 ee6847d1 Gerd Hoffmann
    while (props->name) {
813 036f7166 Markus Armbruster
        /*
814 036f7166 Markus Armbruster
         * TODO Properties without a print method are just for dirty
815 036f7166 Markus Armbruster
         * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
816 036f7166 Markus Armbruster
         * marked for removal.  The test props->info->print should be
817 036f7166 Markus Armbruster
         * removed along with it.
818 036f7166 Markus Armbruster
         */
819 ee6847d1 Gerd Hoffmann
        if (props->info->print) {
820 ee6847d1 Gerd Hoffmann
            props->info->print(dev, props, buf, sizeof(buf));
821 ee6847d1 Gerd Hoffmann
            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
822 ee6847d1 Gerd Hoffmann
        }
823 ee6847d1 Gerd Hoffmann
        props++;
824 ee6847d1 Gerd Hoffmann
    }
825 ee6847d1 Gerd Hoffmann
}
826 ee6847d1 Gerd Hoffmann
827 cae4956e Gerd Hoffmann
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
828 cae4956e Gerd Hoffmann
{
829 cae4956e Gerd Hoffmann
    BusState *child;
830 ccb63de3 Gerd Hoffmann
    qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
831 ccb63de3 Gerd Hoffmann
                dev->id ? dev->id : "");
832 cae4956e Gerd Hoffmann
    indent += 2;
833 cae4956e Gerd Hoffmann
    if (dev->num_gpio_in) {
834 cae4956e Gerd Hoffmann
        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
835 cae4956e Gerd Hoffmann
    }
836 cae4956e Gerd Hoffmann
    if (dev->num_gpio_out) {
837 cae4956e Gerd Hoffmann
        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
838 cae4956e Gerd Hoffmann
    }
839 ee6847d1 Gerd Hoffmann
    qdev_print_props(mon, dev, dev->info->props, "dev", indent);
840 ee6847d1 Gerd Hoffmann
    qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
841 10c4c98a Gerd Hoffmann
    if (dev->parent_bus->info->print_dev)
842 10c4c98a Gerd Hoffmann
        dev->parent_bus->info->print_dev(mon, dev, indent);
843 72cf2d4f Blue Swirl
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
844 cae4956e Gerd Hoffmann
        qbus_print(mon, child, indent);
845 cae4956e Gerd Hoffmann
    }
846 cae4956e Gerd Hoffmann
}
847 cae4956e Gerd Hoffmann
848 cae4956e Gerd Hoffmann
static void qbus_print(Monitor *mon, BusState *bus, int indent)
849 cae4956e Gerd Hoffmann
{
850 cae4956e Gerd Hoffmann
    struct DeviceState *dev;
851 cae4956e Gerd Hoffmann
852 cae4956e Gerd Hoffmann
    qdev_printf("bus: %s\n", bus->name);
853 cae4956e Gerd Hoffmann
    indent += 2;
854 10c4c98a Gerd Hoffmann
    qdev_printf("type %s\n", bus->info->name);
855 72cf2d4f Blue Swirl
    QLIST_FOREACH(dev, &bus->children, sibling) {
856 cae4956e Gerd Hoffmann
        qdev_print(mon, dev, indent);
857 cae4956e Gerd Hoffmann
    }
858 cae4956e Gerd Hoffmann
}
859 cae4956e Gerd Hoffmann
#undef qdev_printf
860 cae4956e Gerd Hoffmann
861 cae4956e Gerd Hoffmann
void do_info_qtree(Monitor *mon)
862 cae4956e Gerd Hoffmann
{
863 cae4956e Gerd Hoffmann
    if (main_system_bus)
864 cae4956e Gerd Hoffmann
        qbus_print(mon, main_system_bus, 0);
865 cae4956e Gerd Hoffmann
}
866 9316d30f Gerd Hoffmann
867 f6c64e0e Gerd Hoffmann
void do_info_qdm(Monitor *mon)
868 9316d30f Gerd Hoffmann
{
869 9316d30f Gerd Hoffmann
    DeviceInfo *info;
870 9316d30f Gerd Hoffmann
871 9316d30f Gerd Hoffmann
    for (info = device_info_list; info != NULL; info = info->next) {
872 8a9662ca Markus Armbruster
        qdev_print_devinfo(info);
873 9316d30f Gerd Hoffmann
    }
874 9316d30f Gerd Hoffmann
}
875 3418bd25 Gerd Hoffmann
876 8bc27249 Markus Armbruster
int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
877 3418bd25 Gerd Hoffmann
{
878 3418bd25 Gerd Hoffmann
    QemuOpts *opts;
879 3418bd25 Gerd Hoffmann
880 3329f07b Gerd Hoffmann
    opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
881 8bc27249 Markus Armbruster
    if (!opts) {
882 8bc27249 Markus Armbruster
        return -1;
883 8bc27249 Markus Armbruster
    }
884 8bc27249 Markus Armbruster
    if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
885 8bc27249 Markus Armbruster
        qemu_opts_del(opts);
886 8bc27249 Markus Armbruster
        return 0;
887 0f853a38 Kevin Wolf
    }
888 8bc27249 Markus Armbruster
    if (!qdev_device_add(opts)) {
889 8bc27249 Markus Armbruster
        qemu_opts_del(opts);
890 8bc27249 Markus Armbruster
        return -1;
891 8bc27249 Markus Armbruster
    }
892 8bc27249 Markus Armbruster
    return 0;
893 3418bd25 Gerd Hoffmann
}
894 3418bd25 Gerd Hoffmann
895 17a38eaa Markus Armbruster
int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
896 3418bd25 Gerd Hoffmann
{
897 3418bd25 Gerd Hoffmann
    const char *id = qdict_get_str(qdict, "id");
898 3418bd25 Gerd Hoffmann
    DeviceState *dev;
899 3418bd25 Gerd Hoffmann
900 3418bd25 Gerd Hoffmann
    dev = qdev_find_recursive(main_system_bus, id);
901 3418bd25 Gerd Hoffmann
    if (NULL == dev) {
902 17a38eaa Markus Armbruster
        qerror_report(QERR_DEVICE_NOT_FOUND, id);
903 17a38eaa Markus Armbruster
        return -1;
904 3418bd25 Gerd Hoffmann
    }
905 17a38eaa Markus Armbruster
    return qdev_unplug(dev);
906 3418bd25 Gerd Hoffmann
}
907 1ca4d09a Gleb Natapov
908 1ca4d09a Gleb Natapov
static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
909 1ca4d09a Gleb Natapov
{
910 1ca4d09a Gleb Natapov
    int l = 0;
911 1ca4d09a Gleb Natapov
912 1ca4d09a Gleb Natapov
    if (dev && dev->parent_bus) {
913 1ca4d09a Gleb Natapov
        char *d;
914 1ca4d09a Gleb Natapov
        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
915 1ca4d09a Gleb Natapov
        if (dev->parent_bus->info->get_fw_dev_path) {
916 1ca4d09a Gleb Natapov
            d = dev->parent_bus->info->get_fw_dev_path(dev);
917 1ca4d09a Gleb Natapov
            l += snprintf(p + l, size - l, "%s", d);
918 1ca4d09a Gleb Natapov
            qemu_free(d);
919 1ca4d09a Gleb Natapov
        } else {
920 1ca4d09a Gleb Natapov
            l += snprintf(p + l, size - l, "%s", dev->info->name);
921 1ca4d09a Gleb Natapov
        }
922 1ca4d09a Gleb Natapov
    }
923 1ca4d09a Gleb Natapov
    l += snprintf(p + l , size - l, "/");
924 1ca4d09a Gleb Natapov
925 1ca4d09a Gleb Natapov
    return l;
926 1ca4d09a Gleb Natapov
}
927 1ca4d09a Gleb Natapov
928 1ca4d09a Gleb Natapov
char* qdev_get_fw_dev_path(DeviceState *dev)
929 1ca4d09a Gleb Natapov
{
930 1ca4d09a Gleb Natapov
    char path[128];
931 1ca4d09a Gleb Natapov
    int l;
932 1ca4d09a Gleb Natapov
933 1ca4d09a Gleb Natapov
    l = qdev_get_fw_dev_path_helper(dev, path, 128);
934 1ca4d09a Gleb Natapov
935 1ca4d09a Gleb Natapov
    path[l-1] = '\0';
936 1ca4d09a Gleb Natapov
937 1ca4d09a Gleb Natapov
    return strdup(path);
938 1ca4d09a Gleb Natapov
}