Statistics
| Branch: | Revision:

root / hw / qdev.c @ ff753bb9

History | View | Annotate | Download (21.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
#include "blockdev.h"
33

    
34
static int qdev_hotplug = 0;
35

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

    
39
DeviceInfo *device_info_list;
40

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
426
static int next_block_unit[IF_COUNT];
427

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
689
}
690

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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