Statistics
| Branch: | Revision:

root / hw / qdev.c @ 97b15621

History | View | Annotate | Download (21 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
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
387
{
388
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
389
    if (nd->vlan)
390
        qdev_prop_set_vlan(dev, "vlan", nd->vlan);
391
    if (nd->netdev)
392
        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
393
    if (nd->nvectors != NIC_NVECTORS_UNSPECIFIED &&
394
        qdev_prop_exists(dev, "vectors")) {
395
        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
396
    }
397
}
398

    
399
static int next_block_unit[IF_COUNT];
400

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

    
409
    dinfo = drive_get(type, 0, unit);
410
    return dinfo ? dinfo->bdrv : NULL;
411
}
412

    
413
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
414
{
415
    BusState *bus;
416

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

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

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

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

    
453
static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
454
{
455
    DeviceState *dev, *ret;
456
    BusState *child;
457

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

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

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

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

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

    
502
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
503
{
504
    BusState *child;
505

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

    
514
static DeviceState *qbus_find_dev(BusState *bus, char *elem)
515
{
516
    DeviceState *dev;
517

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

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

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

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

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

    
601
        /* find bus */
602
        if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
603
            qemu_error("path parse error (\"%s\" pos %d)\n", path, pos);
604
            return NULL;
605
        }
606
        pos += len;
607
        bus = qbus_find_bus(dev, elem);
608
        if (!bus) {
609
            qbus_list_bus(dev, msg, sizeof(msg));
610
            qemu_error("child bus \"%s\" not found\n%s\n", elem, msg);
611
            return NULL;
612
        }
613
    }
614
}
615

    
616
void qbus_create_inplace(BusState *bus, BusInfo *info,
617
                         DeviceState *parent, const char *name)
618
{
619
    char *buf;
620
    int i,len;
621

    
622
    bus->info = info;
623
    bus->parent = parent;
624

    
625
    if (name) {
626
        /* use supplied name */
627
        bus->name = qemu_strdup(name);
628
    } else if (parent && parent->id) {
629
        /* parent device has id -> use it for bus name */
630
        len = strlen(parent->id) + 16;
631
        buf = qemu_malloc(len);
632
        snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
633
        bus->name = buf;
634
    } else {
635
        /* no id -> use lowercase bus type for bus name */
636
        len = strlen(info->name) + 16;
637
        buf = qemu_malloc(len);
638
        len = snprintf(buf, len, "%s.%d", info->name,
639
                       parent ? parent->num_child_bus : 0);
640
        for (i = 0; i < len; i++)
641
            buf[i] = qemu_tolower(buf[i]);
642
        bus->name = buf;
643
    }
644

    
645
    QLIST_INIT(&bus->children);
646
    if (parent) {
647
        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
648
        parent->num_child_bus++;
649
    }
650

    
651
}
652

    
653
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
654
{
655
    BusState *bus;
656

    
657
    bus = qemu_mallocz(info->size);
658
    bus->qdev_allocated = 1;
659
    qbus_create_inplace(bus, info, parent, name);
660
    return bus;
661
}
662

    
663
void qbus_free(BusState *bus)
664
{
665
    DeviceState *dev;
666

    
667
    while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
668
        qdev_free(dev);
669
    }
670
    if (bus->parent) {
671
        QLIST_REMOVE(bus, sibling);
672
        bus->parent->num_child_bus--;
673
    }
674
    if (bus->qdev_allocated) {
675
        qemu_free(bus);
676
    }
677
}
678

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

    
682
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
683
                             const char *prefix, int indent)
684
{
685
    char buf[64];
686

    
687
    if (!props)
688
        return;
689
    while (props->name) {
690
        if (props->info->print) {
691
            props->info->print(dev, props, buf, sizeof(buf));
692
            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
693
        }
694
        props++;
695
    }
696
}
697

    
698
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
699
{
700
    BusState *child;
701
    qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
702
                dev->id ? dev->id : "");
703
    indent += 2;
704
    if (dev->num_gpio_in) {
705
        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
706
    }
707
    if (dev->num_gpio_out) {
708
        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
709
    }
710
    qdev_print_props(mon, dev, dev->info->props, "dev", indent);
711
    qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
712
    if (dev->parent_bus->info->print_dev)
713
        dev->parent_bus->info->print_dev(mon, dev, indent);
714
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
715
        qbus_print(mon, child, indent);
716
    }
717
}
718

    
719
static void qbus_print(Monitor *mon, BusState *bus, int indent)
720
{
721
    struct DeviceState *dev;
722

    
723
    qdev_printf("bus: %s\n", bus->name);
724
    indent += 2;
725
    qdev_printf("type %s\n", bus->info->name);
726
    QLIST_FOREACH(dev, &bus->children, sibling) {
727
        qdev_print(mon, dev, indent);
728
    }
729
}
730
#undef qdev_printf
731

    
732
void do_info_qtree(Monitor *mon)
733
{
734
    if (main_system_bus)
735
        qbus_print(mon, main_system_bus, 0);
736
}
737

    
738
void do_info_qdm(Monitor *mon)
739
{
740
    DeviceInfo *info;
741
    char msg[256];
742

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

    
749
void do_device_add(Monitor *mon, const QDict *qdict)
750
{
751
    QemuOpts *opts;
752

    
753
    opts = qemu_opts_parse(&qemu_device_opts,
754
                           qdict_get_str(qdict, "config"), "driver");
755
    if (opts)
756
        qdev_device_add(opts);
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
}