Statistics
| Branch: | Revision:

root / hw / qdev.c @ 30fbb9fc

History | View | Annotate | Download (41.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
static void main_system_bus_create(void);
40

    
41
DeviceInfo *device_info_list;
42

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

    
47
/* Register a new device type.  */
48
static void qdev_subclass_init(ObjectClass *klass, void *data)
49
{
50
    DeviceClass *dc = DEVICE_CLASS(klass);
51
    dc->info = data;
52
}
53

    
54
DeviceInfo *qdev_get_info(DeviceState *dev)
55
{
56
    return DEVICE_GET_CLASS(dev)->info;
57
}
58

    
59
void qdev_register(DeviceInfo *info)
60
{
61
    TypeInfo type_info = {};
62

    
63
    assert(info->size >= sizeof(DeviceState));
64
    assert(!info->next);
65

    
66
    type_info.name = info->name;
67
    type_info.parent = TYPE_DEVICE;
68
    type_info.instance_size = info->size;
69
    type_info.class_init = qdev_subclass_init;
70
    type_info.class_data = info;
71

    
72
    type_register_static(&type_info);
73

    
74
    info->next = device_info_list;
75
    device_info_list = info;
76
}
77

    
78
static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
79
{
80
    DeviceInfo *info;
81

    
82
    /* first check device names */
83
    for (info = device_info_list; info != NULL; info = info->next) {
84
        if (bus_info && info->bus_info != bus_info)
85
            continue;
86
        if (strcmp(info->name, name) != 0)
87
            continue;
88
        return info;
89
    }
90

    
91
    /* failing that check the aliases */
92
    for (info = device_info_list; info != NULL; info = info->next) {
93
        if (bus_info && info->bus_info != bus_info)
94
            continue;
95
        if (!info->alias)
96
            continue;
97
        if (strcmp(info->alias, name) != 0)
98
            continue;
99
        return info;
100
    }
101
    return NULL;
102
}
103

    
104
bool qdev_exists(const char *name)
105
{
106
    return !!qdev_find_info(NULL, name);
107
}
108
static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
109
                                     Error **errp);
110

    
111
static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
112
{
113
    DeviceState *dev;
114
    Property *prop;
115

    
116
    assert(bus->info == info->bus_info);
117
    dev = DEVICE(object_new(info->name));
118
    dev->parent_bus = bus;
119
    qdev_prop_set_defaults(dev, qdev_get_info(dev)->props);
120
    qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
121
    qdev_prop_set_globals(dev);
122
    QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
123
    if (qdev_hotplug) {
124
        assert(bus->allow_hotplug);
125
        dev->hotplugged = 1;
126
        qdev_hot_added = true;
127
    }
128
    dev->instance_id_alias = -1;
129
    QTAILQ_INIT(&dev->properties);
130
    dev->state = DEV_STATE_CREATED;
131

    
132
    for (prop = qdev_get_info(dev)->props; prop && prop->name; prop++) {
133
        qdev_property_add_legacy(dev, prop, NULL);
134
        qdev_property_add_static(dev, prop, NULL);
135
    }
136

    
137
    for (prop = qdev_get_info(dev)->bus_info->props; prop && prop->name; prop++) {
138
        qdev_property_add_legacy(dev, prop, NULL);
139
        qdev_property_add_static(dev, prop, NULL);
140
    }
141

    
142
    qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL);
143

    
144
    return dev;
145
}
146

    
147
/* Create a new device.  This only initializes the device state structure
148
   and allows properties to be set.  qdev_init should be called to
149
   initialize the actual device emulation.  */
