Statistics
| Branch: | Revision:

root / hw / core / qdev-properties.c @ 7d926864

History | View | Annotate | Download (29.5 kB)

1
#include "net/net.h"
2
#include "hw/qdev.h"
3
#include "qapi/qmp/qerror.h"
4
#include "sysemu/blockdev.h"
5
#include "hw/block/block.h"
6
#include "net/hub.h"
7
#include "qapi/visitor.h"
8
#include "sysemu/char.h"
9

    
10
void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
11
                                  Error **errp)
12
{
13
    if (dev->id) {
14
        error_setg(errp, "Attempt to set property '%s' on device '%s' "
15
                   "(type '%s') after it was realized", name, dev->id,
16
                   object_get_typename(OBJECT(dev)));
17
    } else {
18
        error_setg(errp, "Attempt to set property '%s' on anonymous device "
19
                   "(type '%s') after it was realized", name,
20
                   object_get_typename(OBJECT(dev)));
21
    }
22
}
23

    
24
void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
25
{
26
    void *ptr = dev;
27
    ptr += prop->offset;
28
    return ptr;
29
}
30

    
31
static void get_enum(Object *obj, Visitor *v, void *opaque,
32
                     const char *name, Error **errp)
33
{
34
    DeviceState *dev = DEVICE(obj);
35
    Property *prop = opaque;
36
    int *ptr = qdev_get_prop_ptr(dev, prop);
37

    
38
    visit_type_enum(v, ptr, prop->info->enum_table,
39
                    prop->info->name, prop->name, errp);
40
}
41

    
42
static void set_enum(Object *obj, Visitor *v, void *opaque,
43
                     const char *name, Error **errp)
44
{
45
    DeviceState *dev = DEVICE(obj);
46
    Property *prop = opaque;
47
    int *ptr = qdev_get_prop_ptr(dev, prop);
48

    
49
    if (dev->realized) {
50
        qdev_prop_set_after_realize(dev, name, errp);
51
        return;
52
    }
53

    
54
    visit_type_enum(v, ptr, prop->info->enum_table,
55
                    prop->info->name, prop->name, errp);
56
}
57

    
58
/* Bit */
59

    
60
static uint32_t qdev_get_prop_mask(Property *prop)
61
{
62
    assert(prop->info == &qdev_prop_bit);
63
    return 0x1 << prop->bitnr;
64
}
65

    
66
static void bit_prop_set(DeviceState *dev, Property *props, bool val)
67
{
68
    uint32_t *p = qdev_get_prop_ptr(dev, props);
69
    uint32_t mask = qdev_get_prop_mask(props);
70
    if (val) {
71
        *p |= mask;
72
    } else {
73
        *p &= ~mask;
74
    }
75
}
76

    
77
static int prop_print_bit(DeviceState *dev, Property *prop, char *dest,
78
                          size_t len)
79
{
80
    uint32_t *p = qdev_get_prop_ptr(dev, prop);
81
    return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
82
}
83

    
84
static void prop_get_bit(Object *obj, Visitor *v, void *opaque,
85
                    const char *name, Error **errp)
86
{
87
    DeviceState *dev = DEVICE(obj);
88
    Property *prop = opaque;
89
    uint32_t *p = qdev_get_prop_ptr(dev, prop);
90
    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
91

    
92
    visit_type_bool(v, &value, name, errp);
93
}
94

    
95
static void prop_set_bit(Object *obj, Visitor *v, void *opaque,
96
                    const char *name, Error **errp)
97
{
98
    DeviceState *dev = DEVICE(obj);
99
    Property *prop = opaque;
100
    Error *local_err = NULL;
101
    bool value;
102

    
103
    if (dev->realized) {
104
        qdev_prop_set_after_realize(dev, name, errp);
105
        return;
106
    }
107

    
108
    visit_type_bool(v, &value, name, &local_err);
109
    if (local_err) {
110
        error_propagate(errp, local_err);
111
        return;
112
    }
113
    bit_prop_set(dev, prop, value);
114
}
115

    
116
PropertyInfo qdev_prop_bit = {
117
    .name  = "boolean",
118
    .legacy_name  = "on/off",
119
    .print = prop_print_bit,
120
    .get   = prop_get_bit,
121
    .set   = prop_set_bit,
122
};
123

    
124
/* --- bool --- */
125

    
126
static void get_bool(Object *obj, Visitor *v, void *opaque,
127
                     const char *name, Error **errp)
