Statistics
| Branch: | Revision:

root / hw / qdev.c @ 327867b6

History | View | Annotate | Download (20.1 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_globals(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 void qdev_print_devinfo(DeviceInfo *info)
117
{
118
    error_printf("name \"%s\", bus %s",
119
                 info->name, info->bus_info->name);
120
    if (info->alias) {
121
        error_printf(", alias \"%s\"", info->alias);
122
    }
123
    if (info->desc) {
124
        error_printf(", desc \"%s\"", info->desc);
125
    }
126
    if (info->no_user) {
127
        error_printf(", no-user");
128
    }
129
    error_printf("\n");
130
}
131

    
132
static int set_property(const char *name, const char *value, void *opaque)
133
{
134
    DeviceState *dev = opaque;
135

    
136
    if (strcmp(name, "driver") == 0)
137
        return 0;
138
    if (strcmp(name, "bus") == 0)
139
        return 0;
140

    
141
    if (qdev_prop_parse(dev, name, value) == -1) {
142
        error_report("can't set property \"%s\" to \"%s\" for \"%s\"",
143
                     name, value, dev->info->name);
144
        return -1;
145
    }
146
    return 0;
147
}
148

    
149
int qdev_device_help(QemuOpts *opts)
150
{
151
    const char *driver;
152
    DeviceInfo *info;
153
    Property *prop;
154

    
155
    driver = qemu_opt_get(opts, "driver");
156
    if (driver && !strcmp(driver, "?")) {
157
        for (info = device_info_list; info != NULL; info = info->next) {
158
            qdev_print_devinfo(info);
159
        }
160
        return 1;
161
    }
162

    
163
    if (!qemu_opt_get(opts, "?")) {
164
        return 0;
165
    }
166

    
167
    info = qdev_find_info(NULL, driver);
168
    if (!info) {
169
        return 0;
170
    }
171

    
172
    for (prop = info->props; prop && prop->name; prop++) {
173
        error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
174
    }
175
    return 1;
176
}
177

    
178
DeviceState *qdev_device_add(QemuOpts *opts)
179
{
180
    const char *driver, *path, *id;
181
    DeviceInfo *info;
182
    DeviceState *qdev;
183
    BusState *bus;
184

    
185
    driver = qemu_opt_get(opts, "driver");
186
    if (!driver) {
187
        error_report("-device: no driver specified");
188
        return NULL;
189
    }
190

    
191
    /* find driver */
192
    info = qdev_find_info(NULL, driver);
193
    if (!info) {
194
        qerror_report(QERR_DEVICE_NOT_FOUND, driver);
195
        return NULL;
196
    }
197
    if (info->no_user) {
198
        error_report("device \"%s\" can't be added via command line",
199
                     info->name);
200
        return NULL;
201
    }
202

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

    
226
    /* create device, set properties */
227
    qdev = qdev_create(bus, driver);
228
    id = qemu_opts_id(opts);
229
    if (id) {
230
        qdev->id = id;
231
    }
232
    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
233
        qdev_free(qdev);
234
        return NULL;
235
    }
236
    if (qdev_init(qdev) < 0) {
237
        error_report("Error initializing device %s", driver);
238
        return NULL;
239
    }
240
    qdev->opts = opts;
241
    return qdev;
242
}
243

    
244
static void qdev_reset(void *opaque)
245
{
246
    DeviceState *dev = opaque;
247
    if (dev->info->reset)
248
        dev->info->reset(dev);
249
}
250

    
251
/* Initialize a device.  Device properties should be set before calling
252
   this function.  IRQs and MMIO regions should be connected/mapped after
253
   calling this function.
254
   On failure, destroy the device and return negative value.
255
   Return 0 on success.  */
256
int qdev_init(DeviceState *dev)
257
{
258
    int rc;
259

    
260
    assert(dev->state == DEV_STATE_CREATED);
261
    rc = dev->info->init(dev, dev->info);
262
    if (rc < 0) {
263
        qdev_free(dev);
264
        return rc;
265
    }
266
    qemu_register_reset(qdev_reset, dev);
267
    if (dev->info->vmsd)
268
        vmstate_register(-1, dev->info->vmsd, dev);
269
    dev->state = DEV_STATE_INITIALIZED;
270
    return 0;
271
}
272

    
273
int qdev_unplug(DeviceState *dev)
274
{
275
    if (!dev->parent_bus->allow_hotplug) {
276
        error_report("Bus %s does not support hotplugging",
277
                     dev->parent_bus->name);
278
        return -1;
279
    }
280
    assert(dev->info->unplug != NULL);
281

    
282
    return dev->info->unplug(dev);
283
}
284

    
285
/* can be used as ->unplug() callback for the simple cases */
286
int qdev_simple_unplug_cb(DeviceState *dev)
287
{
288
    /* just zap it */
289
    qdev_free(dev);
290
    return 0;
291
}
292

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

    
304
    if (qdev_init(dev) < 0)
305
        hw_error("Initialization of device %s failed\n", info->name);
306
}
307

    
308
/* Unlink device from bus and free the structure.  */
309
void qdev_free(DeviceState *dev)
310
{
311
    BusState *bus;
312

    
313
    if (dev->state == DEV_STATE_INITIALIZED) {
314
        while (dev->num_child_bus) {
315
            bus = QLIST_FIRST(&dev->child_bus);
316
            qbus_free(bus);
317
        }
318
        if (dev->info->vmsd)
319
            vmstate_unregister(dev->info->vmsd, dev);
320
        if (dev->info->exit)
321
            dev->info->exit(dev);
322
        if (dev->opts)
323
            qemu_opts_del(dev->opts);
324
    }
325
    qemu_unregister_reset(qdev_reset, dev);
326
    QLIST_REMOVE(dev, sibling);
327
    qemu_free(dev);
328
}
329

    
330
void qdev_machine_creation_done(void)
331
{
332
    /*
333
     * ok, initial machine setup is done, starting from now we can
334
     * only create hotpluggable devices
335
     */
336
    qdev_hotplug = 1;
337
}
338

    
339
/* Get a character (serial) device interface.  */
340
CharDriverState *qdev_init_chardev(DeviceState *dev)
341
{
342
    static int next_serial;
343

    
344
    /* FIXME: This function needs to go away: use chardev properties!  */
345
    return serial_hds[next_serial++];
346
}
347

    
348
BusState *qdev_get_parent_bus(DeviceState *dev)
349
{
350
    return dev->parent_bus;
351
}
352

    
353
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
354
{
355
    assert(dev->num_gpio_in == 0);
356
    dev->num_gpio_in = n;
357
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
358
}
359

    
360
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
361
{
362
    assert(dev->num_gpio_out == 0);
363
    dev->num_gpio_out = n;
364
    dev->gpio_out = pins;
365
}
366

    
367
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
368
{
369
    assert(n >= 0 && n < dev->num_gpio_in);
370
    return dev->gpio_in[n];
371
}
372

    
373
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
374
{
375
    assert(n >= 0 && n < dev->num_gpio_out);
376
    dev->gpio_out[n] = pin;
377
}
378

    
379
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
380
{
381
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
382
    if (nd->vlan)
383
        qdev_prop_set_vlan(dev, "vlan", nd->vlan);
384
    if (nd->netdev)
385
        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
386
    if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
387
        qdev_prop_exists(dev, "vectors")) {
388
        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
389
    }
