Statistics
| Branch: | Revision:

root / hw / qdev.c @ 3ced9f7a

History | View | Annotate | Download (20.3 kB)

1
/*
2
 *  Dynamic device configuration and creation.
3
 *
4
 *  Copyright (c) 2009 CodeSourcery
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18
 */
19

    
20
/* The theory here is that it should be possible to create a machine without
21
   knowledge of specific devices.  Historically board init routines have
22
   passed a bunch of arguments to each device, requiring the board know
23
   exactly which device it is dealing with.  This file provides an abstract
24
   API for device configuration and initialization.  Devices will generally
25
   inherit from a particular bus (e.g. PCI or I2C) rather than
26
   this API directly.  */
27

    
28
#include "net.h"
29
#include "qdev.h"
30
#include "sysemu.h"
31
#include "monitor.h"
32
#include "qerror.h"
33

    
34
static int qdev_hotplug = 0;
35

    
36
/* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
37
static BusState *main_system_bus;
38

    
39
DeviceInfo *device_info_list;
40

    
41
static BusState *qbus_find_recursive(BusState *bus, const char *name,
42
                                     const BusInfo *info);
43
static BusState *qbus_find(const char *path);
44

    
45
/* Register a new device type.  */
46
void qdev_register(DeviceInfo *info)
47
{
48
    assert(info->size >= sizeof(DeviceState));
49
    assert(!info->next);
50

    
51
    info->next = device_info_list;
52
    device_info_list = info;
53
}
54

    
55
static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
56
{
57
    DeviceInfo *info;
58

    
59
    /* first check device names */
60
    for (info = device_info_list; info != NULL; info = info->next) {
61
        if (bus_info && info->bus_info != bus_info)
62
            continue;
63
        if (strcmp(info->name, name) != 0)
64
            continue;
65
        return info;
66
    }
67

    
68
    /* failing that check the aliases */
69
    for (info = device_info_list; info != NULL; info = info->next) {
70
        if (bus_info && info->bus_info != bus_info)
71
            continue;
72
        if (!info->alias)
73
            continue;
74
        if (strcmp(info->alias, name) != 0)
75
            continue;
76
        return info;
77
    }
78
    return NULL;
79
}
80

    
81
/* Create a new device.  This only initializes the device state structure
82
   and allows properties to be set.  qdev_init should be called to
83
   initialize the actual device emulation.  */
84
DeviceState *qdev_create(BusState *bus, const char *name)
85
{
86
    DeviceInfo *info;
87
    DeviceState *dev;
88

    
89
    if (!bus) {
90
        if (!main_system_bus) {
91
            main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
92
        }
93
        bus = main_system_bus;
94
    }
95

    
96
    info = qdev_find_info(bus->info, name);
97
    if (!info) {
98
        hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
99
    }
100

    
101
    dev = qemu_mallocz(info->size);
102
    dev->info = info;
103
    dev->parent_bus = bus;
104
    qdev_prop_set_defaults(dev, dev->info->props);
105
    qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
106
    qdev_prop_set_compat(dev);
107
    QLIST_INSERT_HEAD(&bus->children, dev, sibling);
108
    if (qdev_hotplug) {
109
        assert(bus->allow_hotplug);
110
        dev->hotplugged = 1;
111
    }
112
    dev->state = DEV_STATE_CREATED;
113
    return dev;
114
}
115

    
116
static int qdev_print_devinfo(DeviceInfo *info, char *dest, int len)
117
{
118
    int pos = 0;
119
    int ret;
120

    
121
    ret = snprintf(dest+pos, len-pos, "name \"%s\", bus %s",
122
                   info->name, info->bus_info->name);
123
    pos += MIN(len-pos,ret);
124
    if (info->alias) {
125
        ret = snprintf(dest+pos, len-pos, ", alias \"%s\"", info->alias);
126
        pos += MIN(len-pos,ret);
127
    }
128
    if (info->desc) {
129
        ret = snprintf(dest+pos, len-pos, ", desc \"%s\"", info->desc);
130
        pos += MIN(len-pos,ret);
131
    }
132
    if (info->no_user) {
133
        ret = snprintf(dest+pos, len-pos, ", no-user");
134
        pos += MIN(len-pos,ret);
135
    }
136
    return pos;
137
}
138

    
139
static int set_property(const char *name, const char *value, void *opaque)
140
{
141
    DeviceState *dev = opaque;
142

    
143
    if (strcmp(name, "driver") == 0)
144
        return 0;
145
    if (strcmp(name, "bus") == 0)
146
        return 0;
147

    
148
    if (qdev_prop_parse(dev, name, value) == -1) {
149
        qemu_error("can't set property \"%s\" to \"%s\" for \"%s\"\n",
150
                   name, value, dev->info->name);
151
        return -1;
152
    }
153
    return 0;
154
}
155

    
156
DeviceState *qdev_device_add(QemuOpts *opts)
157
{
158
    const char *driver, *path, *id;
159
    DeviceInfo *info;
160
    DeviceState *qdev;
161
    BusState *bus;
162

    
163
    driver = qemu_opt_get(opts, "driver");
164
    if (!driver) {
165
        qemu_error("-device: no driver specified\n");
166
        return NULL;
167
    }
168
    if (strcmp(driver, "?") == 0) {
169
        char msg[256];
170
        for (info = device_info_list; info != NULL; info = info->next) {
171
            qdev_print_devinfo(info, msg, sizeof(msg));
172
            qemu_error("%s\n", msg);
173
        }
174
        return NULL;
175
    }
176

    
177
    /* find driver */
178
    info = qdev_find_info(NULL, driver);
179
    if (!info) {
180
        qemu_error_new(QERR_DEVICE_NOT_FOUND, driver);
181
        return NULL;
182
    }
183
    if (info->no_user) {
184
        qemu_error("device \"%s\" can't be added via command line\n",
185
                   info->name);
186
        return NULL;
187
    }
188

    
189
    /* find bus */
190
    path = qemu_opt_get(opts, "bus");
191
    if (path != NULL) {
192
        bus = qbus_find(path);
193
    } else {
194
        bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
195
    }
196
    if (!bus) {
197
        qemu_error("Did not find %s bus for %s\n",
198
                   path ? path : info->bus_info->name, info->name);
199
        return NULL;
200
    }
201
    if (qdev_hotplug && !bus->allow_hotplug) {
202
        qemu_error("Bus %s does not support hotplugging\n",
203
                   bus->name);
204
        return NULL;
205
    }
206

    
207
    /* create device, set properties */
208
    qdev = qdev_create(bus, driver);
209
    id = qemu_opts_id(opts);
210
    if (id) {
211
        qdev->id = id;
212
    }
213
    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
214
        qdev_free(qdev);
215
        return NULL;
216
    }
