Statistics
| Branch: | Revision:

root / qdev-monitor.c @ 6a1751b7

History | View | Annotate | Download (18.9 kB)

1 ee46d8a5 Anthony Liguori
/*
2 ee46d8a5 Anthony Liguori
 *  Dynamic device configuration and creation.
3 ee46d8a5 Anthony Liguori
 *
4 ee46d8a5 Anthony Liguori
 *  Copyright (c) 2009 CodeSourcery
5 ee46d8a5 Anthony Liguori
 *
6 ee46d8a5 Anthony Liguori
 * This library is free software; you can redistribute it and/or
7 ee46d8a5 Anthony Liguori
 * modify it under the terms of the GNU Lesser General Public
8 ee46d8a5 Anthony Liguori
 * License as published by the Free Software Foundation; either
9 ee46d8a5 Anthony Liguori
 * version 2 of the License, or (at your option) any later version.
10 ee46d8a5 Anthony Liguori
 *
11 ee46d8a5 Anthony Liguori
 * This library is distributed in the hope that it will be useful,
12 ee46d8a5 Anthony Liguori
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ee46d8a5 Anthony Liguori
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ee46d8a5 Anthony Liguori
 * Lesser General Public License for more details.
15 ee46d8a5 Anthony Liguori
 *
16 ee46d8a5 Anthony Liguori
 * You should have received a copy of the GNU Lesser General Public
17 ee46d8a5 Anthony Liguori
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 ee46d8a5 Anthony Liguori
 */
19 ee46d8a5 Anthony Liguori
20 b4a42f81 Paolo Bonzini
#include "hw/qdev.h"
21 2f7bd829 Andreas Färber
#include "hw/sysbus.h"
22 83c9089e Paolo Bonzini
#include "monitor/monitor.h"
23 b4a42f81 Paolo Bonzini
#include "monitor/qdev.h"
24 a15fef21 Luiz Capitulino
#include "qmp-commands.h"
25 9c17d615 Paolo Bonzini
#include "sysemu/arch_init.h"
26 1de7afc9 Paolo Bonzini
#include "qemu/config-file.h"
27 ee46d8a5 Anthony Liguori
28 ee46d8a5 Anthony Liguori
/*
29 ee46d8a5 Anthony Liguori
 * Aliases were a bad idea from the start.  Let's keep them
30 ee46d8a5 Anthony Liguori
 * from spreading further.
31 ee46d8a5 Anthony Liguori
 */
