Statistics
| Branch: | Revision:

root / hw / qdev.c @ d49bc1fb

History | View | Annotate | Download (40.2 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
void qdev_register(DeviceInfo *info)
49
{
50
    assert(info->size >= sizeof(DeviceState));
51
    assert(!info->next);
52

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

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

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

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

    
83
static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
84
                                     Error **errp);
85

    
86
static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
87
{
88
    DeviceState *dev;
89
    Property *prop;
90

    
91
    assert(bus->info == info->bus_info);
92
    dev = g_malloc0(info->size);
93
    dev->info = info;
94
    dev->parent_bus = bus;
95
    qdev_prop_set_defaults(dev, dev->info->props);
96
    qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
97
    qdev_prop_set_globals(dev);
98
    QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
99
    if (qdev_hotplug) {
100
        assert(bus->allow_hotplug);
101
        dev->hotplugged = 1;
102
        qdev_hot_added = true;
103
    }
104
    dev->instance_id_alias = -1;
105
    QTAILQ_INIT(&dev->properties);
106
    dev->state = DEV_STATE_CREATED;
107

    
108
    for (prop = dev->info->props; prop && prop->name; prop++) {
109
        qdev_property_add_legacy(dev, prop, NULL);
110
        qdev_property_add_static(dev, prop, NULL);
111
    }
112

    
113
    for (prop = dev->info->bus_info->props; prop && prop->name; prop++) {
114
        qdev_property_add_legacy(dev, prop, NULL);
115
        qdev_property_add_static(dev, prop, NULL);
116
    }
117

    
118
    qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL);
119

    
120
    return dev;
121
}
122

    
123
/* Create a new device.  This only initializes the device state structure
124
   and allows properties to be set.  qdev_init should be called to
125
   initialize the actual device emulation.  */
126
DeviceState *qdev_create(BusState *bus, const char *name)
127
{
128
    DeviceState *dev;
129

    
130
    dev = qdev_try_create(bus, name);
131
    if (!dev) {
132
        if (bus) {
133
            hw_error("Unknown device '%s' for bus '%s'\n", name,
134
                     bus->info->name);
135
        } else {
136
            hw_error("Unknown device '%s' for default sysbus\n", name);
137
        }
138
    }
139

    
140
    return dev;
141
}
142

    
143
DeviceState *qdev_try_create(BusState *bus, const char *name)
144
{
145
    DeviceInfo *info;
146

    
147
    if (!bus) {
148
        bus = sysbus_get_default();
149
    }
150

    
151
    info = qdev_find_info(bus->info, name);
152
    if (!info) {
153
        return NULL;
154
    }
155

    
156
    return qdev_create_from_info(bus, info);
157
}
158

    
159
static void qdev_print_devinfo(DeviceInfo *info)
160
{
161
    error_printf("name \"%s\", bus %s",
162
                 info->name, info->bus_info->name);
163
    if (info->alias) {
164
        error_printf(", alias \"%s\"", info->alias);
165
    }
166
    if (info->desc) {
167
        error_printf(", desc \"%s\"", info->desc);
168
    }
169
    if (info->no_user) {
170
        error_printf(", no-user");
171
    }
172
    error_printf("\n");
173
}
174

    
175
static int set_property(const char *name, const char *value, void *opaque)
176
{
177
    DeviceState *dev = opaque;
178

    
179
    if (strcmp(name, "driver") == 0)
180
        return 0;
181
    if (strcmp(name, "bus") == 0)
182
        return 0;
183

    
184
    if (qdev_prop_parse(dev, name, value) == -1) {
185
        return -1;
186
    }
187
    return 0;
188
}
189

    
190
int qdev_device_help(QemuOpts *opts)
191
{
192
    const char *driver;
193
    DeviceInfo *info;
194
    Property *prop;
195

    
196
    driver = qemu_opt_get(opts, "driver");
197
    if (driver && !strcmp(driver, "?")) {
198
        for (info = device_info_list; info != NULL; info = info->next) {
199
            if (info->no_user) {
200
                continue;       /* not available, don't show */
201
            }
202
            qdev_print_devinfo(info);
203
        }
204
        return 1;
205
    }
206

    
207
    if (!driver || !qemu_opt_get(opts, "?")) {
208
        return 0;
209
    }
210

    
211
    info = qdev_find_info(NULL, driver);
212
    if (!info) {
213
        return 0;
214
    }
215

    
216
    for (prop = info->props; prop && prop->name; prop++) {
217
        /*
218
         * TODO Properties without a parser are just for dirty hacks.
219
         * qdev_prop_ptr is the only such PropertyInfo.  It's marked
220
         * for removal.  This conditional should be removed along with
221
         * it.
222
         */
223
        if (!prop->info->parse) {
224
            continue;           /* no way to set it, don't show */
225
        }
226
        error_printf("%s.%s=%s\n", info->name, prop->name,
227
                     prop->info->legacy_name ?: prop->info->name);
228
    }
229
    for (prop = info->bus_info->props; prop && prop->name; prop++) {
230
        if (!prop->info->parse) {
231
            continue;           /* no way to set it, don't show */
232
        }
233
        error_printf("%s.%s=%s\n", info->name, prop->name,
234
                     prop->info->legacy_name ?: prop->info->name);
235
    }
236
    return 1;
237
}
238

    
239
static DeviceState *qdev_get_peripheral(void)
240
{
241
    static DeviceState *dev;
242

    
243
    if (dev == NULL) {
244
        dev = qdev_create(NULL, "container");
245
        qdev_property_add_child(qdev_get_root(), "peripheral", dev, NULL);
246
        qdev_init_nofail(dev);
247
    }
248

    
249
    return dev;
250
}
251

    
252
static DeviceState *qdev_get_peripheral_anon(void)
253
{
254
    static DeviceState *dev;
255

    
256
    if (dev == NULL) {
257
        dev = qdev_create(NULL, "container");
258
        qdev_property_add_child(qdev_get_root(), "peripheral-anon", dev, NULL);
259
        qdev_init_nofail(dev);
260
    }
261

    
262
    return dev;
263
}
264

    
265
DeviceState *qdev_device_add(QemuOpts *opts)
266
{
267
    const char *driver, *path, *id;
268
    DeviceInfo *info;
269
    DeviceState *qdev;
270
    BusState *bus;
271

    
272
    driver = qemu_opt_get(opts, "driver");
273
    if (!driver) {
274
        qerror_report(QERR_MISSING_PARAMETER, "driver");
275
        return NULL;
276
    }
277

    
278
    /* find driver */
279
    info = qdev_find_info(NULL, driver);
280
    if (!info || info->no_user) {
281
        qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
282
        error_printf_unless_qmp("Try with argument '?' for a list.\n");
283
        return NULL;
284
    }
285

    
286
    /* find bus */
287
    path = qemu_opt_get(opts, "bus");
288
    if (path != NULL) {
289
        bus = qbus_find(path);
290
        if (!bus) {
291
            return NULL;
292
        }
293
        if (bus->info != info->bus_info) {
294
            qerror_report(QERR_BAD_BUS_FOR_DEVICE,
295
                           driver, bus->info->name);
296
            return NULL;
297
        }
298
    } else {
299
        bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
300
        if (!bus) {
301
            qerror_report(QERR_NO_BUS_FOR_DEVICE,
302
                           info->name, info->bus_info->name);
303
            return NULL;
304
        }
305
    }
306
    if (qdev_hotplug && !bus->allow_hotplug) {
307
        qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
308
        return NULL;
309
    }
310

    
311
    /* create device, set properties */
312
    qdev = qdev_create_from_info(bus, info);
313
    id = qemu_opts_id(opts);
314
    if (id) {
315
        qdev->id = id;
316
        qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL);
317
    } else {
318
        static int anon_count;
319
        gchar *name = g_strdup_printf("device[%d]", anon_count++);
320
        qdev_property_add_child(qdev_get_peripheral_anon(), name,
321
                                qdev, NULL);
322
        g_free(name);
323
    }        