128
{
129
    DeviceState *dev = DEVICE(obj);
130
    Property *prop = opaque;
131
    bool *ptr = qdev_get_prop_ptr(dev, prop);
132

    
133
    visit_type_bool(v, ptr, name, errp);
134
}
135

    
136
static void set_bool(Object *obj, Visitor *v, void *opaque,
137
                     const char *name, Error **errp)
138
{
139
    DeviceState *dev = DEVICE(obj);
140
    Property *prop = opaque;
141
    bool *ptr = qdev_get_prop_ptr(dev, prop);
142

    
143
    if (dev->realized) {
144
        qdev_prop_set_after_realize(dev, name, errp);
145
        return;
146
    }
147

    
148
    visit_type_bool(v, ptr, name, errp);
149
}
150

    
151
PropertyInfo qdev_prop_bool = {
152
    .name  = "boolean",
153
    .get   = get_bool,
154
    .set   = set_bool,
155
};
156

    
157
/* --- 8bit integer --- */
158

    
159
static void get_uint8(Object *obj, Visitor *v, void *opaque,
160
                      const char *name, Error **errp)
161
{
162
    DeviceState *dev = DEVICE(obj);
163
    Property *prop = opaque;
164
    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
165

    
166
    visit_type_uint8(v, ptr, name, errp);
167
}
168

    
169
static void set_uint8(Object *obj, Visitor *v, void *opaque,
170
                      const char *name, Error **errp)
171
{
172
    DeviceState *dev = DEVICE(obj);
173
    Property *prop = opaque;
174
    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
175

    
176
    if (dev->realized) {
177
        qdev_prop_set_after_realize(dev, name, errp);
178
        return;
179
    }
180

    
181
    visit_type_uint8(v, ptr, name, errp);
182
}
183

    
184
PropertyInfo qdev_prop_uint8 = {
185
    .name  = "uint8",
186
    .get   = get_uint8,
187
    .set   = set_uint8,
188
};
189

    
190
/* --- 8bit hex value --- */
191

    
192
static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
193
{
194
    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
195
    char *end;
196

    
197
    if (str[0] != '0' || str[1] != 'x') {
198
        return -EINVAL;
199
    }
200

    
201
    *ptr = strtoul(str, &end, 16);
202
    if ((*end != '\0') || (end == str)) {
203
        return -EINVAL;
204
    }
205

    
206
    return 0;
207
}
208

    
209
static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
210
{
211
    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
212
    return snprintf(dest, len, "0x%" PRIx8, *ptr);
213
}
214

    
215
PropertyInfo qdev_prop_hex8 = {
216
    .name  = "uint8",
217
    .legacy_name  = "hex8",
218
    .parse = parse_hex8,
219
    .print = print_hex8,
220
    .get   = get_uint8,
221
    .set   = set_uint8,
222
};
223

    
224
/* --- 16bit integer --- */
225

    
226
static void get_uint16(Object *obj, Visitor *v, void *opaque,
227
                       const char *name, Error **errp)
228
{
229
    DeviceState *dev = DEVICE(obj);
230
    Property *prop = opaque;
231
    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
232

    
233
    visit_type_uint16(v, ptr, name, errp);
234
}
235

    
236
static void set_uint16(Object *obj, Visitor *v, void *opaque,
237
                       const char *name, Error **errp)
238
{
239
    DeviceState *dev = DEVICE(obj);
240
    Property *prop = opaque;
241
    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
242

    
243
    if (dev->realized) {
244
        qdev_prop_set_after_realize(dev, name, errp);
245
        return;
246
    }
247

    
248
    visit_type_uint16(v, ptr, name, errp);
249
}
250

    
251
PropertyInfo qdev_prop_uint16 = {
252
    .name  = "uint16",
253
    .get   = get_uint16,
254
    .set   = set_uint16,
255
};
256

    
257
/* --- 32bit integer --- */
258

    
259
static void get_uint32(Object *obj, Visitor *v, void *opaque,
260
                       const char *name, Error **errp)
261
{
262
    DeviceState *dev = DEVICE(obj);
263
    Property *prop = opaque;
264
    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
265

    
266
    visit_type_uint32(v, ptr, name, errp);
267
}
268

    
269
static void set_uint32(Object *obj, Visitor *v, void *opaque,
270
                       const char *name, Error **errp)
