Statistics
| Branch: | Revision:

root / hw / qdev.c @ 0c17542d

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
static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
82
{
83
    DeviceState *dev;
84

    
85
    assert(bus->info == info->bus_info);
86
    dev = qemu_mallocz(info->size);
87
    dev->info = info;
88
    dev->parent_bus = bus;
89
    qdev_prop_set_defaults(dev, dev->info->props);
90
    qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
91
    qdev_prop_set_globals(dev);
92
    QLIST_INSERT_HEAD(&bus->children, dev, sibling);
93
    if (qdev_hotplug) {
94
        assert(bus->allow_hotplug);
95
        dev->hotplugged = 1;
96
    }
97
    dev->state = DEV_STATE_CREATED;
98
    return dev;
99
}
100

    
101
/* Create a new device.  This only initializes the device state structure
102
   and allows properties to be set.  qdev_init should be called to
103
   initialize the actual device emulation.  */
104
DeviceState *qdev_create(BusState *bus, const char *name)
105
{
106
    DeviceInfo *info;
107

    
108
    if (!bus) {
109
        if (!main_system_bus) {
110
            main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
111
        }
112
        bus = main_system_bus;
113
    }
114

    
115
    info = qdev_find_info(bus->info, name);
116
    if (!info) {
117
        hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
118
    }
119

    
120
    return qdev_create_from_info(bus, info);
121
}
122

    
123
static void qdev_print_devinfo(DeviceInfo *info)
124
{
125
    error_printf("name \"%s\", bus %s",
126
                 info->name, info->bus_info->name);
127
    if (info->alias) {
128
        error_printf(", alias \"%s\"", info->alias);
129
    }
130
    if (info->desc) {
131
        error_printf(", desc \"%s\"", info->desc);
132
    }
133
    if (info->no_user) {
134
        error_printf(", no-user");
135
    }
136
    error_printf("\n");
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
        error_report("can't set property \"%s\" to \"%s\" for \"%s\"",
150
                     name, value, dev->info->name);
151
        return -1;
152
    }
153
    return 0;
154
}
155

    
156
int qdev_device_help(QemuOpts *opts)
157
{
158
    const char *driver;
159
    DeviceInfo *info;
160
    Property *prop;
161

    
162
    driver = qemu_opt_get(opts, "driver");
163
    if (driver && !strcmp(driver, "?")) {
164
        for (info = device_info_list; info != NULL; info = info->next) {
165
            qdev_print_devinfo(info);
166
        }
167
        return 1;
168
    }
169

    
170
    if (!qemu_opt_get(opts, "?")) {
171
        return 0;
172
    }
173

    
174
    info = qdev_find_info(NULL, driver);
175
    if (!info) {
176
        return 0;
177
    }
178

    
179
    for (prop = info->props; prop && prop->name; prop++) {
180
        error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
181
    }
182
    return 1;
183
}
184

    
185
DeviceState *qdev_device_add(QemuOpts *opts)
186
{
187
    const char *driver, *path, *id;
188
    DeviceInfo *info;
189
    DeviceState *qdev;
190
    BusState *bus;
191

    
192
    driver = qemu_opt_get(opts, "driver");
193
    if (!driver) {
194
        error_report("-device: no driver specified");
195
        return NULL;
196
    }
197

    
198
    /* find driver */
199
    info = qdev_find_info(NULL, driver);
200
    if (!info) {
201
        qerror_report(QERR_DEVICE_NOT_FOUND, driver);
202
        return NULL;
203
    }
204
    if (info->no_user) {
205
        error_report("device \"%s\" can't be added via command line",
206
                     info->name);
207
        return NULL;
208
    }
209

    
210
    /* find bus */
211
    path = qemu_opt_get(opts, "bus");
212
    if (path != NULL) {
213
        bus = qbus_find(path);
214
        if (bus && bus->info != info->bus_info) {
215
            error_report("Device '%s' can't go on a %s bus",
216
                         driver, bus->info->name);
217
            return NULL;
218
        }
219
    } else {
220
        bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
221
    }
222
    if (!bus) {
223
        error_report("Did not find %s bus for %s",
224
                     path ? path : info->bus_info->name, info->name);
225
        return NULL;
226
    }
227
    if (qdev_hotplug && !bus->allow_hotplug) {
228
        error_report("Bus %s does not support hotplugging",
229
                     bus->name);
230
        return NULL;
231
    }
232

    
233
    /* create device, set properties */
234
    qdev = qdev_create_from_info(bus, info);
235
    id = qemu_opts_id(opts);
236
    if (id) {
237
        qdev->id = id;
238
    }
239
    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
240
        qdev_free(qdev);
241
        return NULL;
242
    }