217
    if (qdev_init(qdev) < 0) {
218
        qemu_error("Error initializing device %s\n", driver);
219
        return NULL;
220
    }
221
    qdev->opts = opts;
222
    return qdev;
223
}
224

    
225
static void qdev_reset(void *opaque)
226
{
227
    DeviceState *dev = opaque;
228
    if (dev->info->reset)
229
        dev->info->reset(dev);
230
}
231

    
232
/* Initialize a device.  Device properties should be set before calling
233
   this function.  IRQs and MMIO regions should be connected/mapped after
234
   calling this function.
235
   On failure, destroy the device and return negative value.
236
   Return 0 on success.  */
237
int qdev_init(DeviceState *dev)
238
{
239
    int rc;
240

    
241
    assert(dev->state == DEV_STATE_CREATED);
242
    rc = dev->info->init(dev, dev->info);
243
    if (rc < 0) {
244
        qdev_free(dev);
245
        return rc;
246
    }
247
    qemu_register_reset(qdev_reset, dev);
248
    if (dev->info->vmsd)
249
        vmstate_register(-1, dev->info->vmsd, dev);
250
    dev->state = DEV_STATE_INITIALIZED;
251
    return 0;
252
}
253

    
254
int qdev_unplug(DeviceState *dev)
255
{
256
    if (!dev->parent_bus->allow_hotplug) {
257
        qemu_error("Bus %s does not support hotplugging\n",
258
                   dev->parent_bus->name);
259
        return -1;
260
    }
261
    assert(dev->info->unplug != NULL);
262

    
263
    return dev->info->unplug(dev);
264
}
265

    
266
/* can be used as ->unplug() callback for the simple cases */
267
int qdev_simple_unplug_cb(DeviceState *dev)
268
{
269
    /* just zap it */
270
    qdev_free(dev);
271
    return 0;
272
}
273

    
274
/* Like qdev_init(), but terminate program via hw_error() instead of
275
   returning an error value.  This is okay during machine creation.
276
   Don't use for hotplug, because there callers need to recover from
277
   failure.  Exception: if you know the device's init() callback can't
278
   fail, then qdev_init_nofail() can't fail either, and is therefore
279
   usable even then.  But relying on the device implementation that
280
   way is somewhat unclean, and best avoided.  */