32 ee46d8a5 Anthony Liguori
typedef struct QDevAlias
33 ee46d8a5 Anthony Liguori
{
34 ee46d8a5 Anthony Liguori
    const char *typename;
35 ee46d8a5 Anthony Liguori
    const char *alias;
36 5f629d94 Alexander Graf
    uint32_t arch_mask;
37 ee46d8a5 Anthony Liguori
} QDevAlias;
38 ee46d8a5 Anthony Liguori
39 ee46d8a5 Anthony Liguori
static const QDevAlias qdev_alias_table[] = {
40 5f629d94 Alexander Graf
    { "virtio-blk-pci", "virtio-blk", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
41 5f629d94 Alexander Graf
    { "virtio-net-pci", "virtio-net", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
42 5f629d94 Alexander Graf
    { "virtio-serial-pci", "virtio-serial", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
43 5f629d94 Alexander Graf
    { "virtio-balloon-pci", "virtio-balloon",
44 5f629d94 Alexander Graf
            QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
45 5f629d94 Alexander Graf
    { "virtio-blk-s390", "virtio-blk", QEMU_ARCH_S390X },
46 5f629d94 Alexander Graf
    { "virtio-net-s390", "virtio-net", QEMU_ARCH_S390X },
47 5f629d94 Alexander Graf
    { "virtio-serial-s390", "virtio-serial", QEMU_ARCH_S390X },
48 ee46d8a5 Anthony Liguori
    { "lsi53c895a", "lsi" },
49 ee46d8a5 Anthony Liguori
    { "ich9-ahci", "ahci" },
50 c3ebd3ba Jan Kiszka
    { "kvm-pci-assign", "pci-assign" },
51 ee46d8a5 Anthony Liguori
    { }
52 ee46d8a5 Anthony Liguori
};
53 ee46d8a5 Anthony Liguori
54 ee46d8a5 Anthony Liguori
static const char *qdev_class_get_alias(DeviceClass *dc)
55 ee46d8a5 Anthony Liguori
{
56 ee46d8a5 Anthony Liguori
    const char *typename = object_class_get_name(OBJECT_CLASS(dc));
57 ee46d8a5 Anthony Liguori
    int i;
58 ee46d8a5 Anthony Liguori
59 ee46d8a5 Anthony Liguori
    for (i = 0; qdev_alias_table[i].typename; i++) {
60 5f629d94 Alexander Graf
        if (qdev_alias_table[i].arch_mask &&
61 5f629d94 Alexander Graf
            !(qdev_alias_table[i].arch_mask & arch_type)) {
62 5f629d94 Alexander Graf
            continue;
63 5f629d94 Alexander Graf
        }
64 5f629d94 Alexander Graf
65 ee46d8a5 Anthony Liguori
        if (strcmp(qdev_alias_table[i].typename, typename) == 0) {
66 ee46d8a5 Anthony Liguori
            return qdev_alias_table[i].alias;
67 ee46d8a5 Anthony Liguori
        }
68 ee46d8a5 Anthony Liguori
    }
69 ee46d8a5 Anthony Liguori
70 ee46d8a5 Anthony Liguori
    return NULL;
71 ee46d8a5 Anthony Liguori
}
72 ee46d8a5 Anthony Liguori
73 ee46d8a5 Anthony Liguori
static bool qdev_class_has_alias(DeviceClass *dc)
74 ee46d8a5 Anthony Liguori
{
75 ee46d8a5 Anthony Liguori
    return (qdev_class_get_alias(dc) != NULL);
76 ee46d8a5 Anthony Liguori
}
77 ee46d8a5 Anthony Liguori
78 3d1237fb Marcel Apfelbaum
static void qdev_print_class_devinfo(DeviceClass *dc)
79 ee46d8a5 Anthony Liguori
{
80 3d1237fb Marcel Apfelbaum
    DeviceCategory category;
81 ee46d8a5 Anthony Liguori
82 3d1237fb Marcel Apfelbaum
    if (!dc) {
83 ee46d8a5 Anthony Liguori
        return;
84 ee46d8a5 Anthony Liguori
    }
85 ee46d8a5 Anthony Liguori
86 3d1237fb Marcel Apfelbaum
    error_printf("name \"%s\"", object_class_get_name(OBJECT_CLASS(dc)));
87 0d936928 Anthony Liguori
    if (dc->bus_type) {
88 0d936928 Anthony Liguori
        error_printf(", bus %s", dc->bus_type);
89 ee46d8a5 Anthony Liguori
    }
90 ee46d8a5 Anthony Liguori
    if (qdev_class_has_alias(dc)) {
91 ee46d8a5 Anthony Liguori
        error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
92 ee46d8a5 Anthony Liguori
    }
93 3d1237fb Marcel Apfelbaum
    error_printf(", categories");
94 3d1237fb Marcel Apfelbaum
    for (category = 0; category < DEVICE_CATEGORY_MAX; ++category) {
95 3d1237fb Marcel Apfelbaum
        if (test_bit(category, dc->categories)) {
96 3d1237fb Marcel Apfelbaum
            error_printf(" \"%s\"", qdev_category_get_name(category));
97 3d1237fb Marcel Apfelbaum
        }
98 3d1237fb Marcel Apfelbaum
    }
99 ee46d8a5 Anthony Liguori
    if (dc->desc) {
100 ee46d8a5 Anthony Liguori
        error_printf(", desc \"%s\"", dc->desc);
101 ee46d8a5 Anthony Liguori
    }
102 ee46d8a5 Anthony Liguori
    if (dc->no_user) {
103 ee46d8a5 Anthony Liguori
        error_printf(", no-user");
104 ee46d8a5 Anthony Liguori
    }
105 ee46d8a5 Anthony Liguori
    error_printf("\n");
106 ee46d8a5 Anthony Liguori
}
107 ee46d8a5 Anthony Liguori
108 3d1237fb Marcel Apfelbaum
static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
109 3d1237fb Marcel Apfelbaum
{
110 3d1237fb Marcel Apfelbaum
    DeviceClass *dc;
111 3d1237fb Marcel Apfelbaum
112 3d1237fb Marcel Apfelbaum
    dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
113 3d1237fb Marcel Apfelbaum
114 3d1237fb Marcel Apfelbaum
    qdev_print_class_devinfo(dc);
115 3d1237fb Marcel Apfelbaum
}
116 3d1237fb Marcel Apfelbaum
117 ee46d8a5 Anthony Liguori
static int set_property(const char *name, const char *value, void *opaque)
118 ee46d8a5 Anthony Liguori
{
119 ee46d8a5 Anthony Liguori
    DeviceState *dev = opaque;
120 b1fe9bcb Andreas Färber
    Error *err = NULL;
121 ee46d8a5 Anthony Liguori
122 ee46d8a5 Anthony Liguori
    if (strcmp(name, "driver") == 0)
123 ee46d8a5 Anthony Liguori
        return 0;
124 ee46d8a5 Anthony Liguori
    if (strcmp(name, "bus") == 0)
125 ee46d8a5 Anthony Liguori
        return 0;
126 ee46d8a5 Anthony Liguori
127 b1fe9bcb Andreas Färber
    qdev_prop_parse(dev, name, value, &err);
128 b1fe9bcb Andreas Färber
    if (err != NULL) {
129 b1fe9bcb Andreas Färber
        qerror_report_err(err);
130 b1fe9bcb Andreas Färber
        error_free(err);
131 ee46d8a5 Anthony Liguori
        return -1;
132 ee46d8a5 Anthony Liguori
    }
133 ee46d8a5 Anthony Liguori
    return 0;
134 ee46d8a5 Anthony Liguori
}
135 ee46d8a5 Anthony Liguori
136 ee46d8a5 Anthony Liguori
static const char *find_typename_by_alias(const char *alias)
137 ee46d8a5 Anthony Liguori
{
138 ee46d8a5 Anthony Liguori
    int i;
139 ee46d8a5 Anthony Liguori
140 ee46d8a5 Anthony Liguori
    for (i = 0; qdev_alias_table[i].alias; i++) {
141 5f629d94 Alexander Graf
        if (qdev_alias_table[i].arch_mask &&
142 5f629d94 Alexander Graf
            !(qdev_alias_table[i].arch_mask & arch_type)) {
143 5f629d94 Alexander Graf
            continue;
144 5f629d94 Alexander Graf
        }
145 5f629d94 Alexander Graf
146 ee46d8a5 Anthony Liguori
        if (strcmp(qdev_alias_table[i].alias, alias) == 0) {
147 ee46d8a5 Anthony Liguori
            return qdev_alias_table[i].typename;
148 ee46d8a5 Anthony Liguori
        }
149 ee46d8a5 Anthony Liguori
    }
150 ee46d8a5 Anthony Liguori
151 ee46d8a5 Anthony Liguori
    return NULL;
152 ee46d8a5 Anthony Liguori
}
153 ee46d8a5 Anthony Liguori
154 3d1237fb Marcel Apfelbaum
static void qdev_print_category_devices(DeviceCategory category)
155 3d1237fb Marcel Apfelbaum
{
156 3d1237fb Marcel Apfelbaum
    DeviceClass *dc;
157 3d1237fb Marcel Apfelbaum
    GSList *list, *curr;
158 3d1237fb Marcel Apfelbaum
159 3d1237fb Marcel Apfelbaum
    list = object_class_get_list(TYPE_DEVICE, false);
160 3d1237fb Marcel Apfelbaum
    for (curr = list; curr; curr = g_slist_next(curr)) {
161 3d1237fb Marcel Apfelbaum
        dc = (DeviceClass *)object_class_dynamic_cast(curr->data, TYPE_DEVICE);
162 3d1237fb Marcel Apfelbaum
        if (!dc->no_user && test_bit(category, dc->categories)) {
163 3d1237fb Marcel Apfelbaum
            qdev_print_class_devinfo(dc);
164 3d1237fb Marcel Apfelbaum
        }
165 3d1237fb Marcel Apfelbaum
    }
166 3d1237fb Marcel Apfelbaum
    g_slist_free(list);
167 3d1237fb Marcel Apfelbaum
}
168 3d1237fb Marcel Apfelbaum
169 ee46d8a5 Anthony Liguori
int qdev_device_help(QemuOpts *opts)
170 ee46d8a5 Anthony Liguori
{
171 ee46d8a5 Anthony Liguori
    const char *driver;
172 ee46d8a5 Anthony Liguori
    Property *prop;
173 ee46d8a5 Anthony Liguori
    ObjectClass *klass;
174 ee46d8a5 Anthony Liguori
175 ee46d8a5 Anthony Liguori
    driver = qemu_opt_get(opts, "driver");
176 c8057f95 Peter Maydell
    if (driver && is_help_option(driver)) {
177 3d1237fb Marcel Apfelbaum
        DeviceCategory category;
178 3d1237fb Marcel Apfelbaum
        for (category = 0; category < DEVICE_CATEGORY_MAX; ++category) {
179 3d1237fb Marcel Apfelbaum
            qdev_print_category_devices(category);
180 3d1237fb Marcel Apfelbaum
        }
181 3d1237fb Marcel Apfelbaum
182 ee46d8a5 Anthony Liguori
        return 1;
183 ee46d8a5 Anthony Liguori
    }
184 ee46d8a5 Anthony Liguori
185 c8057f95 Peter Maydell
    if (!driver || !qemu_opt_has_help_opt(opts)) {
186 ee46d8a5 Anthony Liguori
        return 0;
187 ee46d8a5 Anthony Liguori
    }
188 ee46d8a5 Anthony Liguori
189 ee46d8a5 Anthony Liguori
    klass = object_class_by_name(driver);
190 ee46d8a5 Anthony Liguori
    if (!klass) {
191 ee46d8a5 Anthony Liguori
        const char *typename = find_typename_by_alias(driver);
192 ee46d8a5 Anthony Liguori
193 ee46d8a5 Anthony Liguori
        if (typename) {
194 ee46d8a5 Anthony Liguori
            driver = typename;
195 ee46d8a5 Anthony Liguori
            klass = object_class_by_name(driver);
196 ee46d8a5 Anthony Liguori
        }
197 ee46d8a5 Anthony Liguori
    }
198 ee46d8a5 Anthony Liguori
199 ee46d8a5 Anthony Liguori
    if (!klass) {
200 ee46d8a5 Anthony Liguori
        return 0;
201 ee46d8a5 Anthony Liguori
    }
202 bce54474 Paolo Bonzini
    do {
203 bce54474 Paolo Bonzini
        for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) {
204 bce54474 Paolo Bonzini
            /*
205 bce54474 Paolo Bonzini
             * TODO Properties without a parser are just for dirty hacks.
206 bce54474 Paolo Bonzini
             * qdev_prop_ptr is the only such PropertyInfo.  It's marked
207 bce54474 Paolo Bonzini
             * for removal.  This conditional should be removed along with
208 bce54474 Paolo Bonzini
             * it.
209 bce54474 Paolo Bonzini
             */
210 90ca64a9 Paolo Bonzini
            if (!prop->info->set) {
211 d03d6b4e Anthony Liguori
                continue;           /* no way to set it, don't show */
212 d03d6b4e Anthony Liguori
            }
213 d03d6b4e Anthony Liguori
            error_printf("%s.%s=%s\n", driver, prop->name,
214 d03d6b4e Anthony Liguori
                         prop->info->legacy_name ?: prop->info->name);
215 ee46d8a5 Anthony Liguori
        }
216 bce54474 Paolo Bonzini
        klass = object_class_get_parent(klass);
217 bce54474 Paolo Bonzini
    } while (klass != object_class_by_name(TYPE_DEVICE));
218 ee46d8a5 Anthony Liguori
    return 1;
219 ee46d8a5 Anthony Liguori
}
220 ee46d8a5 Anthony Liguori
221 57c9fafe Anthony Liguori
static Object *qdev_get_peripheral(void)
222 ee46d8a5 Anthony Liguori
{
223 8b45d447 Anthony Liguori
    static Object *dev;
224 ee46d8a5 Anthony Liguori
225 ee46d8a5 Anthony Liguori
    if (dev == NULL) {
226 dfe47e70 Andreas Färber
        dev = container_get(qdev_get_machine(), "/peripheral");
227 ee46d8a5 Anthony Liguori
    }
228 ee46d8a5 Anthony Liguori
229 8b45d447 Anthony Liguori
    return dev;
230 ee46d8a5 Anthony Liguori
}
231 ee46d8a5 Anthony Liguori
232 57c9fafe Anthony Liguori
static Object *qdev_get_peripheral_anon(void)
233 ee46d8a5 Anthony Liguori
{
234 8b45d447 Anthony Liguori
    static Object *dev;
235 ee46d8a5 Anthony Liguori
236 ee46d8a5 Anthony Liguori
    if (dev == NULL) {
237 dfe47e70 Andreas Färber
        dev = container_get(qdev_get_machine(), "/peripheral-anon");
238 ee46d8a5 Anthony Liguori
    }
239 ee46d8a5 Anthony Liguori
240 8b45d447 Anthony Liguori
    return dev;
241 ee46d8a5 Anthony Liguori
}
242 ee46d8a5 Anthony Liguori
243 ee46d8a5 Anthony Liguori
static void qbus_list_bus(DeviceState *dev)
244 ee46d8a5 Anthony Liguori
{
245 ee46d8a5 Anthony Liguori
    BusState *child;
246 ee46d8a5 Anthony Liguori
    const char *sep = " ";
247 ee46d8a5 Anthony Liguori
248 ee46d8a5 Anthony Liguori
    error_printf("child busses at \"%s\":",
249 ee46d8a5 Anthony Liguori
                 dev->id ? dev->id : object_get_typename(OBJECT(dev)));
250 ee46d8a5 Anthony Liguori
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
251 ee46d8a5 Anthony Liguori
        error_printf("%s\"%s\"", sep, child->name);
252 ee46d8a5 Anthony Liguori
        sep = ", ";
253 ee46d8a5 Anthony Liguori
    }
254 ee46d8a5 Anthony Liguori
    error_printf("\n");
255 ee46d8a5 Anthony Liguori
}
256 ee46d8a5 Anthony Liguori
257 ee46d8a5 Anthony Liguori
static void qbus_list_dev(BusState *bus)
258 ee46d8a5 Anthony Liguori
{
259 0866aca1 Anthony Liguori
    BusChild *kid;
260 ee46d8a5 Anthony Liguori
    const char *sep = " ";
261 ee46d8a5 Anthony Liguori
262 ee46d8a5 Anthony Liguori
    error_printf("devices at \"%s\":", bus->name);
263 0866aca1 Anthony Liguori
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
264 0866aca1 Anthony Liguori
        DeviceState *dev = kid->child;
265 ee46d8a5 Anthony Liguori
        error_printf("%s\"%s\"", sep, object_get_typename(OBJECT(dev)));
266 ee46d8a5 Anthony Liguori
        if (dev->id)
267 ee46d8a5 Anthony Liguori
            error_printf("/\"%s\"", dev->id);
268 ee46d8a5 Anthony Liguori
        sep = ", ";
269 ee46d8a5 Anthony Liguori
    }
270 ee46d8a5 Anthony Liguori
    error_printf("\n");
271 ee46d8a5 Anthony Liguori
}
272 ee46d8a5 Anthony Liguori
273 ee46d8a5 Anthony Liguori
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
274 ee46d8a5 Anthony Liguori
{
275 ee46d8a5 Anthony Liguori
    BusState *child;
276 ee46d8a5 Anthony Liguori
277 ee46d8a5 Anthony Liguori
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
278 ee46d8a5 Anthony Liguori
        if (strcmp(child->name, elem) == 0) {
279 ee46d8a5 Anthony Liguori
            return child;
280 ee46d8a5 Anthony Liguori
        }
281 ee46d8a5 Anthony Liguori
    }
282 ee46d8a5 Anthony Liguori
    return NULL;
283 ee46d8a5 Anthony Liguori
}
284 ee46d8a5 Anthony Liguori
285 ee46d8a5 Anthony Liguori
static DeviceState *qbus_find_dev(BusState *bus, char *elem)
286 ee46d8a5 Anthony Liguori
{
287 0866aca1 Anthony Liguori
    BusChild *kid;
288 ee46d8a5 Anthony Liguori
289 ee46d8a5 Anthony Liguori
    /*
290 ee46d8a5 Anthony Liguori
     * try to match in order:
291 ee46d8a5 Anthony Liguori
     *   (1) instance id, if present
292 ee46d8a5 Anthony Liguori
     *   (2) driver name
293 ee46d8a5 Anthony Liguori
     *   (3) driver alias, if present
294 ee46d8a5 Anthony Liguori
     */
295 0866aca1 Anthony Liguori
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
296 0866aca1 Anthony Liguori
        DeviceState *dev = kid->child;
297 ee46d8a5 Anthony Liguori
        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
298 ee46d8a5 Anthony Liguori
            return dev;
299 ee46d8a5 Anthony Liguori
        }
