Statistics
| Branch: | Revision:

root / hw / qdev-properties.c @ 7b009e5d

History | View | Annotate | Download (31 kB)

1
#include "net.h"
2
#include "qdev.h"
3
#include "qerror.h"
4
#include "blockdev.h"
5

    
6
void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
7
{
8
    void *ptr = dev;
9
    ptr += prop->offset;
10
    return ptr;
11
}
12

    
13
static uint32_t qdev_get_prop_mask(Property *prop)
14
{
15
    assert(prop->info->type == PROP_TYPE_BIT);
16
    return 0x1 << prop->bitnr;
17
}
18

    
19
static void bit_prop_set(DeviceState *dev, Property *props, bool val)
20
{
21
    uint32_t *p = qdev_get_prop_ptr(dev, props);
22
    uint32_t mask = qdev_get_prop_mask(props);
23
    if (val)
24
        *p |= mask;
25
    else
26
        *p &= ~mask;
27
}
28

    
29
static void qdev_prop_cpy(DeviceState *dev, Property *props, void *src)
30
{
31
    if (props->info->type == PROP_TYPE_BIT) {
32
        bool *defval = src;
33
        bit_prop_set(dev, props, *defval);
34
    } else {
35
        char *dst = qdev_get_prop_ptr(dev, props);
36
        memcpy(dst, src, props->info->size);
37
    }
38
}
39

    
40
/* Bit */
41
static int parse_bit(DeviceState *dev, Property *prop, const char *str)
42
{
43
    if (!strcasecmp(str, "on"))
44
        bit_prop_set(dev, prop, true);
45
    else if (!strcasecmp(str, "off"))
46
        bit_prop_set(dev, prop, false);
47
    else
48
        return -EINVAL;
49
    return 0;
50
}
51

    
52
static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
53
{
54
    uint32_t *p = qdev_get_prop_ptr(dev, prop);
55
    return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
56
}
57

    
58
static void get_bit(Object *obj, Visitor *v, void *opaque,
59
                    const char *name, Error **errp)
60
{
61
    DeviceState *dev = DEVICE(obj);
62
    Property *prop = opaque;
63
    uint32_t *p = qdev_get_prop_ptr(dev, prop);
64
    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
65

    
66
    visit_type_bool(v, &value, name, errp);
67
}
68

    
69
static void set_bit(Object *obj, Visitor *v, void *opaque,
70
                    const char *name, Error **errp)
71
{
72
    DeviceState *dev = DEVICE(obj);
73
    Property *prop = opaque;
74
    Error *local_err = NULL;
75
    bool value;
76

    
77
    if (dev->state != DEV_STATE_CREATED) {
78
        error_set(errp, QERR_PERMISSION_DENIED);
79
        return;
80
    }
81

    
82
    visit_type_bool(v, &value, name, &local_err);
83
    if (local_err) {
84
        error_propagate(errp, local_err);
85
        return;
86
    }
87
    bit_prop_set(dev, prop, value);
88
}
89

    
90
PropertyInfo qdev_prop_bit = {
91
    .name  = "boolean",
92
    .legacy_name  = "on/off",
93
    .type  = PROP_TYPE_BIT,
94
    .size  = sizeof(uint32_t),
95
    .parse = parse_bit,
96
    .print = print_bit,
97
    .get   = get_bit,
98
    .set   = set_bit,
99
};
100

    
101
/* --- 8bit integer --- */
102

    
103
static int parse_uint8(DeviceState *dev, Property *prop, const char *str)
104
{
105
    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
106
    char *end;
107

    
108
    /* accept both hex and decimal */
109
    *ptr = strtoul(str, &end, 0);
110
    if ((*end != '\0') || (end == str)) {
111
        return -EINVAL;
112
    }
113

    
114
    return 0;
115
}
116

    
117
static int print_uint8(DeviceState *dev, Property *prop, char *dest, size_t len)
118
{
119
    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
120
    return snprintf(dest, len, "%" PRIu8, *ptr);
121
}
122

    
123
static void get_int8(Object *obj, Visitor *v, void *opaque,
124
                     const char *name, Error **errp)
125
{
126
    DeviceState *dev = DEVICE(obj);
127
    Property *prop = opaque;
128
    int8_t *ptr = qdev_get_prop_ptr(dev, prop);
129
    int64_t value;
130

    
131
    value = *ptr;
132
    visit_type_int(v, &value, name, errp);
133
}
134

    
135
static void set_int8(Object *obj, Visitor *v, void *opaque,
136
                     const char *name, Error **errp)
137
{
138
    DeviceState *dev = DEVICE(obj);
139
    Property *prop = opaque;
140
    int8_t *ptr = qdev_get_prop_ptr(dev, prop);
141
    Error *local_err = NULL;
142
    int64_t value;
143

    
144
    if (dev->state != DEV_STATE_CREATED) {
145
        error_set(errp, QERR_PERMISSION_DENIED);
146
        return;
147
    }
148

    
149
    visit_type_int(v, &value, name, &local_err);
150
    if (local_err) {
151
        error_propagate(errp, local_err);
152
        return;
153
    }
154
    if (value > prop->info->min && value <= prop->info->max) {
155
        *ptr = value;
156
    } else {
157
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
158
                  dev->id?:"", name, value, prop->info->min,
159
                  prop->info->max);
160
    }
