Statistics
| Branch: | Revision:

root / hw / qdev.c @ 5ab28c83

History | View | Annotate | Download (24.3 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
static bool qdev_hot_added = false;
35
static bool qdev_hot_removed = false;
36

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

    
40
DeviceInfo *device_info_list;
41

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

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

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

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

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

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

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

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

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

    
111
    dev = qdev_try_create(bus, name);
112
    if (!dev) {
113
        hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
114
    }
115

    
116
    return dev;
117
}
118

    
119
DeviceState *qdev_try_create(BusState *bus, const char *name)
120
{
121
    DeviceInfo *info;
122

    
123
    if (!bus) {
124
        bus = sysbus_get_default();
125
    }
126

    
127
    info = qdev_find_info(bus->info, name);
128
    if (!info) {
129
        return NULL;
130
    }
131

    
132
    return qdev_create_from_info(bus, info);
133
}
134

    
135
static void qdev_print_devinfo(DeviceInfo *info)
136
{
137
    error_printf("name \"%s\", bus %s",
138
                 info->name, info->bus_info->name);
139
    if (info->alias) {
140
        error_printf(", alias \"%s\"", info->alias);
141
    }
142
    if (info->desc) {
143
        error_printf(", desc \"%s\"", info->desc);
144
    }
145
    if (info->no_user) {
146
        error_printf(", no-user");
147
    }
148
    error_printf("\n");
149
}
150

    
151
static int set_property(const char *name, const char *value, void *opaque)
152
{
153
    DeviceState *dev = opaque;
154

    
155
    if (strcmp(name, "driver") == 0)
156
        return 0;
157
    if (strcmp(name, "bus") == 0)
158
        return 0;
159

    
160
    if (qdev_prop_parse(dev, name, value) == -1) {
161
        return -1;
162
    }
163
    return 0;
164
}
165

    
166
int qdev_device_help(QemuOpts *opts)
167
{
168
    const char *driver;
169
    DeviceInfo *info;
170
    Property *prop;
171

    
172
    driver = qemu_opt_get(opts, "driver");
173
    if (driver && !strcmp(driver, "?")) {
174
        for (info = device_info_list; info != NULL; info = info->next) {
175
            if (info->no_user) {
176
                continue;       /* not available, don't show */
177
            }
178
            qdev_print_devinfo(info);
179
        }
180
        return 1;
181
    }
182

    
183
    if (!qemu_opt_get(opts, "?")) {
184
        return 0;
185
    }
186

    
187
    info = qdev_find_info(NULL, driver);
188
    if (!info) {
189
        return 0;
190
    }
191

    
192
    for (prop = info->props; prop && prop->name; prop++) {
193
        /*
194
         * TODO Properties without a parser are just for dirty hacks.
195
         * qdev_prop_ptr is the only such PropertyInfo.  It's marked
196
         * for removal.  This conditional should be removed along with
197
         * it.
198
         */
199
        if (!prop->info->parse) {
200
            continue;           /* no way to set it, don't show */
201
        }
202
        error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
203
    }
204
    return 1;
205
}
206

    
207
DeviceState *qdev_device_add(QemuOpts *opts)
208
{
209
    const char *driver, *path, *id;
210
    DeviceInfo *info;
211
    DeviceState *qdev;
212
    BusState *bus;
213

    
214
    driver = qemu_opt_get(opts, "driver");
215
    if (!driver) {
216
        qerror_report(QERR_MISSING_PARAMETER, "driver");
217
        return NULL;
218
    }
219

    
220
    /* find driver */
221
    info = qdev_find_info(NULL, driver);
222
    if (!info || info->no_user) {
223
        qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
224
        error_printf_unless_qmp("Try with argument '?' for a list.\n");
225
        return NULL;
226
    }
227

    
228
    /* find bus */
229
    path = qemu_opt_get(opts, "bus");
230
    if (path != NULL) {
231
        bus = qbus_find(path);
232
        if (!bus) {
233
            return NULL;
234
        }
235
        if (bus->info != info->bus_info) {
236
            qerror_report(QERR_BAD_BUS_FOR_DEVICE,
237
                           driver, bus->info->name);
238
            return NULL;
239
        }
240
    } else {
241
        bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
242
        if (!bus) {
243
            qerror_report(QERR_NO_BUS_FOR_DEVICE,
244
                           info->name, info->bus_info->name);
245
            return NULL;
246
        }
247
    }
248
    if (qdev_hotplug && !bus->allow_hotplug) {
249
        qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
250
        return NULL;
251
    }
252

    
253
    /* create device, set properties */
254
    qdev = qdev_create_from_info(bus, info);
255
    id = qemu_opts_id(opts);
256
    if (id) {
257
        qdev->id = id;
258
    }
259
    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
260
        qdev_free(qdev);
261
        return NULL;
262
    }