150
DeviceState *qdev_create(BusState *bus, const char *name)
151
{
152
    DeviceState *dev;
153

    
154
    dev = qdev_try_create(bus, name);
155
    if (!dev) {
156
        if (bus) {
157
            hw_error("Unknown device '%s' for bus '%s'\n", name,
158
                     bus->info->name);
159
        } else {
160
            hw_error("Unknown device '%s' for default sysbus\n", name);
161
        }
162
    }
163

    
164
    return dev;
165
}
166

    
167
DeviceState *qdev_try_create(BusState *bus, const char *name)
168
{
169
    DeviceInfo *info;
170

    
171
    if (!bus) {
172
        bus = sysbus_get_default();
173
    }
174

    
175
    info = qdev_find_info(bus->info, name);
176
    if (!info) {
177
        return NULL;
178
    }
179

    
180
    return qdev_create_from_info(bus, info);
181
}
182

    
183
static void qdev_print_devinfo(DeviceInfo *info)
184
{
185
    error_printf("name \"%s\", bus %s",
186
                 info->name, info->bus_info->name);
187
    if (info->alias) {
188
        error_printf(", alias \"%s\"", info->alias);
189
    }
190
    if (info->desc) {
191
        error_printf(", desc \"%s\"", info->desc);
192
    }
193
    if (info->no_user) {
194
        error_printf(", no-user");
195
    }
196
    error_printf("\n");
197
}
198

    
199
static int set_property(const char *name, const char *value, void *opaque)
200
{
201
    DeviceState *dev = opaque;
202

    
203
    if (strcmp(name, "driver") == 0)
204
        return 0;
205
    if (strcmp(name, "bus") == 0)
206
        return 0;
207

    
208
    if (qdev_prop_parse(dev, name, value) == -1) {
209
        return -1;
210
    }
211
    return 0;
212
}
213

    
214
int qdev_device_help(QemuOpts *opts)
215
{
216
    const char *driver;
217
    DeviceInfo *info;
218
    Property *prop;
219

    
220
    driver = qemu_opt_get(opts, "driver");
221
    if (driver && !strcmp(driver, "?")) {
222
        for (info = device_info_list; info != NULL; info = info->next) {
223
            if (info->no_user) {
224
                continue;       /* not available, don't show */
225
            }
226
            qdev_print_devinfo(info);
227
        }
228
        return 1;
229
    }
230

    
231
    if (!driver || !qemu_opt_get(opts, "?")) {
232
        return 0;
233
    }
234

    
235
    info = qdev_find_info(NULL, driver);
236
    if (!info) {
237
        return 0;
238
    }
239

    
240
    for (prop = info->props; prop && prop->name; prop++) {
241
        /*
242
         * TODO Properties without a parser are just for dirty hacks.
243
         * qdev_prop_ptr is the only such PropertyInfo.  It's marked
244
         * for removal.  This conditional should be removed along with
245
         * it.
246
         */
247
        if (!prop->info->parse) {
248
            continue;           /* no way to set it, don't show */
249
        }
250
        error_printf("%s.%s=%s\n", info->name, prop->name,
251
                     prop->info->legacy_name ?: prop->info->name);
252
    }
253
    for (prop = info->bus_info->props; prop && prop->name; prop++) {
254
        if (!prop->info->parse) {
255
            continue;           /* no way to set it, don't show */
256
        }
257
        error_printf("%s.%s=%s\n", info->name, prop->name,
258
                     prop->info->legacy_name ?: prop->info->name);
259
    }
260
    return 1;
261
}
262

    
263
static DeviceState *qdev_get_peripheral(void)
264
{
265
    static DeviceState *dev;
266

    
267
    if (dev == NULL) {
268
        dev = qdev_create(NULL, "container");
269
        qdev_property_add_child(qdev_get_root(), "peripheral", dev, NULL);
270
        qdev_init_nofail(dev);
271
    }
272

    
273
    return dev;
274
}
275

    
276
static DeviceState *qdev_get_peripheral_anon(void)
277
{
278
    static DeviceState *dev;
279

    
280
    if (dev == NULL) {
281
        dev = qdev_create(NULL, "container");
282
        qdev_property_add_child(qdev_get_root(), "peripheral-anon", dev, NULL);
283
        qdev_init_nofail(dev);
284
    }
285

    
286
    return dev;
287
}
288

    
289
DeviceState *qdev_device_add(QemuOpts *opts)
290
{
291
    const char *driver, *path, *id;
292
    DeviceInfo *info;
293
    DeviceState *qdev;
294
    BusState *bus;
295

    
296
    driver = qemu_opt_get(opts, "driver");
297
    if (!driver) {
298
        qerror_report(QERR_MISSING_PARAMETER, "driver");
299
        return NULL;
300
    }
301

    
302
    /* find driver */
303
    info = qdev_find_info(NULL, driver);
304
    if (!info || info->no_user) {
305
        qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
306
        error_printf_unless_qmp("Try with argument '?' for a list.\n");
307
        return NULL;
308
    }
309

    
310
    /* find bus */
311
    path = qemu_opt_get(opts, "bus");
312
    if (path != NULL) {
313
        bus = qbus_find(path);
314
        if (!bus) {
315
            return NULL;
316
        }
317
        if (bus->info != info->bus_info) {
318
            qerror_report(QERR_BAD_BUS_FOR_DEVICE,
319
                           driver, bus->info->name);
320
            return NULL;
321
        }
322
    } else {
323
        bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
324
        if (!bus) {
325
            qerror_report(QERR_NO_BUS_FOR_DEVICE,
326
                           info->name, info->bus_info->name);
327
            return NULL;
328
        }
329
    }
330
    if (qdev_hotplug && !bus->allow_hotplug) {
331
        qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
332
        return NULL;
333
    }
334

    
335
    /* create device, set properties */
336
    qdev = qdev_create_from_info(bus, info);
337
    id = qemu_opts_id(opts);
338
    if (id) {
339
        qdev->id = id;
340
        qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL);
341
    } else {
342
        static int anon_count;
343
        gchar *name = g_strdup_printf("device[%d]", anon_count++);
344
        qdev_property_add_child(qdev_get_peripheral_anon(), name,
345
                                qdev, NULL);
346
        g_free(name);
347
    }        
348
    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
349
        qdev_free(qdev);
350
        return NULL;
351
    }
352
    if (qdev_init(qdev) < 0) {
353
        qerror_report(QERR_DEVICE_INIT_FAILED, driver);
354
        return NULL;
355
    }
356
    qdev->opts = opts;
357
    return qdev;
358
}
359

    
360
/* Initialize a device.  Device properties should be set before calling
361
   this function.  IRQs and MMIO regions should be connected/mapped after
362
   calling this function.
363
   On failure, destroy the device and return negative value.
364
   Return 0 on success.  */
365
int qdev_init(DeviceState *dev)
366
{
367
    int rc;
368

    
369
    assert(dev->state == DEV_STATE_CREATED);
370
    rc = qdev_get_info(dev)->init(dev, qdev_get_info(dev));
371
    if (rc < 0) {
372
        qdev_free(dev);
373
        return rc;
374
    }
375
    if (qdev_get_info(dev)->vmsd) {
376
        vmstate_register_with_alias_id(dev, -1, qdev_get_info(dev)->vmsd, dev,
377
                                       dev->instance_id_alias,
378
                                       dev->alias_required_for_version);
379
    }
380
    dev->state = DEV_STATE_INITIALIZED;
381
    if (dev->hotplugged && qdev_get_info(dev)->reset) {
382
        qdev_get_info(dev)->reset(dev);
383
    }
384
    return 0;
385
}
386

    
387
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
388
                                 int required_for_version)
