Statistics
| Branch: | Revision:

root / hw / qdev.c @ 3329f07b

History | View | Annotate | Download (21.8 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->instance_id_alias = -1;
97
    dev->state = DEV_STATE_CREATED;
98
    return dev;
99
}
100

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

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

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

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

    
123
static void qdev_print_devinfo(DeviceInfo *info)
124
{
125
    error_printf("name \"%s\", bus %s",
126
                 info->name, info->bus_info->name);
127
    if (info->alias) {
128
        error_printf(", alias \"%s\"", info->alias);
129
    }
130
    if (info->desc) {
131
        error_printf(", desc \"%s\"", info->desc);
132
    }
133
    if (info->no_user) {
134
        error_printf(", no-user");
135
    }
136
    error_printf("\n");
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
        return -1;
150
    }
151
    return 0;
152
}
153

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

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

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

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

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

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

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

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

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

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

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

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

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

    
291
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
292
                                 int required_for_version)
293
{
294
    assert(dev->state == DEV_STATE_CREATED);
295
    dev->instance_id_alias = alias_id;
296
    dev->alias_required_for_version = required_for_version;
297
}
298

    
299
int qdev_unplug(DeviceState *dev)
300
{
301
    if (!dev->parent_bus->allow_hotplug) {
302
        qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
303
        return -1;
304
    }
305
    assert(dev->info->unplug != NULL);
306

    
307
    return dev->info->unplug(dev);
308
}
309

    
310
/* can be used as ->unplug() callback for the simple cases */
311
int qdev_simple_unplug_cb(DeviceState *dev)
312
{
313
    /* just zap it */
314
    qdev_free(dev);
315
    return 0;
316
}
317

    
318
/* Like qdev_init(), but terminate program via hw_error() instead of
319
   returning an error value.  This is okay during machine creation.
320
   Don't use for hotplug, because there callers need to recover from
321
   failure.  Exception: if you know the device's init() callback can't
322
   fail, then qdev_init_nofail() can't fail either, and is therefore
323
   usable even then.  But relying on the device implementation that
324
   way is somewhat unclean, and best avoided.  */
325
void qdev_init_nofail(DeviceState *dev)
326
{
327
    DeviceInfo *info = dev->info;
328

    
329
    if (qdev_init(dev) < 0) {
330
        error_report("Initialization of device %s failed\n", info->name);
331
        exit(1);
332
    }
333
}
334

    
335
/* Unlink device from bus and free the structure.  */
336
void qdev_free(DeviceState *dev)
337
{
338
    BusState *bus;
339
    Property *prop;
340

    
341
    if (dev->state == DEV_STATE_INITIALIZED) {
342
        while (dev->num_child_bus) {
343
            bus = QLIST_FIRST(&dev->child_bus);
344
            qbus_free(bus);
345
        }
346
        if (dev->info->vmsd)
347
            vmstate_unregister(dev, dev->info->vmsd, dev);
348
        if (dev->info->exit)
349
            dev->info->exit(dev);
350
        if (dev->opts)
351
            qemu_opts_del(dev->opts);
352
    }
353
    qemu_unregister_reset(qdev_reset, dev);
354
    QLIST_REMOVE(dev, sibling);
355
    for (prop = dev->info->props; prop && prop->name; prop++) {
356
        if (prop->info->free) {
357
            prop->info->free(dev, prop);
358
        }
359
    }
360
    qemu_free(dev);
361
}
362

    
363
void qdev_machine_creation_done(void)
364
{
365
    /*
366
     * ok, initial machine setup is done, starting from now we can
367
     * only create hotpluggable devices
368
     */
369
    qdev_hotplug = 1;
370
}
371

    
372
/* Get a character (serial) device interface.  */
373
CharDriverState *qdev_init_chardev(DeviceState *dev)
374
{
375
    static int next_serial;
376

    
377
    /* FIXME: This function needs to go away: use chardev properties!  */
378
    return serial_hds[next_serial++];
379
}
380

    
381
BusState *qdev_get_parent_bus(DeviceState *dev)
382
{
383
    return dev->parent_bus;
384
}
385

    
386
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
387
{
388
    assert(dev->num_gpio_in == 0);
389
    dev->num_gpio_in = n;
390
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
391
}
392

    
393
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
394
{
395
    assert(dev->num_gpio_out == 0);
396
    dev->num_gpio_out = n;
397
    dev->gpio_out = pins;
398
}
399

    
400
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
401
{
402
    assert(n >= 0 && n < dev->num_gpio_in);
403
    return dev->gpio_in[n];
404
}
405

    
406
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
407
{
408
    assert(n >= 0 && n < dev->num_gpio_out);
409
    dev->gpio_out[n] = pin;
410
}
411

    
412
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
413
{
414
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
415
    if (nd->vlan)
416
        qdev_prop_set_vlan(dev, "vlan", nd->vlan);
417
    if (nd->netdev)
418
        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
419
    if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
420
        qdev_prop_exists(dev, "vectors")) {
421
        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
422
    }