300 ee46d8a5 Anthony Liguori
    }
301 0866aca1 Anthony Liguori
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
302 0866aca1 Anthony Liguori
        DeviceState *dev = kid->child;
303 ee46d8a5 Anthony Liguori
        if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) {
304 ee46d8a5 Anthony Liguori
            return dev;
305 ee46d8a5 Anthony Liguori
        }
306 ee46d8a5 Anthony Liguori
    }
307 0866aca1 Anthony Liguori
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
308 0866aca1 Anthony Liguori
        DeviceState *dev = kid->child;
309 ee46d8a5 Anthony Liguori
        DeviceClass *dc = DEVICE_GET_CLASS(dev);
310 ee46d8a5 Anthony Liguori
311 ee46d8a5 Anthony Liguori
        if (qdev_class_has_alias(dc) &&
312 ee46d8a5 Anthony Liguori
            strcmp(qdev_class_get_alias(dc), elem) == 0) {
313 ee46d8a5 Anthony Liguori
            return dev;
314 ee46d8a5 Anthony Liguori
        }
315 ee46d8a5 Anthony Liguori
    }
316 ee46d8a5 Anthony Liguori
    return NULL;
317 ee46d8a5 Anthony Liguori
}
318 ee46d8a5 Anthony Liguori
319 ee46d8a5 Anthony Liguori
static BusState *qbus_find_recursive(BusState *bus, const char *name,
320 0d936928 Anthony Liguori
                                     const char *bus_typename)