271
{
272
    DeviceState *dev = DEVICE(obj);
273
    Property *prop = opaque;
274
    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
275

    
276
    if (dev->realized) {
277
        qdev_prop_set_after_realize(dev, name, errp);
278
        return;
279
    }
280

    
281
    visit_type_uint32(v, ptr, name, errp);
282
}
283

    
284
static void get_int32(Object *obj, Visitor *v, void *opaque,
285
                      const char *name, Error **errp)
286
{
287
    DeviceState *dev = DEVICE(obj);
288
    Property *prop = opaque;
289
    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
290

    
291
    visit_type_int32(v, ptr, name, errp);
292
}
293

    
294
static void set_int32(Object *obj, Visitor *v, void *opaque,
295
                      const char *name, Error **errp)
296
{
297
    DeviceState *dev = DEVICE(obj);
298
    Property *prop = opaque;
299
    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
300

    
301
    if (dev->realized) {
302
        qdev_prop_set_after_realize(dev, name, errp);
303
        return;
304
    }
305

    
306
    visit_type_int32(v, ptr, name, errp);
307
}
308

    
309
PropertyInfo qdev_prop_uint32 = {
310
    .name  = "uint32",
311
    .get   = get_uint32,
312
    .set   = set_uint32,
313
};
314

    
315
PropertyInfo qdev_prop_int32 = {
316
    .name  = "int32",
317
    .get   = get_int32,
318
    .set   = set_int32,
319
};
320

    
321
/* --- 32bit hex value --- */
322

    
323
static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
324
{
325
    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
326
    char *end;
327

    
328
    if (str[0] != '0' || str[1] != 'x') {
329
        return -EINVAL;
330
    }
331

    
332
    *ptr = strtoul(str, &end, 16);
333
    if ((*end != '\0') || (end == str)) {
334
        return -EINVAL;
335
    }
336

    
337
    return 0;
338
}
339

    
340
static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
341
{
342
    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
343
    return snprintf(dest, len, "0x%" PRIx32, *ptr);
344
}
345

    
346
PropertyInfo qdev_prop_hex32 = {
347
    .name  = "uint32",
348
    .legacy_name  = "hex32",
349
    .parse = parse_hex32,
350
    .print = print_hex32,
351
    .get   = get_uint32,
352
    .set   = set_uint32,
353
};
354

    
355
/* --- 64bit integer --- */
356

    
357
static void get_uint64(Object *obj, Visitor *v, void *opaque,
358
                       const char *name, Error **errp)
359
{
360
    DeviceState *dev = DEVICE(obj);
361
    Property *prop = opaque;
362
    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
363

    
364
    visit_type_uint64(v, ptr, name, errp);
365
}
366

    
367
static void set_uint64(Object *obj, Visitor *v, void *opaque,
368
                       const char *name, Error **errp)
369
{
370
    DeviceState *dev = DEVICE(obj);
371
    Property *prop = opaque;
372
    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
373

    
374
    if (dev->realized) {
375
        qdev_prop_set_after_realize(dev, name, errp);
376
        return;
377
    }
378

    
379
    visit_type_uint64(v, ptr, name, errp);
380
}
381

    
382
PropertyInfo qdev_prop_uint64 = {
383
    .name  = "uint64",
384
    .get   = get_uint64,
385
    .set   = set_uint64,
386
};
387

    
388
/* --- 64bit hex value --- */
389

    
390
static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
391
{
392
    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
393
    char *end;
394

    
395
    if (str[0] != '0' || str[1] != 'x') {
396
        return -EINVAL;
397
    }
398

    
399
    *ptr = strtoull(str, &end, 16);
400
    if ((*end != '\0') || (end == str)) {
401
        return -EINVAL;
402
    }
403

    
404
    return 0;
405
}
406

    
407
static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
408
{
409
    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
410
    return snprintf(dest, len, "0x%" PRIx64, *ptr);
411
}
412

    
413
PropertyInfo qdev_prop_hex64 = {
414
    .name  = "uint64",
415
    .legacy_name  = "hex64",
416
    .parse = parse_hex64,
417
    .print = print_hex64,
418
    .get   = get_uint64,
419
    .set   = set_uint64,
420
};
421

    
422
/* --- string --- */
423

    
424
static void release_string(Object *obj, const char *name, void *opaque)
425
{
426
    Property *prop = opaque;
427
    g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
428
}
429

    
430
static int print_string(DeviceState *dev, Property *prop, char *dest,
431
                        size_t len)
