Statistics
| Branch: | Revision:

root / hw / qdev.c @ ab5b027e

History | View | Annotate | Download (19.9 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
    } else {
208
        bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
209
    }
210
    if (!bus) {
211
        error_report("Did not find %s bus for %s",
212
                     path ? path : info->bus_info->name, info->name);
213
        return NULL;
214
    }
215
    if (qdev_hotplug && !bus->allow_hotplug) {
216
        error_report("Bus %s does not support hotplugging",
217
                     bus->name);
218
        return NULL;
219
    }
220

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

    
239
static void qdev_reset(void *opaque)
240
{
241
    DeviceState *dev = opaque;
242
    if (dev->info->reset)
243
        dev->info->reset(dev);
244
}
245

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

    
255
    assert(dev->state == DEV_STATE_CREATED);
256
    rc = dev->info->init(dev, dev->info);
257
    if (rc < 0) {
258
        qdev_free(dev);
259
        return rc;
260
    }
261
    qemu_register_reset(qdev_reset, dev);
262
    if (dev->info->vmsd)
263
        vmstate_register(-1, dev->info->vmsd, dev);
264
    dev->state = DEV_STATE_INITIALIZED;
265
    return 0;
266
}
267

    
268
int qdev_unplug(DeviceState *dev)
269
{
270
    if (!dev->parent_bus->allow_hotplug) {
271
        error_report("Bus %s does not support hotplugging",
272
                     dev->parent_bus->name);
273
        return -1;
274
    }
275
    assert(dev->info->unplug != NULL);
276

    
277
    return dev->info->unplug(dev);
278
}
279

    
280
/* can be used as ->unplug() callback for the simple cases */
281
int qdev_simple_unplug_cb(DeviceState *dev)
282
{
283
    /* just zap it */
284
    qdev_free(dev);
285
    return 0;
286
}
287

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

    
299
    if (qdev_init(dev) < 0)
300
        hw_error("Initialization of device %s failed\n", info->name);
301
}
302

    
303
/* Unlink device from bus and free the structure.  */
304
void qdev_free(DeviceState *dev)
305
{
306
    BusState *bus;
307

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

    
325
void qdev_machine_creation_done(void)
326
{
327
    /*
328
     * ok, initial machine setup is done, starting from now we can
329
     * only create hotpluggable devices
330
     */
331
    qdev_hotplug = 1;
332
}
333

    
334
/* Get a character (serial) device interface.  */
335
CharDriverState *qdev_init_chardev(DeviceState *dev)
336
{
337
    static int next_serial;
338

    
339
    /* FIXME: This function needs to go away: use chardev properties!  */
340
    return serial_hds[next_serial++];
341
}
342

    
343
BusState *qdev_get_parent_bus(DeviceState *dev)
344
{
345
    return dev->parent_bus;
346
}
347

    
348
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
349
{
350
    assert(dev->num_gpio_in == 0);
351
    dev->num_gpio_in = n;
352
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
353
}
354

    
355
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
356
{
357
    assert(dev->num_gpio_out == 0);
358
    dev->num_gpio_out = n;
359
    dev->gpio_out = pins;
360
}
361

    
362
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
363
{
364
    assert(n >= 0 && n < dev->num_gpio_in);
365
    return dev->gpio_in[n];
366
}
367

    
368
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
369
{
370
    assert(n >= 0 && n < dev->num_gpio_out);
371
    dev->gpio_out[n] = pin;
372
}
373

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

    
387
static int next_block_unit[IF_COUNT];
388

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

    
397
    dinfo = drive_get(type, 0, unit);
398
    return dinfo ? dinfo->bdrv : NULL;
399
}
400

    
401
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
402
{
403
    BusState *bus;
404

    
405
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
406
        if (strcmp(name, bus->name) == 0) {
407
            return bus;
408
        }
409
    }
410
    return NULL;
411
}
412

    
413
static BusState *qbus_find_recursive(BusState *bus, const char *name,
414
                                     const BusInfo *info)
415
{
416
    DeviceState *dev;
417
    BusState *child, *ret;
418
    int match = 1;
419

    
420
    if (name && (strcmp(bus->name, name) != 0)) {
421
        match = 0;
422
    }
423
    if (info && (bus->info != info)) {
424
        match = 0;
425
    }
426
    if (match) {
427
        return bus;
428
    }
429

    
430
    QLIST_FOREACH(dev, &bus->children, sibling) {
431
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
432
            ret = qbus_find_recursive(child, name, info);
433
            if (ret) {
434
                return ret;
435
            }
436
        }
437
    }
438
    return NULL;
439
}
440

    
441
static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
442
{
443
    DeviceState *dev, *ret;
444
    BusState *child;
445

    
446
    QLIST_FOREACH(dev, &bus->children, sibling) {
447
        if (dev->id && strcmp(dev->id, id) == 0)
448
            return dev;
449
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
450
            ret = qdev_find_recursive(child, id);
451
            if (ret) {
452
                return ret;
453
            }
454
        }
455
    }