263
    if (qdev_init(qdev) < 0) {
264
        qerror_report(QERR_DEVICE_INIT_FAILED, driver);
265
        return NULL;
266
    }
267
    qdev->opts = opts;
268
    return qdev;
269
}
270

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

    
280
    assert(dev->state == DEV_STATE_CREATED);
281
    rc = dev->info->init(dev, dev->info);
282
    if (rc < 0) {
283
        qdev_free(dev);
284
        return rc;
285
    }
286
    if (dev->info->vmsd) {
287
        vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
288
                                       dev->instance_id_alias,
289
                                       dev->alias_required_for_version);
290
    }
291
    dev->state = DEV_STATE_INITIALIZED;
292
    if (dev->hotplugged && dev->info->reset) {
293
        dev->info->reset(dev);
294
    }
295
    return 0;
296
}
297

    
298
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
299
                                 int required_for_version)
300
{
301
    assert(dev->state == DEV_STATE_CREATED);
302
    dev->instance_id_alias = alias_id;
303
    dev->alias_required_for_version = required_for_version;
304
}
305

    
306
int qdev_unplug(DeviceState *dev)
307
{
308
    if (!dev->parent_bus->allow_hotplug) {
309
        qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
310
        return -1;
311
    }
312
    assert(dev->info->unplug != NULL);
313

    
314
    qdev_hot_removed = true;
315

    
316
    return dev->info->unplug(dev);
317
}
318

    
319
static int qdev_reset_one(DeviceState *dev, void *opaque)
320
{
321
    if (dev->info->reset) {
322
        dev->info->reset(dev);
323
    }
324

    
325
    return 0;
326
}
327

    
328
BusState *sysbus_get_default(void)
329
{
330
    if (!main_system_bus) {
331
        main_system_bus = qbus_create(&system_bus_info, NULL,
332
                                      "main-system-bus");
333
    }
334
    return main_system_bus;
335
}
336

    
337
static int qbus_reset_one(BusState *bus, void *opaque)
338
{
339
    if (bus->info->reset) {
340
        return bus->info->reset(bus);
341
    }
342
    return 0;
343
}
344

    
345
void qdev_reset_all(DeviceState *dev)
346
{
347
    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
348
}
349

    
350
void qbus_reset_all_fn(void *opaque)
351
{
352
    BusState *bus = opaque;
353
    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
354
}
355

    
356
/* can be used as ->unplug() callback for the simple cases */
357
int qdev_simple_unplug_cb(DeviceState *dev)
358
{
359
    /* just zap it */
360
    qdev_free(dev);
361
    return 0;
362
}
363

    
364

    
365
/* Like qdev_init(), but terminate program via error_report() instead of
366
   returning an error value.  This is okay during machine creation.
367
   Don't use for hotplug, because there callers need to recover from
368
   failure.  Exception: if you know the device's init() callback can't
369
   fail, then qdev_init_nofail() can't fail either, and is therefore
370
   usable even then.  But relying on the device implementation that
371
   way is somewhat unclean, and best avoided.  */
