Statistics
| Branch: | Revision:

root / hw / qdev.c @ 8212c64f

History | View | Annotate | Download (20.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

    
33
static int qdev_hotplug = 0;
34

    
35
/* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
36
static BusState *main_system_bus;
37

    
38
DeviceInfo *device_info_list;
39

    
40
static BusState *qbus_find_recursive(BusState *bus, const char *name,
41
                                     const BusInfo *info);
42
static BusState *qbus_find(const char *path);
43

    
44
/* Register a new device type.  */
45
void qdev_register(DeviceInfo *info)
46
{
47
    assert(info->size >= sizeof(DeviceState));
48
    assert(!info->next);
49

    
50
    info->next = device_info_list;
51
    device_info_list = info;
52
}
53

    
54
static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
55
{
56
    DeviceInfo *info;
57

    
58
    /* first check device names */
59
    for (info = device_info_list; info != NULL; info = info->next) {
60
        if (bus_info && info->bus_info != bus_info)
61
            continue;
62
        if (strcmp(info->name, name) != 0)
63
            continue;
64
        return info;
65
    }
66

    
67
    /* failing that check the aliases */
68
    for (info = device_info_list; info != NULL; info = info->next) {
69
        if (bus_info && info->bus_info != bus_info)
70
            continue;
71
        if (!info->alias)
72
            continue;
73
        if (strcmp(info->alias, name) != 0)
74
            continue;
75
        return info;
76
    }
77
    return NULL;
78
}
79

    
80
static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
81
{
82
    DeviceState *dev;
83

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

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

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

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

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

    
122
static void qdev_print_devinfo(DeviceInfo *info)
123
{
124
    error_printf("name \"%s\", bus %s",
125
                 info->name, info->bus_info->name);
126
    if (info->alias) {
127
        error_printf(", alias \"%s\"", info->alias);
128
    }
129
    if (info->desc) {
130
        error_printf(", desc \"%s\"", info->desc);
131
    }
132
    if (info->no_user) {
133
        error_printf(", no-user");
134
    }
135
    error_printf("\n");
136
}
137

    
138
static int set_property(const char *name, const char *value, void *opaque)
139
{
140
    DeviceState *dev = opaque;
141

    
142
    if (strcmp(name, "driver") == 0)
143
        return 0;
144
    if (strcmp(name, "bus") == 0)
145
        return 0;
146

    
147
    if (qdev_prop_parse(dev, name, value) == -1) {
148
        return -1;
149
    }
150
    return 0;
151
}
152

    
153
int qdev_device_help(QemuOpts *opts)
154
{
155
    const char *driver;
156
    DeviceInfo *info;
157
    Property *prop;
158

    
159
    driver = qemu_opt_get(opts, "driver");
160
    if (driver && !strcmp(driver, "?")) {
161
        for (info = device_info_list; info != NULL; info = info->next) {
162
            if (info->no_user) {
163
                continue;       /* not available, don't show */
164
            }
165
            qdev_print_devinfo(info);
166
        }
167
        return 1;
168
    }
169

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

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

    
179
    for (prop = info->props; prop && prop->name; prop++) {
180
        /*
181
         * TODO Properties without a parser are just for dirty hacks.
182
         * qdev_prop_ptr is the only such PropertyInfo.  It's marked
183
         * for removal.  This conditional should be removed along with
184
         * it.
185
         */
186
        if (!prop->info->parse) {
187
            continue;           /* no way to set it, don't show */
188
        }
189
        error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
190
    }
191
    return 1;
192
}
193

    
194
DeviceState *qdev_device_add(QemuOpts *opts)
195
{
196
    const char *driver, *path, *id;
197
    DeviceInfo *info;
198
    DeviceState *qdev;
199
    BusState *bus;
200

    
201
    driver = qemu_opt_get(opts, "driver");
202
    if (!driver) {
203
        qerror_report(QERR_MISSING_PARAMETER, "driver");
204
        return NULL;
205
    }
206

    
207
    /* find driver */
208
    info = qdev_find_info(NULL, driver);
209
    if (!info || info->no_user) {
210
        qerror_report(QERR_INVALID_PARAMETER, "driver");
211
        error_printf_unless_qmp("Try with argument '?' for a list.\n");
212
        return NULL;
213
    }
214

    
215
    /* find bus */
216
    path = qemu_opt_get(opts, "bus");
217
    if (path != NULL) {
218
        bus = qbus_find(path);
219
        if (!bus) {
220
            return NULL;
221
        }
222
        if (bus->info != info->bus_info) {
223
            qerror_report(QERR_BAD_BUS_FOR_DEVICE,
224
                           driver, bus->info->name);
225
            return NULL;
226
        }
227
    } else {
228
        bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
229
        if (!bus) {
230
            qerror_report(QERR_NO_BUS_FOR_DEVICE,
231
                           info->name, info->bus_info->name);
232
            return NULL;
233
        }
234
    }
235
    if (qdev_hotplug && !bus->allow_hotplug) {
236
        qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
237
        return NULL;
238
    }
239

    
240
    /* create device, set properties */
241
    qdev = qdev_create_from_info(bus, info);
242
    id = qemu_opts_id(opts);
243
    if (id) {
244
        qdev->id = id;
245
    }
246
    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
247
        qdev_free(qdev);
248
        return NULL;
249
    }
250
    if (qdev_init(qdev) < 0) {
251
        qerror_report(QERR_DEVICE_INIT_FAILED, driver);
252
        return NULL;
253
    }
254
    qdev->opts = opts;
255
    return qdev;
256
}
257

    
258
static void qdev_reset(void *opaque)
259
{
260
    DeviceState *dev = opaque;
261
    if (dev->info->reset)
262
        dev->info->reset(dev);
263
}
264

    
265
/* Initialize a device.  Device properties should be set before calling
266
   this function.  IRQs and MMIO regions should be connected/mapped after
267
   calling this function.
268
   On failure, destroy the device and return negative value.
269
   Return 0 on success.  */
270
int qdev_init(DeviceState *dev)
271
{
272
    int rc;
273

    
274
    assert(dev->state == DEV_STATE_CREATED);
275
    rc = dev->info->init(dev, dev->info);
276
    if (rc < 0) {
277
        qdev_free(dev);
278
        return rc;
279
    }
280
    qemu_register_reset(qdev_reset, dev);
281
    if (dev->info->vmsd)
282
        vmstate_register(-1, dev->info->vmsd, dev);
283
    dev->state = DEV_STATE_INITIALIZED;
284
    return 0;
285
}
286

    
287
int qdev_unplug(DeviceState *dev)
288
{
289
    if (!dev->parent_bus->allow_hotplug) {
290
        error_report("Bus %s does not support hotplugging",
291
                     dev->parent_bus->name);
292
        return -1;
293
    }
294
    assert(dev->info->unplug != NULL);
295

    
296
    return dev->info->unplug(dev);
297
}
298

    
299
/* can be used as ->unplug() callback for the simple cases */
300
int qdev_simple_unplug_cb(DeviceState *dev)
301
{
302
    /* just zap it */
303
    qdev_free(dev);
304
    return 0;
305
}
306

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

    
318
    if (qdev_init(dev) < 0)
319
        hw_error("Initialization of device %s failed\n", info->name);
320
}
321

    
322
/* Unlink device from bus and free the structure.  */
323
void qdev_free(DeviceState *dev)
324
{
325
    BusState *bus;
326

    
327
    if (dev->state == DEV_STATE_INITIALIZED) {
328
        while (dev->num_child_bus) {
329
            bus = QLIST_FIRST(&dev->child_bus);
330
            qbus_free(bus);
331
        }
332
        if (dev->info->vmsd)
333
            vmstate_unregister(dev->info->vmsd, dev);
334
        if (dev->info->exit)
335
            dev->info->exit(dev);
336
        if (dev->opts)
337
            qemu_opts_del(dev->opts);
338
    }
339
    qemu_unregister_reset(qdev_reset, dev);
340
    QLIST_REMOVE(dev, sibling);
341
    qemu_free(dev);
342
}
343

    
344
void qdev_machine_creation_done(void)
345
{
346
    /*
347
     * ok, initial machine setup is done, starting from now we can
348
     * only create hotpluggable devices
349
     */
350
    qdev_hotplug = 1;
351
}
352

    
353
/* Get a character (serial) device interface.  */
354
CharDriverState *qdev_init_chardev(DeviceState *dev)
355
{
356
    static int next_serial;
357

    
358
    /* FIXME: This function needs to go away: use chardev properties!  */
359
    return serial_hds[next_serial++];
360
}
361

    
362
BusState *qdev_get_parent_bus(DeviceState *dev)
363
{
364
    return dev->parent_bus;
365
}
366

    
367
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
368
{
369
    assert(dev->num_gpio_in == 0);
370
    dev->num_gpio_in = n;
371
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
372
}
373

    
374
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
375
{
376
    assert(dev->num_gpio_out == 0);
377
    dev->num_gpio_out = n;
378
    dev->gpio_out = pins;
379
}
380

    
381
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
382
{
383
    assert(n >= 0 && n < dev->num_gpio_in);
384
    return dev->gpio_in[n];
385
}
386

    
387
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
388
{
389
    assert(n >= 0 && n < dev->num_gpio_out);
390
    dev->gpio_out[n] = pin;
391
}
392

    
393
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
394
{
395
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
396
    if (nd->vlan)
397
        qdev_prop_set_vlan(dev, "vlan", nd->vlan);
398
    if (nd->netdev)
399
        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
400
    if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
401
        qdev_prop_exists(dev, "vectors")) {
402
        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
403
    }