161
}
162

    
163
PropertyInfo qdev_prop_uint8 = {
164
    .name  = "uint8",
165
    .type  = PROP_TYPE_UINT8,
166
    .size  = sizeof(uint8_t),
167
    .parse = parse_uint8,
168
    .print = print_uint8,
169
    .get   = get_int8,
170
    .set   = set_int8,
171
    .min   = 0,
172
    .max   = 255,
173
};
174

    
175
/* --- 8bit hex value --- */
176

    
177
static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
178
{
179
    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
180
    char *end;
181

    
182
    *ptr = strtoul(str, &end, 16);
183
    if ((*end != '\0') || (end == str)) {
184
        return -EINVAL;
185
    }
186

    
187
    return 0;
188
}
189

    
190
static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
191
{
192
    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
193
    return snprintf(dest, len, "0x%" PRIx8, *ptr);
194
}
195

    
196
PropertyInfo qdev_prop_hex8 = {
197
    .name  = "uint8",
198
    .legacy_name  = "hex8",
199
    .type  = PROP_TYPE_UINT8,
200
    .size  = sizeof(uint8_t),
201
    .parse = parse_hex8,
202
    .print = print_hex8,
203
    .get   = get_int8,
204
    .set   = set_int8,
205
    .min   = 0,
206
    .max   = 255,
207
};
208

    
209
/* --- 16bit integer --- */
210

    
211
static int parse_uint16(DeviceState *dev, Property *prop, const char *str)
212
{
213
    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
214
    char *end;
215

    
216
    /* accept both hex and decimal */
217
    *ptr = strtoul(str, &end, 0);
218
    if ((*end != '\0') || (end == str)) {
219
        return -EINVAL;
220
    }
221

    
222
    return 0;
223
}
224

    
225
static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len)
226
{
227
    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
228
    return snprintf(dest, len, "%" PRIu16, *ptr);
229
}
230

    
231
static void get_int16(Object *obj, Visitor *v, void *opaque,
232
                      const char *name, Error **errp)
233
{
234
    DeviceState *dev = DEVICE(obj);
235
    Property *prop = opaque;
236
    int16_t *ptr = qdev_get_prop_ptr(dev, prop);
237
    int64_t value;
238

    
239
    value = *ptr;
240
    visit_type_int(v, &value, name, errp);
241
}
242

    
243
static void set_int16(Object *obj, Visitor *v, void *opaque,
244
                      const char *name, Error **errp)
245
{
246
    DeviceState *dev = DEVICE(obj);
247
    Property *prop = opaque;
248
    int16_t *ptr = qdev_get_prop_ptr(dev, prop);
249
    Error *local_err = NULL;
250
    int64_t value;
251

    
252
    if (dev->state != DEV_STATE_CREATED) {
253
        error_set(errp, QERR_PERMISSION_DENIED);
254
        return;
255
    }
256

    
257
    visit_type_int(v, &value, name, &local_err);
258
    if (local_err) {
259
        error_propagate(errp, local_err);
260
        return;
261
    }
262
    if (value > prop->info->min && value <= prop->info->max) {
263
        *ptr = value;
264
    } else {
265
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
266
                  dev->id?:"", name, value, prop->info->min,
267
                  prop->info->max);
268
    }
269
}
270

    
271
PropertyInfo qdev_prop_uint16 = {
272
    .name  = "uint16",
273
    .type  = PROP_TYPE_UINT16,
274
    .size  = sizeof(uint16_t),
275
    .parse = parse_uint16,
276
    .print = print_uint16,
277
    .get   = get_int16,
278
    .set   = set_int16,
279
    .min   = 0,
280
    .max   = 65535,
281
};
282

    
283
/* --- 32bit integer --- */
284

    
285
static int parse_uint32(DeviceState *dev, Property *prop, const char *str)
286
{
287
    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
288
    char *end;
289

    
290
    /* accept both hex and decimal */
291
    *ptr = strtoul(str, &end, 0);
292
    if ((*end != '\0') || (end == str)) {
293
        return -EINVAL;
294
    }
295

    
296
    return 0;
297
}
298

    
299
static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len)
300
{
301
    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
302
    return snprintf(dest, len, "%" PRIu32, *ptr);
303
}
304

    
305
static void get_int32(Object *obj, Visitor *v, void *opaque,
306
                      const char *name, Error **errp)
307
{
308
    DeviceState *dev = DEVICE(obj);
309
    Property *prop = opaque;
310
    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
311
    int64_t value;
312

    
313
    value = *ptr;
314
    visit_type_int(v, &value, name, errp);
315
}
316

    
317
static void set_int32(Object *obj, Visitor *v, void *opaque,
318
                      const char *name, Error **errp)