423
}
424

    
425
static int next_block_unit[IF_COUNT];
426

    
427
/* Get a block device.  This should only be used for single-drive devices
428
   (e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the
429
   appropriate bus.  */
430
BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
431
{
432
    int unit = next_block_unit[type]++;
433
    DriveInfo *dinfo;
434

    
435
    dinfo = drive_get(type, 0, unit);
436
    return dinfo ? dinfo->bdrv : NULL;
437
}
438

    
439
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
440
{
441
    BusState *bus;
442

    
443
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
444
        if (strcmp(name, bus->name) == 0) {
445
            return bus;
446
        }
447
    }
448
    return NULL;
449
}
450

    
451
static BusState *qbus_find_recursive(BusState *bus, const char *name,
452
                                     const BusInfo *info)
453
{
454
    DeviceState *dev;
455
    BusState *child, *ret;
456
    int match = 1;
457

    
458
    if (name && (strcmp(bus->name, name) != 0)) {
459
        match = 0;
460
    }
461
    if (info && (bus->info != info)) {
462
        match = 0;
463
    }
464
    if (match) {
465
        return bus;
466
    }
467

    
468
    QLIST_FOREACH(dev, &bus->children, sibling) {
469
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
470
            ret = qbus_find_recursive(child, name, info);
471
            if (ret) {
472
                return ret;
473
            }
474
        }
475
    }
476
    return NULL;
477
}
478

    
479
static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
480
{
481
    DeviceState *dev, *ret;
482
    BusState *child;
483

    
484
    QLIST_FOREACH(dev, &bus->children, sibling) {
485
        if (dev->id && strcmp(dev->id, id) == 0)
486
            return dev;
487
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
488
            ret = qdev_find_recursive(child, id);
489
            if (ret) {
490
                return ret;
491
            }
492
        }
493
    }
494
    return NULL;
495
}
496

    
497
static void qbus_list_bus(DeviceState *dev)
498
{
499
    BusState *child;
500
    const char *sep = " ";
501

    
502
    error_printf("child busses at \"%s\":",
503
                 dev->id ? dev->id : dev->info->name);
504
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
505
        error_printf("%s\"%s\"", sep, child->name);
506
        sep = ", ";
507
    }
508
    error_printf("\n");
509
}
510

    
511
static void qbus_list_dev(BusState *bus)
512
{
513
    DeviceState *dev;
514
    const char *sep = " ";
515

    
516
    error_printf("devices at \"%s\":", bus->name);
517
    QLIST_FOREACH(dev, &bus->children, sibling) {
518
        error_printf("%s\"%s\"", sep, dev->info->name);
519
        if (dev->id)
520
            error_printf("/\"%s\"", dev->id);
521
        sep = ", ";
522
    }
523
    error_printf("\n");
524
}
525

    
526
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
527
{
528
    BusState *child;
529

    
530
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
531
        if (strcmp(child->name, elem) == 0) {
532
            return child;
533
        }
534
    }
535
    return NULL;
