Statistics
| Branch: | Revision:

root / hw / qdev.c @ e92714c7

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