319
{
320
    DeviceState *dev = DEVICE(obj);
321
    Property *prop = opaque;
322
    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
323
    Error *local_err = NULL;
324
    int64_t value;
325

    
326
    if (dev->state != DEV_STATE_CREATED) {
327
        error_set(errp, QERR_PERMISSION_DENIED);
328
        return;
329
    }
330

    
331
    visit_type_int(v, &value, name, &local_err);
332
    if (local_err) {
333
        error_propagate(errp, local_err);
334
        return;
335
    }
336
    if (value > prop->info->min && value <= prop->info->max) {
337
        *ptr = value;
338
    } else {
339
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
340
                  dev->id?:"", name, value, prop->info->min,
341
                  prop->info->max);
342
    }
343
}
344

    
345
PropertyInfo qdev_prop_uint32 = {
346
    .name  = "uint32",
347
    .type  = PROP_TYPE_UINT32,
348
    .size  = sizeof(uint32_t),
349
    .parse = parse_uint32,
350
    .print = print_uint32,
351
    .get   = get_int32,
352
    .set   = set_int32,
353
    .min   = 0,
354
    .max   = 0xFFFFFFFFULL,
355
};
356

    
357
static int parse_int32(DeviceState *dev, Property *prop, const char *str)
358
{
359
    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
360
    char *end;
361

    
362
    *ptr = strtol(str, &end, 10);
363
    if ((*end != '\0') || (end == str)) {
364
        return -EINVAL;
365
    }
366

    
367
    return 0;
368
}
369

    
370
static int print_int32(DeviceState *dev, Property *prop, char *dest, size_t len)
371
{
372
    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
373
    return snprintf(dest, len, "%" PRId32, *ptr);
374
}
375

    
376
PropertyInfo qdev_prop_int32 = {
377
    .name  = "int32",
378
    .type  = PROP_TYPE_INT32,
379
    .size  = sizeof(int32_t),
380
    .parse = parse_int32,
381
    .print = print_int32,
382
    .get   = get_int32,
383
    .set   = set_int32,
384
    .min   = -0x80000000LL,
385
    .max   = 0x7FFFFFFFLL,
386
};
387

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

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

    
395
    *ptr = strtoul(str, &end, 16);
396
    if ((*end != '\0') || (end == str)) {
397
        return -EINVAL;
398
    }
399

    
400
    return 0;
401
}
402

    
403
static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
404
{
405
    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
406
    return snprintf(dest, len, "0x%" PRIx32, *ptr);
407
}
408

    
409
PropertyInfo qdev_prop_hex32 = {
410
    .name  = "uint32",
411
    .legacy_name  = "hex32",
412
    .type  = PROP_TYPE_UINT32,
413
    .size  = sizeof(uint32_t),
414
    .parse = parse_hex32,
415
    .print = print_hex32,
416
    .get   = get_int32,
417
    .set   = set_int32,
418
    .min   = 0,
419
    .max   = 0xFFFFFFFFULL,
420
};
421

    
422
/* --- 64bit integer --- */
423

    
424
static int parse_uint64(DeviceState *dev, Property *prop, const char *str)
425
{
426
    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
427
    char *end;
428

    
429
    /* accept both hex and decimal */
430
    *ptr = strtoull(str, &end, 0);
431
    if ((*end != '\0') || (end == str)) {
432
        return -EINVAL;
433
    }
434

    
435
    return 0;
436
}
437

    
438
static int print_uint64(DeviceState *dev, Property *prop, char *dest, size_t len)
439
{
440
    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
441
    return snprintf(dest, len, "%" PRIu64, *ptr);
442
}
443

    
444
static void get_int64(Object *obj, Visitor *v, void *opaque,
445
                      const char *name, Error **errp)
446
{
447
    DeviceState *dev = DEVICE(obj);
448
    Property *prop = opaque;
449
    int64_t *ptr = qdev_get_prop_ptr(dev, prop);
450

    
451
    visit_type_int(v, ptr, name, errp);
452
}
453

    
454
static void set_int64(Object *obj, Visitor *v, void *opaque,
455
                      const char *name, Error **errp)