321 ee46d8a5 Anthony Liguori
{
322 1395af6f KONRAD Frederic
    BusClass *bus_class = BUS_GET_CLASS(bus);
323 0866aca1 Anthony Liguori
    BusChild *kid;
324 ee46d8a5 Anthony Liguori
    BusState *child, *ret;
325 ee46d8a5 Anthony Liguori
    int match = 1;
326 ee46d8a5 Anthony Liguori
327 ee46d8a5 Anthony Liguori
    if (name && (strcmp(bus->name, name) != 0)) {
328 ee46d8a5 Anthony Liguori
        match = 0;
329 95e2af98 Alexey Kardashevskiy
    } else if (bus_typename && !object_dynamic_cast(OBJECT(bus), bus_typename)) {
330 ee46d8a5 Anthony Liguori
        match = 0;
331 95e2af98 Alexey Kardashevskiy
    } else if ((bus_class->max_dev != 0) && (bus_class->max_dev <= bus->max_index)) {
332 1395af6f KONRAD Frederic
        if (name != NULL) {
333 1395af6f KONRAD Frederic
            /* bus was explicitly specified: return an error. */
334 1395af6f KONRAD Frederic
            qerror_report(ERROR_CLASS_GENERIC_ERROR, "Bus '%s' is full",
335 1395af6f KONRAD Frederic
                          bus->name);
336 1395af6f KONRAD Frederic
            return NULL;
337 1395af6f KONRAD Frederic
        } else {
338 1395af6f KONRAD Frederic
            /* bus was not specified: try to find another one. */
339 1395af6f KONRAD Frederic
            match = 0;
340 1395af6f KONRAD Frederic
        }
341 1395af6f KONRAD Frederic
    }
342 ee46d8a5 Anthony Liguori
    if (match) {
343 ee46d8a5 Anthony Liguori
        return bus;
344 ee46d8a5 Anthony Liguori
    }
345 ee46d8a5 Anthony Liguori
346 0866aca1 Anthony Liguori
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
347 0866aca1 Anthony Liguori
        DeviceState *dev = kid->child;
348 ee46d8a5 Anthony Liguori
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
349 0d936928 Anthony Liguori
            ret = qbus_find_recursive(child, name, bus_typename);
350 ee46d8a5 Anthony Liguori
            if (ret) {
351 ee46d8a5 Anthony Liguori
                return ret;
352 ee46d8a5 Anthony Liguori
            }
353 ee46d8a5 Anthony Liguori
        }
