Statistics
| Branch: | Revision:

root / hw / qdev.c @ 0f853a38

History | View | Annotate | Download (20.6 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
    Property *prop;
162

    
163
    driver = qemu_opt_get(opts, "driver");
164
    if (driver && !strcmp(driver, "?")) {
165
        for (info = device_info_list; info != NULL; info = info->next) {
166
            qdev_print_devinfo(info, msg, sizeof(msg));
167
            qemu_error("%s\n", msg);
168
        }
169
        return 1;
170
    }
171

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

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

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

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

    
194
    driver = qemu_opt_get(opts, "driver");
195
    if (!driver) {
196
        qemu_error("-device: no driver specified\n");
197
        return NULL;
198
    }
199

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

    
212
    /* find bus */
213
    path = qemu_opt_get(opts, "bus");
214
    if (path != NULL) {
215
        bus = qbus_find(path);
216
    } else {
217
        bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
218
    }
219
    if (!bus) {
220
        qemu_error("Did not find %s bus for %s\n",
221
                   path ? path : info->bus_info->name, info->name);
222
        return NULL;
223
    }
224
    if (qdev_hotplug && !bus->allow_hotplug) {
225
        qemu_error("Bus %s does not support hotplugging\n",
226
                   bus->name);
227
        return NULL;
228
    }
229

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

    
248
static void qdev_reset(void *opaque)
249
{
250
    DeviceState *dev = opaque;
251
    if (dev->info->reset)
252
        dev->info->reset(dev);
253
}
254

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

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

    
277
int qdev_unplug(DeviceState *dev)
278
{
279
    if (!dev->parent_bus->allow_hotplug) {
280
        qemu_error("Bus %s does not support hotplugging\n",
281
                   dev->parent_bus->name);
282
        return -1;
283
    }
284
    assert(dev->info->unplug != NULL);
285

    
286
    return dev->info->unplug(dev);
287
}
288

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

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

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

    
312
/* Unlink device from bus and free the structure.  */
313
void qdev_free(DeviceState *dev)
314
{
315
    BusState *bus;
316

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

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

    
343
/* Get a character (serial) device interface.  */
344
CharDriverState *qdev_init_chardev(DeviceState *dev)
345
{
346
    static int next_serial;
347

    
348
    /* FIXME: This function needs to go away: use chardev properties!  */
349
    return serial_hds[next_serial++];
350
}
351

    
352
BusState *qdev_get_parent_bus(DeviceState *dev)
353
{
354
    return dev->parent_bus;
355
}
356

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

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

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

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

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

    
396
static int next_block_unit[IF_COUNT];
397

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

    
406
    dinfo = drive_get(type, 0, unit);
407
    return dinfo ? dinfo->bdrv : NULL;
408
}
409

    
410
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
411
{
412
    BusState *bus;
413

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

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

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

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

    
450
static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
451
{
452
    DeviceState *dev, *ret;
453
    BusState *child;
454

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

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

    
474
    pos += snprintf(dest+pos, len-pos,"child busses at \"%s\":",
475
                    dev->id ? dev->id : dev->info->name);
476
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
477
        pos += snprintf(dest+pos, len-pos, "%s\"%s\"", sep, child->name);
478
        sep = ", ";
479
    }
480
}
481

    
482
static void qbus_list_dev(BusState *bus, char *dest, int len)
483
{
484
    DeviceState *dev;
485
    const char *sep = " ";
486
    int pos = 0;
487

    
488
    pos += snprintf(dest+pos, len-pos, "devices at \"%s\":",
489
                    bus->name);
490
    QLIST_FOREACH(dev, &bus->children, sibling) {
491
        pos += snprintf(dest+pos, len-pos, "%s\"%s\"",
492
                        sep, dev->info->name);
493
        if (dev->id)
494
            pos += snprintf(dest+pos, len-pos, "/\"%s\"", dev->id);
495
        sep = ", ";
496
    }
497
}
498

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

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

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

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

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

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

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

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

    
598
        /* find bus */
599
        if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
600
            qemu_error("path parse error (\"%s\" pos %d)\n", path, pos);
601
            return NULL;
602
        }
603
        pos += len;
604
        bus = qbus_find_bus(dev, elem);
605
        if (!bus) {
606
            qbus_list_bus(dev, msg, sizeof(msg));
607
            qemu_error("child bus \"%s\" not found\n%s\n", elem, msg);
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
    char msg[256];
739

    
740
    for (info = device_info_list; info != NULL; info = info->next) {
741
        qdev_print_devinfo(info, msg, sizeof(msg));
742
        monitor_printf(mon, "%s\n", msg);
743
    }
744
}
745

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

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

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

    
764
    dev = qdev_find_recursive(main_system_bus, id);
765
    if (NULL == dev) {
766
        qemu_error("Device '%s' not found\n", id);
767
        return;
768
    }
769
    qdev_unplug(dev);
770
}