281
void qdev_init_nofail(DeviceState *dev)
282
{
283
    DeviceInfo *info = dev->info;
284

    
285
    if (qdev_init(dev) < 0)
286
        hw_error("Initialization of device %s failed\n", info->name);
287
}
288

    
289
/* Unlink device from bus and free the structure.  */
290
void qdev_free(DeviceState *dev)
291
{
292
    BusState *bus;
293

    
294
    if (dev->state == DEV_STATE_INITIALIZED) {
295
        while (dev->num_child_bus) {
296
            bus = QLIST_FIRST(&dev->child_bus);
297
            qbus_free(bus);
298
        }
299
#if 0 /* FIXME: need sane vmstate_unregister function */
300
        if (dev->info->vmsd)
301
            vmstate_unregister(dev->info->vmsd, dev);
302
#endif
303
        if (dev->info->exit)
304
            dev->info->exit(dev);
305
        if (dev->opts)
306
            qemu_opts_del(dev->opts);
307
    }
308
    qemu_unregister_reset(qdev_reset, dev);
309
    QLIST_REMOVE(dev, sibling);
310
    qemu_free(dev);
311
}
312

    
313
void qdev_machine_creation_done(void)
314
{
315
    /*
316
     * ok, initial machine setup is done, starting from now we can
317
     * only create hotpluggable devices
318
     */
319
    qdev_hotplug = 1;
320
}
321

    
322
/* Get a character (serial) device interface.  */
323
CharDriverState *qdev_init_chardev(DeviceState *dev)
324
{
325
    static int next_serial;
326
    static int next_virtconsole;
327
    /* FIXME: This is a nasty hack that needs to go away.  */
328
    if (strncmp(dev->info->name, "virtio", 6) == 0) {
329
        return virtcon_hds[next_virtconsole++];
330
    } else {
331
        return serial_hds[next_serial++];
332
    }
333
}
334

    
335
BusState *qdev_get_parent_bus(DeviceState *dev)
336
{
337
    return dev->parent_bus;
338
}
339

    
340
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
341
{
342
    assert(dev->num_gpio_in == 0);
343
    dev->num_gpio_in = n;
344
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
345
}
346

    
347
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
348
{
349
    assert(dev->num_gpio_out == 0);
350
    dev->num_gpio_out = n;
351
    dev->gpio_out = pins;
352
}
353

    
354
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
355
{
356
    assert(n >= 0 && n < dev->num_gpio_in);
357
    return dev->gpio_in[n];
358
}
359

    
360
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
361
{
362
    assert(n >= 0 && n < dev->num_gpio_out);
363
    dev->gpio_out[n] = pin;
364
}
365

    
366
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
367
{
368
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
369
    if (nd->vlan)
370
        qdev_prop_set_vlan(dev, "vlan", nd->vlan);
371
    if (nd->netdev)
372
        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
373
    if (nd->nvectors != NIC_NVECTORS_UNSPECIFIED &&
374
        qdev_prop_exists(dev, "vectors")) {
375
        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
376
    }
377
}
378

    
379
static int next_block_unit[IF_COUNT];
380

    
381
/* Get a block device.  This should only be used for single-drive devices
382
   (e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the
383
   appropriate bus.  */
384
BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
385
{
386
    int unit = next_block_unit[type]++;
387
    DriveInfo *dinfo;
388

    
389
    dinfo = drive_get(type, 0, unit);
390
    return dinfo ? dinfo->bdrv : NULL;
391
}
392

    
393
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
394
{
395
    BusState *bus;
396

    
397
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
398
        if (strcmp(name, bus->name) == 0) {
399
            return bus;
400
        }
401
    }
402
    return NULL;
403
}
404

    
405
static BusState *qbus_find_recursive(BusState *bus, const char *name,
406
                                     const BusInfo *info)
407
{
408
    DeviceState *dev;
409
    BusState *child, *ret;
410
    int match = 1;
411

    
412
    if (name && (strcmp(bus->name, name) != 0)) {
413
        match = 0;
414
    }
415
    if (info && (bus->info != info)) {
416
        match = 0;
417
    }
418
    if (match) {
419
        return bus;
420
    }
421

    
422
    QLIST_FOREACH(dev, &bus->children, sibling) {
423
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
424
            ret = qbus_find_recursive(child, name, info);
425
            if (ret) {
426
                return ret;
427
            }
428
        }
429
    }
430
    return NULL;
431
}
432

    
433
static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
434
{
435
    DeviceState *dev, *ret;
436
    BusState *child;
437

    
438
    QLIST_FOREACH(dev, &bus->children, sibling) {
439
        if (dev->id && strcmp(dev->id, id) == 0)
440
            return dev;
441
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
442
            ret = qdev_find_recursive(child, id);
443
            if (ret) {
444
                return ret;
445
            }
446
        }
447
    }
