Statistics
| Branch: | Revision:

root / hw / qdev.c @ cafe5bdb

History | View | Annotate | Download (38.5 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 DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
84
{
85
    DeviceState *dev;
86
    Property *prop;
87

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

    
105
    for (prop = dev->info->props; prop && prop->name; prop++) {
106
        qdev_property_add_legacy(dev, prop, NULL);
107
    }
108

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

    
113
    qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL);
114

    
115
    return dev;
116
}
117

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

    
125
    dev = qdev_try_create(bus, name);
126
    if (!dev) {
127
        if (bus) {
128
            hw_error("Unknown device '%s' for bus '%s'\n", name,
129
                     bus->info->name);
130
        } else {
131
            hw_error("Unknown device '%s' for default sysbus\n", name);
132
        }
133
    }
134

    
135
    return dev;
136
}
137

    
138
DeviceState *qdev_try_create(BusState *bus, const char *name)
139
{
140
    DeviceInfo *info;
141

    
142
    if (!bus) {
143
        bus = sysbus_get_default();
144
    }
145

    
146
    info = qdev_find_info(bus->info, name);
147
    if (!info) {
148
        return NULL;
149
    }
150

    
151
    return qdev_create_from_info(bus, info);
152
}
153

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

    
170
static int set_property(const char *name, const char *value, void *opaque)
171
{
172
    DeviceState *dev = opaque;
173

    
174
    if (strcmp(name, "driver") == 0)
175
        return 0;
176
    if (strcmp(name, "bus") == 0)
177
        return 0;
178

    
179
    if (qdev_prop_parse(dev, name, value) == -1) {
180
        return -1;
181
    }
182
    return 0;
183
}
184

    
185
int qdev_device_help(QemuOpts *opts)
186
{
187
    const char *driver;
188
    DeviceInfo *info;
189
    Property *prop;
190

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

    
202
    if (!driver || !qemu_opt_get(opts, "?")) {
203
        return 0;
204
    }
205

    
206
    info = qdev_find_info(NULL, driver);
207
    if (!info) {
208
        return 0;
209
    }
210

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

    
234
static DeviceState *qdev_get_peripheral(void)
235
{
236
    static DeviceState *dev;
237

    
238
    if (dev == NULL) {
239
        dev = qdev_create(NULL, "container");
240
        qdev_property_add_child(qdev_get_root(), "peripheral", dev, NULL);
241
        qdev_init_nofail(dev);
242
    }
243

    
244
    return dev;
245
}
246

    
247
static DeviceState *qdev_get_peripheral_anon(void)
248
{
249
    static DeviceState *dev;
250

    
251
    if (dev == NULL) {
252
        dev = qdev_create(NULL, "container");
253
        qdev_property_add_child(qdev_get_root(), "peripheral-anon", dev, NULL);
254
        qdev_init_nofail(dev);
255
    }
256

    
257
    return dev;
258
}
259

    
260
DeviceState *qdev_device_add(QemuOpts *opts)
261
{
262
    const char *driver, *path, *id;
263
    DeviceInfo *info;
264
    DeviceState *qdev;
265
    BusState *bus;
266

    
267
    driver = qemu_opt_get(opts, "driver");
268
    if (!driver) {
269
        qerror_report(QERR_MISSING_PARAMETER, "driver");
270
        return NULL;
271
    }
272

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

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

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

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

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

    
358
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
359
                                 int required_for_version)
360
{
361
    assert(dev->state == DEV_STATE_CREATED);
362
    dev->instance_id_alias = alias_id;
363
    dev->alias_required_for_version = required_for_version;
364
}
365

    
366
int qdev_unplug(DeviceState *dev)
367
{
368
    if (!dev->parent_bus->allow_hotplug) {
369
        qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
370
        return -1;
371
    }
372
    assert(dev->info->unplug != NULL);
373

    
374
    if (dev->ref != 0) {
375
        qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
376
        return -1;
377
    }
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
/* Unlink device from bus and free the structure.  */
464
void qdev_free(DeviceState *dev)
465
{
466
    BusState *bus;
467
    Property *prop;
468

    
469
    qdev_property_del_all(dev);
470

    
471
    if (dev->state == DEV_STATE_INITIALIZED) {
472
        while (dev->num_child_bus) {
473
            bus = QLIST_FIRST(&dev->child_bus);
474
            qbus_free(bus);
475
        }
476
        if (dev->info->vmsd)
477
            vmstate_unregister(dev, dev->info->vmsd, dev);
478
        if (dev->info->exit)
479
            dev->info->exit(dev);
480
        if (dev->opts)
481
            qemu_opts_del(dev->opts);
482
    }
483
    QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
484
    for (prop = dev->info->props; prop && prop->name; prop++) {
485
        if (prop->info->free) {
486
            prop->info->free(dev, prop);
487
        }
488
    }
489
    g_free(dev);
490
}
491

    
492
void qdev_machine_creation_done(void)
493
{
494
    /*
495
     * ok, initial machine setup is done, starting from now we can
496
     * only create hotpluggable devices
497
     */
498
    qdev_hotplug = 1;
499
}
500

    
501
bool qdev_machine_modified(void)
502
{
503
    return qdev_hot_added || qdev_hot_removed;
504
}
505

    
506
/* Get a character (serial) device interface.  */
507
CharDriverState *qdev_init_chardev(DeviceState *dev)
508
{
509
    static int next_serial;
510

    
511
    /* FIXME: This function needs to go away: use chardev properties!  */
512
    return serial_hds[next_serial++];
513
}
514

    
515
BusState *qdev_get_parent_bus(DeviceState *dev)
516
{
517
    return dev->parent_bus;
518
}
519

    
520
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
521
{
522
    assert(dev->num_gpio_in == 0);
523
    dev->num_gpio_in = n;
524
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
525
}
526

    
527
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
528
{
529
    assert(dev->num_gpio_out == 0);
530
    dev->num_gpio_out = n;
531
    dev->gpio_out = pins;
532
}
533

    
534
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
535
{
536
    assert(n >= 0 && n < dev->num_gpio_in);
537
    return dev->gpio_in[n];
538
}
539

    
540
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
541
{
542
    assert(n >= 0 && n < dev->num_gpio_out);
543
    dev->gpio_out[n] = pin;
544
}
545

    
546
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
547
{
548
    qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
549
    if (nd->vlan)
550
        qdev_prop_set_vlan(dev, "vlan", nd->vlan);
551
    if (nd->netdev)
552
        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
553
    if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
554
        qdev_prop_exists(dev, "vectors")) {
555
        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
556
    }
557
    nd->instantiated = 1;
558
}
559

    
560
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
561
{
562
    BusState *bus;
563

    
564
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
565
        if (strcmp(name, bus->name) == 0) {
566
            return bus;
567
        }
568
    }
569
    return NULL;
570
}
571

    
572
int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
573
                       qbus_walkerfn *busfn, void *opaque)