456
{
457
    DeviceState *dev = DEVICE(obj);
458
    Property *prop = opaque;
459
    int64_t *ptr = qdev_get_prop_ptr(dev, prop);
460

    
461
    if (dev->state != DEV_STATE_CREATED) {
462
        error_set(errp, QERR_PERMISSION_DENIED);
463
        return;
464
    }
465

    
466
    visit_type_int(v, ptr, name, errp);
467
}
468

    
469
PropertyInfo qdev_prop_uint64 = {
470
    .name  = "uint64",
471
    .type  = PROP_TYPE_UINT64,
472
    .size  = sizeof(uint64_t),
473
    .parse = parse_uint64,
474
    .print = print_uint64,
475
    .get   = get_int64,
476
    .set   = set_int64,
477
};
478

    
479
/* --- 64bit hex value --- */
480

    
481
static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
482
{
483
    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
484
    char *end;
485

    
486
    *ptr = strtoull(str, &end, 16);
487
    if ((*end != '\0') || (end == str)) {
488
        return -EINVAL;
489
    }
490

    
491
    return 0;
492
}
493

    
494
static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
495
{
496
    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
497
    return snprintf(dest, len, "0x%" PRIx64, *ptr);
498
}
499

    
500
PropertyInfo qdev_prop_hex64 = {
501
    .name  = "uint64",
502
    .legacy_name  = "hex64",
503
    .type  = PROP_TYPE_UINT64,
504
    .size  = sizeof(uint64_t),
505
    .parse = parse_hex64,
506
    .print = print_hex64,
507
    .get   = get_int64,
508
    .set   = set_int64,
509
};
510

    
511
/* --- string --- */
512

    
513
static void free_string(DeviceState *dev, Property *prop)
514
{
515
    g_free(*(char **)qdev_get_prop_ptr(dev, prop));
516
}
517

    
518
static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
519
{
520
    char **ptr = qdev_get_prop_ptr(dev, prop);
521
    if (!*ptr)
522
        return snprintf(dest, len, "<null>");
523
    return snprintf(dest, len, "\"%s\"", *ptr);
524
}
525

    
526
static void get_string(Object *obj, Visitor *v, void *opaque,
527
                       const char *name, Error **errp)
528
{
529
    DeviceState *dev = DEVICE(obj);
530
    Property *prop = opaque;
531
    char **ptr = qdev_get_prop_ptr(dev, prop);
532

    
533
    if (!*ptr) {
534
        char *str = (char *)"";
535
        visit_type_str(v, &str, name, errp);
536
    } else {
537
        visit_type_str(v, ptr, name, errp);
538
    }
539
}
540

    
541
static void set_string(Object *obj, Visitor *v, void *opaque,
542
                       const char *name, Error **errp)
543
{
544
    DeviceState *dev = DEVICE(obj);
545
    Property *prop = opaque;
546
    char **ptr = qdev_get_prop_ptr(dev, prop);
547
    Error *local_err = NULL;
548
    char *str;
549

    
550
    if (dev->state != DEV_STATE_CREATED) {
551
        error_set(errp, QERR_PERMISSION_DENIED);
552
        return;
553
    }
554

    
555
    visit_type_str(v, &str, name, &local_err);
556
    if (local_err) {
557
        error_propagate(errp, local_err);
558
        return;
559
    }
560
    if (!*str) {
561
        g_free(str);
562
        str = NULL;
563
    }
564
    if (*ptr) {
565
        g_free(*ptr);
566
    }
567
    *ptr = str;
568
}
569

    
570
PropertyInfo qdev_prop_string = {
571
    .name  = "string",
572
    .type  = PROP_TYPE_STRING,
573
    .size  = sizeof(char*),
574
    .print = print_string,
575
    .free  = free_string,
576
    .get   = get_string,
577
    .set   = set_string,
578
};
579

    
580
/* --- drive --- */
581

    
582
static int parse_drive(DeviceState *dev, const char *str, void **ptr)
583
{
584
    BlockDriverState *bs;
585

    
586
    bs = bdrv_find(str);
587
    if (bs == NULL)
588
        return -ENOENT;
589
    if (bdrv_attach_dev(bs, dev) < 0)
590
        return -EEXIST;
591
    *ptr = bs;
592
    return 0;
593
}
594

    
595
static void free_drive(DeviceState *dev, Property *prop)
596
{
597
    BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
598

    
599
    if (*ptr) {
600
        bdrv_detach_dev(*ptr, dev);
601
        blockdev_auto_del(*ptr);
602
    }
603
}
604

    
605
static const char *print_drive(void *ptr)
606
{
607
    return bdrv_get_device_name(ptr);
608
}
609

    
610
static void get_pointer(Object *obj, Visitor *v, Property *prop,
611
                        const char *(*print)(void *ptr),
612
                        const char *name, Error **errp)
613
{
614
    DeviceState *dev = DEVICE(obj);
615
    void **ptr = qdev_get_prop_ptr(dev, prop);
616
    char *p;
617

    
618
    p = (char *) (*ptr ? print(*ptr) : "");
619
    visit_type_str(v, &p, name, errp);
620
}
621

    
622
static void set_pointer(Object *obj, Visitor *v, Property *prop,
623
                        int (*parse)(DeviceState *dev, const char *str, void **ptr),
624
                        const char *name, Error **errp)
625
{
626
    DeviceState *dev = DEVICE(obj);
627
    Error *local_err = NULL;
628
    void **ptr = qdev_get_prop_ptr(dev, prop);
629
    char *str;
630
    int ret;
631

    
632
    if (dev->state != DEV_STATE_CREATED) {
633
        error_set(errp, QERR_PERMISSION_DENIED);
634
        return;
635
    }
636

    
637
    visit_type_str(v, &str, name, &local_err);
638
    if (local_err) {
639
        error_propagate(errp, local_err);
640
        return;
641
    }
642
    if (!*str) {
643
        g_free(str);
644
        error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
645
        return;
646
    }
647
    ret = parse(dev, str, ptr);
648
    error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
649
    g_free(str);
650
}
651

    
652
static void get_drive(Object *obj, Visitor *v, void *opaque,
653
                      const char *name, Error **errp)