448
    return NULL;
449
}
450

    
451
static void qbus_list_bus(DeviceState *dev, char *dest, int len)
452
{
453
    BusState *child;
454
    const char *sep = " ";
455
    int pos = 0;
456

    
457
    pos += snprintf(dest+pos, len-pos,"child busses at \"%s\":",
458
                    dev->id ? dev->id : dev->info->name);
459
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
460
        pos += snprintf(dest+pos, len-pos, "%s\"%s\"", sep, child->name);
461
        sep = ", ";
462
    }
463
}
464

    
465
static void qbus_list_dev(BusState *bus, char *dest, int len)
466
{
467
    DeviceState *dev;
468
    const char *sep = " ";
469
    int pos = 0;
470

    
471
    pos += snprintf(dest+pos, len-pos, "devices at \"%s\":",
472
                    bus->name);
473
    QLIST_FOREACH(dev, &bus->children, sibling) {
474
        pos += snprintf(dest+pos, len-pos, "%s\"%s\"",
475
                        sep, dev->info->name);
476
        if (dev->id)
477
            pos += snprintf(dest+pos, len-pos, "/\"%s\"", dev->id);
478
        sep = ", ";
479
    }
480
}
481

    
482
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
483
{
484
    BusState *child;
485

    
486
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
487
        if (strcmp(child->name, elem) == 0) {
488
            return child;
489
        }
490
    }
491
    return NULL;
492
}
493

    
494
static DeviceState *qbus_find_dev(BusState *bus, char *elem)
495
{
496
    DeviceState *dev;
497

    
498
    /*
499
     * try to match in order:
500
     *   (1) instance id, if present
501
     *   (2) driver name
502
     *   (3) driver alias, if present
503
     */
504
    QLIST_FOREACH(dev, &bus->children, sibling) {
505
        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
506
            return dev;
507
        }
508
    }
509
    QLIST_FOREACH(dev, &bus->children, sibling) {
510
        if (strcmp(dev->info->name, elem) == 0) {
511
            return dev;
512
        }
513
    }
514
    QLIST_FOREACH(dev, &bus->children, sibling) {
515
        if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
516
            return dev;
517
        }
518
    }
519
    return NULL;
520
}
521

    
522
static BusState *qbus_find(const char *path)
523
{
524
    DeviceState *dev;
525
    BusState *bus;
526
    char elem[128], msg[256];
527
    int pos, len;
528

    
529
    /* find start element */
530
    if (path[0] == '/') {
531
        bus = main_system_bus;
532
        pos = 0;
533
    } else {
534
        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
535
            qemu_error("path parse error (\"%s\")\n", path);
536
            return NULL;
537
        }
538
        bus = qbus_find_recursive(main_system_bus, elem, NULL);
539
        if (!bus) {
540
            qemu_error("bus \"%s\" not found\n", elem);
541
            return NULL;
542
        }
543
        pos = len;
544
    }
545

    
546
    for (;;) {
547
        if (path[pos] == '\0') {
548
            /* we are done */
549
            return bus;
550
        }
551

    
552
        /* find device */
553
        if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
554
            qemu_error("path parse error (\"%s\" pos %d)\n", path, pos);
555
            return NULL;
556
        }
557
        pos += len;
558
        dev = qbus_find_dev(bus, elem);
559
        if (!dev) {
560
            qbus_list_dev(bus, msg, sizeof(msg));
561
            qemu_error("device \"%s\" not found\n%s\n", elem, msg);
562
            return NULL;
563
        }
564
        if (path[pos] == '\0') {
565
            /* last specified element is a device.  If it has exactly
566
             * one child bus accept it nevertheless */
567
            switch (dev->num_child_bus) {
568
            case 0:
569
                qemu_error("device has no child bus (%s)\n", path);
570
                return NULL;
571
            case 1:
572
                return QLIST_FIRST(&dev->child_bus);
573
            default:
574
                qbus_list_bus(dev, msg, sizeof(msg));
575
                qemu_error("device has multiple child busses (%s)\n%s\n",
576
                           path, msg);
577
                return NULL;
578
            }
579
        }
580

    
581
        /* find bus */
582
        if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
583
            qemu_error("path parse error (\"%s\" pos %d)\n", path, pos);
584
            return NULL;
585
        }
586
        pos += len;
587
        bus = qbus_find_bus(dev, elem);
588
        if (!bus) {
589
            qbus_list_bus(dev, msg, sizeof(msg));
590
            qemu_error("child bus \"%s\" not found\n%s\n", elem, msg);
591
            return NULL;
592
        }
593
    }