324
    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
325
        qdev_free(qdev);
326
        return NULL;
327
    }
328
    if (qdev_init(qdev) < 0) {
329
        qerror_report(QERR_DEVICE_INIT_FAILED, driver);
330
        return NULL;
331
    }
332
    qdev->opts = opts;
333
    return qdev;
334
}
335

    
336
/* Initialize a device.  Device properties should be set before calling
337
   this function.  IRQs and MMIO regions should be connected/mapped after
338
   calling this function.
339
   On failure, destroy the device and return negative value.
340
   Return 0 on success.  */
341
int qdev_init(DeviceState *dev)
342
{
343
    int rc;
344

    
345
    assert(dev->state == DEV_STATE_CREATED);
346
    rc = dev->info->init(dev, dev->info);
347
    if (rc < 0) {
348
        qdev_free(dev);
349
        return rc;
350
    }
351
    if (dev->info->vmsd) {
352
        vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
353
                                       dev->instance_id_alias,
354
                                       dev->alias_required_for_version);
355
    }
356
    dev->state = DEV_STATE_INITIALIZED;
357
    if (dev->hotplugged && dev->info->reset) {
358
        dev->info->reset(dev);
359
    }
360
    return 0;
361
}
362

    
363
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
364
                                 int required_for_version)
365
{
366
    assert(dev->state == DEV_STATE_CREATED);
367
    dev->instance_id_alias = alias_id;
368
    dev->alias_required_for_version = required_for_version;
369
}
370

    
371
int qdev_unplug(DeviceState *dev)
372
{
373
    if (!dev->parent_bus->allow_hotplug) {
374
        qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
375
        return -1;
376
    }
377
    assert(dev->info->unplug != NULL);
378

    
379
    qdev_hot_removed = true;
380

    
381
    return dev->info->unplug(dev);
382
}
383

    
384
static int qdev_reset_one(DeviceState *dev, void *opaque)
385
{
386
    if (dev->info->reset) {
387
        dev->info->reset(dev);
388
    }
389

    
390
    return 0;
391
}
392

    
393
BusState *sysbus_get_default(void)
394
{
395
    if (!main_system_bus) {
396
        main_system_bus_create();
397
    }
398
    return main_system_bus;
399
}
400

    
401
static int qbus_reset_one(BusState *bus, void *opaque)
402
{
403
    if (bus->info->reset) {
404
        return bus->info->reset(bus);
405
    }
406
    return 0;
407
}
408

    
409
void qdev_reset_all(DeviceState *dev)
410
{
411
    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
412
}
413

    
414
void qbus_reset_all_fn(void *opaque)
415
{
416
    BusState *bus = opaque;
417
    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
418
}
419

    
420
/* can be used as ->unplug() callback for the simple cases */
421
int qdev_simple_unplug_cb(DeviceState *dev)
422
{
423
    /* just zap it */
424
    qdev_free(dev);
425
    return 0;
426
}
427

    
428

    
429
/* Like qdev_init(), but terminate program via error_report() instead of
430
   returning an error value.  This is okay during machine creation.
431
   Don't use for hotplug, because there callers need to recover from
432
   failure.  Exception: if you know the device's init() callback can't
433
   fail, then qdev_init_nofail() can't fail either, and is therefore
434
   usable even then.  But relying on the device implementation that
435
   way is somewhat unclean, and best avoided.  */