536
}
537

    
538
static DeviceState *qbus_find_dev(BusState *bus, char *elem)
539
{
540
    DeviceState *dev;
541

    
542
    /*
543
     * try to match in order:
544
     *   (1) instance id, if present
545
     *   (2) driver name
546
     *   (3) driver alias, if present
547
     */
548
    QLIST_FOREACH(dev, &bus->children, sibling) {
549
        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
550
            return dev;
551
        }
552
    }
553
    QLIST_FOREACH(dev, &bus->children, sibling) {
554
        if (strcmp(dev->info->name, elem) == 0) {
555
            return dev;
556
        }
557
    }
558
    QLIST_FOREACH(dev, &bus->children, sibling) {
559
        if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
560
            return dev;
561
        }
562
    }
563
    return NULL;
564
}
565

    
566
static BusState *qbus_find(const char *path)
567
{
568
    DeviceState *dev;
569
    BusState *bus;
570
    char elem[128];
571
    int pos, len;
572

    
573
    /* find start element */
574
    if (path[0] == '/') {
575
        bus = main_system_bus;
576
        pos = 0;
577
    } else {
578
        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
579
            assert(!path[0]);
580
            elem[0] = len = 0;
581
        }
582
        bus = qbus_find_recursive(main_system_bus, elem, NULL);
583
        if (!bus) {
584
            qerror_report(QERR_BUS_NOT_FOUND, elem);
585
            return NULL;
586
        }
587
        pos = len;
588
    }
589

    
590
    for (;;) {
591
        assert(path[pos] == '/' || !path[pos]);
592
        while (path[pos] == '/') {
593
            pos++;
594
        }
595
        if (path[pos] == '\0') {
596
            return bus;
597
        }
598

    
599
        /* find device */
600
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
601
            assert(0);
602
            elem[0] = len = 0;
603
        }
604
        pos += len;
605
        dev = qbus_find_dev(bus, elem);
606
        if (!dev) {
607
            qerror_report(QERR_DEVICE_NOT_FOUND, elem);
608
            if (!monitor_cur_is_qmp()) {
609
                qbus_list_dev(bus);
610
            }
611
            return NULL;
612
        }
613

    
614
        assert(path[pos] == '/' || !path[pos]);
615
        while (path[pos] == '/') {
616
            pos++;
617
        }
618
        if (path[pos] == '\0') {
619
            /* last specified element is a device.  If it has exactly
620
             * one child bus accept it nevertheless */
621
            switch (dev->num_child_bus) {
622
            case 0:
623
                qerror_report(QERR_DEVICE_NO_BUS, elem);
624
                return NULL;
625
            case 1:
626
                return QLIST_FIRST(&dev->child_bus);
627
            default:
628
                qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
629
                if (!monitor_cur_is_qmp()) {
630
                    qbus_list_bus(dev);
631
                }
632
                return NULL;
633
            }
634
        }
635

    
636
        /* find bus */
637
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
638
            assert(0);
639
            elem[0] = len = 0;
640
        }
641
        pos += len;
642
        bus = qbus_find_bus(dev, elem);
643
        if (!bus) {
644
            qerror_report(QERR_BUS_NOT_FOUND, elem);
645
            if (!monitor_cur_is_qmp()) {
646
                qbus_list_bus(dev);
647
            }
648
            return NULL;
649
        }
650
    }
651
}
652

    
653
void qbus_create_inplace(BusState *bus, BusInfo *info,
654
                         DeviceState *parent, const char *name)
