Statistics
| Branch: | Revision:

root / hw / qdev.c @ 283c7c63

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

    
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
static 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
/* Create a new device.  This only initializes the device state structure
81
   and allows properties to be set.  qdev_init should be called to
82
   initialize the actual device emulation.  */
83
DeviceState *qdev_create(BusState *bus, const char *name)
84
{
85
    DeviceInfo *info;
86
    DeviceState *dev;
87

    
88
    if (!bus) {
89
        if (!main_system_bus) {
90
            main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
91
        }
92
        bus = main_system_bus;
93
    }
94

    
95
    info = qdev_find_info(bus->info, name);
96
    if (!info) {
97
        hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
98
    }
99

    
100
    dev = qemu_mallocz(info->size);
101
    dev->info = info;
102
    dev->parent_bus = bus;
103
    qdev_prop_set_defaults(dev, dev->info->props);
104
    qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
105
    qdev_prop_set_compat(dev);
106
    QLIST_INSERT_HEAD(&bus->children, dev, sibling);
107
    if (qdev_hotplug) {
108
        assert(bus->allow_hotplug);
109
        dev->hotplugged = 1;
110
    }
111
    dev->state = DEV_STATE_CREATED;
112
    return dev;
113
}
114

    
115
static int qdev_print_devinfo(DeviceInfo *info, char *dest, int len)
116
{
117
    int pos = 0;
118
    int ret;
119

    
120
    ret = snprintf(dest+pos, len-pos, "name \"%s\", bus %s",
121
                   info->name, info->bus_info->name);
122
    pos += MIN(len-pos,ret);
123
    if (info->alias) {
124
        ret = snprintf(dest+pos, len-pos, ", alias \"%s\"", info->alias);
125
        pos += MIN(len-pos,ret);
126
    }
127
    if (info->desc) {
128
        ret = snprintf(dest+pos, len-pos, ", desc \"%s\"", info->desc);
129
        pos += MIN(len-pos,ret);
130
    }
131
    if (info->no_user) {
132
        ret = snprintf(dest+pos, len-pos, ", no-user");
133
        pos += MIN(len-pos,ret);
134
    }
135
    return pos;
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
        qemu_error("can't set property \"%s\" to \"%s\" for \"%s\"\n",
149
                   name, value, dev->info->name);
150
        return -1;
151
    }
152
    return 0;
153
}
154

    
155
DeviceState *qdev_device_add(QemuOpts *opts)
156
{
157
    const char *driver, *path, *id;
158
    DeviceInfo *info;
159
    DeviceState *qdev;
160
    BusState *bus;
161

    
162
    driver = qemu_opt_get(opts, "driver");
163
    if (!driver) {
164
        qemu_error("-device: no driver specified\n");
165
        return NULL;
166
    }
167
    if (strcmp(driver, "?") == 0) {
168
        char msg[256];
169
        for (info = device_info_list; info != NULL; info = info->next) {
170
            qdev_print_devinfo(info, msg, sizeof(msg));
171
            qemu_error("%s\n", msg);
172
        }
173
        return NULL;
174
    }
175

    
176
    /* find driver */
177
    info = qdev_find_info(NULL, driver);
178
    if (!info) {
179
        qemu_error("Device \"%s\" not found.  Try -device '?' for a list.\n",
180
                   driver);
181
        return NULL;
182
    }
183
    if (info->no_user) {
184
        qemu_error("device \"%s\" can't be added via command line\n",
185
                   info->name);
186
        return NULL;
187
    }
188

    
189
    /* find bus */
190
    path = qemu_opt_get(opts, "bus");
191
    if (path != NULL) {
192
        bus = qbus_find(path);
193
    } else {
194
        bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
195
    }
196
    if (!bus) {
197
        qemu_error("Did not find %s bus for %s\n",
198
                   path ? path : info->bus_info->name, info->name);
199
        return NULL;
200
    }
201
    if (qdev_hotplug && !bus->allow_hotplug) {
202
        qemu_error("Bus %s does not support hotplugging\n",
203
                   bus->name);
204
        return NULL;
205
    }
206

    
207
    /* create device, set properties */
208
    qdev = qdev_create(bus, driver);
209
    id = qemu_opts_id(opts);
210
    if (id) {
211
        qdev->id = id;
212
    }
213
    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
214
        qdev_free(qdev);
215
        return NULL;
216
    }
217
    if (qdev_init(qdev) < 0) {
218
        qemu_error("Error initializing device %s\n", driver);
219
        return NULL;
220
    }
221
    qdev->opts = opts;
222
    return qdev;
223
}
224

    
225
static void qdev_reset(void *opaque)
226
{
227
    DeviceState *dev = opaque;
228
    if (dev->info->reset)
229
        dev->info->reset(dev);
230
}
231

    
232
/* Initialize a device.  Device properties should be set before calling
233
   this function.  IRQs and MMIO regions should be connected/mapped after
234
   calling this function.
235
   On failure, destroy the device and return negative value.
236
   Return 0 on success.  */