574
{
575
    DeviceState *dev;
576
    int err;
577

    
578
    if (busfn) {
579
        err = busfn(bus, opaque);
580
        if (err) {
581
            return err;
582
        }
583
    }
584

    
585
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
586
        err = qdev_walk_children(dev, devfn, busfn, opaque);
587
        if (err < 0) {
588
            return err;
589
        }
590
    }
591

    
592
    return 0;
593
}
594

    
595
int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
596
                       qbus_walkerfn *busfn, void *opaque)
597
{
598
    BusState *bus;
599
    int err;
600

    
601
    if (devfn) {
602
        err = devfn(dev, opaque);
603
        if (err) {
604
            return err;
605
        }
606
    }
607

    
608
    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
609
        err = qbus_walk_children(bus, devfn, busfn, opaque);
610
        if (err < 0) {
611
            return err;
612
        }
613
    }
614

    
615
    return 0;
616
}
617

    
618
static BusState *qbus_find_recursive(BusState *bus, const char *name,
619
                                     const BusInfo *info)
620
{
621
    DeviceState *dev;
622
    BusState *child, *ret;
623
    int match = 1;
624

    
625
    if (name && (strcmp(bus->name, name) != 0)) {
626
        match = 0;
627
    }
628
    if (info && (bus->info != info)) {
629
        match = 0;
630
    }
631
    if (match) {
632
        return bus;
633
    }
634

    
635
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
636
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
637
            ret = qbus_find_recursive(child, name, info);
638
            if (ret) {
639
                return ret;
640
            }
641
        }
642
    }
643
    return NULL;