354 ee46d8a5 Anthony Liguori
    }
355 ee46d8a5 Anthony Liguori
    return NULL;
356 ee46d8a5 Anthony Liguori
}
357 ee46d8a5 Anthony Liguori
358 ee46d8a5 Anthony Liguori
static BusState *qbus_find(const char *path)
359 ee46d8a5 Anthony Liguori
{
360 ee46d8a5 Anthony Liguori
    DeviceState *dev;
361 ee46d8a5 Anthony Liguori
    BusState *bus;
362 ee46d8a5 Anthony Liguori
    char elem[128];
363 ee46d8a5 Anthony Liguori
    int pos, len;
364 ee46d8a5 Anthony Liguori
365 ee46d8a5 Anthony Liguori
    /* find start element */
366 ee46d8a5 Anthony Liguori
    if (path[0] == '/') {
367 ee46d8a5 Anthony Liguori
        bus = sysbus_get_default();
368 ee46d8a5 Anthony Liguori
        pos = 0;
369 ee46d8a5 Anthony Liguori
    } else {
370 ee46d8a5 Anthony Liguori
        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
371 ee46d8a5 Anthony Liguori
            assert(!path[0]);
372 ee46d8a5 Anthony Liguori
            elem[0] = len = 0;
373 ee46d8a5 Anthony Liguori
        }
374 ee46d8a5 Anthony Liguori
        bus = qbus_find_recursive(sysbus_get_default(), elem, NULL);
375 ee46d8a5 Anthony Liguori
        if (!bus) {
376 ee46d8a5 Anthony Liguori
            qerror_report(QERR_BUS_NOT_FOUND, elem);
377 ee46d8a5 Anthony Liguori
            return NULL;
378 ee46d8a5 Anthony Liguori
        }
379 ee46d8a5 Anthony Liguori
        pos = len;
380 ee46d8a5 Anthony Liguori
    }
381 ee46d8a5 Anthony Liguori
382 ee46d8a5 Anthony Liguori
    for (;;) {
383 ee46d8a5 Anthony Liguori
        assert(path[pos] == '/' || !path[pos]);
384 ee46d8a5 Anthony Liguori
        while (path[pos] == '/') {
385 ee46d8a5 Anthony Liguori
            pos++;
386 ee46d8a5 Anthony Liguori
        }
387 ee46d8a5 Anthony Liguori
        if (path[pos] == '\0') {
388 ee46d8a5 Anthony Liguori
            return bus;
389 ee46d8a5 Anthony Liguori
        }
390 ee46d8a5 Anthony Liguori
391 ee46d8a5 Anthony Liguori
        /* find device */
392 ee46d8a5 Anthony Liguori
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
393 dfc6f865 Stefan Weil
            g_assert_not_reached();
394 ee46d8a5 Anthony Liguori
            elem[0] = len = 0;
395 ee46d8a5 Anthony Liguori
        }
396 ee46d8a5 Anthony Liguori
        pos += len;
397 ee46d8a5 Anthony Liguori
        dev = qbus_find_dev(bus, elem);
398 ee46d8a5 Anthony Liguori
        if (!dev) {
399 ee46d8a5 Anthony Liguori
            qerror_report(QERR_DEVICE_NOT_FOUND, elem);
400 ee46d8a5 Anthony Liguori
            if (!monitor_cur_is_qmp()) {
401 ee46d8a5 Anthony Liguori
                qbus_list_dev(bus);
402 ee46d8a5 Anthony Liguori
            }
403 ee46d8a5 Anthony Liguori
            return NULL;
404 ee46d8a5 Anthony Liguori
        }
405 ee46d8a5 Anthony Liguori
406 ee46d8a5 Anthony Liguori
        assert(path[pos] == '/' || !path[pos]);
407 ee46d8a5 Anthony Liguori
        while (path[pos] == '/') {
408 ee46d8a5 Anthony Liguori
            pos++;
409 ee46d8a5 Anthony Liguori
        }
410 ee46d8a5 Anthony Liguori
        if (path[pos] == '\0') {
411 ee46d8a5 Anthony Liguori
            /* last specified element is a device.  If it has exactly
412 ee46d8a5 Anthony Liguori
             * one child bus accept it nevertheless */
413 ee46d8a5 Anthony Liguori
            switch (dev->num_child_bus) {
414 ee46d8a5 Anthony Liguori
            case 0:
415 ee46d8a5 Anthony Liguori
                qerror_report(QERR_DEVICE_NO_BUS, elem);
416 ee46d8a5 Anthony Liguori
                return NULL;
417 ee46d8a5 Anthony Liguori
            case 1:
418 ee46d8a5 Anthony Liguori
                return QLIST_FIRST(&dev->child_bus);
419 ee46d8a5 Anthony Liguori
            default:
420 ee46d8a5 Anthony Liguori
                qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
421 ee46d8a5 Anthony Liguori
                if (!monitor_cur_is_qmp()) {
422 ee46d8a5 Anthony Liguori
                    qbus_list_bus(dev);
423 ee46d8a5 Anthony Liguori
                }
424 ee46d8a5 Anthony Liguori
                return NULL;
425 ee46d8a5 Anthony Liguori
            }
426 ee46d8a5 Anthony Liguori
        }
427 ee46d8a5 Anthony Liguori
428 ee46d8a5 Anthony Liguori
        /* find bus */
429 ee46d8a5 Anthony Liguori
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
430 dfc6f865 Stefan Weil
            g_assert_not_reached();
431 ee46d8a5 Anthony Liguori
            elem[0] = len = 0;
432 ee46d8a5 Anthony Liguori
        }
433 ee46d8a5 Anthony Liguori
        pos += len;
434 ee46d8a5 Anthony Liguori
        bus = qbus_find_bus(dev, elem);
435 ee46d8a5 Anthony Liguori
        if (!bus) {
436 ee46d8a5 Anthony Liguori
            qerror_report(QERR_BUS_NOT_FOUND, elem);
437 ee46d8a5 Anthony Liguori
            if (!monitor_cur_is_qmp()) {
438 ee46d8a5 Anthony Liguori
                qbus_list_bus(dev);
439 ee46d8a5 Anthony Liguori
            }
440 ee46d8a5 Anthony Liguori
            return NULL;
441 ee46d8a5 Anthony Liguori
        }
442 ee46d8a5 Anthony Liguori
    }