237
int qdev_init(DeviceState *dev)
238
{
239
    int rc;
240

    
241
    assert(dev->state == DEV_STATE_CREATED);
242
    rc = dev->info->init(dev, dev->info);
243
    if (rc < 0) {
244
        qdev_free(dev);
245
        return rc;
246
    }
247
    qemu_register_reset(qdev_reset, dev);
248
    if (dev->info->vmsd)
249
        vmstate_register(-1, dev->info->vmsd, dev);
250
    dev->state = DEV_STATE_INITIALIZED;
251
    return 0;
252
}
253

    
254
int qdev_unplug(DeviceState *dev)
255
{
256
    if (!dev->parent_bus->allow_hotplug) {
257
        qemu_error("Bus %s does not support hotplugging\n",
258
                   dev->parent_bus->name);
259
        return -1;
260
    }
261
    return dev->info->unplug(dev);
262
}
263

    
264
/* can be used as ->unplug() callback for the simple cases */
265
int qdev_simple_unplug_cb(DeviceState *dev)
266
{
267
    /* just zap it */
268
    qdev_free(dev);
269
    return 0;
270
}
271

    
272
/* Like qdev_init(), but terminate program via hw_error() instead of
273
   returning an error value.  This is okay during machine creation.
274
   Don't use for hotplug, because there callers need to recover from
275
   failure.  Exception: if you know the device's init() callback can't
276
   fail, then qdev_init_nofail() can't fail either, and is therefore
277
   usable even then.  But relying on the device implementation that
278
   way is somewhat unclean, and best avoided.  */
279
void qdev_init_nofail(DeviceState *dev)
280
{
281
    DeviceInfo *info = dev->info;
282

    
283
    if (qdev_init(dev) < 0)
284
        hw_error("Initialization of device %s failed\n", info->name);
285
}
286

    
287
/* Unlink device from bus and free the structure.  */
288
void qdev_free(DeviceState *dev)
289
{
290
    BusState *bus;
291

    
292
    if (dev->state == DEV_STATE_INITIALIZED) {
293
        while (dev->num_child_bus) {
294
            bus = QLIST_FIRST(&dev->child_bus);
295
            qbus_free(bus);
296
        }
297
#if 0 /* FIXME: need sane vmstate_unregister function */
298
        if (dev->info->vmsd)
299
            vmstate_unregister(dev->info->vmsd, dev);
300
#endif
301
        if (dev->info->exit)
302
            dev->info->exit(dev);
303
        if (dev->opts)
304
            qemu_opts_del(dev->opts);
305
    }
306
    qemu_unregister_reset(qdev_reset, dev);
307
    QLIST_REMOVE(dev, sibling);
308
    qemu_free(dev);
309
}
310

    
311
void qdev_machine_creation_done(void)
312
{
313
    /*
314
     * ok, initial machine setup is done, starting from now we can
315
     * only create hotpluggable devices
316
     */
317
    qdev_hotplug = 1;
318
}
319

    
320
/* Get a character (serial) device interface.  */
321
CharDriverState *qdev_init_chardev(DeviceState *dev)
322
{
323
    static int next_serial;
324
    static int next_virtconsole;
325
    /* FIXME: This is a nasty hack that needs to go away.  */
326
    if (strncmp(dev->info->name, "virtio", 6) == 0) {
327
        return virtcon_hds[next_virtconsole++];
328
    } else {
329
        return serial_hds[next_serial++];
330
    }
331
}
332

    
333
BusState *qdev_get_parent_bus(DeviceState *dev)
334
{
335
    return dev->parent_bus;
336
}
337

    
338
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
339
{
340
    assert(dev->num_gpio_in == 0);
341
    dev->num_gpio_in = n;
342
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
343
}
344

    
345
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
346
{
347
    assert(dev->num_gpio_out == 0);
348
    dev->num_gpio_out = n;
349
    dev->gpio_out = pins;
350
}
351

    
352
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
353
{
354
    assert(n >= 0 && n < dev->num_gpio_in);
355
    return dev->gpio_in[n];
356
}
357

    
358
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
359
{
360
    assert(n >= 0 && n < dev->num_gpio_out);
361
    dev->gpio_out[n] = pin;
362
}
363

    
364
VLANClientState *qdev_get_vlan_client(DeviceState *dev,
365
                                      NetCanReceive *can_receive,
366
                                      NetReceive *receive,
367
                                      NetReceiveIOV *receive_iov,
368
                                      NetCleanup *cleanup,
369
                                      void *opaque)
370
{
371
    NICInfo *nd = dev->nd;
372
    assert(nd);
373
    nd->vc = qemu_new_vlan_client(nd->vlan, nd->netdev,
374
                                  nd->model, nd->name,
375
                                  can_receive, receive, receive_iov,
376
                                  cleanup, opaque);
377
    return nd->vc;
378
}
379

    
380

    
381
void qdev_get_macaddr(DeviceState *dev, uint8_t *macaddr)
382
{
383
    memcpy(macaddr, dev->nd->macaddr, 6);
384
}
385

    
386
static int next_block_unit[IF_COUNT];
387

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
609
    bus->info = info;
610
    bus->parent = parent;
611

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

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

    
638
}
639

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

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

    
650
void qbus_free(BusState *bus)
651
{
652
    DeviceState *dev;
653

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

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

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

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

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

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

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

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

    
725
void do_info_qdm(Monitor *mon)
726
{
727
    DeviceInfo *info;
728
    char msg[256];
729

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

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

    
740
    opts = qemu_opts_parse(&qemu_device_opts,
741
                           qdict_get_str(qdict, "config"), "driver");
742
    if (opts)
743
        qdev_device_add(opts);
744
}
745

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

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