Statistics
| Branch: | Revision:

root / hw / qdev.c @ ff952ba2

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_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 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
int qdev_device_help(QemuOpts *opts)
157
{
158
    const char *driver;
159
    DeviceInfo *info;
160
    char msg[256];
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, msg, sizeof(msg));
166
            qemu_error("%s\n", msg);
167
        }
168
        return 1;
169
    }
170

    
171
    return 0;
172
}
173

    
174
DeviceState *qdev_device_add(QemuOpts *opts)
175
{
176
    const char *driver, *path, *id;
177
    DeviceInfo *info;
178
    DeviceState *qdev;
179
    BusState *bus;
180

    
181
    driver = qemu_opt_get(opts, "driver");
182
    if (!driver) {
183
        qemu_error("-device: no driver specified\n");
184
        return NULL;
185
    }
186

    
187
    /* find driver */
188
    info = qdev_find_info(NULL, driver);
189
    if (!info) {
190
        qemu_error_new(QERR_DEVICE_NOT_FOUND, driver);
191
        return NULL;
192
    }
193
    if (info->no_user) {
194
        qemu_error("device \"%s\" can't be added via command line\n",
195
                   info->name);
196
        return NULL;
197
    }
198

    
199
    /* find bus */
200
    path = qemu_opt_get(opts, "bus");
201
    if (path != NULL) {
202
        bus = qbus_find(path);
203
    } else {
204
        bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
205
    }
206
    if (!bus) {
207
        qemu_error("Did not find %s bus for %s\n",
208
                   path ? path : info->bus_info->name, info->name);
209
        return NULL;
210
    }
211
    if (qdev_hotplug && !bus->allow_hotplug) {
212
        qemu_error("Bus %s does not support hotplugging\n",
213
                   bus->name);
214
        return NULL;
215
    }
216

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

    
235
static void qdev_reset(void *opaque)
236
{
237
    DeviceState *dev = opaque;
238
    if (dev->info->reset)
239
        dev->info->reset(dev);
240
}
241

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

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

    
264
int qdev_unplug(DeviceState *dev)
265
{
266
    if (!dev->parent_bus->allow_hotplug) {
267
        qemu_error("Bus %s does not support hotplugging\n",
268
                   dev->parent_bus->name);
269
        return -1;
270
    }
271
    assert(dev->info->unplug != NULL);
272

    
273
    return dev->info->unplug(dev);
274
}
275

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

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

    
295
    if (qdev_init(dev) < 0)
296
        hw_error("Initialization of device %s failed\n", info->name);
297
}
298

    
299
/* Unlink device from bus and free the structure.  */
300
void qdev_free(DeviceState *dev)
301
{
302
    BusState *bus;
303

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

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

    
330
/* Get a character (serial) device interface.  */
331
CharDriverState *qdev_init_chardev(DeviceState *dev)
332
{
333
    static int next_serial;
334

    
335
    /* FIXME: This function needs to go away: use chardev properties!  */
336
    return serial_hds[next_serial++];
337
}
338

    
339
BusState *qdev_get_parent_bus(DeviceState *dev)
340
{
341
    return dev->parent_bus;
342
}
343

    
344
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
345
{
346
    assert(dev->num_gpio_in == 0);
347
    dev->num_gpio_in = n;
348
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
349
}
350

    
351
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
352
{
353
    assert(dev->num_gpio_out == 0);
354
    dev->num_gpio_out = n;
355
    dev->gpio_out = pins;
356
}
357

    
358
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
359
{
360
    assert(n >= 0 && n < dev->num_gpio_in);
361
    return dev->gpio_in[n];
362
}
363

    
364
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
365
{
366
    assert(n >= 0 && n < dev->num_gpio_out);
367
    dev->gpio_out[n] = pin;
368
}
369

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

    
383
static int next_block_unit[IF_COUNT];
384

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

    
393
    dinfo = drive_get(type, 0, unit);
394
    return dinfo ? dinfo->bdrv : NULL;
395
}
396

    
397
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
398
{
399
    BusState *bus;
400

    
401
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
402
        if (strcmp(name, bus->name) == 0) {
403
            return bus;
404
        }
405
    }
406
    return NULL;
407
}
408

    
409
static BusState *qbus_find_recursive(BusState *bus, const char *name,
410
                                     const BusInfo *info)
411
{
412
    DeviceState *dev;
413
    BusState *child, *ret;
414
    int match = 1;
415

    
416
    if (name && (strcmp(bus->name, name) != 0)) {
417
        match = 0;
418
    }
419
    if (info && (bus->info != info)) {
420
        match = 0;
421
    }
422
    if (match) {
423
        return bus;
424
    }
425

    
426
    QLIST_FOREACH(dev, &bus->children, sibling) {
427
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
428
            ret = qbus_find_recursive(child, name, info);
429
            if (ret) {
430
                return ret;
431
            }
432
        }
433
    }
434
    return NULL;
435
}
436

    
437
static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
438
{
439
    DeviceState *dev, *ret;
440
    BusState *child;
441

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

    
455
static void qbus_list_bus(DeviceState *dev, char *dest, int len)
456
{
457
    BusState *child;
458
    const char *sep = " ";
459
    int pos = 0;
460

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

    
469
static void qbus_list_dev(BusState *bus, char *dest, int len)
470
{
471
    DeviceState *dev;
472
    const char *sep = " ";
473
    int pos = 0;
474

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
635
}
636

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

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

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

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

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

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

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

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

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

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

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

    
722
void do_info_qdm(Monitor *mon)
723
{
724
    DeviceInfo *info;
725
    char msg[256];
726

    
727
    for (info = device_info_list; info != NULL; info = info->next) {
728
        qdev_print_devinfo(info, msg, sizeof(msg));
729
        monitor_printf(mon, "%s\n", msg);
730
    }
731
}
732

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

    
737
    opts = qemu_opts_parse(&qemu_device_opts,
738
                           qdict_get_str(qdict, "config"), "driver");
739
    if (opts && !qdev_device_help(opts))
740
        qdev_device_add(opts);
741
}
742

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

    
748
    dev = qdev_find_recursive(main_system_bus, id);
749
    if (NULL == dev) {
750
        qemu_error("Device '%s' not found\n", id);
751
        return;
752
    }
753
    qdev_unplug(dev);
754
}