243
    if (qdev_init(qdev) < 0) {
244
        error_report("Error initializing device %s", driver);
245
        return NULL;
246
    }
247
    qdev->opts = opts;
248
    return qdev;
249
}
250

    
251
static void qdev_reset(void *opaque)
252
{
253
    DeviceState *dev = opaque;
254
    if (dev->info->reset)
255
        dev->info->reset(dev);
256
}
257

    
258
/* Initialize a device.  Device properties should be set before calling
259
   this function.  IRQs and MMIO regions should be connected/mapped after
260
   calling this function.
261
   On failure, destroy the device and return negative value.
262
   Return 0 on success.  */
263
int qdev_init(DeviceState *dev)
264
{
265
    int rc;
266

    
267
    assert(dev->state == DEV_STATE_CREATED);
268
    rc = dev->info->init(dev, dev->info);
269
    if (rc < 0) {
270
        qdev_free(dev);
271
        return rc;
272
    }
273
    qemu_register_reset(qdev_reset, dev);
274
    if (dev->info->vmsd)
275
        vmstate_register(-1, dev->info->vmsd, dev);
276
    dev->state = DEV_STATE_INITIALIZED;
277
    return 0;
278
}
279

    
280
int qdev_unplug(DeviceState *dev)
281
{
282
    if (!dev->parent_bus->allow_hotplug) {
283
        error_report("Bus %s does not support hotplugging",
284
                     dev->parent_bus->name);
285
        return -1;
286
    }
287
    assert(dev->info->unplug != NULL);
288

    
289
    return dev->info->unplug(dev);
290
}
291

    
292
/* can be used as ->unplug() callback for the simple cases */
293
int qdev_simple_unplug_cb(DeviceState *dev)
294
{
295
    /* just zap it */
296
    qdev_free(dev);
297
    return 0;
298
}
299

    
300
/* Like qdev_init(), but terminate program via hw_error() instead of
301
   returning an error value.  This is okay during machine creation.
302
   Don't use for hotplug, because there callers need to recover from
303
   failure.  Exception: if you know the device's init() callback can't
304
   fail, then qdev_init_nofail() can't fail either, and is therefore
305
   usable even then.  But relying on the device implementation that
306
   way is somewhat unclean, and best avoided.  */