372
void qdev_init_nofail(DeviceState *dev)
373
{
374
    DeviceInfo *info = dev->info;
375

    
376
    if (qdev_init(dev) < 0) {
377
        error_report("Initialization of device %s failed", info->name);
378
        exit(1);
379
    }
380
}
381

    
382
/* Unlink device from bus and free the structure.  */
383
void qdev_free(DeviceState *dev)
384
{
385
    BusState *bus;
386
    Property *prop;
387

    
388
    if (dev->state == DEV_STATE_INITIALIZED) {
389
        while (dev->num_child_bus) {
390
            bus = QLIST_FIRST(&dev->child_bus);
391
            qbus_free(bus);
392
        }
393
        if (dev->info->vmsd)
394
            vmstate_unregister(dev, dev->info->vmsd, dev);
395
        if (dev->info->exit)
396
            dev->info->exit(dev);
397
        if (dev->opts)
398
            qemu_opts_del(dev->opts);
399
    }
400
    QLIST_REMOVE(dev, sibling);
401
    for (prop = dev->info->props; prop && prop->name; prop++) {
402
        if (prop->info->free) {
403
            prop->info->free(dev, prop);
404
        }
405
    }
406
    qemu_free(dev);
407
}
408

    
409
void qdev_machine_creation_done(void)
410
{
411
    /*
412
     * ok, initial machine setup is done, starting from now we can
413
     * only create hotpluggable devices
414
     */
415
    qdev_hotplug = 1;
416
}
417

    
418
bool qdev_machine_modified(void)
419
{
420
    return qdev_hot_added || qdev_hot_removed;
421
}
422

    
423
/* Get a character (serial) device interface.  */
424
CharDriverState *qdev_init_chardev(DeviceState *dev)
425
{
426
    static int next_serial;
427

    
428
    /* FIXME: This function needs to go away: use chardev properties!  */
429
    return serial_hds[next_serial++];
430
}
431

    
432
BusState *qdev_get_parent_bus(DeviceState *dev)
433
{
434
    return dev->parent_bus;
435
}
436

    
437
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
438
{
439
    assert(dev->num_gpio_in == 0);
440
    dev->num_gpio_in = n;
441
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
442
}
443

    
444
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
445
{
446
    assert(dev->num_gpio_out == 0);
447
    dev->num_gpio_out = n;
448
    dev->gpio_out = pins;
449
}
450

    
451
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
452
{
453
    assert(n >= 0 && n < dev->num_gpio_in);
454
    return dev->gpio_in[n];
455
}
456

    
457
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
458
{
459
    assert(n >= 0 && n < dev->num_gpio_out);
460
    dev->gpio_out[n] = pin;
461
}
462

    
463
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
464
{
465
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
466
    if (nd->vlan)
467
        qdev_prop_set_vlan(dev, "vlan", nd->vlan);
468
    if (nd->netdev)
469
        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
470
    if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
471
        qdev_prop_exists(dev, "vectors")) {
472
        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
473
    }
474
    nd->instantiated = 1;
475
}
476

    
477
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
478
{
479
    BusState *bus;
480

    
481
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
482
        if (strcmp(name, bus->name) == 0) {
483
            return bus;
484
        }
485
    }
486
    return NULL;
487
}
488

    
489
int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
490
                       qbus_walkerfn *busfn, void *opaque)
491
{
492
    DeviceState *dev;
493
    int err;
494

    
495
    if (busfn) {
496
        err = busfn(bus, opaque);
497
        if (err) {
498
            return err;
499
        }
500
    }
501

    
502
    QLIST_FOREACH(dev, &bus->children, sibling) {
503
        err = qdev_walk_children(dev, devfn, busfn, opaque);
504
        if (err < 0) {
505
            return err;
506
        }
507
    }
508

    
509
    return 0;
510
}
511

    
512
int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
513
                       qbus_walkerfn *busfn, void *opaque)
514
{
515
    BusState *bus;
516
    int err;
517

    
518
    if (devfn) {
519
        err = devfn(dev, opaque);
520
        if (err) {
521
            return err;
522
        }
523
    }
524

    
525
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
526
        err = qbus_walk_children(bus, devfn, busfn, opaque);
527
        if (err < 0) {
528
            return err;
529
        }
530
    }