404
}
405

    
406
static int next_block_unit[IF_COUNT];
407

    
408
/* Get a block device.  This should only be used for single-drive devices
409
   (e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the
410
   appropriate bus.  */
411
BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
412
{
413
    int unit = next_block_unit[type]++;
414
    DriveInfo *dinfo;
415

    
416
    dinfo = drive_get(type, 0, unit);
417
    return dinfo ? dinfo->bdrv : NULL;
418
}
419

    
420
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
421
{
422
    BusState *bus;
423

    
424
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
425
        if (strcmp(name, bus->name) == 0) {
426
            return bus;
427
        }
428
    }
429
    return NULL;
430
}
431

    
432
static BusState *qbus_find_recursive(BusState *bus, const char *name,
433
                                     const BusInfo *info)
434
{
435
    DeviceState *dev;
436
    BusState *child, *ret;
437
    int match = 1;
438

    
439
    if (name && (strcmp(bus->name, name) != 0)) {
440
        match = 0;
441
    }
442
    if (info && (bus->info != info)) {
443
        match = 0;
444
    }
445
    if (match) {
446
        return bus;
447
    }
448

    
449
    QLIST_FOREACH(dev, &bus->children, sibling) {
450
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
451
            ret = qbus_find_recursive(child, name, info);
452
            if (ret) {
453
                return ret;
454
            }
455
        }
456
    }