389
{
390
    assert(dev->state == DEV_STATE_CREATED);
391
    dev->instance_id_alias = alias_id;
392
    dev->alias_required_for_version = required_for_version;
393
}
394

    
395
int qdev_unplug(DeviceState *dev)
396
{
397
    if (!dev->parent_bus->allow_hotplug) {
398
        qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
399
        return -1;
400
    }
401
    assert(qdev_get_info(dev)->unplug != NULL);
402

    
403
    qdev_hot_removed = true;
404

    
405
    return qdev_get_info(dev)->unplug(dev);
406
}
407

    
408
static int qdev_reset_one(DeviceState *dev, void *opaque)
409
{
410
    if (qdev_get_info(dev)->reset) {
411
        qdev_get_info(dev)->reset(dev);
412
    }
413

    
414
    return 0;
415
}
416

    
417
BusState *sysbus_get_default(void)
418
{
419
    if (!main_system_bus) {
420
        main_system_bus_create();
421
    }
422
    return main_system_bus;
423
}
424

    
425
static int qbus_reset_one(BusState *bus, void *opaque)
426
{
427
    if (bus->info->reset) {
428
        return bus->info->reset(bus);
429
    }
430
    return 0;
431
}
432

    
433
void qdev_reset_all(DeviceState *dev)
434
{
435
    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
436
}
437

    
438
void qbus_reset_all_fn(void *opaque)
439
{
440
    BusState *bus = opaque;
441
    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
442
}
443

    
444
/* can be used as ->unplug() callback for the simple cases */
445
int qdev_simple_unplug_cb(DeviceState *dev)
446
{
447
    /* just zap it */
448
    qdev_free(dev);
449
    return 0;
450
}
451

    
452

    
453
/* Like qdev_init(), but terminate program via error_report() instead of
454
   returning an error value.  This is okay during machine creation.
455
   Don't use for hotplug, because there callers need to recover from
456
   failure.  Exception: if you know the device's init() callback can't
457
   fail, then qdev_init_nofail() can't fail either, and is therefore
458
   usable even then.  But relying on the device implementation that
459
   way is somewhat unclean, and best avoided.  */
460
void qdev_init_nofail(DeviceState *dev)
461
{
462
    DeviceInfo *info = qdev_get_info(dev);
463

    
464
    if (qdev_init(dev) < 0) {
465
        error_report("Initialization of device %s failed", info->name);
466
        exit(1);
467
    }
468
}
469

    
470
static void qdev_property_del_all(DeviceState *dev)
471
{
472
    while (!QTAILQ_EMPTY(&dev->properties)) {
473
        DeviceProperty *prop = QTAILQ_FIRST(&dev->properties);
474

    
475
        QTAILQ_REMOVE(&dev->properties, prop, node);
476

    
477
        if (prop->release) {
478
            prop->release(dev, prop->name, prop->opaque);
479
        }
480

    
481
        g_free(prop->name);
482
        g_free(prop->type);
483
        g_free(prop);
484
    }
485
}
486

    
487
static void qdev_property_del_child(DeviceState *dev, DeviceState *child, Error **errp)
488
{
489
    DeviceProperty *prop;
490

    
491
    QTAILQ_FOREACH(prop, &dev->properties, node) {
492
        if (strstart(prop->type, "child<", NULL) && prop->opaque == child) {
493
            break;
494
        }
495
    }
496

    
497
    g_assert(prop != NULL);
498

    
499
    QTAILQ_REMOVE(&dev->properties, prop, node);
500

    
501
    if (prop->release) {
502
        prop->release(dev, prop->name, prop->opaque);
503
    }
504

    
505
    g_free(prop->name);
506
    g_free(prop->type);
507
    g_free(prop);
508
}
509

    
510
/* Unlink device from bus and free the structure.  */
511
void qdev_free(DeviceState *dev)
512
{
513
    BusState *bus;
514
    Property *prop;
515

    
516
    qdev_property_del_all(dev);
517

    
518
    if (dev->state == DEV_STATE_INITIALIZED) {
519
        while (dev->num_child_bus) {
520
            bus = QLIST_FIRST(&dev->child_bus);
521
            qbus_free(bus);
522
        }
523
        if (qdev_get_info(dev)->vmsd)
524
            vmstate_unregister(dev, qdev_get_info(dev)->vmsd, dev);
525
        if (qdev_get_info(dev)->exit)
526
            qdev_get_info(dev)->exit(dev);
527
        if (dev->opts)
528
            qemu_opts_del(dev->opts);
529
    }
530
    QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
531
    for (prop = qdev_get_info(dev)->props; prop && prop->name; prop++) {
532
        if (prop->info->free) {
533
            prop->info->free(dev, prop);
534
        }
535
    }
536
    if (dev->parent) {
537
        qdev_property_del_child(dev->parent, dev, NULL);
538
    }
539
    if (dev->ref != 0) {
540
        qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
541
    }
542
    object_delete(OBJECT(dev));
543
}
544

    
545
void qdev_machine_creation_done(void)
546
{
547
    /*
548
     * ok, initial machine setup is done, starting from now we can
549
     * only create hotpluggable devices
550
     */
551
    qdev_hotplug = 1;
552
}
553

    
554
bool qdev_machine_modified(void)
555
{
556
    return qdev_hot_added || qdev_hot_removed;
557
}
558

    
559
/* Get a character (serial) device interface.  */
560
CharDriverState *qdev_init_chardev(DeviceState *dev)
561
{
562
    static int next_serial;
563

    
564
    /* FIXME: This function needs to go away: use chardev properties!  */
565
    return serial_hds[next_serial++];
566
}
567

    
568
BusState *qdev_get_parent_bus(DeviceState *dev)
569
{
570
    return dev->parent_bus;
571
}
572

    
573
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
574
{
575
    assert(dev->num_gpio_in == 0);
576
    dev->num_gpio_in = n;
577
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
578
}
579

    
580
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
581
{
582
    assert(dev->num_gpio_out == 0);
583
    dev->num_gpio_out = n;
584
    dev->gpio_out = pins;
585
}
586

    
587
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
588
{
589
    assert(n >= 0 && n < dev->num_gpio_in);
590
    return dev->gpio_in[n];
591
}
592

    
593
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
594
{
595
    assert(n >= 0 && n < dev->num_gpio_out);
596
    dev->gpio_out[n] = pin;
597
}
598

    
599
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
600
{
601
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
602
    if (nd->vlan)
603
        qdev_prop_set_vlan(dev, "vlan", nd->vlan);
604
    if (nd->netdev)
605
        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
606
    if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
607
        qdev_prop_exists(dev, "vectors")) {
608
        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
609
    }
610
    nd->instantiated = 1;