390
}
391

    
392
static int next_block_unit[IF_COUNT];
393

    
394
/* Get a block device.  This should only be used for single-drive devices
395
   (e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the
396
   appropriate bus.  */
397
BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
398
{
399
    int unit = next_block_unit[type]++;
400
    DriveInfo *dinfo;
401

    
402
    dinfo = drive_get(type, 0, unit);
403
    return dinfo ? dinfo->bdrv : NULL;
404
}
405

    
406
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
407
{
408
    BusState *bus;
409

    
410
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
411
        if (strcmp(name, bus->name) == 0) {
412
            return bus;
413
        }
414
    }
415
    return NULL;
416
}
417

    
418
static BusState *qbus_find_recursive(BusState *bus, const char *name,
419
                                     const BusInfo *info)
420
{
421
    DeviceState *dev;
422
    BusState *child, *ret;
423
    int match = 1;
424

    
425
    if (name && (strcmp(bus->name, name) != 0)) {
426
        match = 0;
427
    }
428
    if (info && (bus->info != info)) {
429
        match = 0;
430
    }
431
    if (match) {
432
        return bus;
433
    }
434

    
435
    QLIST_FOREACH(dev, &bus->children, sibling) {
436
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
437
            ret = qbus_find_recursive(child, name, info);
438
            if (ret) {
439
                return ret;
440
            }
441
        }
442
    }
443
    return NULL;
444
}
445

    
446
static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
447
{
448
    DeviceState *dev, *ret;
449
    BusState *child;
450

    
451
    QLIST_FOREACH(dev, &bus->children, sibling) {
452
        if (dev->id && strcmp(dev->id, id) == 0)
453
            return dev;
454
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
455
            ret = qdev_find_recursive(child, id);
456
            if (ret) {
457
                return ret;
458
            }
459
        }
460
    }
461
    return NULL;
462
}
463

    
464
static void qbus_list_bus(DeviceState *dev)
465
{
466
    BusState *child;
467
    const char *sep = " ";
468

    
469
    error_printf("child busses at \"%s\":",
470
                 dev->id ? dev->id : dev->info->name);
471
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
472
        error_printf("%s\"%s\"", sep, child->name);
473
        sep = ", ";
474
    }
475
    error_printf("\n");