457
    return NULL;
458
}
459

    
460
static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
461
{
462
    DeviceState *dev, *ret;
463
    BusState *child;
464

    
465
    QLIST_FOREACH(dev, &bus->children, sibling) {
466
        if (dev->id && strcmp(dev->id, id) == 0)
467
            return dev;
468
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
469
            ret = qdev_find_recursive(child, id);
470
            if (ret) {
471
                return ret;
472
            }
473
        }
474
    }
475
    return NULL;
476
}
477

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

    
483
    error_printf("child busses at \"%s\":",
484
                 dev->id ? dev->id : dev->info->name);
485
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
486
        error_printf("%s\"%s\"", sep, child->name);
487
        sep = ", ";
488
    }
489
    error_printf("\n");
490
}
491

    
492
static void qbus_list_dev(BusState *bus)
493
{
494
    DeviceState *dev;
495
    const char *sep = " ";
496

    
497
    error_printf("devices at \"%s\":", bus->name);
498
    QLIST_FOREACH(dev, &bus->children, sibling) {
499
        error_printf("%s\"%s\"", sep, dev->info->name);
500
        if (dev->id)
501
            error_printf("/\"%s\"", dev->id);
502
        sep = ", ";
503
    }
504
    error_printf("\n");
505
}
506

    
507
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
508
{
509
    BusState *child;
510

    
511
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
512
        if (strcmp(child->name, elem) == 0) {
513
            return child;
514
        }
515
    }