432
{
433
    char **ptr = qdev_get_prop_ptr(dev, prop);
434
    if (!*ptr) {
435
        return snprintf(dest, len, "<null>");
436
    }
437
    return snprintf(dest, len, "\"%s\"", *ptr);
438
}
439

    
440
static void get_string(Object *obj, Visitor *v, void *opaque,
441
                       const char *name, Error **errp)
442
{
443
    DeviceState *dev = DEVICE(obj);
444
    Property *prop = opaque;
445
    char **ptr = qdev_get_prop_ptr(dev, prop);
446

    
447
    if (!*ptr) {
448
        char *str = (char *)"";
449
        visit_type_str(v, &str, name, errp);
450
    } else {
451
        visit_type_str(v, ptr, name, errp);
452
    }
453
}
454

    
455
static void set_string(Object *obj, Visitor *v, void *opaque,
456
                       const char *name, Error **errp)
457
{
458
    DeviceState *dev = DEVICE(obj);
459
    Property *prop = opaque;
460
    char **ptr = qdev_get_prop_ptr(dev, prop);
461
    Error *local_err = NULL;
462
    char *str;
463

    
464
    if (dev->realized) {
465
        qdev_prop_set_after_realize(dev, name, errp);
466
        return;
467
    }
468

    
469
    visit_type_str(v, &str, name, &local_err);
470
    if (local_err) {
471
        error_propagate(errp, local_err);
472
        return;
473
    }
474
    if (*ptr) {
475
        g_free(*ptr);
476
    }
477
    *ptr = str;
478
}
479

    
480
PropertyInfo qdev_prop_string = {
481
    .name  = "string",
482
    .print = print_string,
483
    .release = release_string,
484
    .get   = get_string,
485
    .set   = set_string,
486
};
487

    
488
/* --- pointer --- */
489

    
490
/* Not a proper property, just for dirty hacks.  TODO Remove it!  */
491
PropertyInfo qdev_prop_ptr = {
492
    .name  = "ptr",
493
};
494

    
495
/* --- mac address --- */
496

    
497
/*
498
 * accepted syntax versions:
499
 *   01:02:03:04:05:06
500
 *   01-02-03-04-05-06
501
 */
502
static void get_mac(Object *obj, Visitor *v, void *opaque,
503
                    const char *name, Error **errp)
504
{
505
    DeviceState *dev = DEVICE(obj);
506
    Property *prop = opaque;
507
    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
508
    char buffer[2 * 6 + 5 + 1];
509
    char *p = buffer;
510

    
511
    snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
512
             mac->a[0], mac->a[1], mac->a[2],
513
             mac->a[3], mac->a[4], mac->a[5]);
514

    
515
    visit_type_str(v, &p, name, errp);
516
}
517

    
518
static void set_mac(Object *obj, Visitor *v, void *opaque,
519
                    const char *name, Error **errp)
520
{
521
    DeviceState *dev = DEVICE(obj);
522
    Property *prop = opaque;
523
    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
524
    Error *local_err = NULL;
525
    int i, pos;
526
    char *str, *p;
527

    
528
    if (dev->realized) {
529
        qdev_prop_set_after_realize(dev, name, errp);
530
        return;
531
    }
532

    
533
    visit_type_str(v, &str, name, &local_err);
534
    if (local_err) {
535
        error_propagate(errp, local_err);
536
        return;
537
    }
538

    
539
    for (i = 0, pos = 0; i < 6; i++, pos += 3) {
540
        if (!qemu_isxdigit(str[pos])) {
541
            goto inval;
542
        }
543
        if (!qemu_isxdigit(str[pos+1])) {
544
            goto inval;
545
        }
546
        if (i == 5) {
547
            if (str[pos+2] != '\0') {
548
                goto inval;
549
            }
550
        } else {
551
            if (str[pos+2] != ':' && str[pos+2] != '-') {
552
                goto inval;
553
            }
554
        }
555
        mac->a[i] = strtol(str+pos, &p, 16);
556
    }
557
    g_free(str);
558
    return;
559

    
560
inval:
561
    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
562
    g_free(str);
563
}
564

    
565
PropertyInfo qdev_prop_macaddr = {
566
    .name  = "macaddr",
567
    .get   = get_mac,
568
    .set   = set_mac,
569
};
570

    
571
/* --- lost tick policy --- */
572

    
573
static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
574
    [LOST_TICK_DISCARD] = "discard",
575
    [LOST_TICK_DELAY] = "delay",
576
    [LOST_TICK_MERGE] = "merge",
577
    [LOST_TICK_SLEW] = "slew",
578
    [LOST_TICK_MAX] = NULL,
