Statistics
| Branch: | Revision:

root / hw / qdev.c @ f7613bee

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