516
    return NULL;
517
}
518

    
519
static DeviceState *qbus_find_dev(BusState *bus, char *elem)
520
{
521
    DeviceState *dev;
522

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

    
547
static BusState *qbus_find(const char *path)
548
{
549
    DeviceState *dev;
550
    BusState *bus;
551
    char elem[128];
552
    int pos, len;
553

    
554
    /* find start element */
555
    if (path[0] == '/') {
556
        bus = main_system_bus;
557
        pos = 0;
558
    } else {
559
        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
560
            assert(!path[0]);
561
            elem[0] = len = 0;
562
        }
563
        bus = qbus_find_recursive(main_system_bus, elem, NULL);
564
        if (!bus) {
565
            qerror_report(QERR_BUS_NOT_FOUND, elem);
566
            return NULL;
567
        }
568
        pos = len;
569
    }
570

    
571
    for (;;) {
572
        assert(path[pos] == '/' || !path[pos]);
573
        while (path[pos] == '/') {
574
            pos++;
575
        }
576
        if (path[pos] == '\0') {
577
            return bus;
578
        }
579

    
580
        /* find device */
581
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
582
            assert(0);
583
            elem[0] = len = 0;
584
        }
585
        pos += len;
586
        dev = qbus_find_dev(bus, elem);
587
        if (!dev) {
588
            qerror_report(QERR_DEVICE_NOT_FOUND, elem);
589
            qbus_list_dev(bus);
590
            return NULL;
591
        }
592

    
593
        assert(path[pos] == '/' || !path[pos]);
594
        while (path[pos] == '/') {
595
            pos++;
596
        }
597
        if (path[pos] == '\0') {
598
            /* last specified element is a device.  If it has exactly
599
             * one child bus accept it nevertheless */
600
            switch (dev->num_child_bus) {
601
            case 0:
602
                qerror_report(QERR_DEVICE_NO_BUS, elem);
603
                return NULL;
604
            case 1:
605
                return QLIST_FIRST(&dev->child_bus);
606
            default:
607
                qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
608
                qbus_list_bus(dev);
609
                return NULL;
610
            }
611
        }
612

    
613
        /* find bus */
614
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
615
            assert(0);
616
            elem[0] = len = 0;
617
        }
618
        pos += len;
619
        bus = qbus_find_bus(dev, elem);
620
        if (!bus) {
621
            qerror_report(QERR_BUS_NOT_FOUND, elem);
622
            qbus_list_bus(dev);
623
            return NULL;
624
        }
625
    }
626
}
627

    
628
void qbus_create_inplace(BusState *bus, BusInfo *info,
629
                         DeviceState *parent, const char *name)