456
    return NULL;
457
}
458

    
459
static void qbus_list_bus(DeviceState *dev)
460
{
461
    BusState *child;
462
    const char *sep = " ";
463

    
464
    error_printf("child busses at \"%s\":",
465
                 dev->id ? dev->id : dev->info->name);
466
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
467
        error_printf("%s\"%s\"", sep, child->name);
468
        sep = ", ";
469
    }
470
    error_printf("\n");
471
}
472

    
473
static void qbus_list_dev(BusState *bus)
474
{
475
    DeviceState *dev;
476
    const char *sep = " ";
477

    
478
    error_printf("devices at \"%s\":", bus->name);
479
    QLIST_FOREACH(dev, &bus->children, sibling) {
480
        error_printf("%s\"%s\"", sep, dev->info->name);
481
        if (dev->id)
482
            error_printf("/\"%s\"", dev->id);
483
        sep = ", ";
484
    }
485
    error_printf("\n");
486
}
487

    
488
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
489
{
490
    BusState *child;
491

    
492
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
493
        if (strcmp(child->name, elem) == 0) {
494
            return child;
495
        }
496
    }
497
    return NULL;
498
}
499

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

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

    
528
static BusState *qbus_find(const char *path)
529
{
530
    DeviceState *dev;
531
    BusState *bus;
532
    char elem[128];
533
    int pos, len;
534

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

    
552
    for (;;) {
553
        if (path[pos] == '\0') {
554
            /* we are done */
555
            return bus;
556
        }
557

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

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

    
601
void qbus_create_inplace(BusState *bus, BusInfo *info,
602
                         DeviceState *parent, const char *name)
603
{
604
    char *buf;
605
    int i,len;
606

    
607
    bus->info = info;
608
    bus->parent = parent;
609

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

    
630
    QLIST_INIT(&bus->children);
631
    if (parent) {
632
        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
633
        parent->num_child_bus++;
634
    }
635

    
636
}
637

    
638
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
639
{
640
    BusState *bus;
641

    
642
    bus = qemu_mallocz(info->size);
643
    bus->qdev_allocated = 1;
644
    qbus_create_inplace(bus, info, parent, name);
645
    return bus;
646
}
647

    
648
void qbus_free(BusState *bus)
649
{
650
    DeviceState *dev;
651

    
652
    while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
653
        qdev_free(dev);
654
    }
655
    if (bus->parent) {
656
        QLIST_REMOVE(bus, sibling);
657
        bus->parent->num_child_bus--;
658
    }
659
    if (bus->qdev_allocated) {
660
        qemu_free(bus);
661
    }
662
}
663

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

    
667
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
668
                             const char *prefix, int indent)
669
{
670
    char buf[64];
671

    
672
    if (!props)
673
        return;
674
    while (props->name) {
675
        if (props->info->print) {
676
            props->info->print(dev, props, buf, sizeof(buf));
677
            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
678
        }
679
        props++;
680
    }
681
}
682

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

    
704
static void qbus_print(Monitor *mon, BusState *bus, int indent)
705
{
706
    struct DeviceState *dev;
707

    
708
    qdev_printf("bus: %s\n", bus->name);
709
    indent += 2;
710
    qdev_printf("type %s\n", bus->info->name);
711
    QLIST_FOREACH(dev, &bus->children, sibling) {
712
        qdev_print(mon, dev, indent);
713
    }
714
}
715
#undef qdev_printf
716

    
717
void do_info_qtree(Monitor *mon)
718
{
719
    if (main_system_bus)
720
        qbus_print(mon, main_system_bus, 0);
721
}
722

    
723
void do_info_qdm(Monitor *mon)
724
{
725
    DeviceInfo *info;
726

    
727
    for (info = device_info_list; info != NULL; info = info->next) {
728
        qdev_print_devinfo(info);
729
    }
730
}
731

    
732
void do_device_add(Monitor *mon, const QDict *qdict)
733
{
734
    QemuOpts *opts;
735

    
736
    opts = qemu_opts_parse(&qemu_device_opts,
737
                           qdict_get_str(qdict, "config"), "driver");
738
    if (opts) {
739
        if (qdev_device_help(opts) || qdev_device_add(opts) == NULL) {
740
            qemu_opts_del(opts);
741
        }
742
    }
743
}
744

    
745
void do_device_del(Monitor *mon, const QDict *qdict)
746
{
747
    const char *id = qdict_get_str(qdict, "id");
748
    DeviceState *dev;
749

    
750
    dev = qdev_find_recursive(main_system_bus, id);
751
    if (NULL == dev) {
752
        error_report("Device '%s' not found", id);
753
        return;
754
    }
755
    qdev_unplug(dev);
756
}