436
void qdev_init_nofail(DeviceState *dev)
437
{
438
    DeviceInfo *info = dev->info;
439

    
440
    if (qdev_init(dev) < 0) {
441
        error_report("Initialization of device %s failed", info->name);
442
        exit(1);
443
    }
444
}
445

    
446
static void qdev_property_del_all(DeviceState *dev)
447
{
448
    while (!QTAILQ_EMPTY(&dev->properties)) {
449
        DeviceProperty *prop = QTAILQ_FIRST(&dev->properties);
450

    
451
        QTAILQ_REMOVE(&dev->properties, prop, node);
452

    
453
        if (prop->release) {
454
            prop->release(dev, prop->name, prop->opaque);
455
        }
456

    
457
        g_free(prop->name);
458
        g_free(prop->type);
459
        g_free(prop);
460
    }
461
}
462

    
463
static void qdev_property_del_child(DeviceState *dev, DeviceState *child, Error **errp)
464
{
465
    DeviceProperty *prop;
466

    
467
    QTAILQ_FOREACH(prop, &dev->properties, node) {
468
        if (strstart(prop->type, "child<", NULL) && prop->opaque == child) {
469
            break;
470
        }
471
    }
472

    
473
    g_assert(prop != NULL);
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
/* Unlink device from bus and free the structure.  */
487
void qdev_free(DeviceState *dev)
488
{
489
    BusState *bus;
490
    Property *prop;
491

    
492
    qdev_property_del_all(dev);
493

    
494
    if (dev->state == DEV_STATE_INITIALIZED) {
495
        while (dev->num_child_bus) {
496
            bus = QLIST_FIRST(&dev->child_bus);
497
            qbus_free(bus);
498
        }
499
        if (dev->info->vmsd)
500
            vmstate_unregister(dev, dev->info->vmsd, dev);
501
        if (dev->info->exit)
502
            dev->info->exit(dev);
503
        if (dev->opts)
504
            qemu_opts_del(dev->opts);
505
    }
506
    QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
507
    for (prop = dev->info->props; prop && prop->name; prop++) {
508
        if (prop->info->free) {
509
            prop->info->free(dev, prop);
510
        }
511
    }
512
    if (dev->parent) {
513
        qdev_property_del_child(dev->parent, dev, NULL);
514
    }
515
    if (dev->ref != 0) {
516
        qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
517
    }
518
    g_free(dev);
519
}
520

    
521
void qdev_machine_creation_done(void)
522
{
523
    /*
524
     * ok, initial machine setup is done, starting from now we can
525
     * only create hotpluggable devices
526
     */
527
    qdev_hotplug = 1;
528
}
529

    
530
bool qdev_machine_modified(void)
531
{
532
    return qdev_hot_added || qdev_hot_removed;
533
}
534

    
535
/* Get a character (serial) device interface.  */
536
CharDriverState *qdev_init_chardev(DeviceState *dev)
537
{
538
    static int next_serial;
539

    
540
    /* FIXME: This function needs to go away: use chardev properties!  */
541
    return serial_hds[next_serial++];
542
}
543

    
544
BusState *qdev_get_parent_bus(DeviceState *dev)
545
{
546
    return dev->parent_bus;
547
}
548

    
549
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
550
{
551
    assert(dev->num_gpio_in == 0);
552
    dev->num_gpio_in = n;
553
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
554
}
555

    
556
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
557
{
558
    assert(dev->num_gpio_out == 0);
559
    dev->num_gpio_out = n;
560
    dev->gpio_out = pins;
561
}
562

    
563
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
564
{
565
    assert(n >= 0 && n < dev->num_gpio_in);
566
    return dev->gpio_in[n];
567
}
568

    
569
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
570
{
571
    assert(n >= 0 && n < dev->num_gpio_out);
572
    dev->gpio_out[n] = pin;
573
}
574

    
575
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
576
{
577
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
578
    if (nd->vlan)
579
        qdev_prop_set_vlan(dev, "vlan", nd->vlan);
580
    if (nd->netdev)
581
        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
582
    if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
583
        qdev_prop_exists(dev, "vectors")) {
584
        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
585
    }
586
    nd->instantiated = 1;
587
}
588

    
589
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
590
{
591
    BusState *bus;
592

    
593
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
594
        if (strcmp(name, bus->name) == 0) {
595
            return bus;
596
        }
597
    }
598
    return NULL;
599
}
600

    
601
int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
602
                       qbus_walkerfn *busfn, void *opaque)
603
{
604
    DeviceState *dev;
605
    int err;
606

    
607
    if (busfn) {
608
        err = busfn(bus, opaque);
609
        if (err) {
610
            return err;
611
        }
612
    }
613

    
614
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
615
        err = qdev_walk_children(dev, devfn, busfn, opaque);
616
        if (err < 0) {
617
            return err;
618
        }
619
    }
620

    
621
    return 0;
622
}
623

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

    
630
    if (devfn) {
631
        err = devfn(dev, opaque);
632
        if (err) {
633
            return err;
634
        }
635
    }
636

    
637
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
638
        err = qbus_walk_children(bus, devfn, busfn, opaque);
639
        if (err < 0) {
640
            return err;
641
        }
642
    }
643

    
644
    return 0;
645
}
646

    
647
static BusState *qbus_find_recursive(BusState *bus, const char *name,
648
                                     const BusInfo *info)