630
{
631
    char *buf;
632
    int i,len;
633

    
634
    bus->info = info;
635
    bus->parent = parent;
636

    
637
    if (name) {
638
        /* use supplied name */
639
        bus->name = qemu_strdup(name);
640
    } else if (parent && parent->id) {
641
        /* parent device has id -> use it for bus name */
642
        len = strlen(parent->id) + 16;
643
        buf = qemu_malloc(len);
644
        snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
645
        bus->name = buf;
646
    } else {
647
        /* no id -> use lowercase bus type for bus name */
648
        len = strlen(info->name) + 16;
649
        buf = qemu_malloc(len);
650
        len = snprintf(buf, len, "%s.%d", info->name,
651
                       parent ? parent->num_child_bus : 0);
652
        for (i = 0; i < len; i++)
653
            buf[i] = qemu_tolower(buf[i]);
654
        bus->name = buf;
655
    }
656

    
657
    QLIST_INIT(&bus->children);
658
    if (parent) {
659
        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
660
        parent->num_child_bus++;
661
    }
662

    
663
}
664

    
665
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
666
{
667
    BusState *bus;
668

    
669
    bus = qemu_mallocz(info->size);
670
    bus->qdev_allocated = 1;
671
    qbus_create_inplace(bus, info, parent, name);
672
    return bus;
673
}
674

    
675
void qbus_free(BusState *bus)
676
{
677
    DeviceState *dev;
678

    
679
    while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
680
        qdev_free(dev);
681
    }
682
    if (bus->parent) {
683
        QLIST_REMOVE(bus, sibling);
684
        bus->parent->num_child_bus--;
685
    }
686
    if (bus->qdev_allocated) {
687
        qemu_free(bus);
688
    }
689
}
690

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

    
694
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
695
                             const char *prefix, int indent)
696
{
697
    char buf[64];
698

    
699
    if (!props)
700
        return;
701
    while (props->name) {
702
        /*
703
         * TODO Properties without a print method are just for dirty
704
         * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
705
         * marked for removal.  The test props->info->print should be
706
         * removed along with it.
707
         */
708
        if (props->info->print) {
709
            props->info->print(dev, props, buf, sizeof(buf));
710
            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
711
        }
712
        props++;
713
    }
714
}
715

    
716
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
717
{
718
    BusState *child;
719
    qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
720
                dev->id ? dev->id : "");
721
    indent += 2;
722
    if (dev->num_gpio_in) {
723
        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
724
    }
725
    if (dev->num_gpio_out) {
726
        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
727
    }
728
    qdev_print_props(mon, dev, dev->info->props, "dev", indent);
729
    qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
730
    if (dev->parent_bus->info->print_dev)
731
        dev->parent_bus->info->print_dev(mon, dev, indent);
732
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
733
        qbus_print(mon, child, indent);
734
    }
735
}
736

    
737
static void qbus_print(Monitor *mon, BusState *bus, int indent)
738
{
739
    struct DeviceState *dev;
740

    
741
    qdev_printf("bus: %s\n", bus->name);
742
    indent += 2;
743
    qdev_printf("type %s\n", bus->info->name);
744
    QLIST_FOREACH(dev, &bus->children, sibling) {
745
        qdev_print(mon, dev, indent);
746
    }
747
}
748
#undef qdev_printf
749

    
750
void do_info_qtree(Monitor *mon)
751
{
752
    if (main_system_bus)
753
        qbus_print(mon, main_system_bus, 0);
754
}
755

    
756
void do_info_qdm(Monitor *mon)
757
{
758
    DeviceInfo *info;
759

    
760
    for (info = device_info_list; info != NULL; info = info->next) {
761
        qdev_print_devinfo(info);
762
    }
763
}
764

    
765
void do_device_add(Monitor *mon, const QDict *qdict)
766
{
767
    QemuOpts *opts;
768

    
769
    opts = qemu_opts_parse(&qemu_device_opts,
770
                           qdict_get_str(qdict, "config"), 1);
771
    if (opts) {
772
        if (qdev_device_help(opts) || qdev_device_add(opts) == NULL) {
773
            qemu_opts_del(opts);
774
        }
775
    }
776
}
777

    
778
void do_device_del(Monitor *mon, const QDict *qdict)
779
{
780
    const char *id = qdict_get_str(qdict, "id");
781
    DeviceState *dev;
782

    
783
    dev = qdev_find_recursive(main_system_bus, id);
784
    if (NULL == dev) {
785
        error_report("Device '%s' not found", id);
786
        return;
787
    }
788
    qdev_unplug(dev);
789
}