644
}
645

    
646
DeviceState *qdev_find_recursive(BusState *bus, const char *id)
647
{
648
    DeviceState *dev, *ret;
649
    BusState *child;
650

    
651
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
652
        if (dev->id && strcmp(dev->id, id) == 0)
653
            return dev;
654
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
655
            ret = qdev_find_recursive(child, id);
656
            if (ret) {
657
                return ret;
658
            }
659
        }
660
    }
661
    return NULL;
662
}
663

    
664
static void qbus_list_bus(DeviceState *dev)
665
{
666
    BusState *child;
667
    const char *sep = " ";
668

    
669
    error_printf("child busses at \"%s\":",
670
                 dev->id ? dev->id : dev->info->name);
671
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
672
        error_printf("%s\"%s\"", sep, child->name);
673
        sep = ", ";
674
    }
675
    error_printf("\n");
676
}
677

    
678
static void qbus_list_dev(BusState *bus)
679
{
680
    DeviceState *dev;
681
    const char *sep = " ";
682

    
683
    error_printf("devices at \"%s\":", bus->name);
684
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
685
        error_printf("%s\"%s\"", sep, dev->info->name);
686
        if (dev->id)
687
            error_printf("/\"%s\"", dev->id);
688
        sep = ", ";
689
    }
690
    error_printf("\n");
691
}
692

    
693
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
694
{
695
    BusState *child;
696

    
697
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
698
        if (strcmp(child->name, elem) == 0) {
699
            return child;
700
        }
701
    }
702
    return NULL;
703
}
704

    
705
static DeviceState *qbus_find_dev(BusState *bus, char *elem)
706
{
707
    DeviceState *dev;
708

    
709
    /*
710
     * try to match in order:
711
     *   (1) instance id, if present
712
     *   (2) driver name
713
     *   (3) driver alias, if present
714
     */
715
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
716
        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
717
            return dev;
718
        }
719
    }
720
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
721
        if (strcmp(dev->info->name, elem) == 0) {
722
            return dev;
723
        }
724
    }
725
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
726
        if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
727
            return dev;
728
        }
729
    }
730
    return NULL;
731
}
732

    
733
static BusState *qbus_find(const char *path)
734
{
735
    DeviceState *dev;
736
    BusState *bus;
737
    char elem[128];
738
    int pos, len;
739

    
740
    /* find start element */
741
    if (path[0] == '/') {
742
        bus = main_system_bus;
743
        pos = 0;
744
    } else {
745
        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
746
            assert(!path[0]);
747
            elem[0] = len = 0;
748
        }
749
        bus = qbus_find_recursive(main_system_bus, elem, NULL);
750
        if (!bus) {
751
            qerror_report(QERR_BUS_NOT_FOUND, elem);
752
            return NULL;
753
        }
754
        pos = len;
755
    }
756

    
757
    for (;;) {
758
        assert(path[pos] == '/' || !path[pos]);
759
        while (path[pos] == '/') {
760
            pos++;
761
        }
762
        if (path[pos] == '\0') {
763
            return bus;
764
        }
765

    
766
        /* find device */
767
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
768
            assert(0);
769
            elem[0] = len = 0;
770
        }
771
        pos += len;
772
        dev = qbus_find_dev(bus, elem);
773
        if (!dev) {
774
            qerror_report(QERR_DEVICE_NOT_FOUND, elem);
775
            if (!monitor_cur_is_qmp()) {
776
                qbus_list_dev(bus);
777
            }
778
            return NULL;
779
        }
780

    
781
        assert(path[pos] == '/' || !path[pos]);
782
        while (path[pos] == '/') {
783
            pos++;
784
        }
785
        if (path[pos] == '\0') {
786
            /* last specified element is a device.  If it has exactly
787
             * one child bus accept it nevertheless */
788
            switch (dev->num_child_bus) {
789
            case 0:
790
                qerror_report(QERR_DEVICE_NO_BUS, elem);
791
                return NULL;
792
            case 1:
793
                return QLIST_FIRST(&dev->child_bus);
794
            default:
795
                qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
796
                if (!monitor_cur_is_qmp()) {
797
                    qbus_list_bus(dev);
798
                }
799
                return NULL;
800
            }
801
        }
802

    
803
        /* find bus */
804
        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
805
            assert(0);
806
            elem[0] = len = 0;
807
        }
808
        pos += len;
809
        bus = qbus_find_bus(dev, elem);