649
{
650
    DeviceState *dev;
651
    BusState *child, *ret;
652
    int match = 1;
653

    
654
    if (name && (strcmp(bus->name, name) != 0)) {
655
        match = 0;
656
    }
657
    if (info && (bus->info != info)) {
658
        match = 0;
659
    }
660
    if (match) {
661
        return bus;
662
    }
663

    
664
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
665
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
666
            ret = qbus_find_recursive(child, name, info);
667
            if (ret) {
668
                return ret;
669
            }
670
        }
671
    }
672
    return NULL;
673
}
674

    
675
DeviceState *qdev_find_recursive(BusState *bus, const char *id)
676
{
677
    DeviceState *dev, *ret;
678
    BusState *child;
679

    
680
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
681
        if (dev->id && strcmp(dev->id, id) == 0)
682
            return dev;
683
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
684
            ret = qdev_find_recursive(child, id);
685
            if (ret) {
686
                return ret;
687
            }
688
        }
689
    }
690
    return NULL;
691
}
692

    
693
static void qbus_list_bus(DeviceState *dev)
694
{
695
    BusState *child;
696
    const char *sep = " ";
697

    
698
    error_printf("child busses at \"%s\":",
699
                 dev->id ? dev->id : dev->info->name);
700
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
701
        error_printf("%s\"%s\"", sep, child->name);
702
        sep = ", ";
703
    }
704
    error_printf("\n");
705
}
706

    
707
static void qbus_list_dev(BusState *bus)
708
{
709
    DeviceState *dev;
710
    const char *sep = " ";
711

    
712
    error_printf("devices at \"%s\":", bus->name);
713
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
714
        error_printf("%s\"%s\"", sep, dev->info->name);
715
        if (dev->id)
716
            error_printf("/\"%s\"", dev->id);
717
        sep = ", ";
718
    }
719
    error_printf("\n");
720
}
721

    
722
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
723
{
724
    BusState *child;
725

    
726
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
727
        if (strcmp(child->name, elem) == 0) {
728
            return child;
729
        }
730
    }
731
    return NULL;
732
}
733

    
734
static DeviceState *qbus_find_dev(BusState *bus, char *elem)
735
{
736
    DeviceState *dev;
737

    
738
    /*
739
     * try to match in order:
740
     *   (1) instance id, if present
741
     *   (2) driver name
742
     *   (3) driver alias, if present
743
     */
744
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
745
        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
746
            return dev;
747
        }
748
    }
749
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
750
        if (strcmp(dev->info->name, elem) == 0) {
751
            return dev;
752
        }
753
    }
754
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
755
        if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
756
            return dev;
757
        }
758
    }
759
    return NULL;
760
}
761

    
762
static BusState *qbus_find(const char *path)
763
{
764
    DeviceState *dev;
765
    BusState *bus;
766
    char elem[128];
767
    int pos, len;
768

    
769
    /* find start element */
770
    if (path[0] == '/') {
771
        bus = main_system_bus;
772
        pos = 0;
773
    } else {
774
        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
775
            assert(!path[0]);
776
            elem[0] = len = 0;
777
        }
778
        bus = qbus_find_recursive(main_system_bus, elem, NULL);
779
        if (!bus) {
780
            qerror_report(QERR_BUS_NOT_FOUND, elem);
781
            return NULL;
782
        }
783
        pos = len;
784
    }
785

    
786
    for (;;) {
787
        assert(path[pos] == '/' || !path[pos]);
788
        while (path[pos] == '/') {
789
            pos++;
790
        }
791
        if (path[pos] == '\0') {
792
            return bus;
793
        }
794

    
795
        /* find device */
796
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
797
            assert(0);
798
            elem[0] = len = 0;
799
        }
800
        pos += len;
801
        dev = qbus_find_dev(bus, elem);
802
        if (!dev) {
803
            qerror_report(QERR_DEVICE_NOT_FOUND, elem);
804
            if (!monitor_cur_is_qmp()) {
805
                qbus_list_dev(bus);
806
            }
807
            return NULL;
808
        }
809

    
810
        assert(path[pos] == '/' || !path[pos]);
811
        while (path[pos] == '/') {
812
            pos++;
813
        }
814
        if (path[pos] == '\0') {
815
            /* last specified element is a device.  If it has exactly
816
             * one child bus accept it nevertheless */
817
            switch (dev->num_child_bus) {
818
            case 0:
819
                qerror_report(QERR_DEVICE_NO_BUS, elem);
820
                return NULL;
821
            case 1:
822
                return QLIST_FIRST(&dev->child_bus);
823
            default:
824
                qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
825
                if (!monitor_cur_is_qmp()) {
826
                    qbus_list_bus(dev);
827
                }
828
                return NULL;
829
            }
830
        }
831

    
832
        /* find bus */
833
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
834
            assert(0);
835
            elem[0] = len = 0;
836
        }
837
        pos += len;
838
        bus = qbus_find_bus(dev, elem);
839
        if (!bus) {
840
            qerror_report(QERR_BUS_NOT_FOUND, elem);
841
            if (!monitor_cur_is_qmp()) {
842
                qbus_list_bus(dev);
843
            }
844
            return NULL;
845
        }
846
    }
847
}
848

    
849
void qbus_create_inplace(BusState *bus, BusInfo *info,
850
                         DeviceState *parent, const char *name)