579
};
580

    
581
QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
582

    
583
PropertyInfo qdev_prop_losttickpolicy = {
584
    .name  = "LostTickPolicy",
585
    .enum_table  = lost_tick_policy_table,
586
    .get   = get_enum,
587
    .set   = set_enum,
588
};
589

    
590
/* --- BIOS CHS translation */
591

    
592
static const char *bios_chs_trans_table[] = {
593
    [BIOS_ATA_TRANSLATION_AUTO] = "auto",
594
    [BIOS_ATA_TRANSLATION_NONE] = "none",
595
    [BIOS_ATA_TRANSLATION_LBA]  = "lba",
596
};
597

    
598
PropertyInfo qdev_prop_bios_chs_trans = {
599
    .name = "bios-chs-trans",
600
    .enum_table = bios_chs_trans_table,
601
    .get = get_enum,
602
    .set = set_enum,
603
};
604

    
605
/* --- pci address --- */
606

    
607
/*
608
 * bus-local address, i.e. "$slot" or "$slot.$fn"
609
 */
610
static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
611
                          const char *name, Error **errp)
612
{
613
    DeviceState *dev = DEVICE(obj);
614
    Property *prop = opaque;
615
    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
616
    unsigned int slot, fn, n;
617
    Error *local_err = NULL;
618
    char *str;
619

    
620
    if (dev->realized) {
621
        qdev_prop_set_after_realize(dev, name, errp);
622
        return;
623
    }
624

    
625
    visit_type_str(v, &str, name, &local_err);
626
    if (local_err) {
627
        error_free(local_err);
628
        local_err = NULL;
629
        visit_type_int32(v, &value, name, &local_err);
630
        if (local_err) {
631
            error_propagate(errp, local_err);
632
        } else if (value < -1 || value > 255) {
633
            error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
634
                      "pci_devfn");
635
        } else {
636
            *ptr = value;
637
        }
638
        return;
639
    }
640

    
641
    if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
642
        fn = 0;
643
        if (sscanf(str, "%x%n", &slot, &n) != 1) {
644
            goto invalid;
645
        }
646
    }
647
    if (str[n] != '\0' || fn > 7 || slot > 31) {
648
        goto invalid;
649
    }
650
    *ptr = slot << 3 | fn;
651
    g_free(str);
652
    return;
653

    
654
invalid:
655
    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
656
    g_free(str);
657
}
658

    
659
static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest,
660
                           size_t len)
661
{
662
    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
663

    
664
    if (*ptr == -1) {
665
        return snprintf(dest, len, "<unset>");
666
    } else {
667
        return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
668
    }
669
}
670

    
671
PropertyInfo qdev_prop_pci_devfn = {
672
    .name  = "int32",
673
    .legacy_name  = "pci-devfn",
674
    .print = print_pci_devfn,
675
    .get   = get_int32,
676
    .set   = set_pci_devfn,
677
};
678

    
679
/* --- blocksize --- */
680

    
681
static void set_blocksize(Object *obj, Visitor *v, void *opaque,
682
                          const char *name, Error **errp)
683
{
684
    DeviceState *dev = DEVICE(obj);
685
    Property *prop = opaque;
686
    uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
687
    Error *local_err = NULL;
688
    const int64_t min = 512;
689
    const int64_t max = 32768;
690

    
691
    if (dev->realized) {
692
        qdev_prop_set_after_realize(dev, name, errp);
693
        return;
694
    }
695

    
696
    visit_type_uint16(v, &value, name, &local_err);
697
    if (local_err) {
698
        error_propagate(errp, local_err);
699
        return;
700
    }
701
    if (value < min || value > max) {
702
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
703
                  dev->id?:"", name, (int64_t)value, min, max);
704
        return;
705
    }
706

    
707
    /* We rely on power-of-2 blocksizes for bitmasks */
708
    if ((value & (value - 1)) != 0) {
709
        error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
710
                  dev->id?:"", name, (int64_t)value);
711
        return;
712
    }
713

    
714
    *ptr = value;
715
}
716

    
717
PropertyInfo qdev_prop_blocksize = {
718
    .name  = "blocksize",
719
    .get   = get_uint16,
720
    .set   = set_blocksize,
721
};
722

    
723
/* --- pci host address --- */
724

    
725
static void get_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
726
                                 const char *name, Error **errp)