655
{
656
    char *buf;
657
    int i,len;
658

    
659
    bus->info = info;
660
    bus->parent = parent;
661

    
662
    if (name) {
663
        /* use supplied name */
664
        bus->name = qemu_strdup(name);
665
    } else if (parent && parent->id) {
666
        /* parent device has id -> use it for bus name */
667
        len = strlen(parent->id) + 16;
668
        buf = qemu_malloc(len);
669
        snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
670
        bus->name = buf;
671
    } else {
672
        /* no id -> use lowercase bus type for bus name */
673
        len = strlen(info->name) + 16;
674
        buf = qemu_malloc(len);
675
        len = snprintf(buf, len, "%s.%d", info->name,
676
                       parent ? parent->num_child_bus : 0);
677
        for (i = 0; i < len; i++)
678
            buf[i] = qemu_tolower(buf[i]);
679
        bus->name = buf;
680
    }
681

    
682
    QLIST_INIT(&bus->children);
683
    if (parent) {
684
        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
685
        parent->num_child_bus++;
686
    }
687

    
688
}
689

    
690
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
691
{
692
    BusState *bus;
693

    
694
    bus = qemu_mallocz(info->size);
695
    bus->qdev_allocated = 1;
696
    qbus_create_inplace(bus, info, parent, name);
697
    return bus;
698
}
699

    
700
void qbus_free(BusState *bus)
701
{
702
    DeviceState *dev;
703

    
704
    while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
705
        qdev_free(dev);
706
    }
707
    if (bus->parent) {
708
        QLIST_REMOVE(bus, sibling);
709
        bus->parent->num_child_bus--;
710
    }
711
    qemu_free((void*)bus->name);
712
    if (bus->qdev_allocated) {
713
        qemu_free(bus);
714
    }
715
}
716

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

    
720
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
721
                             const char *prefix, int indent)
722
{
723
    char buf[64];
724

    
725
    if (!props)
726
        return;
727
    while (props->name) {
728
        /*
729
         * TODO Properties without a print method are just for dirty
730
         * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
731
         * marked for removal.  The test props->info->print should be
732
         * removed along with it.
733
         */
734
        if (props->info->print) {
735
            props->info->print(dev, props, buf, sizeof(buf));
736
            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
737
        }
738
        props++;
739
    }
740
}
741

    
742
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
743
{
744
    BusState *child;
745
    qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
746
                dev->id ? dev->id : "");
747
    indent += 2;
748
    if (dev->num_gpio_in) {
749
        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
750
    }
751
    if (dev->num_gpio_out) {
752
        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
753
    }
754
    qdev_print_props(mon, dev, dev->info->props, "dev", indent);
755
    qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
756
    if (dev->parent_bus->info->print_dev)
757
        dev->parent_bus->info->print_dev(mon, dev, indent);
758
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
759
        qbus_print(mon, child, indent);
760
    }
761
}
762

    
763
static void qbus_print(Monitor *mon, BusState *bus, int indent)
764
{
765
    struct DeviceState *dev;
766

    
767
    qdev_printf("bus: %s\n", bus->name);
768
    indent += 2;
769
    qdev_printf("type %s\n", bus->info->name);
770
    QLIST_FOREACH(dev, &bus->children, sibling) {
771
        qdev_print(mon, dev, indent);
772
    }
773
}
774
#undef qdev_printf
775

    
776
void do_info_qtree(Monitor *mon)
777
{
778
    if (main_system_bus)
779
        qbus_print(mon, main_system_bus, 0);
780
}
781

    
782
void do_info_qdm(Monitor *mon)
783
{
784
    DeviceInfo *info;
785

    
786
    for (info = device_info_list; info != NULL; info = info->next) {
787
        qdev_print_devinfo(info);
788
    }
789
}
790

    
791
int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
792
{
793
    QemuOpts *opts;
794

    
795
    opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
796
    if (!opts) {
797
        return -1;
798
    }
799
    if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
800
        qemu_opts_del(opts);
801
        return 0;
802
    }
803
    if (!qdev_device_add(opts)) {
804
        qemu_opts_del(opts);
805
        return -1;
806
    }
807
    return 0;
808
}
809

    
810
int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
811
{
812
    const char *id = qdict_get_str(qdict, "id");
813
    DeviceState *dev;
814

    
815
    dev = qdev_find_recursive(main_system_bus, id);
816
    if (NULL == dev) {
817
        qerror_report(QERR_DEVICE_NOT_FOUND, id);
818
        return -1;
819
    }
820
    return qdev_unplug(dev);
821
}