810
        if (!bus) {
811
            qerror_report(QERR_BUS_NOT_FOUND, elem);
812
            if (!monitor_cur_is_qmp()) {
813
                qbus_list_bus(dev);
814
            }
815
            return NULL;
816
        }
817
    }
818
}
819

    
820
void qbus_create_inplace(BusState *bus, BusInfo *info,
821
                         DeviceState *parent, const char *name)
822
{
823
    char *buf;
824
    int i,len;
825

    
826
    bus->info = info;
827
    bus->parent = parent;
828

    
829
    if (name) {
830
        /* use supplied name */
831
        bus->name = g_strdup(name);
832
    } else if (parent && parent->id) {
833
        /* parent device has id -> use it for bus name */
834
        len = strlen(parent->id) + 16;
835
        buf = g_malloc(len);
836
        snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
837
        bus->name = buf;
838
    } else {
839
        /* no id -> use lowercase bus type for bus name */
840
        len = strlen(info->name) + 16;
841
        buf = g_malloc(len);
842
        len = snprintf(buf, len, "%s.%d", info->name,
843
                       parent ? parent->num_child_bus : 0);
844
        for (i = 0; i < len; i++)
845
            buf[i] = qemu_tolower(buf[i]);
846
        bus->name = buf;
847
    }
848

    
849
    QTAILQ_INIT(&bus->children);
850
    if (parent) {
851
        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
852
        parent->num_child_bus++;
853
    } else if (bus != main_system_bus) {
854
        /* TODO: once all bus devices are qdevified,
855
           only reset handler for main_system_bus should be registered here. */
856
        qemu_register_reset(qbus_reset_all_fn, bus);
857
    }
858
}
859

    
860
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
861
{
862
    BusState *bus;
863

    
864
    bus = g_malloc0(info->size);
865
    bus->qdev_allocated = 1;
866
    qbus_create_inplace(bus, info, parent, name);
867
    return bus;
868
}
869

    
870
static void main_system_bus_create(void)
871
{
872
    /* assign main_system_bus before qbus_create_inplace()
873
     * in order to make "if (bus != main_system_bus)" work */
874
    main_system_bus = g_malloc0(system_bus_info.size);
875
    main_system_bus->qdev_allocated = 1;
876
    qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
877
                        "main-system-bus");
878
}
879

    
880
void qbus_free(BusState *bus)
881
{
882
    DeviceState *dev;
883

    
884
    while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
885
        qdev_free(dev);
886
    }
887
    if (bus->parent) {
888
        QLIST_REMOVE(bus, sibling);
889
        bus->parent->num_child_bus--;
890
    } else {
891
        assert(bus != main_system_bus); /* main_system_bus is never freed */
892
        qemu_unregister_reset(qbus_reset_all_fn, bus);
893
    }
894
    g_free((void*)bus->name);
895
    if (bus->qdev_allocated) {
896
        g_free(bus);
897
    }
898
}
899

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

    
903
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
904
                             const char *prefix, int indent)
905
{
906
    char buf[64];
907

    
908
    if (!props)
909
        return;
910
    while (props->name) {
911
        /*
912
         * TODO Properties without a print method are just for dirty
913
         * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
914
         * marked for removal.  The test props->info->print should be
915
         * removed along with it.
916
         */
917
        if (props->info->print) {
918
            props->info->print(dev, props, buf, sizeof(buf));
919
            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
920
        }
921
        props++;
922
    }
923
}
924

    
925
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
926
{
927
    BusState *child;
928
    qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
929
                dev->id ? dev->id : "");
930
    indent += 2;
931
    if (dev->num_gpio_in) {
932
        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
933
    }
934
    if (dev->num_gpio_out) {
935
        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
936
    }
937
    qdev_print_props(mon, dev, dev->info->props, "dev", indent);
938
    qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
939
    if (dev->parent_bus->info->print_dev)
940
        dev->parent_bus->info->print_dev(mon, dev, indent);
941
    QLIST_FOREACH(child, &dev->child_bus, sibling) {
942
        qbus_print(mon, child, indent);
943
    }
944
}
945

    
946
static void qbus_print(Monitor *mon, BusState *bus, int indent)
947
{
948
    struct DeviceState *dev;
949

    
950
    qdev_printf("bus: %s\n", bus->name);
951
    indent += 2;
952
    qdev_printf("type %s\n", bus->info->name);
953
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
954
        qdev_print(mon, dev, indent);
955
    }