654
{
655
    get_pointer(obj, v, opaque, print_drive, name, errp);
656
}
657

    
658
static void set_drive(Object *obj, Visitor *v, void *opaque,
659
                      const char *name, Error **errp)
660
{
661
    set_pointer(obj, v, opaque, parse_drive, name, errp);
662
}
663

    
664
PropertyInfo qdev_prop_drive = {
665
    .name  = "drive",
666
    .type  = PROP_TYPE_DRIVE,
667
    .size  = sizeof(BlockDriverState *),
668
    .get   = get_drive,
669
    .set   = set_drive,
670
    .free  = free_drive,
671
};
672

    
673
/* --- character device --- */
674

    
675
static int parse_chr(DeviceState *dev, const char *str, void **ptr)
676
{
677
    CharDriverState *chr = qemu_chr_find(str);
678
    if (chr == NULL) {
679
        return -ENOENT;
680
    }
681
    if (chr->avail_connections < 1) {
682
        return -EEXIST;
683
    }
684
    *ptr = chr;
685
    --chr->avail_connections;
686
    return 0;
687
}
688

    
689
static void free_chr(DeviceState *dev, Property *prop)
690
{
691
    CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
692

    
693
    if (*ptr) {
694
        qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL);
695
    }
696
}
697

    
698

    
699
static const char *print_chr(void *ptr)
700
{
701
    CharDriverState *chr = ptr;
702

    
703
    return chr->label ? chr->label : "";
704
}
705

    
706
static void get_chr(Object *obj, Visitor *v, void *opaque,
707
                    const char *name, Error **errp)
708
{
709
    get_pointer(obj, v, opaque, print_chr, name, errp);
710
}
711

    
712
static void set_chr(Object *obj, Visitor *v, void *opaque,
713
                    const char *name, Error **errp)
714
{
715
    set_pointer(obj, v, opaque, parse_chr, name, errp);
716
}
717

    
718
PropertyInfo qdev_prop_chr = {
719
    .name  = "chr",
720
    .type  = PROP_TYPE_CHR,
721
    .size  = sizeof(CharDriverState*),
722
    .get   = get_chr,
723
    .set   = set_chr,
724
    .free  = free_chr,
725
};
726

    
727
/* --- netdev device --- */
728

    
729
static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
730
{
731
    VLANClientState *netdev = qemu_find_netdev(str);
732

    
733
    if (netdev == NULL) {
734
        return -ENOENT;
735
    }
736
    if (netdev->peer) {
737
        return -EEXIST;
738
    }
739
    *ptr = netdev;
740
    return 0;
741
}
742

    
743
static const char *print_netdev(void *ptr)
744
{
745
    VLANClientState *netdev = ptr;
746

    
747
    return netdev->name ? netdev->name : "";
748
}
749

    
750
static void get_netdev(Object *obj, Visitor *v, void *opaque,
751
                       const char *name, Error **errp)
752
{
753
    get_pointer(obj, v, opaque, print_netdev, name, errp);
754
}
755

    
756
static void set_netdev(Object *obj, Visitor *v, void *opaque,
757
                       const char *name, Error **errp)
758
{
759
    set_pointer(obj, v, opaque, parse_netdev, name, errp);
760
}
761

    
762
PropertyInfo qdev_prop_netdev = {
763
    .name  = "netdev",
764
    .type  = PROP_TYPE_NETDEV,
765
    .size  = sizeof(VLANClientState*),
766
    .get   = get_netdev,
767
    .set   = set_netdev,
768
};
769

    
770
/* --- vlan --- */
771

    
772
static int parse_vlan(DeviceState *dev, Property *prop, const char *str)
773
{
774
    VLANState **ptr = qdev_get_prop_ptr(dev, prop);
775
    int id;
776

    
777
    if (sscanf(str, "%d", &id) != 1)
778
        return -EINVAL;
779
    *ptr = qemu_find_vlan(id, 1);
780
    if (*ptr == NULL)
781
        return -ENOENT;
782
    return 0;
783
}
784

    
785
static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
786
{
787
    VLANState **ptr = qdev_get_prop_ptr(dev, prop);
788

    
789
    if (*ptr) {
790
        return snprintf(dest, len, "%d", (*ptr)->id);
791
    } else {
792
        return snprintf(dest, len, "<null>");
793
    }
794
}
795

    
796
static void get_vlan(Object *obj, Visitor *v, void *opaque,
797
                     const char *name, Error **errp)
798
{
799
    DeviceState *dev = DEVICE(obj);
800
    Property *prop = opaque;
801
    VLANState **ptr = qdev_get_prop_ptr(dev, prop);
802
    int64_t id;
803

    
804
    id = *ptr ? (*ptr)->id : -1;
805
    visit_type_int(v, &id, name, errp);
806
}
807

    
808
static void set_vlan(Object *obj, Visitor *v, void *opaque,
809
                     const char *name, Error **errp)