594
}
595

    
596
void qbus_create_inplace(BusState *bus, BusInfo *info,
597
                         DeviceState *parent, const char *name)
598
{
599
    char *buf;
600
    int i,len;
601

    
602
    bus->info = info;
603
    bus->parent = parent;
604

    
605
    if (name) {
606
        /* use supplied name */
607
        bus->name = qemu_strdup(name);
608
    } else if (parent && parent->id) {
609
        /* parent device has id -> use it for bus name */
610
        len = strlen(parent->id) + 16;
611
        buf = qemu_malloc(len);
612
        snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
613
        bus->name = buf;
614
    } else {
615
        /* no id -> use lowercase bus type for bus name */
616
        len = strlen(info->name) + 16;
617
        buf = qemu_malloc(len);
618
        len = snprintf(buf, len, "%s.%d", info->name,
619
                       parent ? parent->num_child_bus : 0);
620
        for (i = 0; i < len; i++)
621
            buf[i] = qemu_tolower(buf[i]);
622
        bus->name = buf;
623
    }
624

    
625
    QLIST_INIT(&bus->children);
626
    if (parent) {
627
        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
628
        parent->num_child_bus++;
629
    }
630

    
631
}
632

    
633
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
634
{
635
    BusState *bus;
636

    
637
    bus = qemu_mallocz(info->size);
638
    bus->qdev_allocated = 1;
639
    qbus_create_inplace(bus, info, parent, name);
640
    return bus;
641
}
642

    
643
void qbus_free(BusState *bus)
644
{
645
    DeviceState *dev;
646

    
647
    while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
648
        qdev_free(dev);
649
    }
650
    if (bus->parent) {
651
        QLIST_REMOVE(bus, sibling);
652
        bus->parent->num_child_bus--;
653
    }
654
    if (bus->qdev_allocated) {
655
        qemu_free(bus);
656
    }
657
}
658

    
659
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
660
static void qbus_print(Monitor *mon, BusState *bus, int indent);
661

    
662
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
663
                             const char *prefix, int indent)
664
{
665
    char buf[64];
666

    
667
    if (!props)
668
        return;
669
    while (props->name) {
670
        if (props->info->print) {
671
            props->info->print(dev, props, buf, sizeof(buf));
672
            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
673
        }
674
        props++;
675
    }
676
}
677

    
678
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
679
{
680
    BusState *child;
681
    qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
682
                dev->id ? dev->id : "");
683
    indent += 2;
684
    if (dev->num_gpio_in) {
685
        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
686
    }
687
    if (dev->num_gpio_out) {
688
        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
689
    }
690
    qdev_print_props(mon, dev, dev->info->props, "dev", indent);
691
    qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
692
    if (dev->parent_bus->info->print_dev)
693
        dev->parent_bus->info->print_dev(mon, dev, indent);
694
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
695
        qbus_print(mon, child, indent);
696
    }
697
}
698

    
699
static void qbus_print(Monitor *mon, BusState *bus, int indent)
700
{
701
    struct DeviceState *dev;
702

    
703
    qdev_printf("bus: %s\n", bus->name);
704
    indent += 2;
705
    qdev_printf("type %s\n", bus->info->name);
706
    QLIST_FOREACH(dev, &bus->children, sibling) {
707
        qdev_print(mon, dev, indent);
708
    }
709
}
710
#undef qdev_printf
711

    
712
void do_info_qtree(Monitor *mon)
713
{
714
    if (main_system_bus)
715
        qbus_print(mon, main_system_bus, 0);
716
}
717

    
718
void do_info_qdm(Monitor *mon)
719
{
720
    DeviceInfo *info;
721
    char msg[256];
722

    
723
    for (info = device_info_list; info != NULL; info = info->next) {
724
        qdev_print_devinfo(info, msg, sizeof(msg));
725
        monitor_printf(mon, "%s\n", msg);
726
    }
727
}
728

    
729
void do_device_add(Monitor *mon, const QDict *qdict)
730
{
731
    QemuOpts *opts;
732

    
733
    opts = qemu_opts_parse(&qemu_device_opts,
734
                           qdict_get_str(qdict, "config"), "driver");
735
    if (opts)
736
        qdev_device_add(opts);
737
}
738

    
739
void do_device_del(Monitor *mon, const QDict *qdict)
740
{
741
    const char *id = qdict_get_str(qdict, "id");
742
    DeviceState *dev;
743

    
744
    dev = qdev_find_recursive(main_system_bus, id);
745
    if (NULL == dev) {
746
        qemu_error("Device '%s' not found\n", id);
747
        return;
748
    }
749
    qdev_unplug(dev);
750
}