611
}
612

    
613
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
614
{
615
    BusState *bus;
616

    
617
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
618
        if (strcmp(name, bus->name) == 0) {
619
            return bus;
620
        }
621
    }
622
    return NULL;
623
}
624

    
625
int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
626
                       qbus_walkerfn *busfn, void *opaque)
627
{
628
    DeviceState *dev;
629
    int err;
630

    
631
    if (busfn) {
632
        err = busfn(bus, opaque);
633
        if (err) {
634
            return err;
635
        }
636
    }
637

    
638
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
639
        err = qdev_walk_children(dev, devfn, busfn, opaque);
640
        if (err < 0) {
641
            return err;
642
        }
643
    }
644

    
645
    return 0;
646
}
647

    
648
int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
649
                       qbus_walkerfn *busfn, void *opaque)
650
{
651
    BusState *bus;
652
    int err;
653

    
654
    if (devfn) {
655
        err = devfn(dev, opaque);
656
        if (err) {
657
            return err;
658
        }
659
    }
660

    
661
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
662
        err = qbus_walk_children(bus, devfn, busfn, opaque);
663
        if (err < 0) {
664
            return err;
665
        }
666
    }
667

    
668
    return 0;
669
}
670

    
671
static BusState *qbus_find_recursive(BusState *bus, const char *name,
672
                                     const BusInfo *info)
673
{
674
    DeviceState *dev;
675
    BusState *child, *ret;
676
    int match = 1;
677

    
678
    if (name && (strcmp(bus->name, name) != 0)) {
679
        match = 0;
680
    }
681
    if (info && (bus->info != info)) {
682
        match = 0;
683
    }
684
    if (match) {
685
        return bus;
686
    }
687

    
688
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
689
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
690
            ret = qbus_find_recursive(child, name, info);
691
            if (ret) {
692
                return ret;
693
            }
694
        }
695
    }
696
    return NULL;
697
}
698

    
699
DeviceState *qdev_find_recursive(BusState *bus, const char *id)
700
{
701
    DeviceState *dev, *ret;
702
    BusState *child;
703

    
704
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
705
        if (dev->id && strcmp(dev->id, id) == 0)
706
            return dev;
707
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
708
            ret = qdev_find_recursive(child, id);
709
            if (ret) {
710
                return ret;
711
            }
712
        }
713
    }
714
    return NULL;
715
}
716

    
717
static void qbus_list_bus(DeviceState *dev)
718
{
719
    BusState *child;
720
    const char *sep = " ";
721

    
722
    error_printf("child busses at \"%s\":",
723
                 dev->id ? dev->id : qdev_get_info(dev)->name);
724
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
725
        error_printf("%s\"%s\"", sep, child->name);
726
        sep = ", ";
727
    }
728
    error_printf("\n");
729
}
730

    
731
static void qbus_list_dev(BusState *bus)
732
{
733
    DeviceState *dev;
734
    const char *sep = " ";
735

    
736
    error_printf("devices at \"%s\":", bus->name);
737
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
738
        error_printf("%s\"%s\"", sep, qdev_get_info(dev)->name);
739
        if (dev->id)
740
            error_printf("/\"%s\"", dev->id);
741
        sep = ", ";
742
    }
743
    error_printf("\n");
744
}
745

    
746
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
747
{
748
    BusState *child;
749

    
750
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
751
        if (strcmp(child->name, elem) == 0) {
752
            return child;
753
        }
754
    }
755
    return NULL;
756
}
757

    
758
static DeviceState *qbus_find_dev(BusState *bus, char *elem)
759
{
760
    DeviceState *dev;
761

    
762
    /*
763
     * try to match in order:
764
     *   (1) instance id, if present
765
     *   (2) driver name
766
     *   (3) driver alias, if present
767
     */
768
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
769
        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
770
            return dev;
771
        }
772
    }
773
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
774
        if (strcmp(qdev_get_info(dev)->name, elem) == 0) {
775
            return dev;
776
        }
777
    }
778
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
779
        if (qdev_get_info(dev)->alias && strcmp(qdev_get_info(dev)->alias, elem) == 0) {
780
            return dev;
781
        }
782
    }
783
    return NULL;
784
}
785

    
786
static BusState *qbus_find(const char *path)
787
{
788
    DeviceState *dev;
789
    BusState *bus;
790
    char elem[128];
791
    int pos, len;
792

    
793
    /* find start element */
794
    if (path[0] == '/') {
795
        bus = main_system_bus;
796
        pos = 0;
797
    } else {
798
        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
799
            assert(!path[0]);
800
            elem[0] = len = 0;
801
        }
802
        bus = qbus_find_recursive(main_system_bus, elem, NULL);
803
        if (!bus) {
804
            qerror_report(QERR_BUS_NOT_FOUND, elem);
805
            return NULL;
806
        }
807
        pos = len;
808
    }
809

    
810
    for (;;) {
811
        assert(path[pos] == '/' || !path[pos]);
812
        while (path[pos] == '/') {
813
            pos++;
814
        }
815
        if (path[pos] == '\0') {
816
            return bus;
817
        }
818

    
819
        /* find device */
820
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
821
            assert(0);
822
            elem[0] = len = 0;
823
        }
824
        pos += len;
825
        dev = qbus_find_dev(bus, elem);
826
        if (!dev) {
827
            qerror_report(QERR_DEVICE_NOT_FOUND, elem);
828
            if (!monitor_cur_is_qmp()) {
829
                qbus_list_dev(bus);
830
            }
831
            return NULL;
832
        }
833

    
834
        assert(path[pos] == '/' || !path[pos]);
835
        while (path[pos] == '/') {
836
            pos++;
837
        }
838
        if (path[pos] == '\0') {
839
            /* last specified element is a device.  If it has exactly
840
             * one child bus accept it nevertheless */
841
            switch (dev->num_child_bus) {
842
            case 0:
843
                qerror_report(QERR_DEVICE_NO_BUS, elem);
844
                return NULL;
845
            case 1:
846
                return QLIST_FIRST(&dev->child_bus);
847
            default:
848
                qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
849
                if (!monitor_cur_is_qmp()) {
850
                    qbus_list_bus(dev);
851
                }
852
                return NULL;
853
            }
854
        }