810
{
811
    DeviceState *dev = DEVICE(obj);
812
    Property *prop = opaque;
813
    VLANState **ptr = qdev_get_prop_ptr(dev, prop);
814
    Error *local_err = NULL;
815
    int64_t id;
816
    VLANState *vlan;
817

    
818
    if (dev->state != DEV_STATE_CREATED) {
819
        error_set(errp, QERR_PERMISSION_DENIED);
820
        return;
821
    }
822

    
823
    visit_type_int(v, &id, name, &local_err);
824
    if (local_err) {
825
        error_propagate(errp, local_err);
826
        return;
827
    }
828
    if (id == -1) {
829
        *ptr = NULL;
830
        return;
831
    }
832
    vlan = qemu_find_vlan(id, 1);
833
    if (!vlan) {
834
        error_set(errp, QERR_INVALID_PARAMETER_VALUE,
835
                  name, prop->info->name);
836
        return;
837
    }
838
    *ptr = vlan;
839
}
840

    
841
PropertyInfo qdev_prop_vlan = {
842
    .name  = "vlan",
843
    .type  = PROP_TYPE_VLAN,
844
    .size  = sizeof(VLANClientState*),
845
    .parse = parse_vlan,
846
    .print = print_vlan,
847
    .get   = get_vlan,
848
    .set   = set_vlan,
849
};
850

    
851
/* --- pointer --- */
852

    
853
/* Not a proper property, just for dirty hacks.  TODO Remove it!  */
854
PropertyInfo qdev_prop_ptr = {
855
    .name  = "ptr",
856
    .type  = PROP_TYPE_PTR,
857
    .size  = sizeof(void*),
858
};
859

    
860
/* --- mac address --- */
861

    
862
/*
863
 * accepted syntax versions:
864
 *   01:02:03:04:05:06
865
 *   01-02-03-04-05-06
866
 */
867
static void get_mac(Object *obj, Visitor *v, void *opaque,
868
                    const char *name, Error **errp)
869
{
870
    DeviceState *dev = DEVICE(obj);
871
    Property *prop = opaque;
872
    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
873
    char buffer[2 * 6 + 5 + 1];
874
    char *p = buffer;
875

    
876
    snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
877
             mac->a[0], mac->a[1], mac->a[2],
878
             mac->a[3], mac->a[4], mac->a[5]);
879

    
880
    visit_type_str(v, &p, name, errp);
881
}
882

    
883
static void set_mac(Object *obj, Visitor *v, void *opaque,
884
                    const char *name, Error **errp)
885
{
886
    DeviceState *dev = DEVICE(obj);
887
    Property *prop = opaque;
888
    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
889
    Error *local_err = NULL;
890
    int i, pos;
891
    char *str, *p;
892

    
893
    if (dev->state != DEV_STATE_CREATED) {
894
        error_set(errp, QERR_PERMISSION_DENIED);
895
        return;
896
    }
897

    
898
    visit_type_str(v, &str, name, &local_err);
899
    if (local_err) {
900
        error_propagate(errp, local_err);
901
        return;
902
    }
903

    
904
    for (i = 0, pos = 0; i < 6; i++, pos += 3) {
905
        if (!qemu_isxdigit(str[pos]))
906
            goto inval;
907
        if (!qemu_isxdigit(str[pos+1]))
908
            goto inval;
909
        if (i == 5) {
910
            if (str[pos+2] != '\0')
911
                goto inval;
912
        } else {
913
            if (str[pos+2] != ':' && str[pos+2] != '-')
914
                goto inval;
915
        }
916
        mac->a[i] = strtol(str+pos, &p, 16);
917
    }
918
    return;
919

    
920
inval:
921
    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
922
}
923

    
924
PropertyInfo qdev_prop_macaddr = {
925
    .name  = "macaddr",
926
    .type  = PROP_TYPE_MACADDR,
927
    .size  = sizeof(MACAddr),
928
    .get   = get_mac,
929
    .set   = set_mac,
930
};
931

    
932

    
933
/* --- lost tick policy --- */
934

    
935
static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
936
    [LOST_TICK_DISCARD] = "discard",
937
    [LOST_TICK_DELAY] = "delay",
938
    [LOST_TICK_MERGE] = "merge",
939
    [LOST_TICK_SLEW] = "slew",
940
    [LOST_TICK_MAX] = NULL,
941
};
942

    
943
QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
944

    
945
static void get_enum(Object *obj, Visitor *v, void *opaque,
946
                     const char *name, Error **errp)
947
{
948
    DeviceState *dev = DEVICE(obj);
949
    Property *prop = opaque;
950
    int *ptr = qdev_get_prop_ptr(dev, prop);
951

    
952
    visit_type_enum(v, ptr, prop->info->enum_table,
953
                    prop->info->name, prop->name, errp);
954
}
955

    
956
static void set_enum(Object *obj, Visitor *v, void *opaque,
957
                     const char *name, Error **errp)