727
{
728
    DeviceState *dev = DEVICE(obj);
729
    Property *prop = opaque;
730
    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
731
    char buffer[] = "xxxx:xx:xx.x";
732
    char *p = buffer;
733
    int rc = 0;
734

    
735
    rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d",
736
                  addr->domain, addr->bus, addr->slot, addr->function);
737
    assert(rc == sizeof(buffer) - 1);
738

    
739
    visit_type_str(v, &p, name, errp);
740
}
741

    
742
/*
743
 * Parse [<domain>:]<bus>:<slot>.<func>
744
 *   if <domain> is not supplied, it's assumed to be 0.
745
 */
746
static void set_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
747
                                 const char *name, Error **errp)
748
{
749
    DeviceState *dev = DEVICE(obj);
750
    Property *prop = opaque;
751
    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
752
    Error *local_err = NULL;
753
    char *str, *p;
754
    char *e;
755
    unsigned long val;
756
    unsigned long dom = 0, bus = 0;
757
    unsigned int slot = 0, func = 0;
758

    
759
    if (dev->realized) {
760
        qdev_prop_set_after_realize(dev, name, errp);
761
        return;
762
    }
763

    
764
    visit_type_str(v, &str, name, &local_err);
765
    if (local_err) {
766
        error_propagate(errp, local_err);
767
        return;
768
    }
769

    
770
    p = str;
771
    val = strtoul(p, &e, 16);
772
    if (e == p || *e != ':') {
773
        goto inval;
774
    }
775
    bus = val;
776

    
777
    p = e + 1;
778
    val = strtoul(p, &e, 16);
779
    if (e == p) {
780
        goto inval;
781
    }
782
    if (*e == ':') {
783
        dom = bus;
784
        bus = val;
785
        p = e + 1;
786
        val = strtoul(p, &e, 16);
787
        if (e == p) {
788
            goto inval;
789
        }
790
    }
791
    slot = val;
792

    
793
    if (*e != '.') {
794
        goto inval;
795
    }
796
    p = e + 1;
797
    val = strtoul(p, &e, 10);
798
    if (e == p) {
799
        goto inval;
800
    }
801
    func = val;
802

    
803
    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
804
        goto inval;
805
    }
806

    
807
    if (*e) {
808
        goto inval;
809
    }
810

    
811
    addr->domain = dom;
812
    addr->bus = bus;
813
    addr->slot = slot;
814
    addr->function = func;
815

    
816
    g_free(str);
817
    return;
818

    
819
inval:
820
    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
821
    g_free(str);
822
}
823

    
824
PropertyInfo qdev_prop_pci_host_devaddr = {
825
    .name = "pci-host-devaddr",
826
    .get = get_pci_host_devaddr,
827
    .set = set_pci_host_devaddr,
828
};
829

    
830
/* --- support for array properties --- */
831

    
832
/* Used as an opaque for the object properties we add for each
833
 * array element. Note that the struct Property must be first
834
 * in the struct so that a pointer to this works as the opaque
835
 * for the underlying element's property hooks as well as for
836
 * our own release callback.
837
 */
838
typedef struct {
839
    struct Property prop;
840
    char *propname;
841
    ObjectPropertyRelease *release;
842
} ArrayElementProperty;
843

    
844
/* object property release callback for array element properties:
845
 * we call the underlying element's property release hook, and
846
 * then free the memory we allocated when we added the property.
847
 */
848
static void array_element_release(Object *obj, const char *name, void *opaque)
849
{
850
    ArrayElementProperty *p = opaque;
851
    if (p->release) {
852
        p->release(obj, name, opaque);
853
    }
854
    g_free(p->propname);
855
    g_free(p);
856
}
857

    
858
static void set_prop_arraylen(Object *obj, Visitor *v, void *opaque,
859
                              const char *name, Error **errp)