855

    
856
        /* find bus */
857
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
858
            assert(0);
859
            elem[0] = len = 0;
860
        }
861
        pos += len;
862
        bus = qbus_find_bus(dev, elem);
863
        if (!bus) {
864
            qerror_report(QERR_BUS_NOT_FOUND, elem);
865
            if (!monitor_cur_is_qmp()) {
866
                qbus_list_bus(dev);
867
            }
868
            return NULL;
869
        }
870
    }
871
}
872

    
873
void qbus_create_inplace(BusState *bus, BusInfo *info,
874
                         DeviceState *parent, const char *name)
875
{
876
    char *buf;
877
    int i,len;
878

    
879
    bus->info = info;
880
    bus->parent = parent;
881

    
882
    if (name) {
883
        /* use supplied name */
884
        bus->name = g_strdup(name);
885
    } else if (parent && parent->id) {
886
        /* parent device has id -> use it for bus name */
887
        len = strlen(parent->id) + 16;
888
        buf = g_malloc(len);
889
        snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
890
        bus->name = buf;
891
    } else {
892
        /* no id -> use lowercase bus type for bus name */
893
        len = strlen(info->name) + 16;
894
        buf = g_malloc(len);
895
        len = snprintf(buf, len, "%s.%d", info->name,
896
                       parent ? parent->num_child_bus : 0);
897
        for (i = 0; i < len; i++)
898
            buf[i] = qemu_tolower(buf[i]);
899
        bus->name = buf;
900
    }
901

    
902
    QTAILQ_INIT(&bus->children);
903
    if (parent) {
904
        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
905
        parent->num_child_bus++;
906
    } else if (bus != main_system_bus) {
907
        /* TODO: once all bus devices are qdevified,
908
           only reset handler for main_system_bus should be registered here. */
909
        qemu_register_reset(qbus_reset_all_fn, bus);
910
    }
911
}
912

    
913
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
914
{
915
    BusState *bus;
916

    
917
    bus = g_malloc0(info->size);
918
    bus->qdev_allocated = 1;
919
    qbus_create_inplace(bus, info, parent, name);
920
    return bus;
921
}
922

    
923
static void main_system_bus_create(void)
924
{
925
    /* assign main_system_bus before qbus_create_inplace()
926
     * in order to make "if (bus != main_system_bus)" work */
927
    main_system_bus = g_malloc0(system_bus_info.size);
928
    main_system_bus->qdev_allocated = 1;
929
    qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
930
                        "main-system-bus");
931
}
932

    
933
void qbus_free(BusState *bus)
934
{
935
    DeviceState *dev;
936

    
937
    while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
938
        qdev_free(dev);
939
    }
940
    if (bus->parent) {
941
        QLIST_REMOVE(bus, sibling);
942
        bus->parent->num_child_bus--;
943
    } else {
944
        assert(bus != main_system_bus); /* main_system_bus is never freed */
945
        qemu_unregister_reset(qbus_reset_all_fn, bus);
946
    }
947
    g_free((void*)bus->name);
948
    if (bus->qdev_allocated) {
949
        g_free(bus);
950
    }
951
}
952

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

    
956
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
957
                             const char *prefix, int indent)
958
{
959
    char buf[64];
960

    
961
    if (!props)
962
        return;
963
    while (props->name) {
964
        /*
965
         * TODO Properties without a print method are just for dirty
966
         * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
967
         * marked for removal.  The test props->info->print should be
968
         * removed along with it.
969
         */
970
        if (props->info->print) {
971
            props->info->print(dev, props, buf, sizeof(buf));
972
            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
973
        }
974
        props++;
975
    }
976
}
977

    
978
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
979
{
980
    BusState *child;
981
    qdev_printf("dev: %s, id \"%s\"\n", qdev_get_info(dev)->name,
982
                dev->id ? dev->id : "");
983
    indent += 2;
984
    if (dev->num_gpio_in) {
985
        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
986
    }
987
    if (dev->num_gpio_out) {
988
        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
989
    }
990
    qdev_print_props(mon, dev, qdev_get_info(dev)->props, "dev", indent);
991
    qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
992
    if (dev->parent_bus->info->print_dev)
993
        dev->parent_bus->info->print_dev(mon, dev, indent);
994
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
995
        qbus_print(mon, child, indent);
996
    }
997
}
998

    
999
static void qbus_print(Monitor *mon, BusState *bus, int indent)
1000
{
1001
    struct DeviceState *dev;
1002

    
1003
    qdev_printf("bus: %s\n", bus->name);
1004
    indent += 2;
1005
    qdev_printf("type %s\n", bus->info->name);
1006
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
1007
        qdev_print(mon, dev, indent);
1008
    }
1009
}
1010
#undef qdev_printf
1011

    
1012
void do_info_qtree(Monitor *mon)
1013
{
1014
    if (main_system_bus)
1015
        qbus_print(mon, main_system_bus, 0);
1016
}
1017

    
1018
void do_info_qdm(Monitor *mon)
1019
{
1020
    DeviceInfo *info;
1021

    
1022
    for (info = device_info_list; info != NULL; info = info->next) {
1023
        qdev_print_devinfo(info);
1024
    }
1025
}
1026

    
1027
int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
1028
{
1029
    QemuOpts *opts;
1030

    
1031
    opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
1032
    if (!opts) {
1033
        return -1;
1034
    }
1035
    if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
1036
        qemu_opts_del(opts);
1037
        return 0;
1038
    }
1039
    if (!qdev_device_add(opts)) {
1040
        qemu_opts_del(opts);
1041
        return -1;
1042
    }
1043
    return 0;