443 ee46d8a5 Anthony Liguori
}
444 ee46d8a5 Anthony Liguori
445 ee46d8a5 Anthony Liguori
DeviceState *qdev_device_add(QemuOpts *opts)
446 ee46d8a5 Anthony Liguori
{
447 ee46d8a5 Anthony Liguori
    ObjectClass *obj;
448 ee46d8a5 Anthony Liguori
    DeviceClass *k;
449 ee46d8a5 Anthony Liguori
    const char *driver, *path, *id;
450 ee46d8a5 Anthony Liguori
    DeviceState *qdev;
451 2f7bd829 Andreas Färber
    BusState *bus = NULL;
452 ee46d8a5 Anthony Liguori
453 ee46d8a5 Anthony Liguori
    driver = qemu_opt_get(opts, "driver");
454 ee46d8a5 Anthony Liguori
    if (!driver) {
455 ee46d8a5 Anthony Liguori
        qerror_report(QERR_MISSING_PARAMETER, "driver");
456 ee46d8a5 Anthony Liguori
        return NULL;
457 ee46d8a5 Anthony Liguori
    }
458 ee46d8a5 Anthony Liguori
459 ee46d8a5 Anthony Liguori
    /* find driver */
460 ee46d8a5 Anthony Liguori
    obj = object_class_by_name(driver);
461 ee46d8a5 Anthony Liguori
    if (!obj) {
462 ee46d8a5 Anthony Liguori
        const char *typename = find_typename_by_alias(driver);
463 ee46d8a5 Anthony Liguori
464 ee46d8a5 Anthony Liguori
        if (typename) {
465 ee46d8a5 Anthony Liguori
            driver = typename;
466 ee46d8a5 Anthony Liguori
            obj = object_class_by_name(driver);
467 ee46d8a5 Anthony Liguori
        }
468 ee46d8a5 Anthony Liguori
    }
469 ee46d8a5 Anthony Liguori
470 ee46d8a5 Anthony Liguori
    if (!obj) {
471 ee46d8a5 Anthony Liguori
        qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "device type");
472 ee46d8a5 Anthony Liguori
        return NULL;
473 ee46d8a5 Anthony Liguori
    }
474 ee46d8a5 Anthony Liguori
475 ee46d8a5 Anthony Liguori
    k = DEVICE_CLASS(obj);
476 ee46d8a5 Anthony Liguori
477 ee46d8a5 Anthony Liguori
    /* find bus */
478 ee46d8a5 Anthony Liguori
    path = qemu_opt_get(opts, "bus");
479 ee46d8a5 Anthony Liguori
    if (path != NULL) {
480 ee46d8a5 Anthony Liguori
        bus = qbus_find(path);
481 ee46d8a5 Anthony Liguori
        if (!bus) {
482 ee46d8a5 Anthony Liguori
            return NULL;
483 ee46d8a5 Anthony Liguori
        }
484 e912c96f Anthony Liguori
        if (!object_dynamic_cast(OBJECT(bus), k->bus_type)) {
485 ee46d8a5 Anthony Liguori
            qerror_report(QERR_BAD_BUS_FOR_DEVICE,
486 0d936928 Anthony Liguori
                          driver, object_get_typename(OBJECT(bus)));
487 ee46d8a5 Anthony Liguori
            return NULL;
488 ee46d8a5 Anthony Liguori
        }
489 2f7bd829 Andreas Färber
    } else if (k->bus_type != NULL) {
490 0d936928 Anthony Liguori
        bus = qbus_find_recursive(sysbus_get_default(), NULL, k->bus_type);
491 ee46d8a5 Anthony Liguori
        if (!bus) {
492 ee46d8a5 Anthony Liguori
            qerror_report(QERR_NO_BUS_FOR_DEVICE,
493 c3594ed7 Alberto Garcia
                          k->bus_type, driver);
494 ee46d8a5 Anthony Liguori
            return NULL;
495 ee46d8a5 Anthony Liguori
        }
496 ee46d8a5 Anthony Liguori
    }
497 2f7bd829 Andreas Färber
    if (qdev_hotplug && bus && !bus->allow_hotplug) {
498 ee46d8a5 Anthony Liguori
        qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
499 ee46d8a5 Anthony Liguori
        return NULL;
500 ee46d8a5 Anthony Liguori
    }
501 ee46d8a5 Anthony Liguori
502 ee46d8a5 Anthony Liguori
    /* create device, set properties */
503 ee46d8a5 Anthony Liguori
    qdev = DEVICE(object_new(driver));
504 2f7bd829 Andreas Färber
505 2f7bd829 Andreas Färber
    if (bus) {
506 2f7bd829 Andreas Färber
        qdev_set_parent_bus(qdev, bus);
507 2f7bd829 Andreas Färber
    }
508 ee46d8a5 Anthony Liguori
509 ee46d8a5 Anthony Liguori
    id = qemu_opts_id(opts);
510 ee46d8a5 Anthony Liguori
    if (id) {
511 ee46d8a5 Anthony Liguori
        qdev->id = id;
512 b2d4b3f7 Anthony Liguori
    }
513 b2d4b3f7 Anthony Liguori
    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
514 b2d4b3f7 Anthony Liguori
        qdev_free(qdev);
515 b2d4b3f7 Anthony Liguori
        return NULL;
516 b2d4b3f7 Anthony Liguori
    }
517 b2d4b3f7 Anthony Liguori
    if (qdev->id) {
518 57c9fafe Anthony Liguori
        object_property_add_child(qdev_get_peripheral(), qdev->id,
519 57c9fafe Anthony Liguori
                                  OBJECT(qdev), NULL);
520 ee46d8a5 Anthony Liguori
    } else {
521 ee46d8a5 Anthony Liguori
        static int anon_count;
522 ee46d8a5 Anthony Liguori
        gchar *name = g_strdup_printf("device[%d]", anon_count++);
523 57c9fafe Anthony Liguori
        object_property_add_child(qdev_get_peripheral_anon(), name,
524 57c9fafe Anthony Liguori
                                  OBJECT(qdev), NULL);
525 ee46d8a5 Anthony Liguori
        g_free(name);
526 ee46d8a5 Anthony Liguori
    }        
527 f424d5c4 Paolo Bonzini
    if (qdev_init(qdev) < 0) {
528 f424d5c4 Paolo Bonzini
        qerror_report(QERR_DEVICE_INIT_FAILED, driver);
529 f424d5c4 Paolo Bonzini
        return NULL;
530 f424d5c4 Paolo Bonzini
    }