958
{
959
    DeviceState *dev = DEVICE(obj);
960
    Property *prop = opaque;
961
    int *ptr = qdev_get_prop_ptr(dev, prop);
962

    
963
    if (dev->state != DEV_STATE_CREATED) {
964
        error_set(errp, QERR_PERMISSION_DENIED);
965
        return;
966
    }
967

    
968
    visit_type_enum(v, ptr, prop->info->enum_table,
969
                    prop->info->name, prop->name, errp);
970
}
971

    
972
PropertyInfo qdev_prop_losttickpolicy = {
973
    .name  = "LostTickPolicy",
974
    .type  = PROP_TYPE_LOSTTICKPOLICY,
975
    .size  = sizeof(LostTickPolicy),
976
    .enum_table  = lost_tick_policy_table,
977
    .get   = get_enum,
978
    .set   = set_enum,
979
};
980

    
981
/* --- pci address --- */
982

    
983
/*
984
 * bus-local address, i.e. "$slot" or "$slot.$fn"
985
 */
986
static int parse_pci_devfn(DeviceState *dev, Property *prop, const char *str)
987
{
988
    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
989
    unsigned int slot, fn, n;
990

    
991
    if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
992
        fn = 0;
993
        if (sscanf(str, "%x%n", &slot, &n) != 1) {
994
            return -EINVAL;
995
        }
996
    }
997
    if (str[n] != '\0')
998
        return -EINVAL;
999
    if (fn > 7)
1000
        return -EINVAL;
1001
    if (slot > 31)
1002
        return -EINVAL;
1003
    *ptr = slot << 3 | fn;
1004
    return 0;
1005
}
1006

    
1007
static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
1008
{
1009
    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
1010

    
1011
    if (*ptr == -1) {
1012
        return snprintf(dest, len, "<unset>");
1013
    } else {
1014
        return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
1015
    }
1016
}
1017

    
1018
PropertyInfo qdev_prop_pci_devfn = {
1019
    .name  = "int32",
1020
    .legacy_name  = "pci-devfn",
1021
    .type  = PROP_TYPE_UINT32,
1022
    .size  = sizeof(uint32_t),
1023
    .parse = parse_pci_devfn,
1024
    .print = print_pci_devfn,
1025
    .get   = get_int32,
1026
    .set   = set_int32,
1027
    /* FIXME: this should be -1...255, but the address is stored
1028
     * into an uint32_t rather than int32_t.
1029
     */
1030
    .min   = 0,
1031
    .max   = 0xFFFFFFFFULL,
1032
};
1033

    
1034
/* --- public helpers --- */
1035

    
1036
static Property *qdev_prop_walk(Property *props, const char *name)
1037
{
1038
    if (!props)
1039
        return NULL;
1040
    while (props->name) {
1041
        if (strcmp(props->name, name) == 0)
1042
            return props;
1043
        props++;
1044
    }
1045
    return NULL;
1046
}
1047

    
1048
static Property *qdev_prop_find(DeviceState *dev, const char *name)
1049
{
1050
    Property *prop;
1051

    
1052
    /* device properties */
1053
    prop = qdev_prop_walk(qdev_get_props(dev), name);
1054
    if (prop)
1055
        return prop;
1056

    
1057
    /* bus properties */
1058
    prop = qdev_prop_walk(dev->parent_bus->info->props, name);
1059
    if (prop)
1060
        return prop;
1061

    
1062
    return NULL;
1063
}
1064

    
1065
int qdev_prop_exists(DeviceState *dev, const char *name)
1066
{
1067
    return qdev_prop_find(dev, name) ? true : false;
1068
}
1069

    
1070
void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
1071
                                    Property *prop, const char *value)
1072
{
1073
    switch (ret) {
1074
    case -EEXIST:
1075
        error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
1076
                  object_get_typename(OBJECT(dev)), prop->name, value);
1077
        break;
1078
    default:
1079
    case -EINVAL:
1080
        error_set(errp, QERR_PROPERTY_VALUE_BAD,
1081
                  object_get_typename(OBJECT(dev)), prop->name, value);
1082
        break;
1083
    case -ENOENT:
1084
        error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
1085
                  object_get_typename(OBJECT(dev)), prop->name, value);
1086
        break;
1087
    case 0:
1088
        break;
1089
    }
1090
}
1091

    
1092
int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
1093
{
1094
    char *legacy_name;
1095
    Error *err = NULL;
1096

    
1097
    legacy_name = g_strdup_printf("legacy-%s", name);
1098
    if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
1099
        object_property_set_str(OBJECT(dev), value, legacy_name, &err);
1100
    } else {
1101
        object_property_set_str(OBJECT(dev), value, name, &err);
1102
    }
1103
    g_free(legacy_name);
1104

    
1105
    if (err) {
1106
        qerror_report_err(err);
1107
        error_free(err);
1108
        return -1;
1109
    }
1110
    return 0;
1111
}
1112

    
1113
void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
1114
{
1115
    Property *prop;
1116

    
1117
    prop = qdev_prop_find(dev, name);
1118
    if (!prop) {
1119
        fprintf(stderr, "%s: property \"%s.%s\" not found\n",
1120
                __FUNCTION__, object_get_typename(OBJECT(dev)), name);
1121
        abort();
1122
    }
1123
    if (prop->info->type != type) {
1124
        fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n",
1125
                __FUNCTION__, object_get_typename(OBJECT(dev)), name);
1126
        abort();
1127
    }