860
{
861
    /* Setter for the property which defines the length of a
862
     * variable-sized property array. As well as actually setting the
863
     * array-length field in the device struct, we have to create the
864
     * array itself and dynamically add the corresponding properties.
865
     */
866
    DeviceState *dev = DEVICE(obj);
867
    Property *prop = opaque;
868
    uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
869
    void **arrayptr = (void *)dev + prop->arrayoffset;
870
    void *eltptr;
871
    const char *arrayname;
872
    int i;
873

    
874
    if (dev->realized) {
875
        qdev_prop_set_after_realize(dev, name, errp);
876
        return;
877
    }
878
    if (*alenptr) {
879
        error_setg(errp, "array size property %s may not be set more than once",
880
                   name);
881
        return;
882
    }
883
    visit_type_uint32(v, alenptr, name, errp);
884
    if (error_is_set(errp)) {
885
        return;
886
    }
887
    if (!*alenptr) {
888
        return;
889
    }
890

    
891
    /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
892
     * strip it off so we can get the name of the array itself.
893
     */
894
    assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
895
                   strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
896
    arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
897

    
898
    /* Note that it is the responsibility of the individual device's deinit
899
     * to free the array proper.
900
     */
901
    *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
902
    for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
903
        char *propname = g_strdup_printf("%s[%d]", arrayname, i);
904
        ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
905
        arrayprop->release = prop->arrayinfo->release;
906
        arrayprop->propname = propname;
907
        arrayprop->prop.info = prop->arrayinfo;
908
        arrayprop->prop.name = propname;
909
        /* This ugly piece of pointer arithmetic sets up the offset so
910
         * that when the underlying get/set hooks call qdev_get_prop_ptr
911
         * they get the right answer despite the array element not actually
912
         * being inside the device struct.
913
         */
914
        arrayprop->prop.offset = eltptr - (void *)dev;
915
        assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
916
        object_property_add(obj, propname,
917
                            arrayprop->prop.info->name,
918
                            arrayprop->prop.info->get,
919
                            arrayprop->prop.info->set,
920
                            array_element_release,
921
                            arrayprop, errp);
922
        if (error_is_set(errp)) {
923
            return;
924
        }
925
    }
926
}
927

    
928
PropertyInfo qdev_prop_arraylen = {
929
    .name = "uint32",
930
    .get = get_uint32,
931
    .set = set_prop_arraylen,
932
};
933

    
934
/* --- public helpers --- */
935

    
936
static Property *qdev_prop_walk(Property *props, const char *name)
937
{
938
    if (!props) {
939
        return NULL;
940
    }
941
    while (props->name) {
942
        if (strcmp(props->name, name) == 0) {
943
            return props;
944
        }
945
        props++;
946
    }
947
    return NULL;
948
}
949

    
950
static Property *qdev_prop_find(DeviceState *dev, const char *name)
951
{
952
    ObjectClass *class;
953
    Property *prop;
954

    
955
    /* device properties */
956
    class = object_get_class(OBJECT(dev));
957
    do {
958
        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
959
        if (prop) {
960
            return prop;
961
        }
962
        class = object_class_get_parent(class);
963
    } while (class != object_class_by_name(TYPE_DEVICE));
964

    
965
    return NULL;
966
}
967

    
968
void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
969
                                    Property *prop, const char *value)
970
{
971
    switch (ret) {
972
    case -EEXIST:
973
        error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
974
                  object_get_typename(OBJECT(dev)), prop->name, value);
975
        break;
976
    default:
977
    case -EINVAL:
978
        error_set(errp, QERR_PROPERTY_VALUE_BAD,
979
                  object_get_typename(OBJECT(dev)), prop->name, value);
980
        break;
981
    case -ENOENT:
982
        error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
983
                  object_get_typename(OBJECT(dev)), prop->name, value);
984
        break;
985
    case 0:
986
        break;
987
    }
988
}
989

    
990
void qdev_prop_parse(DeviceState *dev, const char *name, const char *value,
991
                     Error **errp)
992
{
993
    char *legacy_name;
994

    
995
    legacy_name = g_strdup_printf("legacy-%s", name);
996
    if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
997
        object_property_parse(OBJECT(dev), value, legacy_name, errp);
998
    } else {
999
        object_property_parse(OBJECT(dev), value, name, errp);
1000
    }
1001
    g_free(legacy_name);
1002
}
1003

    
1004
void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1005
{
1006
    object_property_set_bool(OBJECT(dev), value, name, &error_abort);
1007
}
1008

    
1009
void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1010
{
1011
    object_property_set_int(OBJECT(dev), value, name, &error_abort);
1012
}
1013

    
1014
void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1015
{
1016
    object_property_set_int(OBJECT(dev), value, name, &error_abort);
1017
}
1018

    
1019
void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1020
{
1021
    object_property_set_int(OBJECT(dev), value, name, &error_abort);
1022
}
1023

    
1024
void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1025
{
1026
    object_property_set_int(OBJECT(dev), value, name, &error_abort);
1027
}
1028

    
1029
void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1030
{
1031
    object_property_set_int(OBJECT(dev), value, name, &error_abort);
1032
}
1033

    
1034
void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
1035
{
1036
    object_property_set_str(OBJECT(dev), value, name, &error_abort);
1037
}
1038

    
1039
void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
1040
{
1041
    char str[2 * 6 + 5 + 1];
1042
    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1043
             value[0], value[1], value[2], value[3], value[4], value[5]);