851
{
852
    char *buf;
853
    int i,len;
854

    
855
    bus->info = info;
856
    bus->parent = parent;
857

    
858
    if (name) {
859
        /* use supplied name */
860
        bus->name = g_strdup(name);
861
    } else if (parent && parent->id) {
862
        /* parent device has id -> use it for bus name */
863
        len = strlen(parent->id) + 16;
864
        buf = g_malloc(len);
865
        snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
866
        bus->name = buf;
867
    } else {
868
        /* no id -> use lowercase bus type for bus name */
869
        len = strlen(info->name) + 16;
870
        buf = g_malloc(len);
871
        len = snprintf(buf, len, "%s.%d", info->name,
872
                       parent ? parent->num_child_bus : 0);
873
        for (i = 0; i < len; i++)
874
            buf[i] = qemu_tolower(buf[i]);
875
        bus->name = buf;
876
    }
877

    
878
    QTAILQ_INIT(&bus->children);
879
    if (parent) {
880
        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
881
        parent->num_child_bus++;
882
    } else if (bus != main_system_bus) {
883
        /* TODO: once all bus devices are qdevified,
884
           only reset handler for main_system_bus should be registered here. */
885
        qemu_register_reset(qbus_reset_all_fn, bus);
886
    }
887
}
888

    
889
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
890
{
891
    BusState *bus;
892

    
893
    bus = g_malloc0(info->size);
894
    bus->qdev_allocated = 1;
895
    qbus_create_inplace(bus, info, parent, name);
896
    return bus;
897
}
898

    
899
static void main_system_bus_create(void)
900
{
901
    /* assign main_system_bus before qbus_create_inplace()
902
     * in order to make "if (bus != main_system_bus)" work */
903
    main_system_bus = g_malloc0(system_bus_info.size);
904
    main_system_bus->qdev_allocated = 1;
905
    qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
906
                        "main-system-bus");
907
}
908

    
909
void qbus_free(BusState *bus)
910
{
911
    DeviceState *dev;
912

    
913
    while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
914
        qdev_free(dev);
915
    }
916
    if (bus->parent) {
917
        QLIST_REMOVE(bus, sibling);
918
        bus->parent->num_child_bus--;
919
    } else {
920
        assert(bus != main_system_bus); /* main_system_bus is never freed */
921
        qemu_unregister_reset(qbus_reset_all_fn, bus);
922
    }
923
    g_free((void*)bus->name);
924
    if (bus->qdev_allocated) {
925
        g_free(bus);
926
    }
927
}
928

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

    
932
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
933
                             const char *prefix, int indent)
934
{
935
    char buf[64];
936

    
937
    if (!props)
938
        return;
939
    while (props->name) {
940
        /*
941
         * TODO Properties without a print method are just for dirty
942
         * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
943
         * marked for removal.  The test props->info->print should be
944
         * removed along with it.
945
         */
946
        if (props->info->print) {
947
            props->info->print(dev, props, buf, sizeof(buf));
948
            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
949
        }
950
        props++;
951
    }
952
}
953

    
954
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
955
{
956
    BusState *child;
957
    qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
958
                dev->id ? dev->id : "");
959
    indent += 2;
960
    if (dev->num_gpio_in) {
961
        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
962
    }
963
    if (dev->num_gpio_out) {
964
        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
965
    }
966
    qdev_print_props(mon, dev, dev->info->props, "dev", indent);
967
    qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
968
    if (dev->parent_bus->info->print_dev)
969
        dev->parent_bus->info->print_dev(mon, dev, indent);
970
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
971
        qbus_print(mon, child, indent);
972
    }
973
}
974

    
975
static void qbus_print(Monitor *mon, BusState *bus, int indent)
976
{
977
    struct DeviceState *dev;
978

    
979
    qdev_printf("bus: %s\n", bus->name);
980
    indent += 2;
981
    qdev_printf("type %s\n", bus->info->name);
982
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
983
        qdev_print(mon, dev, indent);
984
    }
985
}
986
#undef qdev_printf
987

    
988
void do_info_qtree(Monitor *mon)
989
{
990
    if (main_system_bus)
991
        qbus_print(mon, main_system_bus, 0);
992
}
993

    
994
void do_info_qdm(Monitor *mon)
995
{
996
    DeviceInfo *info;
997

    
998
    for (info = device_info_list; info != NULL; info = info->next) {
999
        qdev_print_devinfo(info);
1000
    }
1001
}
1002

    
1003
int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
1004
{
1005
    QemuOpts *opts;
1006

    
1007
    opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
1008
    if (!opts) {
1009
        return -1;
1010
    }
1011
    if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
1012
        qemu_opts_del(opts);
1013
        return 0;
1014
    }
1015
    if (!qdev_device_add(opts)) {
1016
        qemu_opts_del(opts);
1017
        return -1;
1018
    }
1019
    return 0;