1044
}
1045

    
1046
int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
1047
{
1048
    const char *id = qdict_get_str(qdict, "id");
1049
    DeviceState *dev;
1050

    
1051
    dev = qdev_find_recursive(main_system_bus, id);
1052
    if (NULL == dev) {
1053
        qerror_report(QERR_DEVICE_NOT_FOUND, id);
1054
        return -1;
1055
    }
1056
    return qdev_unplug(dev);
1057
}
1058

    
1059
static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
1060
{
1061
    int l = 0;
1062

    
1063
    if (dev && dev->parent_bus) {
1064
        char *d;
1065
        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
1066
        if (dev->parent_bus->info->get_fw_dev_path) {
1067
            d = dev->parent_bus->info->get_fw_dev_path(dev);
1068
            l += snprintf(p + l, size - l, "%s", d);
1069
            g_free(d);
1070
        } else {
1071
            l += snprintf(p + l, size - l, "%s", qdev_get_info(dev)->name);
1072
        }
1073
    }
1074
    l += snprintf(p + l , size - l, "/");
1075

    
1076
    return l;
1077
}
1078

    
1079
char* qdev_get_fw_dev_path(DeviceState *dev)
1080
{
1081
    char path[128];
1082
    int l;
1083

    
1084
    l = qdev_get_fw_dev_path_helper(dev, path, 128);
1085

    
1086
    path[l-1] = '\0';
1087

    
1088
    return strdup(path);
1089
}
1090

    
1091
char *qdev_get_type(DeviceState *dev, Error **errp)
1092
{
1093
    return g_strdup(qdev_get_info(dev)->name);
1094
}
1095

    
1096
void qdev_ref(DeviceState *dev)
1097
{
1098
    dev->ref++;
1099
}
1100

    
1101
void qdev_unref(DeviceState *dev)
1102
{
1103
    g_assert(dev->ref > 0);
1104
    dev->ref--;
1105
}
1106

    
1107
void qdev_property_add(DeviceState *dev, const char *name, const char *type,
1108
                       DevicePropertyAccessor *get, DevicePropertyAccessor *set,
1109
                       DevicePropertyRelease *release,
1110
                       void *opaque, Error **errp)
1111
{
1112
    DeviceProperty *prop = g_malloc0(sizeof(*prop));
1113

    
1114
    prop->name = g_strdup(name);
1115
    prop->type = g_strdup(type);
1116

    
1117
    prop->get = get;
1118
    prop->set = set;
1119
    prop->release = release;
1120
    prop->opaque = opaque;
1121

    
1122
    QTAILQ_INSERT_TAIL(&dev->properties, prop, node);
1123
}
1124

    
1125
static DeviceProperty *qdev_property_find(DeviceState *dev, const char *name)
1126
{
1127
    DeviceProperty *prop;
1128

    
1129
    QTAILQ_FOREACH(prop, &dev->properties, node) {
1130
        if (strcmp(prop->name, name) == 0) {
1131
            return prop;
1132
        }
1133
    }
1134

    
1135
    return NULL;
1136
}
1137

    
1138
void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
1139
                       Error **errp)
1140
{
1141
    DeviceProperty *prop = qdev_property_find(dev, name);
1142

    
1143
    if (prop == NULL) {
1144
        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1145
        return;
1146
    }
1147

    
1148
    if (!prop->get) {
1149
        error_set(errp, QERR_PERMISSION_DENIED);
1150
    } else {
1151
        prop->get(dev, v, prop->opaque, name, errp);
1152
    }
1153
}
1154

    
1155
void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
1156
                       Error **errp)
1157
{
1158
    DeviceProperty *prop = qdev_property_find(dev, name);
1159

    
1160
    if (prop == NULL) {
1161
        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1162
        return;
1163
    }
1164

    
1165
    if (!prop->set) {
1166
        error_set(errp, QERR_PERMISSION_DENIED);
1167
    } else {
1168
        prop->set(dev, v, prop->opaque, name, errp);
1169
    }
1170
}
1171

    
1172
const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **errp)
1173
{
1174
    DeviceProperty *prop = qdev_property_find(dev, name);
1175

    
1176
    if (prop == NULL) {
1177
        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1178
        return NULL;
1179
    }
1180

    
1181
    return prop->type;
1182
}
1183

    
1184
/**
1185
 * Legacy property handling
1186
 */
1187

    
1188
static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1189
                                     const char *name, Error **errp)
1190
{
1191
    Property *prop = opaque;
1192

    
1193
    char buffer[1024];
1194
    char *ptr = buffer;
1195

    
1196
    prop->info->print(dev, prop, buffer, sizeof(buffer));
1197
    visit_type_str(v, &ptr, name, errp);
1198
}
1199

    
1200
static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1201
                                     const char *name, Error **errp)
1202
{
1203
    Property *prop = opaque;
1204
    Error *local_err = NULL;
1205
    char *ptr = NULL;
1206
    int ret;
1207

    
1208
    if (dev->state != DEV_STATE_CREATED) {
1209
        error_set(errp, QERR_PERMISSION_DENIED);
1210
        return;
1211
    }
1212

    
1213
    visit_type_str(v, &ptr, name, &local_err);
1214
    if (local_err) {
1215
        error_propagate(errp, local_err);
1216
        return;
1217
    }
1218

    
1219
    ret = prop->info->parse(dev, prop, ptr);
1220
    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
1221
    g_free(ptr);
1222
}
1223

    
1224
/**
1225
 * @qdev_add_legacy_property - adds a legacy property
1226
 *
1227
 * Do not use this is new code!  Properties added through this interface will
1228
 * be given names and types in the "legacy" namespace.
1229
 *
1230
 * Legacy properties are always processed as strings.  The format of the string
1231
 * depends on the property type.
1232
 */
1233
void qdev_property_add_legacy(DeviceState *dev, Property *prop,
1234
                              Error **errp)