531 ee46d8a5 Anthony Liguori
    qdev->opts = opts;
532 ee46d8a5 Anthony Liguori
    return qdev;
533 ee46d8a5 Anthony Liguori
}
534 ee46d8a5 Anthony Liguori
535 ee46d8a5 Anthony Liguori
536 ee46d8a5 Anthony Liguori
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
537 ee46d8a5 Anthony Liguori
static void qbus_print(Monitor *mon, BusState *bus, int indent);
538 ee46d8a5 Anthony Liguori
539 ee46d8a5 Anthony Liguori
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
540 bce54474 Paolo Bonzini
                             int indent)
541 ee46d8a5 Anthony Liguori
{
542 ee46d8a5 Anthony Liguori
    if (!props)
543 ee46d8a5 Anthony Liguori
        return;
544 d822979b Paolo Bonzini
    for (; props->name; props++) {
545 d822979b Paolo Bonzini
        Error *err = NULL;
546 d822979b Paolo Bonzini
        char *value;
547 d822979b Paolo Bonzini
        char *legacy_name = g_strdup_printf("legacy-%s", props->name);
548 d822979b Paolo Bonzini
        if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
549 d822979b Paolo Bonzini
            value = object_property_get_str(OBJECT(dev), legacy_name, &err);
550 d822979b Paolo Bonzini
        } else {
551 8185bfc1 Paolo Bonzini
            value = object_property_print(OBJECT(dev), props->name, &err);
552 d822979b Paolo Bonzini
        }
553 d822979b Paolo Bonzini
        g_free(legacy_name);
554 d822979b Paolo Bonzini
555 d822979b Paolo Bonzini
        if (err) {
556 d822979b Paolo Bonzini
            error_free(err);
557 d822979b Paolo Bonzini
            continue;
558 ee46d8a5 Anthony Liguori
        }
559 bce54474 Paolo Bonzini
        qdev_printf("%s = %s\n", props->name,
560 d822979b Paolo Bonzini
                    value && *value ? value : "<null>");
561 d822979b Paolo Bonzini
        g_free(value);
562 ee46d8a5 Anthony Liguori
    }
563 ee46d8a5 Anthony Liguori
}
564 ee46d8a5 Anthony Liguori
565 0d936928 Anthony Liguori
static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int indent)
566 0d936928 Anthony Liguori
{
567 0d936928 Anthony Liguori
    BusClass *bc = BUS_GET_CLASS(bus);
568 0d936928 Anthony Liguori
569 0d936928 Anthony Liguori
    if (bc->print_dev) {
570 0d936928 Anthony Liguori
        bc->print_dev(mon, dev, indent);
571 0d936928 Anthony Liguori
    }
572 0d936928 Anthony Liguori
}
573 0d936928 Anthony Liguori
574 ee46d8a5 Anthony Liguori
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
575 ee46d8a5 Anthony Liguori
{
576 bce54474 Paolo Bonzini
    ObjectClass *class;
577 ee46d8a5 Anthony Liguori
    BusState *child;
578 ee46d8a5 Anthony Liguori
    qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
579 ee46d8a5 Anthony Liguori
                dev->id ? dev->id : "");
580 ee46d8a5 Anthony Liguori
    indent += 2;
581 ee46d8a5 Anthony Liguori
    if (dev->num_gpio_in) {
582 ee46d8a5 Anthony Liguori
        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
583 ee46d8a5 Anthony Liguori
    }
584 ee46d8a5 Anthony Liguori
    if (dev->num_gpio_out) {
585 ee46d8a5 Anthony Liguori
        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
586 ee46d8a5 Anthony Liguori
    }
587 bce54474 Paolo Bonzini
    class = object_get_class(OBJECT(dev));
588 bce54474 Paolo Bonzini
    do {
589 bce54474 Paolo Bonzini
        qdev_print_props(mon, dev, DEVICE_CLASS(class)->props, indent);
590 bce54474 Paolo Bonzini
        class = object_class_get_parent(class);
591 bce54474 Paolo Bonzini
    } while (class != object_class_by_name(TYPE_DEVICE));
592 da9fbe76 Gerd Hoffmann
    bus_print_dev(dev->parent_bus, mon, dev, indent);
593 ee46d8a5 Anthony Liguori
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
594 ee46d8a5 Anthony Liguori
        qbus_print(mon, child, indent);
595 ee46d8a5 Anthony Liguori
    }
596 ee46d8a5 Anthony Liguori
}
597 ee46d8a5 Anthony Liguori
598 ee46d8a5 Anthony Liguori
static void qbus_print(Monitor *mon, BusState *bus, int indent)
599 ee46d8a5 Anthony Liguori
{
600 0866aca1 Anthony Liguori
    BusChild *kid;
601 ee46d8a5 Anthony Liguori
602 ee46d8a5 Anthony Liguori
    qdev_printf("bus: %s\n", bus->name);
603 ee46d8a5 Anthony Liguori
    indent += 2;
604 0d936928 Anthony Liguori
    qdev_printf("type %s\n", object_get_typename(OBJECT(bus)));
605 0866aca1 Anthony Liguori
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
606 0866aca1 Anthony Liguori
        DeviceState *dev = kid->child;
607 ee46d8a5 Anthony Liguori
        qdev_print(mon, dev, indent);
608 ee46d8a5 Anthony Liguori
    }
609 ee46d8a5 Anthony Liguori
}
610 ee46d8a5 Anthony Liguori
#undef qdev_printf
611 ee46d8a5 Anthony Liguori
612 84f2d0ea Wenchao Xia
void do_info_qtree(Monitor *mon, const QDict *qdict)
613 ee46d8a5 Anthony Liguori
{
614 ee46d8a5 Anthony Liguori
    if (sysbus_get_default())
615 ee46d8a5 Anthony Liguori
        qbus_print(mon, sysbus_get_default(), 0);
616 ee46d8a5 Anthony Liguori
}
617 ee46d8a5 Anthony Liguori
618 84f2d0ea Wenchao Xia
void do_info_qdm(Monitor *mon, const QDict *qdict)
619 ee46d8a5 Anthony Liguori
{
620 ee46d8a5 Anthony Liguori
    object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, NULL);