531

    
532
    return 0;
533
}
534

    
535
static BusState *qbus_find_recursive(BusState *bus, const char *name,
536
                                     const BusInfo *info)
537
{
538
    DeviceState *dev;
539
    BusState *child, *ret;
540
    int match = 1;
541

    
542
    if (name && (strcmp(bus->name, name) != 0)) {
543
        match = 0;
544
    }
545
    if (info && (bus->info != info)) {
546
        match = 0;
547
    }
548
    if (match) {
549
        return bus;
550
    }
551

    
552
    QLIST_FOREACH(dev, &bus->children, sibling) {
553
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
554
            ret = qbus_find_recursive(child, name, info);
555
            if (ret) {
556
                return ret;
557
            }
558
        }
559
    }
560
    return NULL;
561
}
562

    
563
DeviceState *qdev_find_recursive(BusState *bus, const char *id)
564
{
565
    DeviceState *dev, *ret;
566
    BusState *child;
567

    
568
    QLIST_FOREACH(dev, &bus->children, sibling) {
569
        if (dev->id && strcmp(dev->id, id) == 0)
570
            return dev;
571
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
572
            ret = qdev_find_recursive(child, id);
573
            if (ret) {
574
                return ret;
575
            }
576
        }
577
    }
578
    return NULL;
579
}
580

    
581
static void qbus_list_bus(DeviceState *dev)
582
{
583
    BusState *child;
584
    const char *sep = " ";
585

    
586
    error_printf("child busses at \"%s\":",
587
                 dev->id ? dev->id : dev->info->name);
588
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
589
        error_printf("%s\"%s\"", sep, child->name);
590
        sep = ", ";
591
    }
592
    error_printf("\n");
593
}
594

    
595
static void qbus_list_dev(BusState *bus)
596
{
597
    DeviceState *dev;
598
    const char *sep = " ";
599

    
600
    error_printf("devices at \"%s\":", bus->name);
601
    QLIST_FOREACH(dev, &bus->children, sibling) {
602
        error_printf("%s\"%s\"", sep, dev->info->name);
603
        if (dev->id)
604
            error_printf("/\"%s\"", dev->id);
605
        sep = ", ";
606
    }
607
    error_printf("\n");
608
}
609

    
610
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
611
{
612
    BusState *child;
613

    
614
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
615
        if (strcmp(child->name, elem) == 0) {
616
            return child;
617
        }
618
    }
619
    return NULL;
620
}
621

    
622
static DeviceState *qbus_find_dev(BusState *bus, char *elem)
623
{
624
    DeviceState *dev;
625

    
626
    /*
627
     * try to match in order:
628
     *   (1) instance id, if present
629
     *   (2) driver name
630
     *   (3) driver alias, if present
631
     */
632
    QLIST_FOREACH(dev, &bus->children, sibling) {
633
        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
634
            return dev;
635
        }
636
    }
637
    QLIST_FOREACH(dev, &bus->children, sibling) {
638
        if (strcmp(dev->info->name, elem) == 0) {
639
            return dev;
640
        }
641
    }
642
    QLIST_FOREACH(dev, &bus->children, sibling) {
643
        if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
644
            return dev;
645
        }
646
    }
647
    return NULL;
648
}
649

    
650
static BusState *qbus_find(const char *path)
651
{
652
    DeviceState *dev;
653
    BusState *bus;
654
    char elem[128];
655
    int pos, len;
656

    
657
    /* find start element */
658
    if (path[0] == '/') {
659
        bus = main_system_bus;
660
        pos = 0;
661
    } else {
662
        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
663
            assert(!path[0]);
664
            elem[0] = len = 0;
665
        }
666
        bus = qbus_find_recursive(main_system_bus, elem, NULL);
667
        if (!bus) {
668
            qerror_report(QERR_BUS_NOT_FOUND, elem);
669
            return NULL;
670
        }
671
        pos = len;
672
    }
