Statistics
| Branch: | Revision:

root / hw / qdev.c @ 0be71e32

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
        hw_error("Initialization of device %s failed\n", info->name);
331
}
332

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

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

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

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

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

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

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

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

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

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

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

    
423
static int next_block_unit[IF_COUNT];
424

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
657
    bus->info = info;
658
    bus->parent = parent;
659

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

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

    
686
}
687

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

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

    
698
void qbus_free(BusState *bus)
699
{
700
    DeviceState *dev;
701

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

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

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

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

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

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

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

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

    
780
void do_info_qdm(Monitor *mon)
781
{
782
    DeviceInfo *info;
783

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

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

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

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

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