Statistics
| Branch: | Revision:

root / hw / qdev.c @ 71cf9e62

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