673

    
674
    for (;;) {
675
        assert(path[pos] == '/' || !path[pos]);
676
        while (path[pos] == '/') {
677
            pos++;
678
        }
679
        if (path[pos] == '\0') {
680
            return bus;
681
        }
682

    
683
        /* find device */
684
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
685
            assert(0);
686
            elem[0] = len = 0;
687
        }
688
        pos += len;
689
        dev = qbus_find_dev(bus, elem);
690
        if (!dev) {
691
            qerror_report(QERR_DEVICE_NOT_FOUND, elem);
692
            if (!monitor_cur_is_qmp()) {
693
                qbus_list_dev(bus);
694
            }
695
            return NULL;
696
        }
697

    
698
        assert(path[pos] == '/' || !path[pos]);
699
        while (path[pos] == '/') {
700
            pos++;
701
        }
702
        if (path[pos] == '\0') {
703
            /* last specified element is a device.  If it has exactly
704
             * one child bus accept it nevertheless */
705
            switch (dev->num_child_bus) {
706
            case 0:
707
                qerror_report(QERR_DEVICE_NO_BUS, elem);
708
                return NULL;
709
            case 1:
710
                return QLIST_FIRST(&dev->child_bus);
711
            default:
712
                qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
713
                if (!monitor_cur_is_qmp()) {
714
                    qbus_list_bus(dev);
715
                }
716
                return NULL;
717
            }
718
        }
719

    
720
        /* find bus */
721
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
722
            assert(0);
723
            elem[0] = len = 0;
724
        }
725
        pos += len;
726
        bus = qbus_find_bus(dev, elem);
727
        if (!bus) {
728
            qerror_report(QERR_BUS_NOT_FOUND, elem);
729
            if (!monitor_cur_is_qmp()) {
730
                qbus_list_bus(dev);
731
            }
732
            return NULL;
733
        }
734
    }
735
}
736

    
737
void qbus_create_inplace(BusState *bus, BusInfo *info,
738
                         DeviceState *parent, const char *name)
739
{
740
    char *buf;
741
    int i,len;
742

    
743
    bus->info = info;
744
    bus->parent = parent;
745

    
746
    if (name) {
747
        /* use supplied name */
748
        bus->name = qemu_strdup(name);
749
    } else if (parent && parent->id) {
750
        /* parent device has id -> use it for bus name */
751
        len = strlen(parent->id) + 16;
752
        buf = qemu_malloc(len);
753
        snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
754
        bus->name = buf;
755
    } else {
756
        /* no id -> use lowercase bus type for bus name */
757
        len = strlen(info->name) + 16;
758
        buf = qemu_malloc(len);
759
        len = snprintf(buf, len, "%s.%d", info->name,
760
                       parent ? parent->num_child_bus : 0);
761
        for (i = 0; i < len; i++)
762
            buf[i] = qemu_tolower(buf[i]);
763
        bus->name = buf;
764
    }
765

    
766
    QLIST_INIT(&bus->children);
767
    if (parent) {
768
        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
769
        parent->num_child_bus++;
770
    } else if (bus != main_system_bus) {
771
        /* TODO: once all bus devices are qdevified,
772
           only reset handler for main_system_bus should be registered here. */
773
        qemu_register_reset(qbus_reset_all_fn, bus);
774
    }
775
}
776

    
777
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
778
{
779
    BusState *bus;
780

    
781
    bus = qemu_mallocz(info->size);
782
    bus->qdev_allocated = 1;
783
    qbus_create_inplace(bus, info, parent, name);
784
    return bus;
785
}
786

    
787
void qbus_free(BusState *bus)
788
{
789
    DeviceState *dev;
790

    
791
    while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
792
        qdev_free(dev);
793
    }
794
    if (bus->parent) {
795
        QLIST_REMOVE(bus, sibling);
796
        bus->parent->num_child_bus--;
797
    } else {
798
        assert(bus != main_system_bus); /* main_system_bus is never freed */
799
        qemu_unregister_reset(qbus_reset_all_fn, bus);
800
    }