1044

    
1045
    object_property_set_str(OBJECT(dev), str, name, &error_abort);
1046
}
1047

    
1048
void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1049
{
1050
    Property *prop;
1051

    
1052
    prop = qdev_prop_find(dev, name);
1053
    object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
1054
                            name, &error_abort);
1055
}
1056

    
1057
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1058
{
1059
    Property *prop;
1060
    void **ptr;
1061

    
1062
    prop = qdev_prop_find(dev, name);
1063
    assert(prop && prop->info == &qdev_prop_ptr);
1064
    ptr = qdev_get_prop_ptr(dev, prop);
1065
    *ptr = value;
1066
}
1067

    
1068
static QTAILQ_HEAD(, GlobalProperty) global_props =
1069
        QTAILQ_HEAD_INITIALIZER(global_props);
1070

    
1071
void qdev_prop_register_global(GlobalProperty *prop)
1072
{
1073
    QTAILQ_INSERT_TAIL(&global_props, prop, next);
1074
}
1075

    
1076
void qdev_prop_register_global_list(GlobalProperty *props)
1077
{
1078
    int i;
1079

    
1080
    for (i = 0; props[i].driver != NULL; i++) {
1081
        qdev_prop_register_global(props+i);
1082
    }
1083
}
1084

    
1085
void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
1086
                                    Error **errp)
1087
{
1088
    GlobalProperty *prop;
1089

    
1090
    QTAILQ_FOREACH(prop, &global_props, next) {
1091
        Error *err = NULL;
1092

    
1093
        if (strcmp(typename, prop->driver) != 0) {
1094
            continue;
1095
        }
1096
        qdev_prop_parse(dev, prop->property, prop->value, &err);
1097
        if (err != NULL) {
1098
            error_propagate(errp, err);
1099
            return;
1100
        }
1101
    }
1102
}
1103

    
1104
void qdev_prop_set_globals(DeviceState *dev, Error **errp)
1105
{
1106
    ObjectClass *class = object_get_class(OBJECT(dev));
1107

    
1108
    do {
1109
        Error *err = NULL;
1110

    
1111
        qdev_prop_set_globals_for_type(dev, object_class_get_name(class),
1112
                                       &err);
1113
        if (err != NULL) {
1114
            error_propagate(errp, err);
1115
            return;
1116
        }
1117
        class = object_class_get_parent(class);
1118
    } while (class);
1119
}
1120

    
1121
/* --- 64bit unsigned int 'size' type --- */
1122

    
1123
static void get_size(Object *obj, Visitor *v, void *opaque,
1124
                     const char *name, Error **errp)
1125
{
1126
    DeviceState *dev = DEVICE(obj);
1127
    Property *prop = opaque;
1128
    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1129

    
1130
    visit_type_size(v, ptr, name, errp);
1131
}
1132

    
1133
static void set_size(Object *obj, Visitor *v, void *opaque,
1134
                     const char *name, Error **errp)
1135
{
1136
    DeviceState *dev = DEVICE(obj);
1137
    Property *prop = opaque;
1138
    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1139

    
1140
    visit_type_size(v, ptr, name, errp);
1141
}
1142

    
1143
static int print_size(DeviceState *dev, Property *prop, char *dest, size_t len)
1144
{
1145
    static const char suffixes[] = { 'B', 'K', 'M', 'G', 'T' };
1146
    uint64_t div, val = *(uint64_t *)qdev_get_prop_ptr(dev, prop);
1147
    int i;
1148

    
1149
    /* Compute floor(log2(val)).  */
1150
    i = 64 - clz64(val);
1151

    
1152
    /* Find the power of 1024 that we'll display as the units.  */
1153
    i /= 10;
1154
    if (i >= ARRAY_SIZE(suffixes)) {
1155
        i = ARRAY_SIZE(suffixes) - 1;
1156
    }
1157
    div = 1ULL << (i * 10);
1158

    
1159
    return snprintf(dest, len, "%0.03f%c", (double)val/div, suffixes[i]);
1160
}
1161

    
1162
PropertyInfo qdev_prop_size = {
1163
    .name  = "size",
1164
    .print = print_size,
1165
    .get = get_size,
1166
    .set = set_size,
1167
};