Statistics
| Branch: | Revision:

root / hw / qdev.c @ 44677ded

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