1020
}
1021

    
1022
int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
1023
{
1024
    const char *id = qdict_get_str(qdict, "id");
1025
    DeviceState *dev;
1026

    
1027
    dev = qdev_find_recursive(main_system_bus, id);
1028
    if (NULL == dev) {
1029
        qerror_report(QERR_DEVICE_NOT_FOUND, id);
1030
        return -1;
1031
    }
1032
    return qdev_unplug(dev);
1033
}
1034

    
1035
static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
1036
{
1037
    int l = 0;
1038

    
1039
    if (dev && dev->parent_bus) {
1040
        char *d;
1041
        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
1042
        if (dev->parent_bus->info->get_fw_dev_path) {
1043
            d = dev->parent_bus->info->get_fw_dev_path(dev);
1044
            l += snprintf(p + l, size - l, "%s", d);
1045
            g_free(d);
1046
        } else {
1047
            l += snprintf(p + l, size - l, "%s", dev->info->name);
1048
        }
1049
    }
1050
    l += snprintf(p + l , size - l, "/");
1051

    
1052
    return l;
1053
}
1054

    
1055
char* qdev_get_fw_dev_path(DeviceState *dev)
1056
{
1057
    char path[128];
1058
    int l;
1059

    
1060
    l = qdev_get_fw_dev_path_helper(dev, path, 128);
1061

    
1062
    path[l-1] = '\0';
1063

    
1064
    return strdup(path);
1065
}
1066

    
1067
char *qdev_get_type(DeviceState *dev, Error **errp)
1068
{
1069
    return g_strdup(dev->info->name);
1070
}
1071

    
1072
void qdev_ref(DeviceState *dev)
1073
{
1074
    dev->ref++;
1075
}
1076

    
1077
void qdev_unref(DeviceState *dev)
1078
{
1079
    g_assert(dev->ref > 0);
1080
    dev->ref--;
1081
}
1082

    
1083
void qdev_property_add(DeviceState *dev, const char *name, const char *type,
1084
                       DevicePropertyAccessor *get, DevicePropertyAccessor *set,
1085
                       DevicePropertyRelease *release,
1086
                       void *opaque, Error **errp)
1087
{
1088
    DeviceProperty *prop = g_malloc0(sizeof(*prop));
1089

    
1090
    prop->name = g_strdup(name);
1091
    prop->type = g_strdup(type);
1092

    
1093
    prop->get = get;
1094
    prop->set = set;
1095
    prop->release = release;
1096
    prop->opaque = opaque;
1097

    
1098
    QTAILQ_INSERT_TAIL(&dev->properties, prop, node);
1099
}
1100

    
1101
static DeviceProperty *qdev_property_find(DeviceState *dev, const char *name)
1102
{
1103
    DeviceProperty *prop;
1104

    
1105
    QTAILQ_FOREACH(prop, &dev->properties, node) {
1106
        if (strcmp(prop->name, name) == 0) {
1107
            return prop;
1108
        }
1109
    }
1110

    
1111
    return NULL;
1112
}
1113

    
1114
void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
1115
                       Error **errp)
1116
{
1117
    DeviceProperty *prop = qdev_property_find(dev, name);
1118

    
1119
    if (prop == NULL) {
1120
        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1121
        return;
1122
    }
1123

    
1124
    if (!prop->get) {
1125
        error_set(errp, QERR_PERMISSION_DENIED);
1126
    } else {
1127
        prop->get(dev, v, prop->opaque, name, errp);
1128
    }
1129
}
1130

    
1131
void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
1132
                       Error **errp)
1133
{
1134
    DeviceProperty *prop = qdev_property_find(dev, name);
1135

    
1136
    if (prop == NULL) {
1137
        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1138
        return;
1139
    }
1140

    
1141
    if (!prop->set) {
1142
        error_set(errp, QERR_PERMISSION_DENIED);
1143
    } else {
1144
        prop->set(dev, v, prop->opaque, name, errp);
1145
    }
1146
}
1147

    
1148
const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **errp)
1149
{
1150
    DeviceProperty *prop = qdev_property_find(dev, name);
1151

    
1152
    if (prop == NULL) {
1153
        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1154
        return NULL;
1155
    }
1156

    
1157
    return prop->type;
1158
}
1159

    
1160
/**
1161
 * Legacy property handling
1162
 */
1163

    
1164
static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1165
                                     const char *name, Error **errp)
1166
{
1167
    Property *prop = opaque;
1168

    
1169
    char buffer[1024];
1170
    char *ptr = buffer;
1171

    
1172
    prop->info->print(dev, prop, buffer, sizeof(buffer));
1173
    visit_type_str(v, &ptr, name, errp);
1174
}
1175

    
1176
static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1177
                                     const char *name, Error **errp)
1178
{
1179
    Property *prop = opaque;
1180
    Error *local_err = NULL;
1181
    char *ptr = NULL;
1182
    int ret;
1183

    
1184
    if (dev->state != DEV_STATE_CREATED) {
1185
        error_set(errp, QERR_PERMISSION_DENIED);
1186
        return;
1187
    }
1188

    
1189
    visit_type_str(v, &ptr, name, &local_err);
1190
    if (local_err) {
1191
        error_propagate(errp, local_err);
1192
        return;
1193
    }
1194

    
1195
    ret = prop->info->parse(dev, prop, ptr);
1196
    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
1197
    g_free(ptr);
1198
}
1199

    
1200
/**
1201
 * @qdev_add_legacy_property - adds a legacy property
1202
 *
1203
 * Do not use this is new code!  Properties added through this interface will
1204
 * be given names and types in the "legacy" namespace.
1205
 *
1206
 * Legacy properties are always processed as strings.  The format of the string
1207
 * depends on the property type.
1208
 */
1209
void qdev_property_add_legacy(DeviceState *dev, Property *prop,
1210
                              Error **errp)
1211
{
1212
    gchar *name, *type;
1213

    
1214
    name = g_strdup_printf("legacy-%s", prop->name);
1215
    type = g_strdup_printf("legacy<%s>",
1216
                           prop->info->legacy_name ?: prop->info->name);
1217

    
1218
    qdev_property_add(dev, name, type,
1219
                      prop->info->print ? qdev_get_legacy_property : NULL,
1220
                      prop->info->parse ? qdev_set_legacy_property : NULL,
1221
                      NULL,
1222
                      prop, errp);
1223

    
1224
    g_free(type);
1225
    g_free(name);
1226
}
1227

    
1228
/**
1229
 * @qdev_property_add_static - add a @Property to a device.
1230
 *
1231
 * Static properties access data in a struct.  The actual type of the
1232
 * property and the field depends on the property type.
1233
 */