956
}
957
#undef qdev_printf
958

    
959
void do_info_qtree(Monitor *mon)
960
{
961
    if (main_system_bus)
962
        qbus_print(mon, main_system_bus, 0);
963
}
964

    
965
void do_info_qdm(Monitor *mon)
966
{
967
    DeviceInfo *info;
968

    
969
    for (info = device_info_list; info != NULL; info = info->next) {
970
        qdev_print_devinfo(info);
971
    }
972
}
973

    
974
int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
975
{
976
    QemuOpts *opts;
977

    
978
    opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
979
    if (!opts) {
980
        return -1;
981
    }
982
    if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
983
        qemu_opts_del(opts);
984
        return 0;
985
    }
986
    if (!qdev_device_add(opts)) {
987
        qemu_opts_del(opts);
988
        return -1;
989
    }
990
    return 0;
991
}
992

    
993
int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
994
{
995
    const char *id = qdict_get_str(qdict, "id");
996
    DeviceState *dev;
997

    
998
    dev = qdev_find_recursive(main_system_bus, id);
999
    if (NULL == dev) {
1000
        qerror_report(QERR_DEVICE_NOT_FOUND, id);
1001
        return -1;
1002
    }
1003
    return qdev_unplug(dev);
1004
}
1005

    
1006
static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
1007
{
1008
    int l = 0;
1009

    
1010
    if (dev && dev->parent_bus) {
1011
        char *d;
1012
        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
1013
        if (dev->parent_bus->info->get_fw_dev_path) {
1014
            d = dev->parent_bus->info->get_fw_dev_path(dev);
1015
            l += snprintf(p + l, size - l, "%s", d);
1016
            g_free(d);
1017
        } else {
1018
            l += snprintf(p + l, size - l, "%s", dev->info->name);
1019
        }
1020
    }
1021
    l += snprintf(p + l , size - l, "/");
1022

    
1023
    return l;
1024
}
1025

    
1026
char* qdev_get_fw_dev_path(DeviceState *dev)
1027
{
1028
    char path[128];
1029
    int l;
1030

    
1031
    l = qdev_get_fw_dev_path_helper(dev, path, 128);
1032

    
1033
    path[l-1] = '\0';
1034

    
1035
    return strdup(path);
1036
}
1037

    
1038
char *qdev_get_type(DeviceState *dev, Error **errp)
1039
{
1040
    return g_strdup(dev->info->name);
1041
}
1042

    
1043
void qdev_ref(DeviceState *dev)
1044
{
1045
    dev->ref++;
1046
}
1047

    
1048
void qdev_unref(DeviceState *dev)
1049
{
1050
    g_assert(dev->ref > 0);
1051
    dev->ref--;
1052
}
1053

    
1054
void qdev_property_add(DeviceState *dev, const char *name, const char *type,
1055
                       DevicePropertyAccessor *get, DevicePropertyAccessor *set,
1056
                       DevicePropertyRelease *release,
1057
                       void *opaque, Error **errp)
1058
{
1059
    DeviceProperty *prop = g_malloc0(sizeof(*prop));
1060

    
1061
    prop->name = g_strdup(name);
1062
    prop->type = g_strdup(type);
1063

    
1064
    prop->get = get;
1065
    prop->set = set;
1066
    prop->release = release;
1067
    prop->opaque = opaque;
1068

    
1069
    QTAILQ_INSERT_TAIL(&dev->properties, prop, node);
1070
}
1071

    
1072
static DeviceProperty *qdev_property_find(DeviceState *dev, const char *name)
1073
{
1074
    DeviceProperty *prop;
1075

    
1076
    QTAILQ_FOREACH(prop, &dev->properties, node) {
1077
        if (strcmp(prop->name, name) == 0) {
1078
            return prop;
1079
        }
1080
    }
1081

    
1082
    return NULL;
1083
}
1084

    
1085
void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
1086
                       Error **errp)
1087
{
1088
    DeviceProperty *prop = qdev_property_find(dev, name);
1089

    
1090
    if (prop == NULL) {
1091
        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1092
        return;
1093
    }
1094

    
1095
    if (!prop->get) {
1096
        error_set(errp, QERR_PERMISSION_DENIED);
1097
    } else {
1098
        prop->get(dev, v, prop->opaque, name, errp);
1099
    }
1100
}
1101

    
1102
void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
1103
                       Error **errp)