307
void qdev_init_nofail(DeviceState *dev)
308
{
309
    DeviceInfo *info = dev->info;
310

    
311
    if (qdev_init(dev) < 0)
312
        hw_error("Initialization of device %s failed\n", info->name);
313
}
314

    
315
/* Unlink device from bus and free the structure.  */
316
void qdev_free(DeviceState *dev)
317
{
318
    BusState *bus;
319

    
320
    if (dev->state == DEV_STATE_INITIALIZED) {
321
        while (dev->num_child_bus) {
322
            bus = QLIST_FIRST(&dev->child_bus);
323
            qbus_free(bus);
324
        }
325
        if (dev->info->vmsd)
326
            vmstate_unregister(dev->info->vmsd, dev);
327
        if (dev->info->exit)
328
            dev->info->exit(dev);
329
        if (dev->opts)
330
            qemu_opts_del(dev->opts);
331
    }
332
    qemu_unregister_reset(qdev_reset, dev);
333
    QLIST_REMOVE(dev, sibling);
334
    qemu_free(dev);
335
}
336

    
337
void qdev_machine_creation_done(void)
338
{
339
    /*
340
     * ok, initial machine setup is done, starting from now we can
341
     * only create hotpluggable devices
342
     */
343
    qdev_hotplug = 1;
344
}
345

    
346
/* Get a character (serial) device interface.  */
347
CharDriverState *qdev_init_chardev(DeviceState *dev)
348
{
349
    static int next_serial;
350

    
351
    /* FIXME: This function needs to go away: use chardev properties!  */
352
    return serial_hds[next_serial++];
353
}
354

    
355
BusState *qdev_get_parent_bus(DeviceState *dev)
356
{
357
    return dev->parent_bus;
358
}
359

    
360
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
361
{
362
    assert(dev->num_gpio_in == 0);
363
    dev->num_gpio_in = n;
364
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
365
}
366

    
367
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
368
{
369
    assert(dev->num_gpio_out == 0);
370
    dev->num_gpio_out = n;
371
    dev->gpio_out = pins;
372
}
373

    
374
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
375
{
376
    assert(n >= 0 && n < dev->num_gpio_in);
377
    return dev->gpio_in[n];
378
}
379

    
380
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
381
{
382
    assert(n >= 0 && n < dev->num_gpio_out);
383
    dev->gpio_out[n] = pin;
384
}
385

    
386
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
387
{
388
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
389
    if (nd->vlan)
390
        qdev_prop_set_vlan(dev, "vlan", nd->vlan);
391
    if (nd->netdev)
392
        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
393
    if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
394
        qdev_prop_exists(dev, "vectors")) {
395
        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
396
    }
397
}
398

    
399
static int next_block_unit[IF_COUNT];
400

    
401
/* Get a block device.  This should only be used for single-drive devices
402
   (e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the
403
   appropriate bus.  */
404
BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
405
{
406
    int unit = next_block_unit[type]++;
407
    DriveInfo *dinfo;
408

    
409
    dinfo = drive_get(type, 0, unit);
410
    return dinfo ? dinfo->bdrv : NULL;
411
}
412

    
413
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
414
{
415
    BusState *bus;
416

    
417
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
418
        if (strcmp(name, bus->name) == 0) {
419
            return bus;
420
        }
421
    }
422
    return NULL;
423
}
424

    
425
static BusState *qbus_find_recursive(BusState *bus, const char *name,
426
                                     const BusInfo *info)
427
{
428
    DeviceState *dev;
429
    BusState *child, *ret;
430
    int match = 1;
431

    
432
    if (name && (strcmp(bus->name, name) != 0)) {
433
        match = 0;
434
    }
435
    if (info && (bus->info != info)) {
436
        match = 0;
437
    }
438
    if (match) {
439
        return bus;
440
    }
441

    
442
    QLIST_FOREACH(dev, &bus->children, sibling) {
443
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
444
            ret = qbus_find_recursive(child, name, info);
445
            if (ret) {
446
                return ret;
447
            }
448
        }
449
    }
450
    return NULL;
451
}
452

    
453
static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
454
{
455
    DeviceState *dev, *ret;
456
    BusState *child;
457

    
458
    QLIST_FOREACH(dev, &bus->children, sibling) {
459
        if (dev->id && strcmp(dev->id, id) == 0)
460
            return dev;
461
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
462
            ret = qdev_find_recursive(child, id);
463
            if (ret) {
464
                return ret;
465
            }
466
        }
467
    }
468
    return NULL;
469
}
470

    
471
static void qbus_list_bus(DeviceState *dev)
472
{
473
    BusState *child;
474
    const char *sep = " ";
475

    
476
    error_printf("child busses at \"%s\":",
477
                 dev->id ? dev->id : dev->info->name);
478
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
479
        error_printf("%s\"%s\"", sep, child->name);
480
        sep = ", ";
481
    }
482
    error_printf("\n");