801
    qemu_free((void*)bus->name);
802
    if (bus->qdev_allocated) {
803
        qemu_free(bus);
804
    }
805
}
806

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

    
810
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
811
                             const char *prefix, int indent)
812
{
813
    char buf[64];
814

    
815
    if (!props)
816
        return;
817
    while (props->name) {
818
        /*
819
         * TODO Properties without a print method are just for dirty
820
         * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
821
         * marked for removal.  The test props->info->print should be
822
         * removed along with it.
823
         */
824
        if (props->info->print) {
825
            props->info->print(dev, props, buf, sizeof(buf));
826
            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
827
        }
828
        props++;
829
    }
830
}
831

    
832
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
833
{
834
    BusState *child;
835
    qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
836
                dev->id ? dev->id : "");
837
    indent += 2;
838
    if (dev->num_gpio_in) {
839
        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
840
    }
841
    if (dev->num_gpio_out) {
842
        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
843
    }
844
    qdev_print_props(mon, dev, dev->info->props, "dev", indent);
845
    qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
846
    if (dev->parent_bus->info->print_dev)
847
        dev->parent_bus->info->print_dev(mon, dev, indent);
848
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
849
        qbus_print(mon, child, indent);
850
    }
851
}
852

    
853
static void qbus_print(Monitor *mon, BusState *bus, int indent)
854
{
855
    struct DeviceState *dev;
856

    
857
    qdev_printf("bus: %s\n", bus->name);
858
    indent += 2;
859
    qdev_printf("type %s\n", bus->info->name);
860
    QLIST_FOREACH(dev, &bus->children, sibling) {
861
        qdev_print(mon, dev, indent);
862
    }
863
}
864
#undef qdev_printf
865

    
866
void do_info_qtree(Monitor *mon)
867
{
868
    if (main_system_bus)
869
        qbus_print(mon, main_system_bus, 0);
870
}
871

    
872
void do_info_qdm(Monitor *mon)
873
{
874
    DeviceInfo *info;
875

    
876
    for (info = device_info_list; info != NULL; info = info->next) {
877
        qdev_print_devinfo(info);
878
    }
879
}
880

    
881
int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
882
{
883
    QemuOpts *opts;
884

    
885
    opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
886
    if (!opts) {
887
        return -1;
888
    }
889
    if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
890
        qemu_opts_del(opts);
891
        return 0;
892
    }
893
    if (!qdev_device_add(opts)) {
894
        qemu_opts_del(opts);
895
        return -1;
896
    }
897
    return 0;
898
}
899

    
900
int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
901
{
902
    const char *id = qdict_get_str(qdict, "id");
903
    DeviceState *dev;
904

    
905
    dev = qdev_find_recursive(main_system_bus, id);
906
    if (NULL == dev) {
907
        qerror_report(QERR_DEVICE_NOT_FOUND, id);
908
        return -1;
909
    }
910
    return qdev_unplug(dev);
911
}
912

    
913
static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
914
{
915
    int l = 0;
916

    
917
    if (dev && dev->parent_bus) {
918
        char *d;
919
        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
920
        if (dev->parent_bus->info->get_fw_dev_path) {
921
            d = dev->parent_bus->info->get_fw_dev_path(dev);
922
            l += snprintf(p + l, size - l, "%s", d);
923
            qemu_free(d);
924
        } else {
925
            l += snprintf(p + l, size - l, "%s", dev->info->name);
926
        }
927
    }
928
    l += snprintf(p + l , size - l, "/");
929

    
930
    return l;
931
}
932

    
933
char* qdev_get_fw_dev_path(DeviceState *dev)
934
{
935
    char path[128];
936
    int l;
937

    
938
    l = qdev_get_fw_dev_path_helper(dev, path, 128);
939

    
940
    path[l-1] = '\0';
941

    
942
    return strdup(path);
943
}