1104
{
1105
    DeviceProperty *prop = qdev_property_find(dev, name);
1106

    
1107
    if (prop == NULL) {
1108
        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1109
        return;
1110
    }
1111

    
1112
    if (!prop->set) {
1113
        error_set(errp, QERR_PERMISSION_DENIED);
1114
    } else {
1115
        prop->set(dev, v, prop->opaque, name, errp);
1116
    }
1117
}
1118

    
1119
const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **errp)
1120
{
1121
    DeviceProperty *prop = qdev_property_find(dev, name);
1122

    
1123
    if (prop == NULL) {
1124
        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1125
        return NULL;
1126
    }
1127

    
1128
    return prop->type;
1129
}
1130

    
1131
/**
1132
 * Legacy property handling
1133
 */
1134

    
1135
static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1136
                                     const char *name, Error **errp)
1137
{
1138
    Property *prop = opaque;
1139

    
1140
    char buffer[1024];
1141
    char *ptr = buffer;
1142

    
1143
    prop->info->print(dev, prop, buffer, sizeof(buffer));
1144
    visit_type_str(v, &ptr, name, errp);
1145
}
1146

    
1147
static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1148
                                     const char *name, Error **errp)
1149
{
1150
    Property *prop = opaque;
1151
    Error *local_err = NULL;
1152
    char *ptr = NULL;
1153
    int ret;
1154

    
1155
    if (dev->state != DEV_STATE_CREATED) {
1156
        error_set(errp, QERR_PERMISSION_DENIED);
1157
        return;
1158
    }
1159

    
1160
    visit_type_str(v, &ptr, name, &local_err);
1161
    if (local_err) {
1162
        error_propagate(errp, local_err);
1163
        return;
1164
    }
1165

    
1166
    ret = prop->info->parse(dev, prop, ptr);
1167
    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
1168
    g_free(ptr);
1169
}
1170

    
1171
/**
1172
 * @qdev_add_legacy_property - adds a legacy property
1173
 *
1174
 * Do not use this is new code!  Properties added through this interface will
1175
 * be given types in the "legacy<>" type namespace.
1176
 *
1177
 * Legacy properties are always processed as strings.  The format of the string
1178
 * depends on the property type.
1179
 */
1180
void qdev_property_add_legacy(DeviceState *dev, Property *prop,
1181
                              Error **errp)
1182
{
1183
    gchar *type;
1184

    
1185
    type = g_strdup_printf("legacy<%s>",
1186
                           prop->info->legacy_name ?: prop->info->name);
1187

    
1188
    qdev_property_add(dev, prop->name, type,
1189
                      prop->info->print ? qdev_get_legacy_property : NULL,
1190
                      prop->info->parse ? qdev_set_legacy_property : NULL,
1191
                      NULL,
1192
                      prop, errp);
1193

    
1194
    g_free(type);
1195
}
1196

    
1197
DeviceState *qdev_get_root(void)
1198
{
1199
    static DeviceState *qdev_root;
1200

    
1201
    if (!qdev_root) {
1202
        qdev_root = qdev_create(NULL, "container");
1203
        qdev_init_nofail(qdev_root);
1204
    }
1205

    
1206
    return qdev_root;
1207
}
1208

    
1209
static void qdev_get_child_property(DeviceState *dev, Visitor *v, void *opaque,
1210
                                    const char *name, Error **errp)
1211
{
1212
    DeviceState *child = opaque;
1213
    gchar *path;
1214

    
1215
    path = qdev_get_canonical_path(child);
1216
    visit_type_str(v, &path, name, errp);
1217
    g_free(path);
1218
}
1219

    
1220
void qdev_property_add_child(DeviceState *dev, const char *name,
1221
                             DeviceState *child, Error **errp)
1222
{
1223
    gchar *type;
1224

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

    
1227
    qdev_property_add(dev, name, type, qdev_get_child_property,
1228
                      NULL, NULL, child, errp);
1229

    
1230
    qdev_ref(child);
1231
    g_assert(child->parent == NULL);
1232
    child->parent = dev;
1233

    
1234
    g_free(type);
1235
}
1236

    
1237
static void qdev_get_link_property(DeviceState *dev, Visitor *v, void *opaque,
1238
                                   const char *name, Error **errp)