483
}
484

    
485
static void qbus_list_dev(BusState *bus)
486
{
487
    DeviceState *dev;
488
    const char *sep = " ";
489

    
490
    error_printf("devices at \"%s\":", bus->name);
491
    QLIST_FOREACH(dev, &bus->children, sibling) {
492
        error_printf("%s\"%s\"", sep, dev->info->name);
493
        if (dev->id)
494
            error_printf("/\"%s\"", dev->id);
495
        sep = ", ";
496
    }
497
    error_printf("\n");
498
}
499

    
500
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
501
{
502
    BusState *child;
503

    
504
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
505
        if (strcmp(child->name, elem) == 0) {
506
            return child;
507
        }
508
    }
509
    return NULL;
510
}
511

    
512
static DeviceState *qbus_find_dev(BusState *bus, char *elem)
513
{
514
    DeviceState *dev;
515

    
516
    /*
517
     * try to match in order:
518
     *   (1) instance id, if present
519
     *   (2) driver name
520
     *   (3) driver alias, if present
521
     */
522
    QLIST_FOREACH(dev, &bus->children, sibling) {
523
        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
524
            return dev;
525
        }
526
    }
527
    QLIST_FOREACH(dev, &bus->children, sibling) {
528
        if (strcmp(dev->info->name, elem) == 0) {
529
            return dev;
530
        }
531
    }
532
    QLIST_FOREACH(dev, &bus->children, sibling) {
533
        if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
534
            return dev;
535
        }
536
    }
537
    return NULL;
538
}
539

    
540
static BusState *qbus_find(const char *path)
541
{
542
    DeviceState *dev;
543
    BusState *bus;
544
    char elem[128];
545
    int pos, len;
546

    
547
    /* find start element */
548
    if (path[0] == '/') {
549
        bus = main_system_bus;
550
        pos = 0;
551
    } else {
552
        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
553
            error_report("path parse error (\"%s\")", path);
554
            return NULL;
555
        }
556
        bus = qbus_find_recursive(main_system_bus, elem, NULL);
557
        if (!bus) {
558
            error_report("bus \"%s\" not found", elem);
559
            return NULL;
560
        }
561
        pos = len;
562
    }
563

    
564
    for (;;) {
565
        if (path[pos] == '\0') {
566
            /* we are done */
567
            return bus;
568
        }
569

    
570
        /* find device */
571
        if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
572
            error_report("path parse error (\"%s\" pos %d)", path, pos);
573
            return NULL;
574
        }
575
        pos += len;
576
        dev = qbus_find_dev(bus, elem);
577
        if (!dev) {
578
            error_report("device \"%s\" not found", elem);
579
            qbus_list_dev(bus);
580
            return NULL;
581
        }
582
        if (path[pos] == '\0') {
583
            /* last specified element is a device.  If it has exactly
584
             * one child bus accept it nevertheless */
585
            switch (dev->num_child_bus) {
586
            case 0:
587
                error_report("device has no child bus (%s)", path);
588
                return NULL;
589
            case 1:
590
                return QLIST_FIRST(&dev->child_bus);
591
            default:
592
                error_report("device has multiple child busses (%s)", path);
593
                qbus_list_bus(dev);
594
                return NULL;
595
            }
596
        }
597

    
598
        /* find bus */
599
        if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
600
            error_report("path parse error (\"%s\" pos %d)", path, pos);
601
            return NULL;
602
        }
603
        pos += len;
604
        bus = qbus_find_bus(dev, elem);
605
        if (!bus) {
606
            error_report("child bus \"%s\" not found", elem);
607
            qbus_list_bus(dev);
608
            return NULL;
609
        }
610
    }
611
}
612

    
613
void qbus_create_inplace(BusState *bus, BusInfo *info,
614
                         DeviceState *parent, const char *name)