1235
{
1236
    gchar *name, *type;
1237

    
1238
    name = g_strdup_printf("legacy-%s", prop->name);
1239
    type = g_strdup_printf("legacy<%s>",
1240
                           prop->info->legacy_name ?: prop->info->name);
1241

    
1242
    qdev_property_add(dev, name, type,
1243
                      prop->info->print ? qdev_get_legacy_property : NULL,
1244
                      prop->info->parse ? qdev_set_legacy_property : NULL,
1245
                      NULL,
1246
                      prop, errp);
1247

    
1248
    g_free(type);
1249
    g_free(name);
1250
}
1251

    
1252
/**
1253
 * @qdev_property_add_static - add a @Property to a device.
1254
 *
1255
 * Static properties access data in a struct.  The actual type of the
1256
 * property and the field depends on the property type.
1257
 */
1258
void qdev_property_add_static(DeviceState *dev, Property *prop,
1259
                              Error **errp)
1260
{
1261
    qdev_property_add(dev, prop->name, prop->info->name,
1262
                      prop->info->get, prop->info->set,
1263
                      NULL,
1264
                      prop, errp);
1265
}
1266

    
1267
DeviceState *qdev_get_root(void)
1268
{
1269
    static DeviceState *qdev_root;
1270

    
1271
    if (!qdev_root) {
1272
        qdev_root = qdev_create(NULL, "container");
1273
        qdev_init_nofail(qdev_root);
1274
    }
1275

    
1276
    return qdev_root;
1277
}
1278

    
1279
static void qdev_get_child_property(DeviceState *dev, Visitor *v, void *opaque,
1280
                                    const char *name, Error **errp)
1281
{
1282
    DeviceState *child = opaque;
1283
    gchar *path;
1284

    
1285
    path = qdev_get_canonical_path(child);
1286
    visit_type_str(v, &path, name, errp);
1287
    g_free(path);
1288
}
1289

    
1290
static void qdev_release_child_property(DeviceState *dev, const char *name,
1291
                                        void *opaque)
1292
{
1293
    DeviceState *child = opaque;
1294

    
1295
    qdev_unref(child);
1296
}
1297

    
1298
void qdev_property_add_child(DeviceState *dev, const char *name,
1299
                             DeviceState *child, Error **errp)
1300
{
1301
    gchar *type;
1302

    
1303
    type = g_strdup_printf("child<%s>", qdev_get_info(child)->name);
1304

    
1305
    qdev_property_add(dev, name, type, qdev_get_child_property,
1306
                      NULL, qdev_release_child_property,
1307
                      child, errp);
1308

    
1309
    qdev_ref(child);
1310
    g_assert(child->parent == NULL);
1311
    child->parent = dev;
1312

    
1313
    g_free(type);
1314
}
1315

    
1316
static void qdev_get_link_property(DeviceState *dev, Visitor *v, void *opaque,
1317
                                   const char *name, Error **errp)
1318
{
1319
    DeviceState **child = opaque;
1320
    gchar *path;
1321

    
1322
    if (*child) {
1323
        path = qdev_get_canonical_path(*child);
1324
        visit_type_str(v, &path, name, errp);
1325
        g_free(path);
1326
    } else {
1327
        path = (gchar *)"";
1328
        visit_type_str(v, &path, name, errp);
1329
    }
1330
}
1331

    
1332
static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque,
1333
                                   const char *name, Error **errp)
1334
{
1335
    DeviceState **child = opaque;
1336
    bool ambiguous = false;
1337
    const char *type;
1338
    char *path;
1339

    
1340
    type = qdev_property_get_type(dev, name, NULL);
1341

    
1342
    visit_type_str(v, &path, name, errp);
1343

    
1344
    if (*child) {
1345
        qdev_unref(*child);
1346
    }
1347

    
1348
    if (strcmp(path, "") != 0) {
1349
        DeviceState *target;
1350

    
1351
        target = qdev_resolve_path(path, &ambiguous);
1352
        if (target) {
1353
            gchar *target_type;
1354

    
1355
            target_type = g_strdup_printf("link<%s>", qdev_get_info(target)->name);
1356
            if (strcmp(target_type, type) == 0) {
1357
                *child = target;
1358
                qdev_ref(target);
1359
            } else {
1360
                error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
1361
            }
1362

    
1363
            g_free(target_type);
1364
        } else {
1365
            error_set(errp, QERR_DEVICE_NOT_FOUND, path);
1366
        }
1367
    } else {
1368
        *child = NULL;
1369
    }
1370

    
1371
    g_free(path);
1372
}
1373

    
1374
void qdev_property_add_link(DeviceState *dev, const char *name,
1375
                            const char *type, DeviceState **child,
1376
                            Error **errp)
1377
{
1378
    gchar *full_type;
1379

    
1380
    full_type = g_strdup_printf("link<%s>", type);
1381

    
1382
    qdev_property_add(dev, name, full_type,
1383
                      qdev_get_link_property,
1384
                      qdev_set_link_property,
1385
                      NULL, child, errp);
1386

    
1387
    g_free(full_type);
1388
}
1389

    
1390
gchar *qdev_get_canonical_path(DeviceState *dev)
1391
{
1392
    DeviceState *root = qdev_get_root();
1393
    char *newpath = NULL, *path = NULL;
1394

    
1395
    while (dev != root) {
1396
        DeviceProperty *prop = NULL;
1397

    
1398
        g_assert(dev->parent != NULL);
1399

    
1400
        QTAILQ_FOREACH(prop, &dev->parent->properties, node) {
1401
            if (!strstart(prop->type, "child<", NULL)) {
1402
                continue;
1403
            }
1404

    
1405
            if (prop->opaque == dev) {
1406
                if (path) {
1407
                    newpath = g_strdup_printf("%s/%s", prop->name, path);
1408
                    g_free(path);
1409
                    path = newpath;
1410
                } else {
1411
                    path = g_strdup(prop->name);
1412
                }
1413
                break;
1414
            }
1415
        }
1416

    
1417
        g_assert(prop != NULL);
1418

    
1419
        dev = dev->parent;
1420
    }
1421

    
1422
    newpath = g_strdup_printf("/%s", path);
1423
    g_free(path);
1424

    
1425
    return newpath;
1426
}
1427

    
1428
static DeviceState *qdev_resolve_abs_path(DeviceState *parent,
1429
                                          gchar **parts,
1430
                                          int index)
