Statistics
| Branch: | Revision:

root / hw / qdev.c @ 295587f7

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