1239
{
1240
    DeviceState **child = opaque;
1241
    gchar *path;
1242

    
1243
    if (*child) {
1244
        path = qdev_get_canonical_path(*child);
1245
        visit_type_str(v, &path, name, errp);
1246
        g_free(path);
1247
    } else {
1248
        path = (gchar *)"";
1249
        visit_type_str(v, &path, name, errp);
1250
    }
1251
}
1252

    
1253
static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque,
1254
                                   const char *name, Error **errp)
1255
{
1256
    DeviceState **child = opaque;
1257
    bool ambiguous = false;
1258
    const char *type;
1259
    char *path;
1260

    
1261
    type = qdev_property_get_type(dev, name, NULL);
1262

    
1263
    visit_type_str(v, &path, name, errp);
1264

    
1265
    if (*child) {
1266
        qdev_unref(*child);
1267
    }
1268

    
1269
    if (strcmp(path, "") != 0) {
1270
        DeviceState *target;
1271

    
1272
        target = qdev_resolve_path(path, &ambiguous);
1273
        if (target) {
1274
            gchar *target_type;
1275

    
1276
            target_type = g_strdup_printf("link<%s>", target->info->name);
1277
            if (strcmp(target_type, type) == 0) {
1278
                *child = target;
1279
                qdev_ref(target);
1280
            } else {
1281
                error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
1282
            }
1283

    
1284
            g_free(target_type);
1285
        } else {
1286
            error_set(errp, QERR_DEVICE_NOT_FOUND, path);
1287
        }
1288
    } else {
1289
        *child = NULL;
1290
    }
1291

    
1292
    g_free(path);
1293
}
1294

    
1295
void qdev_property_add_link(DeviceState *dev, const char *name,
1296
                            const char *type, DeviceState **child,
1297
                            Error **errp)
1298
{
1299
    gchar *full_type;
1300

    
1301
    full_type = g_strdup_printf("link<%s>", type);
1302

    
1303
    qdev_property_add(dev, name, full_type,
1304
                      qdev_get_link_property,
1305
                      qdev_set_link_property,
1306
                      NULL, child, errp);
1307

    
1308
    g_free(full_type);
1309
}
1310

    
1311
gchar *qdev_get_canonical_path(DeviceState *dev)
1312
{
1313
    DeviceState *root = qdev_get_root();
1314
    char *newpath = NULL, *path = NULL;
1315

    
1316
    while (dev != root) {
1317
        DeviceProperty *prop = NULL;
1318

    
1319
        g_assert(dev->parent != NULL);
1320

    
1321
        QTAILQ_FOREACH(prop, &dev->parent->properties, node) {
1322
            if (!strstart(prop->type, "child<", NULL)) {
1323
                continue;
1324
            }
1325

    
1326
            if (prop->opaque == dev) {
1327
                if (path) {
1328
                    newpath = g_strdup_printf("%s/%s", prop->name, path);
1329
                    g_free(path);
1330
                    path = newpath;
1331
                } else {
1332
                    path = g_strdup(prop->name);
1333
                }
1334
                break;
1335
            }
1336
        }
1337

    
1338
        g_assert(prop != NULL);
1339

    
1340
        dev = dev->parent;
1341
    }
1342

    
1343
    newpath = g_strdup_printf("/%s", path);
1344
    g_free(path);
1345

    
1346
    return newpath;
1347
}
1348

    
1349
static DeviceState *qdev_resolve_abs_path(DeviceState *parent,
1350
                                          gchar **parts,
1351
                                          int index)
1352
{
1353
    DeviceProperty *prop;
1354
    DeviceState *child;
1355

    
1356
    if (parts[index] == NULL) {
1357
        return parent;
1358
    }
1359

    
1360
    if (strcmp(parts[index], "") == 0) {
1361
        return qdev_resolve_abs_path(parent, parts, index + 1);
1362
    }
1363

    
1364
    prop = qdev_property_find(parent, parts[index]);
1365
    if (prop == NULL) {
1366
        return NULL;
1367
    }
1368

    
1369
    child = NULL;
1370
    if (strstart(prop->type, "link<", NULL)) {
1371
        DeviceState **pchild = prop->opaque;
1372
        if (*pchild) {
1373
            child = *pchild;
1374
        }
1375
    } else if (strstart(prop->type, "child<", NULL)) {
1376
        child = prop->opaque;
1377
    }
1378

    
1379
    if (!child) {
1380
        return NULL;
1381
    }
1382

    
1383
    return qdev_resolve_abs_path(child, parts, index + 1);
1384
}
1385

    
1386
static DeviceState *qdev_resolve_partial_path(DeviceState *parent,
1387
                                              gchar **parts,
1388
                                              bool *ambiguous)