476
}
477

    
478
static void qbus_list_dev(BusState *bus)
479
{
480
    DeviceState *dev;
481
    const char *sep = " ";
482

    
483
    error_printf("devices at \"%s\":", bus->name);
484
    QLIST_FOREACH(dev, &bus->children, sibling) {
485
        error_printf("%s\"%s\"", sep, dev->info->name);
486
        if (dev->id)
487
            error_printf("/\"%s\"", dev->id);
488
        sep = ", ";
489
    }
490
    error_printf("\n");
491
}
492

    
493
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
494
{
495
    BusState *child;
496

    
497
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
498
        if (strcmp(child->name, elem) == 0) {
499
            return child;
500
        }
501
    }
502
    return NULL;
503
}
504

    
505
static DeviceState *qbus_find_dev(BusState *bus, char *elem)
506
{
507
    DeviceState *dev;
508

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

    
533
static BusState *qbus_find(const char *path)
534
{
535
    DeviceState *dev;
536
    BusState *bus;
537
    char elem[128];
538
    int pos, len;
539

    
540
    /* find start element */
541
    if (path[0] == '/') {
542
        bus = main_system_bus;
543
        pos = 0;
544
    } else {
545
        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
546
            error_report("path parse error (\"%s\")", path);
547
            return NULL;
548
        }
549
        bus = qbus_find_recursive(main_system_bus, elem, NULL);
550
        if (!bus) {
551
            error_report("bus \"%s\" not found", elem);
552
            return NULL;
553
        }
554
        pos = len;
555
    }
556

    
557
    for (;;) {
558
        if (path[pos] == '\0') {
559
            /* we are done */
560
            return bus;
561
        }
562

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

    
591
        /* find bus */
592
        if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
593
            error_report("path parse error (\"%s\" pos %d)", path, pos);
594
            return NULL;
595
        }
596
        pos += len;
597
        bus = qbus_find_bus(dev, elem);
598
        if (!bus) {
599
            error_report("child bus \"%s\" not found", elem);
600
            qbus_list_bus(dev);
601
            return NULL;
602
        }
603
    }
604
}
605

    
606
void qbus_create_inplace(BusState *bus, BusInfo *info,
607
                         DeviceState *parent, const char *name)
608
{
609
    char *buf;
610
    int i,len;
611

    
612
    bus->info = info;
613
    bus->parent = parent;
614

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

    
635
    QLIST_INIT(&bus->children);
636
    if (parent) {
637
        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
638
        parent->num_child_bus++;
639
    }
640

    
641
}
642

    
643
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
644
{
645
    BusState *bus;
646

    
647
    bus = qemu_mallocz(info->size);
648
    bus->qdev_allocated = 1;
649
    qbus_create_inplace(bus, info, parent, name);
650
    return bus;
651
}
652

    
653
void qbus_free(BusState *bus)
654
{
655
    DeviceState *dev;
656

    
657
    while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
658
        qdev_free(dev);
659
    }
660
    if (bus->parent) {
661
        QLIST_REMOVE(bus, sibling);
662
        bus->parent->num_child_bus--;
663
    }
664
    if (bus->qdev_allocated) {
665
        qemu_free(bus);
666
    }
667
}
668

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

    
672
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
673
                             const char *prefix, int indent)
674
{
675
    char buf[64];
676

    
677
    if (!props)
678
        return;
679
    while (props->name) {
680
        if (props->info->print) {
681
            props->info->print(dev, props, buf, sizeof(buf));
682
            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
683
        }
684
        props++;
685
    }
686
}
687

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

    
709
static void qbus_print(Monitor *mon, BusState *bus, int indent)
710
{
711
    struct DeviceState *dev;
712

    
713
    qdev_printf("bus: %s\n", bus->name);
714
    indent += 2;
715
    qdev_printf("type %s\n", bus->info->name);
716
    QLIST_FOREACH(dev, &bus->children, sibling) {
717
        qdev_print(mon, dev, indent);
718
    }
719
}
720
#undef qdev_printf
721

    
722
void do_info_qtree(Monitor *mon)
723
{
724
    if (main_system_bus)
725
        qbus_print(mon, main_system_bus, 0);
726
}
727

    
728
void do_info_qdm(Monitor *mon)
729
{
730
    DeviceInfo *info;
731

    
732
    for (info = device_info_list; info != NULL; info = info->next) {
733
        qdev_print_devinfo(info);
734
    }
735
}
736

    
737
void do_device_add(Monitor *mon, const QDict *qdict)
738
{
739
    QemuOpts *opts;
740

    
741
    opts = qemu_opts_parse(&qemu_device_opts,
742
                           qdict_get_str(qdict, "config"), "driver");
743
    if (opts) {
744
        if (qdev_device_help(opts) || qdev_device_add(opts) == NULL) {
745
            qemu_opts_del(opts);
746
        }
747
    }
748
}
749

    
750
void do_device_del(Monitor *mon, const QDict *qdict)
751
{
752
    const char *id = qdict_get_str(qdict, "id");
753
    DeviceState *dev;
754

    
755
    dev = qdev_find_recursive(main_system_bus, id);
756
    if (NULL == dev) {
757
        error_report("Device '%s' not found", id);
758
        return;
759
    }
760
    qdev_unplug(dev);
761
}