1234
void qdev_property_add_static(DeviceState *dev, Property *prop,
1235
                              Error **errp)
1236
{
1237
    qdev_property_add(dev, prop->name, prop->info->name,
1238
                      prop->info->get, prop->info->set,
1239
                      NULL,
1240
                      prop, errp);
1241
}
1242

    
1243
DeviceState *qdev_get_root(void)
1244
{
1245
    static DeviceState *qdev_root;
1246

    
1247
    if (!qdev_root) {
1248
        qdev_root = qdev_create(NULL, "container");
1249
        qdev_init_nofail(qdev_root);
1250
    }
1251

    
1252
    return qdev_root;
1253
}
1254

    
1255
static void qdev_get_child_property(DeviceState *dev, Visitor *v, void *opaque,
1256
                                    const char *name, Error **errp)
1257
{
1258
    DeviceState *child = opaque;
1259
    gchar *path;
1260

    
1261
    path = qdev_get_canonical_path(child);
1262
    visit_type_str(v, &path, name, errp);
1263
    g_free(path);
1264
}
1265

    
1266
static void qdev_release_child_property(DeviceState *dev, const char *name,
1267
                                        void *opaque)
1268
{
1269
    DeviceState *child = opaque;
1270

    
1271
    qdev_unref(child);
1272
}
1273

    
1274
void qdev_property_add_child(DeviceState *dev, const char *name,
1275
                             DeviceState *child, Error **errp)
1276
{
1277
    gchar *type;
1278

    
1279
    type = g_strdup_printf("child<%s>", child->info->name);
1280

    
1281
    qdev_property_add(dev, name, type, qdev_get_child_property,
1282
                      NULL, qdev_release_child_property,
1283
                      child, errp);
1284

    
1285
    qdev_ref(child);
1286
    g_assert(child->parent == NULL);
1287
    child->parent = dev;
1288

    
1289
    g_free(type);
1290
}
1291

    
1292
static void qdev_get_link_property(DeviceState *dev, Visitor *v, void *opaque,
1293
                                   const char *name, Error **errp)
1294
{
1295
    DeviceState **child = opaque;
1296
    gchar *path;
1297

    
1298
    if (*child) {
1299
        path = qdev_get_canonical_path(*child);
1300
        visit_type_str(v, &path, name, errp);
1301
        g_free(path);
1302
    } else {
1303
        path = (gchar *)"";
1304
        visit_type_str(v, &path, name, errp);
1305
    }
1306
}
1307

    
1308
static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque,
1309
                                   const char *name, Error **errp)
1310
{
1311
    DeviceState **child = opaque;
1312
    bool ambiguous = false;
1313
    const char *type;
1314
    char *path;
1315

    
1316
    type = qdev_property_get_type(dev, name, NULL);
1317

    
1318
    visit_type_str(v, &path, name, errp);
1319

    
1320
    if (*child) {
1321
        qdev_unref(*child);
1322
    }
1323

    
1324
    if (strcmp(path, "") != 0) {
1325
        DeviceState *target;
1326

    
1327
        target = qdev_resolve_path(path, &ambiguous);
1328
        if (target) {
1329
            gchar *target_type;
1330

    
1331
            target_type = g_strdup_printf("link<%s>", target->info->name);
1332
            if (strcmp(target_type, type) == 0) {
1333
                *child = target;
1334
                qdev_ref(target);
1335
            } else {
1336
                error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
1337
            }
1338

    
1339
            g_free(target_type);
1340
        } else {
1341
            error_set(errp, QERR_DEVICE_NOT_FOUND, path);
1342
        }
1343
    } else {
1344
        *child = NULL;
1345
    }
1346

    
1347
    g_free(path);
1348
}
1349

    
1350
void qdev_property_add_link(DeviceState *dev, const char *name,
1351
                            const char *type, DeviceState **child,
1352
                            Error **errp)
1353
{
1354
    gchar *full_type;
1355

    
1356
    full_type = g_strdup_printf("link<%s>", type);
1357

    
1358
    qdev_property_add(dev, name, full_type,
1359
                      qdev_get_link_property,
1360
                      qdev_set_link_property,
1361
                      NULL, child, errp);
1362

    
1363
    g_free(full_type);
1364
}
1365

    
1366
gchar *qdev_get_canonical_path(DeviceState *dev)
1367
{
1368
    DeviceState *root = qdev_get_root();
1369
    char *newpath = NULL, *path = NULL;
1370

    
1371
    while (dev != root) {
1372
        DeviceProperty *prop = NULL;
1373

    
1374
        g_assert(dev->parent != NULL);
1375

    
1376
        QTAILQ_FOREACH(prop, &dev->parent->properties, node) {
1377
            if (!strstart(prop->type, "child<", NULL)) {
1378
                continue;
1379
            }
1380

    
1381
            if (prop->opaque == dev) {
1382
                if (path) {
1383
                    newpath = g_strdup_printf("%s/%s", prop->name, path);
1384
                    g_free(path);
1385
                    path = newpath;
1386
                } else {
1387
                    path = g_strdup(prop->name);
1388
                }
1389
                break;
1390
            }
1391
        }
1392

    
1393
        g_assert(prop != NULL);
1394

    
1395
        dev = dev->parent;
1396
    }
1397

    
1398
    newpath = g_strdup_printf("/%s", path);
1399
    g_free(path);
1400

    
1401
    return newpath;
1402
}
1403

    
1404
static DeviceState *qdev_resolve_abs_path(DeviceState *parent,
1405
                                          gchar **parts,
1406
                                          int index)