1389
{
1390
    DeviceState *dev;
1391
    DeviceProperty *prop;
1392

    
1393
    dev = qdev_resolve_abs_path(parent, parts, 0);
1394

    
1395
    QTAILQ_FOREACH(prop, &parent->properties, node) {
1396
        DeviceState *found;
1397

    
1398
        if (!strstart(prop->type, "child<", NULL)) {
1399
            continue;
1400
        }
1401

    
1402
        found = qdev_resolve_partial_path(prop->opaque, parts, ambiguous);
1403
        if (found) {
1404
            if (dev) {
1405
                if (ambiguous) {
1406
                    *ambiguous = true;
1407
                }
1408
                return NULL;
1409
            }
1410
            dev = found;
1411
        }
1412

    
1413
        if (ambiguous && *ambiguous) {
1414
            return NULL;
1415
        }
1416
    }
1417

    
1418
    return dev;
1419
}
1420

    
1421
DeviceState *qdev_resolve_path(const char *path, bool *ambiguous)
1422
{
1423
    bool partial_path = true;
1424
    DeviceState *dev;
1425
    gchar **parts;
1426

    
1427
    parts = g_strsplit(path, "/", 0);
1428
    if (parts == NULL || parts[0] == NULL) {
1429
        g_strfreev(parts);
1430
        return qdev_get_root();
1431
    }
1432

    
1433
    if (strcmp(parts[0], "") == 0) {
1434
        partial_path = false;
1435
    }
1436

    
1437
    if (partial_path) {
1438
        if (ambiguous) {
1439
            *ambiguous = false;
1440
        }
1441
        dev = qdev_resolve_partial_path(qdev_get_root(), parts, ambiguous);
1442
    } else {
1443
        dev = qdev_resolve_abs_path(qdev_get_root(), parts, 1);
1444
    }
1445

    
1446
    g_strfreev(parts);
1447

    
1448
    return dev;
1449
}
1450

    
1451
typedef struct StringProperty
1452
{
1453
    char *(*get)(DeviceState *, Error **);
1454
    void (*set)(DeviceState *, const char *, Error **);
1455
} StringProperty;
1456

    
1457
static void qdev_property_get_str(DeviceState *dev, Visitor *v, void *opaque,
1458
                                  const char *name, Error **errp)
1459
{
1460
    StringProperty *prop = opaque;
1461
    char *value;
1462

    
1463
    value = prop->get(dev, errp);
1464
    if (value) {
1465
        visit_type_str(v, &value, name, errp);
1466
        g_free(value);
1467
    }
1468
}
1469

    
1470
static void qdev_property_set_str(DeviceState *dev, Visitor *v, void *opaque,
1471
                                  const char *name, Error **errp)
1472
{
1473
    StringProperty *prop = opaque;
1474
    char *value;
1475
    Error *local_err = NULL;
1476

    
1477
    visit_type_str(v, &value, name, &local_err);
1478
    if (local_err) {
1479
        error_propagate(errp, local_err);
1480
        return;
1481
    }
1482

    
1483
    prop->set(dev, value, errp);
1484
    g_free(value);
1485
}
1486

    
1487
static void qdev_property_release_str(DeviceState *dev, const char *name,
1488
                                      void *opaque)
1489
{
1490
    StringProperty *prop = opaque;
1491
    g_free(prop);
1492
}
1493

    
1494
void qdev_property_add_str(DeviceState *dev, const char *name,
1495
                           char *(*get)(DeviceState *, Error **),
1496
                           void (*set)(DeviceState *, const char *, Error **),
1497
                           Error **errp)
1498
{
1499
    StringProperty *prop = g_malloc0(sizeof(*prop));
1500

    
1501
    prop->get = get;
1502
    prop->set = set;
1503

    
1504
    qdev_property_add(dev, name, "string",
1505
                      get ? qdev_property_get_str : NULL,
1506
                      set ? qdev_property_set_str : NULL,
1507
                      qdev_property_release_str,
1508
                      prop, errp);
1509
}