1431
{
1432
    DeviceProperty *prop;
1433
    DeviceState *child;
1434

    
1435
    if (parts[index] == NULL) {
1436
        return parent;
1437
    }
1438

    
1439
    if (strcmp(parts[index], "") == 0) {
1440
        return qdev_resolve_abs_path(parent, parts, index + 1);
1441
    }
1442

    
1443
    prop = qdev_property_find(parent, parts[index]);
1444
    if (prop == NULL) {
1445
        return NULL;
1446
    }
1447

    
1448
    child = NULL;
1449
    if (strstart(prop->type, "link<", NULL)) {
1450
        DeviceState **pchild = prop->opaque;
1451
        if (*pchild) {
1452
            child = *pchild;
1453
        }
1454
    } else if (strstart(prop->type, "child<", NULL)) {
1455
        child = prop->opaque;
1456
    }
1457

    
1458
    if (!child) {
1459
        return NULL;
1460
    }
1461

    
1462
    return qdev_resolve_abs_path(child, parts, index + 1);
1463
}
1464

    
1465
static DeviceState *qdev_resolve_partial_path(DeviceState *parent,
1466
                                              gchar **parts,
1467
                                              bool *ambiguous)
1468
{
1469
    DeviceState *dev;
1470
    DeviceProperty *prop;
1471

    
1472
    dev = qdev_resolve_abs_path(parent, parts, 0);
1473

    
1474
    QTAILQ_FOREACH(prop, &parent->properties, node) {
1475
        DeviceState *found;
1476

    
1477
        if (!strstart(prop->type, "child<", NULL)) {
1478
            continue;
1479
        }
1480

    
1481
        found = qdev_resolve_partial_path(prop->opaque, parts, ambiguous);
1482
        if (found) {
1483
            if (dev) {
1484
                if (ambiguous) {
1485
                    *ambiguous = true;
1486
                }
1487
                return NULL;
1488
            }
1489
            dev = found;
1490
        }
1491

    
1492
        if (ambiguous && *ambiguous) {
1493
            return NULL;
1494
        }
1495
    }
1496

    
1497
    return dev;
1498
}
1499

    
1500
DeviceState *qdev_resolve_path(const char *path, bool *ambiguous)
1501
{
1502
    bool partial_path = true;
1503
    DeviceState *dev;
1504
    gchar **parts;
1505

    
1506
    parts = g_strsplit(path, "/", 0);
1507
    if (parts == NULL || parts[0] == NULL) {
1508
        g_strfreev(parts);
1509
        return qdev_get_root();
1510
    }
1511

    
1512
    if (strcmp(parts[0], "") == 0) {
1513
        partial_path = false;
1514
    }
1515

    
1516
    if (partial_path) {
1517
        if (ambiguous) {
1518
            *ambiguous = false;
1519
        }
1520
        dev = qdev_resolve_partial_path(qdev_get_root(), parts, ambiguous);
1521
    } else {
1522
        dev = qdev_resolve_abs_path(qdev_get_root(), parts, 1);
1523
    }
1524

    
1525
    g_strfreev(parts);
1526

    
1527
    return dev;
1528
}
1529

    
1530
typedef struct StringProperty
1531
{
1532
    char *(*get)(DeviceState *, Error **);
1533
    void (*set)(DeviceState *, const char *, Error **);
1534
} StringProperty;
1535

    
1536
static void qdev_property_get_str(DeviceState *dev, Visitor *v, void *opaque,
1537
                                  const char *name, Error **errp)
1538
{
1539
    StringProperty *prop = opaque;
1540
    char *value;
1541

    
1542
    value = prop->get(dev, errp);
1543
    if (value) {
1544
        visit_type_str(v, &value, name, errp);
1545
        g_free(value);
1546
    }
1547
}
1548

    
1549
static void qdev_property_set_str(DeviceState *dev, Visitor *v, void *opaque,
1550
                                  const char *name, Error **errp)
1551
{
1552
    StringProperty *prop = opaque;
1553
    char *value;
1554
    Error *local_err = NULL;
1555

    
1556
    visit_type_str(v, &value, name, &local_err);
1557
    if (local_err) {
1558
        error_propagate(errp, local_err);
1559
        return;
1560
    }
1561

    
1562
    prop->set(dev, value, errp);
1563
    g_free(value);
1564
}
1565

    
1566
static void qdev_property_release_str(DeviceState *dev, const char *name,
1567
                                      void *opaque)
1568
{
1569
    StringProperty *prop = opaque;
1570
    g_free(prop);
1571
}
1572

    
1573
void qdev_property_add_str(DeviceState *dev, const char *name,
1574
                           char *(*get)(DeviceState *, Error **),
1575
                           void (*set)(DeviceState *, const char *, Error **),
1576
                           Error **errp)
1577
{
1578
    StringProperty *prop = g_malloc0(sizeof(*prop));
1579

    
1580
    prop->get = get;
1581
    prop->set = set;
1582

    
1583
    qdev_property_add(dev, name, "string",
1584
                      get ? qdev_property_get_str : NULL,
1585
                      set ? qdev_property_set_str : NULL,
1586
                      qdev_property_release_str,
1587
                      prop, errp);
1588
}
1589

    
1590
void qdev_machine_init(void)
1591
{
1592
    qdev_get_peripheral_anon();
1593
    qdev_get_peripheral();
1594
}
1595

    
1596
static TypeInfo device_type_info = {
1597
    .name = TYPE_DEVICE,
1598
    .parent = TYPE_OBJECT,
1599
    .instance_size = sizeof(DeviceState),
1600
    .abstract = true,
1601
    .class_size = sizeof(DeviceClass),
1602
};
1603

    
1604
static void init_qdev(void)
1605
{
1606
    type_register_static(&device_type_info);
1607
}
1608

    
1609
device_init(init_qdev);