1407
{
1408
    DeviceProperty *prop;
1409
    DeviceState *child;
1410

    
1411
    if (parts[index] == NULL) {
1412
        return parent;
1413
    }
1414

    
1415
    if (strcmp(parts[index], "") == 0) {
1416
        return qdev_resolve_abs_path(parent, parts, index + 1);
1417
    }
1418

    
1419
    prop = qdev_property_find(parent, parts[index]);
1420
    if (prop == NULL) {
1421
        return NULL;
1422
    }
1423

    
1424
    child = NULL;
1425
    if (strstart(prop->type, "link<", NULL)) {
1426
        DeviceState **pchild = prop->opaque;
1427
        if (*pchild) {
1428
            child = *pchild;
1429
        }
1430
    } else if (strstart(prop->type, "child<", NULL)) {
1431
        child = prop->opaque;
1432
    }
1433

    
1434
    if (!child) {
1435
        return NULL;
1436
    }
1437

    
1438
    return qdev_resolve_abs_path(child, parts, index + 1);
1439
}
1440

    
1441
static DeviceState *qdev_resolve_partial_path(DeviceState *parent,
1442
                                              gchar **parts,
1443
                                              bool *ambiguous)
1444
{
1445
    DeviceState *dev;
1446
    DeviceProperty *prop;
1447

    
1448
    dev = qdev_resolve_abs_path(parent, parts, 0);
1449

    
1450
    QTAILQ_FOREACH(prop, &parent->properties, node) {
1451
        DeviceState *found;
1452

    
1453
        if (!strstart(prop->type, "child<", NULL)) {
1454
            continue;
1455
        }
1456

    
1457
        found = qdev_resolve_partial_path(prop->opaque, parts, ambiguous);
1458
        if (found) {
1459
            if (dev) {
1460
                if (ambiguous) {
1461
                    *ambiguous = true;
1462
                }
1463
                return NULL;
1464
            }
1465
            dev = found;
1466
        }
1467

    
1468
        if (ambiguous && *ambiguous) {
1469
            return NULL;
1470
        }
1471
    }
1472

    
1473
    return dev;
1474
}
1475

    
1476
DeviceState *qdev_resolve_path(const char *path, bool *ambiguous)
1477
{
1478
    bool partial_path = true;
1479
    DeviceState *dev;
1480
    gchar **parts;
1481

    
1482
    parts = g_strsplit(path, "/", 0);
1483
    if (parts == NULL || parts[0] == NULL) {
1484
        g_strfreev(parts);
1485
        return qdev_get_root();
1486
    }
1487

    
1488
    if (strcmp(parts[0], "") == 0) {
1489
        partial_path = false;
1490
    }
1491

    
1492
    if (partial_path) {
1493
        if (ambiguous) {
1494
            *ambiguous = false;
1495
        }
1496
        dev = qdev_resolve_partial_path(qdev_get_root(), parts, ambiguous);
1497
    } else {
1498
        dev = qdev_resolve_abs_path(qdev_get_root(), parts, 1);
1499
    }
1500

    
1501
    g_strfreev(parts);
1502

    
1503
    return dev;
1504
}
1505

    
1506
typedef struct StringProperty
1507
{
1508
    char *(*get)(DeviceState *, Error **);
1509
    void (*set)(DeviceState *, const char *, Error **);
1510
} StringProperty;
1511

    
1512
static void qdev_property_get_str(DeviceState *dev, Visitor *v, void *opaque,
1513
                                  const char *name, Error **errp)
1514
{
1515
    StringProperty *prop = opaque;
1516
    char *value;
1517

    
1518
    value = prop->get(dev, errp);
1519
    if (value) {
1520
        visit_type_str(v, &value, name, errp);
1521
        g_free(value);
1522
    }
1523
}
1524

    
1525
static void qdev_property_set_str(DeviceState *dev, Visitor *v, void *opaque,
1526
                                  const char *name, Error **errp)
1527
{
1528
    StringProperty *prop = opaque;
1529
    char *value;
1530
    Error *local_err = NULL;
1531

    
1532
    visit_type_str(v, &value, name, &local_err);
1533
    if (local_err) {
1534
        error_propagate(errp, local_err);
1535
        return;
1536
    }
1537

    
1538
    prop->set(dev, value, errp);
1539
    g_free(value);
1540
}
1541

    
1542
static void qdev_property_release_str(DeviceState *dev, const char *name,
1543
                                      void *opaque)
1544
{
1545
    StringProperty *prop = opaque;
1546
    g_free(prop);
1547
}
1548

    
1549
void qdev_property_add_str(DeviceState *dev, const char *name,
1550
                           char *(*get)(DeviceState *, Error **),
1551
                           void (*set)(DeviceState *, const char *, Error **),
1552
                           Error **errp)
1553
{
1554
    StringProperty *prop = g_malloc0(sizeof(*prop));
1555

    
1556
    prop->get = get;
1557
    prop->set = set;
1558

    
1559
    qdev_property_add(dev, name, "string",
1560
                      get ? qdev_property_get_str : NULL,
1561
                      set ? qdev_property_set_str : NULL,
1562
                      qdev_property_release_str,
1563
                      prop, errp);
1564
}
1565

    
1566
void qdev_machine_init(void)
1567
{
1568
    qdev_get_peripheral_anon();
1569
    qdev_get_peripheral();
1570
}