615
{
616
    char *buf;
617
    int i,len;
618

    
619
    bus->info = info;
620
    bus->parent = parent;
621

    
622
    if (name) {
623
        /* use supplied name */
624
        bus->name = qemu_strdup(name);
625
    } else if (parent && parent->id) {
626
        /* parent device has id -> use it for bus name */
627
        len = strlen(parent->id) + 16;
628
        buf = qemu_malloc(len);
629
        snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
630
        bus->name = buf;
631
    } else {
632
        /* no id -> use lowercase bus type for bus name */
633
        len = strlen(info->name) + 16;
634
        buf = qemu_malloc(len);
635
        len = snprintf(buf, len, "%s.%d", info->name,
636
                       parent ? parent->num_child_bus : 0);
637
        for (i = 0; i < len; i++)
638
            buf[i] = qemu_tolower(buf[i]);
639
        bus->name = buf;
640
    }
641

    
642
    QLIST_INIT(&bus->children);
643
    if (parent) {
644
        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
645
        parent->num_child_bus++;
646
    }
647

    
648
}
649

    
650
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
651
{
652
    BusState *bus;
653

    
654
    bus = qemu_mallocz(info->size);
655
    bus->qdev_allocated = 1;
656
    qbus_create_inplace(bus, info, parent, name);
657
    return bus;
658
}
659

    
660
void qbus_free(BusState *bus)
661
{
662
    DeviceState *dev;
663

    
664
    while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
665
        qdev_free(dev);
666
    }
667
    if (bus->parent) {
668
        QLIST_REMOVE(bus, sibling);
669
        bus->parent->num_child_bus--;
670
    }
671
    if (bus->qdev_allocated) {
672
        qemu_free(bus);
673
    }
674
}
675

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

    
679
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
680
                             const char *prefix, int indent)
681
{
682
    char buf[64];
683

    
684
    if (!props)
685
        return;
686
    while (props->name) {
687
        if (props->info->print) {
688
            props->info->print(dev, props, buf, sizeof(buf));
689
            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
690
        }
691
        props++;
692
    }
693
}
694

    
695
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
696
{
697
    BusState *child;
698
    qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
699
                dev->id ? dev->id : "");
700
    indent += 2;
701
    if (dev->num_gpio_in) {
702
        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
703
    }
704
    if (dev->num_gpio_out) {
705
        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
706
    }
707
    qdev_print_props(mon, dev, dev->info->props, "dev", indent);
708
    qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
709
    if (dev->parent_bus->info->print_dev)
710
        dev->parent_bus->info->print_dev(mon, dev, indent);
711
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
712
        qbus_print(mon, child, indent);
713
    }
714
}
715

    
716
static void qbus_print(Monitor *mon, BusState *bus, int indent)
717
{
718
    struct DeviceState *dev;
719

    
720
    qdev_printf("bus: %s\n", bus->name);
721
    indent += 2;
722
    qdev_printf("type %s\n", bus->info->name);
723
    QLIST_FOREACH(dev, &bus->children, sibling) {
724
        qdev_print(mon, dev, indent);
725
    }
726
}
727
#undef qdev_printf
728

    
729
void do_info_qtree(Monitor *mon)
730
{
731
    if (main_system_bus)
732
        qbus_print(mon, main_system_bus, 0);
733
}
734

    
735
void do_info_qdm(Monitor *mon)
736
{
737
    DeviceInfo *info;
738

    
739
    for (info = device_info_list; info != NULL; info = info->next) {
740
        qdev_print_devinfo(info);
741
    }
742
}
743

    
744
void do_device_add(Monitor *mon, const QDict *qdict)
745
{
746
    QemuOpts *opts;
747

    
748
    opts = qemu_opts_parse(&qemu_device_opts,
749
                           qdict_get_str(qdict, "config"), "driver");
750
    if (opts) {
751
        if (qdev_device_help(opts) || qdev_device_add(opts) == NULL) {
752
            qemu_opts_del(opts);
753
        }
754
    }
755
}
756

    
757
void do_device_del(Monitor *mon, const QDict *qdict)
758
{
759
    const char *id = qdict_get_str(qdict, "id");
760
    DeviceState *dev;
761

    
762
    dev = qdev_find_recursive(main_system_bus, id);
763
    if (NULL == dev) {
764
        error_report("Device '%s' not found", id);
765
        return;
766
    }
767
    qdev_unplug(dev);
768
}