621 ee46d8a5 Anthony Liguori
}
622 ee46d8a5 Anthony Liguori
623 ee46d8a5 Anthony Liguori
int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
624 ee46d8a5 Anthony Liguori
{
625 4e89978e Luiz Capitulino
    Error *local_err = NULL;
626 ee46d8a5 Anthony Liguori
    QemuOpts *opts;
627 b09995ae Paolo Bonzini
    DeviceState *dev;
628 ee46d8a5 Anthony Liguori
629 4e89978e Luiz Capitulino
    opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
630 4e89978e Luiz Capitulino
    if (error_is_set(&local_err)) {
631 4e89978e Luiz Capitulino
        qerror_report_err(local_err);
632 4e89978e Luiz Capitulino
        error_free(local_err);
633 ee46d8a5 Anthony Liguori
        return -1;
634 ee46d8a5 Anthony Liguori
    }
635 ee46d8a5 Anthony Liguori
    if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
636 ee46d8a5 Anthony Liguori
        qemu_opts_del(opts);
637 ee46d8a5 Anthony Liguori
        return 0;
638 ee46d8a5 Anthony Liguori
    }
639 b09995ae Paolo Bonzini
    dev = qdev_device_add(opts);
640 b09995ae Paolo Bonzini
    if (!dev) {
641 ee46d8a5 Anthony Liguori
        qemu_opts_del(opts);
642 ee46d8a5 Anthony Liguori
        return -1;
643 ee46d8a5 Anthony Liguori
    }
644 b09995ae Paolo Bonzini
    object_unref(OBJECT(dev));
645 ee46d8a5 Anthony Liguori
    return 0;
646 ee46d8a5 Anthony Liguori
}
647 ee46d8a5 Anthony Liguori
648 a15fef21 Luiz Capitulino
void qmp_device_del(const char *id, Error **errp)
649 ee46d8a5 Anthony Liguori
{
650 ee46d8a5 Anthony Liguori
    DeviceState *dev;
651 ee46d8a5 Anthony Liguori
652 ee46d8a5 Anthony Liguori
    dev = qdev_find_recursive(sysbus_get_default(), id);
653 ee46d8a5 Anthony Liguori
    if (NULL == dev) {
654 a15fef21 Luiz Capitulino
        error_set(errp, QERR_DEVICE_NOT_FOUND, id);
655 a15fef21 Luiz Capitulino
        return;
656 56f9107e Luiz Capitulino
    }
657 56f9107e Luiz Capitulino
658 a15fef21 Luiz Capitulino
    qdev_unplug(dev, errp);
659 ee46d8a5 Anthony Liguori
}
660 ee46d8a5 Anthony Liguori
661 ee46d8a5 Anthony Liguori
void qdev_machine_init(void)
662 ee46d8a5 Anthony Liguori
{
663 ee46d8a5 Anthony Liguori
    qdev_get_peripheral_anon();
664 ee46d8a5 Anthony Liguori
    qdev_get_peripheral();
665 ee46d8a5 Anthony Liguori
}
666 4d454574 Paolo Bonzini
667 4d454574 Paolo Bonzini
QemuOptsList qemu_device_opts = {
668 4d454574 Paolo Bonzini
    .name = "device",
669 4d454574 Paolo Bonzini
    .implied_opt_name = "driver",
670 4d454574 Paolo Bonzini
    .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
671 4d454574 Paolo Bonzini
    .desc = {
672 4d454574 Paolo Bonzini
        /*
673 4d454574 Paolo Bonzini
         * no elements => accept any
674 4d454574 Paolo Bonzini
         * sanity checking will happen later
675 4d454574 Paolo Bonzini
         * when setting device properties
676 4d454574 Paolo Bonzini
         */
677 4d454574 Paolo Bonzini
        { /* end of list */ }
678 4d454574 Paolo Bonzini
    },
679 4d454574 Paolo Bonzini
};
680 4d454574 Paolo Bonzini
681 4d454574 Paolo Bonzini
QemuOptsList qemu_global_opts = {
682 4d454574 Paolo Bonzini
    .name = "global",
683 4d454574 Paolo Bonzini
    .head = QTAILQ_HEAD_INITIALIZER(qemu_global_opts.head),
684 4d454574 Paolo Bonzini
    .desc = {
685 4d454574 Paolo Bonzini
        {
686 4d454574 Paolo Bonzini
            .name = "driver",
687 4d454574 Paolo Bonzini
            .type = QEMU_OPT_STRING,
688 4d454574 Paolo Bonzini
        },{
689 4d454574 Paolo Bonzini
            .name = "property",
690 4d454574 Paolo Bonzini
            .type = QEMU_OPT_STRING,
691 4d454574 Paolo Bonzini
        },{
692 4d454574 Paolo Bonzini
            .name = "value",
693 4d454574 Paolo Bonzini
            .type = QEMU_OPT_STRING,
694 4d454574 Paolo Bonzini
        },
695 4d454574 Paolo Bonzini
        { /* end of list */ }
696 4d454574 Paolo Bonzini
    },
697 4d454574 Paolo Bonzini
};
698 4d454574 Paolo Bonzini
699 4d454574 Paolo Bonzini
int qemu_global_option(const char *str)
700 4d454574 Paolo Bonzini
{
701 4d454574 Paolo Bonzini
    char driver[64], property[64];
702 4d454574 Paolo Bonzini
    QemuOpts *opts;
703 4d454574 Paolo Bonzini
    int rc, offset;
704 4d454574 Paolo Bonzini
705 4d454574 Paolo Bonzini
    rc = sscanf(str, "%63[^.].%63[^=]%n", driver, property, &offset);
706 4d454574 Paolo Bonzini
    if (rc < 2 || str[offset] != '=') {
707 4d454574 Paolo Bonzini
        error_report("can't parse: \"%s\"", str);
708 4d454574 Paolo Bonzini
        return -1;
709 4d454574 Paolo Bonzini
    }
710 4d454574 Paolo Bonzini
711 4d454574 Paolo Bonzini
    opts = qemu_opts_create_nofail(&qemu_global_opts);
712 4d454574 Paolo Bonzini
    qemu_opt_set(opts, "driver", driver);
713 4d454574 Paolo Bonzini
    qemu_opt_set(opts, "property", property);
714 4d454574 Paolo Bonzini
    qemu_opt_set(opts, "value", str+offset+1);
715 4d454574 Paolo Bonzini
    return 0;
716 4d454574 Paolo Bonzini
}