1128
    qdev_prop_cpy(dev, prop, src);
1129
}
1130

    
1131
void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1132
{
1133
    qdev_prop_set(dev, name, &value, PROP_TYPE_BIT);
1134
}
1135

    
1136
void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1137
{
1138
    qdev_prop_set(dev, name, &value, PROP_TYPE_UINT8);
1139
}
1140

    
1141
void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1142
{
1143
    qdev_prop_set(dev, name, &value, PROP_TYPE_UINT16);
1144
}
1145

    
1146
void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1147
{
1148
    qdev_prop_set(dev, name, &value, PROP_TYPE_UINT32);
1149
}
1150

    
1151
void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1152
{
1153
    qdev_prop_set(dev, name, &value, PROP_TYPE_INT32);
1154
}
1155

    
1156
void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1157
{
1158
    qdev_prop_set(dev, name, &value, PROP_TYPE_UINT64);
1159
}
1160

    
1161
void qdev_prop_set_string(DeviceState *dev, const char *name, char *value)
1162
{
1163
    qdev_prop_set(dev, name, &value, PROP_TYPE_STRING);
1164
}
1165

    
1166
int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
1167
{
1168
    int res;
1169

    
1170
    res = bdrv_attach_dev(value, dev);
1171
    if (res < 0) {
1172
        error_report("Can't attach drive %s to %s.%s: %s",
1173
                     bdrv_get_device_name(value),
1174
                     dev->id ? dev->id : object_get_typename(OBJECT(dev)),
1175
                     name, strerror(-res));
1176
        return -1;
1177
    }
1178
    qdev_prop_set(dev, name, &value, PROP_TYPE_DRIVE);
1179
    return 0;
1180
}
1181

    
1182
void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value)
1183
{
1184
    if (qdev_prop_set_drive(dev, name, value) < 0) {
1185
        exit(1);
1186
    }
1187
}
1188
void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
1189
{
1190
    qdev_prop_set(dev, name, &value, PROP_TYPE_CHR);
1191
}
1192

    
1193
void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value)
1194
{
1195
    qdev_prop_set(dev, name, &value, PROP_TYPE_NETDEV);
1196
}
1197

    
1198
void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
1199
{
1200
    qdev_prop_set(dev, name, &value, PROP_TYPE_VLAN);
1201
}
1202

    
1203
void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
1204
{
1205
    qdev_prop_set(dev, name, value, PROP_TYPE_MACADDR);
1206
}
1207

    
1208
void qdev_prop_set_losttickpolicy(DeviceState *dev, const char *name,
1209
                                  LostTickPolicy *value)
1210
{
1211
    qdev_prop_set(dev, name, value, PROP_TYPE_LOSTTICKPOLICY);
1212
}
1213

    
1214
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1215
{
1216
    qdev_prop_set(dev, name, &value, PROP_TYPE_PTR);
1217
}
1218

    
1219
void qdev_prop_set_defaults(DeviceState *dev, Property *props)
1220
{
1221
    if (!props)
1222
        return;
1223
    while (props->name) {
1224
        if (props->defval) {
1225
            qdev_prop_cpy(dev, props, props->defval);
1226
        }
1227
        props++;
1228
    }
1229
}
1230

    
1231
static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
1232

    
1233
static void qdev_prop_register_global(GlobalProperty *prop)
1234
{
1235
    QTAILQ_INSERT_TAIL(&global_props, prop, next);
1236
}
1237

    
1238
void qdev_prop_register_global_list(GlobalProperty *props)
1239
{
1240
    int i;
1241

    
1242
    for (i = 0; props[i].driver != NULL; i++) {
1243
        qdev_prop_register_global(props+i);
1244
    }
1245
}
1246

    
1247
void qdev_prop_set_globals(DeviceState *dev)
1248
{
1249
    GlobalProperty *prop;
1250

    
1251
    QTAILQ_FOREACH(prop, &global_props, next) {
1252
        if (strcmp(object_get_typename(OBJECT(dev)), prop->driver) != 0 &&
1253
            strcmp(qdev_get_bus_info(dev)->name, prop->driver) != 0) {
1254
            continue;
1255
        }
1256
        if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
1257
            exit(1);
1258
        }
1259
    }
1260
}
1261

    
1262
static int qdev_add_one_global(QemuOpts *opts, void *opaque)
1263
{
1264
    GlobalProperty *g;
1265

    
1266
    g = g_malloc0(sizeof(*g));
1267
    g->driver   = qemu_opt_get(opts, "driver");
1268
    g->property = qemu_opt_get(opts, "property");
1269
    g->value    = qemu_opt_get(opts, "value");
1270
    qdev_prop_register_global(g);
1271
    return 0;
1272
}
1273

    
1274
void qemu_add_globals(void)
1275
{
1276
    qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0);
1277
}