]> Git Repo - qemu.git/blame - hw/qdev-properties.c
net: Drop vlan argument to qemu_new_net_client()
[qemu.git] / hw / qdev-properties.c
CommitLineData
1503fff3 1#include "net.h"
ee6847d1 2#include "qdev.h"
9f59b566 3#include "qerror.h"
2446333c 4#include "blockdev.h"
2b584959 5#include "hw/block-common.h"
ee6847d1
GH
6
7void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
8{
9 void *ptr = dev;
10 ptr += prop->offset;
11 return ptr;
12}
13
d4d34b0d
MA
14static void get_pointer(Object *obj, Visitor *v, Property *prop,
15 const char *(*print)(void *ptr),
16 const char *name, Error **errp)
17{
18 DeviceState *dev = DEVICE(obj);
19 void **ptr = qdev_get_prop_ptr(dev, prop);
20 char *p;
21
22 p = (char *) (*ptr ? print(*ptr) : "");
23 visit_type_str(v, &p, name, errp);
24}
25
26static void set_pointer(Object *obj, Visitor *v, Property *prop,
27 int (*parse)(DeviceState *dev, const char *str,
28 void **ptr),
29 const char *name, Error **errp)
30{
31 DeviceState *dev = DEVICE(obj);
32 Error *local_err = NULL;
33 void **ptr = qdev_get_prop_ptr(dev, prop);
34 char *str;
35 int ret;
36
37 if (dev->state != DEV_STATE_CREATED) {
38 error_set(errp, QERR_PERMISSION_DENIED);
39 return;
40 }
41
42 visit_type_str(v, &str, name, &local_err);
43 if (local_err) {
44 error_propagate(errp, local_err);
45 return;
46 }
47 if (!*str) {
48 g_free(str);
49 *ptr = NULL;
50 return;
51 }
52 ret = parse(dev, str, ptr);
53 error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
54 g_free(str);
55}
56
57static void get_enum(Object *obj, Visitor *v, void *opaque,
58 const char *name, Error **errp)
59{
60 DeviceState *dev = DEVICE(obj);
61 Property *prop = opaque;
62 int *ptr = qdev_get_prop_ptr(dev, prop);
63
64 visit_type_enum(v, ptr, prop->info->enum_table,
65 prop->info->name, prop->name, errp);
66}
67
68static void set_enum(Object *obj, Visitor *v, void *opaque,
69 const char *name, Error **errp)
70{
71 DeviceState *dev = DEVICE(obj);
72 Property *prop = opaque;
73 int *ptr = qdev_get_prop_ptr(dev, prop);
74
75 if (dev->state != DEV_STATE_CREATED) {
76 error_set(errp, QERR_PERMISSION_DENIED);
77 return;
78 }
79
80 visit_type_enum(v, ptr, prop->info->enum_table,
81 prop->info->name, prop->name, errp);
82}
83
84/* Bit */
85
d2364ee4
MT
86static uint32_t qdev_get_prop_mask(Property *prop)
87{
a3d4a1b0 88 assert(prop->info == &qdev_prop_bit);
d2364ee4
MT
89 return 0x1 << prop->bitnr;
90}
91
92static void bit_prop_set(DeviceState *dev, Property *props, bool val)
93{
94 uint32_t *p = qdev_get_prop_ptr(dev, props);
95 uint32_t mask = qdev_get_prop_mask(props);
96 if (val)
dbd48324 97 *p |= mask;
d2364ee4
MT
98 else
99 *p &= ~mask;
100}
101
d2364ee4
MT
102static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
103{
5a5e3d55 104 uint32_t *p = qdev_get_prop_ptr(dev, prop);
d2364ee4
MT
105 return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
106}
107
57c9fafe 108static void get_bit(Object *obj, Visitor *v, void *opaque,
80e555c2
PB
109 const char *name, Error **errp)
110{
57c9fafe 111 DeviceState *dev = DEVICE(obj);
80e555c2
PB
112 Property *prop = opaque;
113 uint32_t *p = qdev_get_prop_ptr(dev, prop);
114 bool value = (*p & qdev_get_prop_mask(prop)) != 0;
115
116 visit_type_bool(v, &value, name, errp);
117}
118
57c9fafe 119static void set_bit(Object *obj, Visitor *v, void *opaque,
80e555c2
PB
120 const char *name, Error **errp)
121{
57c9fafe 122 DeviceState *dev = DEVICE(obj);
80e555c2
PB
123 Property *prop = opaque;
124 Error *local_err = NULL;
125 bool value;
126
127 if (dev->state != DEV_STATE_CREATED) {
128 error_set(errp, QERR_PERMISSION_DENIED);
129 return;
130 }
131
132 visit_type_bool(v, &value, name, &local_err);
133 if (local_err) {
134 error_propagate(errp, local_err);
135 return;
136 }
137 bit_prop_set(dev, prop, value);
138}
139
d2364ee4 140PropertyInfo qdev_prop_bit = {
cafe5bdb
PB
141 .name = "boolean",
142 .legacy_name = "on/off",
d2364ee4 143 .print = print_bit,
80e555c2
PB
144 .get = get_bit,
145 .set = set_bit,
d2364ee4
MT
146};
147
c7cc172d
JQ
148/* --- 8bit integer --- */
149
c08fb2ac
MR
150static void get_uint8(Object *obj, Visitor *v, void *opaque,
151 const char *name, Error **errp)
80e555c2 152{
57c9fafe 153 DeviceState *dev = DEVICE(obj);
80e555c2 154 Property *prop = opaque;
c08fb2ac 155 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
80e555c2 156
c08fb2ac 157 visit_type_uint8(v, ptr, name, errp);
80e555c2
PB
158}
159
c08fb2ac
MR
160static void set_uint8(Object *obj, Visitor *v, void *opaque,
161 const char *name, Error **errp)
80e555c2 162{
57c9fafe 163 DeviceState *dev = DEVICE(obj);
80e555c2 164 Property *prop = opaque;
27712df9 165 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
80e555c2
PB
166
167 if (dev->state != DEV_STATE_CREATED) {
168 error_set(errp, QERR_PERMISSION_DENIED);
169 return;
170 }
171
27712df9 172 visit_type_uint8(v, ptr, name, errp);
80e555c2
PB
173}
174
c7cc172d
JQ
175PropertyInfo qdev_prop_uint8 = {
176 .name = "uint8",
c08fb2ac
MR
177 .get = get_uint8,
178 .set = set_uint8,
c7cc172d
JQ
179};
180
6835678c
JK
181/* --- 8bit hex value --- */
182
183static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
184{
185 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
186 char *end;
187
97aa6e9b
PB
188 if (str[0] != '0' || str[1] != 'x') {
189 return -EINVAL;
190 }
191
6835678c
JK
192 *ptr = strtoul(str, &end, 16);
193 if ((*end != '\0') || (end == str)) {
194 return -EINVAL;
195 }
196
197 return 0;
198}
199
200static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
201{
202 uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
203 return snprintf(dest, len, "0x%" PRIx8, *ptr);
204}
205
206PropertyInfo qdev_prop_hex8 = {
cafe5bdb
PB
207 .name = "uint8",
208 .legacy_name = "hex8",
6835678c
JK
209 .parse = parse_hex8,
210 .print = print_hex8,
c08fb2ac
MR
211 .get = get_uint8,
212 .set = set_uint8,
6835678c
JK
213};
214
ee6847d1
GH
215/* --- 16bit integer --- */
216
c08fb2ac
MR
217static void get_uint16(Object *obj, Visitor *v, void *opaque,
218 const char *name, Error **errp)
80e555c2 219{
57c9fafe 220 DeviceState *dev = DEVICE(obj);
80e555c2 221 Property *prop = opaque;
c08fb2ac 222 uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
80e555c2 223
c08fb2ac 224 visit_type_uint16(v, ptr, name, errp);
80e555c2
PB
225}
226
c08fb2ac
MR
227static void set_uint16(Object *obj, Visitor *v, void *opaque,
228 const char *name, Error **errp)
80e555c2 229{
57c9fafe 230 DeviceState *dev = DEVICE(obj);
80e555c2 231 Property *prop = opaque;
27712df9 232 uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
80e555c2
PB
233
234 if (dev->state != DEV_STATE_CREATED) {
235 error_set(errp, QERR_PERMISSION_DENIED);
236 return;
237 }
238
27712df9 239 visit_type_uint16(v, ptr, name, errp);
80e555c2
PB
240}
241
ee6847d1
GH
242PropertyInfo qdev_prop_uint16 = {
243 .name = "uint16",
c08fb2ac
MR
244 .get = get_uint16,
245 .set = set_uint16,
ee6847d1
GH
246};
247
248/* --- 32bit integer --- */
249
c08fb2ac
MR
250static void get_uint32(Object *obj, Visitor *v, void *opaque,
251 const char *name, Error **errp)
252{
253 DeviceState *dev = DEVICE(obj);
254 Property *prop = opaque;
27712df9 255 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
c08fb2ac 256
27712df9 257 visit_type_uint32(v, ptr, name, errp);
c08fb2ac
MR
258}
259
260static void set_uint32(Object *obj, Visitor *v, void *opaque,
261 const char *name, Error **errp)
262{
263 DeviceState *dev = DEVICE(obj);
264 Property *prop = opaque;
27712df9 265 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
c08fb2ac
MR
266
267 if (dev->state != DEV_STATE_CREATED) {
268 error_set(errp, QERR_PERMISSION_DENIED);
269 return;
270 }
271
27712df9 272 visit_type_uint32(v, ptr, name, errp);
c08fb2ac
MR
273}
274
57c9fafe 275static void get_int32(Object *obj, Visitor *v, void *opaque,
80e555c2
PB
276 const char *name, Error **errp)
277{
57c9fafe 278 DeviceState *dev = DEVICE(obj);
80e555c2
PB
279 Property *prop = opaque;
280 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
80e555c2 281
c08fb2ac 282 visit_type_int32(v, ptr, name, errp);
80e555c2
PB
283}
284
57c9fafe 285static void set_int32(Object *obj, Visitor *v, void *opaque,
80e555c2
PB
286 const char *name, Error **errp)
287{
57c9fafe 288 DeviceState *dev = DEVICE(obj);
80e555c2 289 Property *prop = opaque;
27712df9 290 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
80e555c2
PB
291
292 if (dev->state != DEV_STATE_CREATED) {
293 error_set(errp, QERR_PERMISSION_DENIED);
294 return;
295 }
296
27712df9 297 visit_type_int32(v, ptr, name, errp);
80e555c2
PB
298}
299
ee6847d1
GH
300PropertyInfo qdev_prop_uint32 = {
301 .name = "uint32",
c08fb2ac
MR
302 .get = get_uint32,
303 .set = set_uint32,
ee6847d1
GH
304};
305
316940b0
GH
306PropertyInfo qdev_prop_int32 = {
307 .name = "int32",
80e555c2
PB
308 .get = get_int32,
309 .set = set_int32,
316940b0
GH
310};
311
ee6847d1
GH
312/* --- 32bit hex value --- */
313
314static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
315{
316 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
449041d4 317 char *end;
ee6847d1 318
97aa6e9b
PB
319 if (str[0] != '0' || str[1] != 'x') {
320 return -EINVAL;
321 }
322
449041d4
KW
323 *ptr = strtoul(str, &end, 16);
324 if ((*end != '\0') || (end == str)) {
6bf38816 325 return -EINVAL;
449041d4
KW
326 }
327
ee6847d1
GH
328 return 0;
329}
330
331static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
332{
333 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
334 return snprintf(dest, len, "0x%" PRIx32, *ptr);
335}
336
337PropertyInfo qdev_prop_hex32 = {
cafe5bdb
PB
338 .name = "uint32",
339 .legacy_name = "hex32",
ee6847d1
GH
340 .parse = parse_hex32,
341 .print = print_hex32,
c08fb2ac
MR
342 .get = get_uint32,
343 .set = set_uint32,
ee6847d1
GH
344};
345
5a053d1f
BS
346/* --- 64bit integer --- */
347
c08fb2ac
MR
348static void get_uint64(Object *obj, Visitor *v, void *opaque,
349 const char *name, Error **errp)
80e555c2 350{
57c9fafe 351 DeviceState *dev = DEVICE(obj);
80e555c2 352 Property *prop = opaque;
c08fb2ac 353 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
80e555c2 354
c08fb2ac 355 visit_type_uint64(v, ptr, name, errp);
80e555c2
PB
356}
357
c08fb2ac
MR
358static void set_uint64(Object *obj, Visitor *v, void *opaque,
359 const char *name, Error **errp)
80e555c2 360{
57c9fafe 361 DeviceState *dev = DEVICE(obj);
80e555c2 362 Property *prop = opaque;
c08fb2ac 363 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
80e555c2
PB
364
365 if (dev->state != DEV_STATE_CREATED) {
366 error_set(errp, QERR_PERMISSION_DENIED);
367 return;
368 }
369
c08fb2ac 370 visit_type_uint64(v, ptr, name, errp);
80e555c2
PB
371}
372
5a053d1f
BS
373PropertyInfo qdev_prop_uint64 = {
374 .name = "uint64",
c08fb2ac
MR
375 .get = get_uint64,
376 .set = set_uint64,
5a053d1f
BS
377};
378
379/* --- 64bit hex value --- */
380
381static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
382{
383 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
449041d4 384 char *end;
5a053d1f 385
97aa6e9b
PB
386 if (str[0] != '0' || str[1] != 'x') {
387 return -EINVAL;
388 }
389
449041d4
KW
390 *ptr = strtoull(str, &end, 16);
391 if ((*end != '\0') || (end == str)) {
6bf38816 392 return -EINVAL;
449041d4
KW
393 }
394
5a053d1f
BS
395 return 0;
396}
397
398static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
399{
400 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
401 return snprintf(dest, len, "0x%" PRIx64, *ptr);
402}
403
404PropertyInfo qdev_prop_hex64 = {
cafe5bdb
PB
405 .name = "uint64",
406 .legacy_name = "hex64",
5a053d1f
BS
407 .parse = parse_hex64,
408 .print = print_hex64,
c08fb2ac
MR
409 .get = get_uint64,
410 .set = set_uint64,
5a053d1f
BS
411};
412
59419663
GH
413/* --- string --- */
414
dd0ba250 415static void release_string(Object *obj, const char *name, void *opaque)
d21357df 416{
dd0ba250
PB
417 Property *prop = opaque;
418 g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
d21357df
MA
419}
420
59419663
GH
421static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
422{
423 char **ptr = qdev_get_prop_ptr(dev, prop);
424 if (!*ptr)
425 return snprintf(dest, len, "<null>");
426 return snprintf(dest, len, "\"%s\"", *ptr);
427}
428
57c9fafe 429static void get_string(Object *obj, Visitor *v, void *opaque,
80e555c2
PB
430 const char *name, Error **errp)
431{
57c9fafe 432 DeviceState *dev = DEVICE(obj);
80e555c2
PB
433 Property *prop = opaque;
434 char **ptr = qdev_get_prop_ptr(dev, prop);
435
436 if (!*ptr) {
437 char *str = (char *)"";
438 visit_type_str(v, &str, name, errp);
439 } else {
440 visit_type_str(v, ptr, name, errp);
441 }
442}
443
57c9fafe 444static void set_string(Object *obj, Visitor *v, void *opaque,
80e555c2
PB
445 const char *name, Error **errp)
446{
57c9fafe 447 DeviceState *dev = DEVICE(obj);
80e555c2
PB
448 Property *prop = opaque;
449 char **ptr = qdev_get_prop_ptr(dev, prop);
450 Error *local_err = NULL;
451 char *str;
452
453 if (dev->state != DEV_STATE_CREATED) {
454 error_set(errp, QERR_PERMISSION_DENIED);
455 return;
456 }
457
458 visit_type_str(v, &str, name, &local_err);
459 if (local_err) {
460 error_propagate(errp, local_err);
461 return;
462 }
80e555c2
PB
463 if (*ptr) {
464 g_free(*ptr);
465 }
466 *ptr = str;
467}
468
59419663
GH
469PropertyInfo qdev_prop_string = {
470 .name = "string",
59419663 471 .print = print_string,
dd0ba250 472 .release = release_string,
80e555c2
PB
473 .get = get_string,
474 .set = set_string,
59419663
GH
475};
476
14b41872
GH
477/* --- drive --- */
478
7b009e5d 479static int parse_drive(DeviceState *dev, const char *str, void **ptr)
14b41872 480{
f8b6cc00 481 BlockDriverState *bs;
14b41872 482
f8b6cc00
MA
483 bs = bdrv_find(str);
484 if (bs == NULL)
6bf38816 485 return -ENOENT;
fa879d62 486 if (bdrv_attach_dev(bs, dev) < 0)
18846dee 487 return -EEXIST;
f8b6cc00 488 *ptr = bs;
14b41872
GH
489 return 0;
490}
491
dd0ba250 492static void release_drive(Object *obj, const char *name, void *opaque)
14bafc54 493{
dd0ba250
PB
494 DeviceState *dev = DEVICE(obj);
495 Property *prop = opaque;
f8b6cc00 496 BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
14bafc54
MA
497
498 if (*ptr) {
fa879d62 499 bdrv_detach_dev(*ptr, dev);
f8b6cc00 500 blockdev_auto_del(*ptr);
14bafc54
MA
501 }
502}
503
7b009e5d 504static const char *print_drive(void *ptr)
14b41872 505{
7b009e5d 506 return bdrv_get_device_name(ptr);
14b41872
GH
507}
508
7b009e5d
PB
509static void get_drive(Object *obj, Visitor *v, void *opaque,
510 const char *name, Error **errp)
511{
512 get_pointer(obj, v, opaque, print_drive, name, errp);
513}
514
515static void set_drive(Object *obj, Visitor *v, void *opaque,
516 const char *name, Error **errp)
517{
518 set_pointer(obj, v, opaque, parse_drive, name, errp);
519}
520
14b41872
GH
521PropertyInfo qdev_prop_drive = {
522 .name = "drive",
7b009e5d
PB
523 .get = get_drive,
524 .set = set_drive,
dd0ba250 525 .release = release_drive,
14b41872
GH
526};
527
313feaab
GH
528/* --- character device --- */
529
7b009e5d 530static int parse_chr(DeviceState *dev, const char *str, void **ptr)
06113719 531{
7b009e5d
PB
532 CharDriverState *chr = qemu_chr_find(str);
533 if (chr == NULL) {
6bf38816 534 return -ENOENT;
2d6c1ef4 535 }
7b009e5d 536 if (chr->avail_connections < 1) {
2d6c1ef4
AS
537 return -EEXIST;
538 }
7b009e5d
PB
539 *ptr = chr;
540 --chr->avail_connections;
06113719
GH
541 return 0;
542}
543
dd0ba250 544static void release_chr(Object *obj, const char *name, void *opaque)
a87f3e8b 545{
dd0ba250
PB
546 DeviceState *dev = DEVICE(obj);
547 Property *prop = opaque;
a87f3e8b
AS
548 CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
549
550 if (*ptr) {
551 qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL);
552 }
553}
554
555
7b009e5d 556static const char *print_chr(void *ptr)
313feaab 557{
7b009e5d 558 CharDriverState *chr = ptr;
bc19fcaa 559
7b009e5d
PB
560 return chr->label ? chr->label : "";
561}
562
563static void get_chr(Object *obj, Visitor *v, void *opaque,
564 const char *name, Error **errp)
565{
566 get_pointer(obj, v, opaque, print_chr, name, errp);
567}
568
569static void set_chr(Object *obj, Visitor *v, void *opaque,
570 const char *name, Error **errp)
571{
572 set_pointer(obj, v, opaque, parse_chr, name, errp);
313feaab
GH
573}
574
575PropertyInfo qdev_prop_chr = {
576 .name = "chr",
7b009e5d
PB
577 .get = get_chr,
578 .set = set_chr,
dd0ba250 579 .release = release_chr,
313feaab
GH
580};
581
2ef924b4
GH
582/* --- netdev device --- */
583
7b009e5d 584static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
2ef924b4 585{
7b009e5d 586 VLANClientState *netdev = qemu_find_netdev(str);
2ef924b4 587
7b009e5d 588 if (netdev == NULL) {
6bf38816 589 return -ENOENT;
7b009e5d
PB
590 }
591 if (netdev->peer) {
27f3f8a3
MA
592 return -EEXIST;
593 }
7b009e5d 594 *ptr = netdev;
2ef924b4
GH
595 return 0;
596}
597
7b009e5d 598static const char *print_netdev(void *ptr)
2ef924b4 599{
7b009e5d 600 VLANClientState *netdev = ptr;
2ef924b4 601
7b009e5d
PB
602 return netdev->name ? netdev->name : "";
603}
604
605static void get_netdev(Object *obj, Visitor *v, void *opaque,
606 const char *name, Error **errp)
607{
608 get_pointer(obj, v, opaque, print_netdev, name, errp);
609}
610
611static void set_netdev(Object *obj, Visitor *v, void *opaque,
612 const char *name, Error **errp)
613{
614 set_pointer(obj, v, opaque, parse_netdev, name, errp);
2ef924b4
GH
615}
616
617PropertyInfo qdev_prop_netdev = {
618 .name = "netdev",
7b009e5d
PB
619 .get = get_netdev,
620 .set = set_netdev,
2ef924b4
GH
621};
622
851bec09
GH
623/* --- vlan --- */
624
851bec09
GH
625static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
626{
627 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
628
629 if (*ptr) {
630 return snprintf(dest, len, "%d", (*ptr)->id);
631 } else {
632 return snprintf(dest, len, "<null>");
633 }
634}
635
57c9fafe 636static void get_vlan(Object *obj, Visitor *v, void *opaque,
80e555c2
PB
637 const char *name, Error **errp)
638{
57c9fafe 639 DeviceState *dev = DEVICE(obj);
80e555c2
PB
640 Property *prop = opaque;
641 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
642 int64_t id;
643
644 id = *ptr ? (*ptr)->id : -1;
c08fb2ac 645 visit_type_int64(v, &id, name, errp);
80e555c2
PB
646}
647
57c9fafe 648static void set_vlan(Object *obj, Visitor *v, void *opaque,
80e555c2
PB
649 const char *name, Error **errp)
650{
57c9fafe 651 DeviceState *dev = DEVICE(obj);
80e555c2
PB
652 Property *prop = opaque;
653 VLANState **ptr = qdev_get_prop_ptr(dev, prop);
654 Error *local_err = NULL;
655 int64_t id;
656 VLANState *vlan;
657
658 if (dev->state != DEV_STATE_CREATED) {
659 error_set(errp, QERR_PERMISSION_DENIED);
660 return;
661 }
662
c08fb2ac 663 visit_type_int64(v, &id, name, &local_err);
80e555c2
PB
664 if (local_err) {
665 error_propagate(errp, local_err);
666 return;
667 }
668 if (id == -1) {
669 *ptr = NULL;
670 return;
671 }
672 vlan = qemu_find_vlan(id, 1);
673 if (!vlan) {
674 error_set(errp, QERR_INVALID_PARAMETER_VALUE,
675 name, prop->info->name);
676 return;
677 }
678 *ptr = vlan;
679}
680
851bec09
GH
681PropertyInfo qdev_prop_vlan = {
682 .name = "vlan",
851bec09 683 .print = print_vlan,
80e555c2
PB
684 .get = get_vlan,
685 .set = set_vlan,
851bec09
GH
686};
687
ee6847d1
GH
688/* --- pointer --- */
689
036f7166 690/* Not a proper property, just for dirty hacks. TODO Remove it! */
ee6847d1
GH
691PropertyInfo qdev_prop_ptr = {
692 .name = "ptr",
ee6847d1
GH
693};
694
695/* --- mac address --- */
696
697/*
698 * accepted syntax versions:
699 * 01:02:03:04:05:06
700 * 01-02-03-04-05-06
701 */
e39e5d60
PB
702static void get_mac(Object *obj, Visitor *v, void *opaque,
703 const char *name, Error **errp)
ee6847d1 704{
e39e5d60
PB
705 DeviceState *dev = DEVICE(obj);
706 Property *prop = opaque;
1503fff3 707 MACAddr *mac = qdev_get_prop_ptr(dev, prop);
e39e5d60
PB
708 char buffer[2 * 6 + 5 + 1];
709 char *p = buffer;
710
711 snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
712 mac->a[0], mac->a[1], mac->a[2],
713 mac->a[3], mac->a[4], mac->a[5]);
714
715 visit_type_str(v, &p, name, errp);
716}
717
718static void set_mac(Object *obj, Visitor *v, void *opaque,
719 const char *name, Error **errp)
720{
721 DeviceState *dev = DEVICE(obj);
722 Property *prop = opaque;
723 MACAddr *mac = qdev_get_prop_ptr(dev, prop);
724 Error *local_err = NULL;
ee6847d1 725 int i, pos;
e39e5d60
PB
726 char *str, *p;
727
728 if (dev->state != DEV_STATE_CREATED) {
729 error_set(errp, QERR_PERMISSION_DENIED);
730 return;
731 }
732
733 visit_type_str(v, &str, name, &local_err);
734 if (local_err) {
735 error_propagate(errp, local_err);
736 return;
737 }
ee6847d1
GH
738
739 for (i = 0, pos = 0; i < 6; i++, pos += 3) {
88e150a5 740 if (!qemu_isxdigit(str[pos]))
e39e5d60 741 goto inval;
88e150a5 742 if (!qemu_isxdigit(str[pos+1]))
e39e5d60 743 goto inval;
1503fff3
GH
744 if (i == 5) {
745 if (str[pos+2] != '\0')
e39e5d60 746 goto inval;
1503fff3
GH
747 } else {
748 if (str[pos+2] != ':' && str[pos+2] != '-')
e39e5d60 749 goto inval;
1503fff3
GH
750 }
751 mac->a[i] = strtol(str+pos, &p, 16);
ee6847d1 752 }
a3400466 753 g_free(str);
e39e5d60 754 return;
1503fff3 755
e39e5d60
PB
756inval:
757 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
a3400466 758 g_free(str);
ee6847d1
GH
759}
760
761PropertyInfo qdev_prop_macaddr = {
1503fff3 762 .name = "macaddr",
e39e5d60
PB
763 .get = get_mac,
764 .set = set_mac,
ee6847d1
GH
765};
766
4e4fa398
JK
767/* --- lost tick policy --- */
768
1ce05125
PB
769static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
770 [LOST_TICK_DISCARD] = "discard",
771 [LOST_TICK_DELAY] = "delay",
772 [LOST_TICK_MERGE] = "merge",
773 [LOST_TICK_SLEW] = "slew",
774 [LOST_TICK_MAX] = NULL,
4e4fa398
JK
775};
776
1ce05125
PB
777QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
778
4e4fa398 779PropertyInfo qdev_prop_losttickpolicy = {
1ce05125 780 .name = "LostTickPolicy",
1ce05125
PB
781 .enum_table = lost_tick_policy_table,
782 .get = get_enum,
783 .set = set_enum,
4e4fa398
JK
784};
785
8cd41745
MA
786/* --- BIOS CHS translation */
787
788static const char *bios_chs_trans_table[] = {
789 [BIOS_ATA_TRANSLATION_AUTO] = "auto",
790 [BIOS_ATA_TRANSLATION_NONE] = "none",
791 [BIOS_ATA_TRANSLATION_LBA] = "lba",
792};
793
794PropertyInfo qdev_prop_bios_chs_trans = {
795 .name = "bios-chs-trans",
796 .enum_table = bios_chs_trans_table,
797 .get = get_enum,
798 .set = set_enum,
799};
800
05cb5fe4
GH
801/* --- pci address --- */
802
803/*
804 * bus-local address, i.e. "$slot" or "$slot.$fn"
805 */
768a9ebe
PB
806static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
807 const char *name, Error **errp)
05cb5fe4 808{
768a9ebe
PB
809 DeviceState *dev = DEVICE(obj);
810 Property *prop = opaque;
27712df9 811 int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
05cb5fe4 812 unsigned int slot, fn, n;
768a9ebe 813 Error *local_err = NULL;
a3400466 814 char *str;
768a9ebe
PB
815
816 if (dev->state != DEV_STATE_CREATED) {
817 error_set(errp, QERR_PERMISSION_DENIED);
818 return;
819 }
820
821 visit_type_str(v, &str, name, &local_err);
822 if (local_err) {
5c878008 823 error_free(local_err);
27712df9
PB
824 local_err = NULL;
825 visit_type_int32(v, &value, name, &local_err);
826 if (local_err) {
827 error_propagate(errp, local_err);
828 } else if (value < -1 || value > 255) {
829 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
830 "pci_devfn");
831 } else {
832 *ptr = value;
833 }
834 return;
768a9ebe 835 }
05cb5fe4
GH
836
837 if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
838 fn = 0;
839 if (sscanf(str, "%x%n", &slot, &n) != 1) {
768a9ebe 840 goto invalid;
05cb5fe4
GH
841 }
842 }
768a9ebe
PB
843 if (str[n] != '\0' || fn > 7 || slot > 31) {
844 goto invalid;
845 }
05cb5fe4 846 *ptr = slot << 3 | fn;
a3400466 847 g_free(str);
768a9ebe
PB
848 return;
849
850invalid:
851 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
a3400466 852 g_free(str);
05cb5fe4
GH
853}
854
855static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
856{
09f1bbcd 857 int32_t *ptr = qdev_get_prop_ptr(dev, prop);
05cb5fe4 858
73538c31 859 if (*ptr == -1) {
05cb5fe4
GH
860 return snprintf(dest, len, "<unset>");
861 } else {
862 return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
863 }
864}
865
866PropertyInfo qdev_prop_pci_devfn = {
b403298a
PB
867 .name = "int32",
868 .legacy_name = "pci-devfn",
05cb5fe4 869 .print = print_pci_devfn,
b403298a 870 .get = get_int32,
768a9ebe 871 .set = set_pci_devfn,
05cb5fe4
GH
872};
873
02fda01c
SH
874/* --- blocksize --- */
875
876static void set_blocksize(Object *obj, Visitor *v, void *opaque,
877 const char *name, Error **errp)
878{
879 DeviceState *dev = DEVICE(obj);
880 Property *prop = opaque;
c08fb2ac 881 uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
02fda01c 882 Error *local_err = NULL;
27712df9
PB
883 const int64_t min = 512;
884 const int64_t max = 32768;
02fda01c
SH
885
886 if (dev->state != DEV_STATE_CREATED) {
887 error_set(errp, QERR_PERMISSION_DENIED);
888 return;
889 }
890
c08fb2ac 891 visit_type_uint16(v, &value, name, &local_err);
02fda01c
SH
892 if (local_err) {
893 error_propagate(errp, local_err);
894 return;
895 }
27712df9 896 if (value < min || value > max) {
02fda01c 897 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
27712df9 898 dev->id?:"", name, (int64_t)value, min, max);
02fda01c
SH
899 return;
900 }
901
902 /* We rely on power-of-2 blocksizes for bitmasks */
903 if ((value & (value - 1)) != 0) {
904 error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
c08fb2ac 905 dev->id?:"", name, (int64_t)value);
02fda01c
SH
906 return;
907 }
908
909 *ptr = value;
910}
911
912PropertyInfo qdev_prop_blocksize = {
913 .name = "blocksize",
c08fb2ac 914 .get = get_uint16,
02fda01c 915 .set = set_blocksize,
02fda01c
SH
916};
917
679042f0
AP
918/* --- pci host address --- */
919
920static void get_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
921 const char *name, Error **errp)
922{
923 DeviceState *dev = DEVICE(obj);
924 Property *prop = opaque;
925 PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
926 char buffer[] = "xxxx:xx:xx.x";
927 char *p = buffer;
928 int rc = 0;
929
930 rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d",
931 addr->domain, addr->bus, addr->slot, addr->function);
932 assert(rc == sizeof(buffer) - 1);
933
934 visit_type_str(v, &p, name, errp);
935}
936
937/*
938 * Parse [<domain>:]<bus>:<slot>.<func>
939 * if <domain> is not supplied, it's assumed to be 0.
940 */
941static void set_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
942 const char *name, Error **errp)
943{
944 DeviceState *dev = DEVICE(obj);
945 Property *prop = opaque;
946 PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
947 Error *local_err = NULL;
948 char *str, *p;
949 char *e;
950 unsigned long val;
951 unsigned long dom = 0, bus = 0;
952 unsigned int slot = 0, func = 0;
953
954 if (dev->state != DEV_STATE_CREATED) {
955 error_set(errp, QERR_PERMISSION_DENIED);
956 return;
957 }
958
959 visit_type_str(v, &str, name, &local_err);
960 if (local_err) {
961 error_propagate(errp, local_err);
962 return;
963 }
964
965 p = str;
966 val = strtoul(p, &e, 16);
967 if (e == p || *e != ':') {
968 goto inval;
969 }
970 bus = val;
971
972 p = e + 1;
973 val = strtoul(p, &e, 16);
974 if (e == p) {
975 goto inval;
976 }
977 if (*e == ':') {
978 dom = bus;
979 bus = val;
980 p = e + 1;
981 val = strtoul(p, &e, 16);
982 if (e == p) {
983 goto inval;
984 }
985 }
986 slot = val;
987
988 if (*e != '.') {
989 goto inval;
990 }
991 p = e + 1;
992 val = strtoul(p, &e, 10);
993 if (e == p) {
994 goto inval;
995 }
996 func = val;
997
998 if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
999 goto inval;
1000 }
1001
1002 if (*e) {
1003 goto inval;
1004 }
1005
1006 addr->domain = dom;
1007 addr->bus = bus;
1008 addr->slot = slot;
1009 addr->function = func;
1010
1011 g_free(str);
1012 return;
1013
1014inval:
1015 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
1016 g_free(str);
1017}
1018
1019PropertyInfo qdev_prop_pci_host_devaddr = {
1020 .name = "pci-host-devaddr",
1021 .get = get_pci_host_devaddr,
1022 .set = set_pci_host_devaddr,
1023};
1024
ee6847d1
GH
1025/* --- public helpers --- */
1026
1027static Property *qdev_prop_walk(Property *props, const char *name)
1028{
1029 if (!props)
1030 return NULL;
1031 while (props->name) {
1032 if (strcmp(props->name, name) == 0)
1033 return props;
1034 props++;
1035 }
1036 return NULL;
1037}
1038
1039static Property *qdev_prop_find(DeviceState *dev, const char *name)
1040{
bce54474 1041 ObjectClass *class;
ee6847d1
GH
1042 Property *prop;
1043
1044 /* device properties */
bce54474
PB
1045 class = object_get_class(OBJECT(dev));
1046 do {
1047 prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
1048 if (prop) {
1049 return prop;
1050 }
1051 class = object_class_get_parent(class);
1052 } while (class != object_class_by_name(TYPE_DEVICE));
ee6847d1
GH
1053
1054 return NULL;
1055}
1056
7db4c4e8
PB
1057void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
1058 Property *prop, const char *value)
1059{
1060 switch (ret) {
1061 case -EEXIST:
1062 error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
f79f2bfc 1063 object_get_typename(OBJECT(dev)), prop->name, value);
7db4c4e8
PB
1064 break;
1065 default:
1066 case -EINVAL:
1067 error_set(errp, QERR_PROPERTY_VALUE_BAD,
f79f2bfc 1068 object_get_typename(OBJECT(dev)), prop->name, value);
7db4c4e8
PB
1069 break;
1070 case -ENOENT:
1071 error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
f79f2bfc 1072 object_get_typename(OBJECT(dev)), prop->name, value);
7db4c4e8
PB
1073 break;
1074 case 0:
1075 break;
1076 }
1077}
1078
ee6847d1
GH
1079int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
1080{
d822979b
PB
1081 char *legacy_name;
1082 Error *err = NULL;
ee6847d1 1083
d822979b
PB
1084 legacy_name = g_strdup_printf("legacy-%s", name);
1085 if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
0c96e285 1086 object_property_parse(OBJECT(dev), value, legacy_name, &err);
d822979b 1087 } else {
0c96e285 1088 object_property_parse(OBJECT(dev), value, name, &err);
ee6847d1 1089 }
d822979b
PB
1090 g_free(legacy_name);
1091
1092 if (err) {
7db4c4e8
PB
1093 qerror_report_err(err);
1094 error_free(err);
9ef5c4bf
GH
1095 return -1;
1096 }
1097 return 0;
ee6847d1
GH
1098}
1099
f4594a3b
IY
1100void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1101{
9b170e60
PB
1102 Error *errp = NULL;
1103 object_property_set_bool(OBJECT(dev), value, name, &errp);
59f971d4 1104 assert_no_error(errp);
f4594a3b
IY
1105}
1106
c7cc172d
JQ
1107void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1108{
9b170e60
PB
1109 Error *errp = NULL;
1110 object_property_set_int(OBJECT(dev), value, name, &errp);
59f971d4 1111 assert_no_error(errp);
c7cc172d
JQ
1112}
1113
ee6847d1
GH
1114void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1115{
9b170e60
PB
1116 Error *errp = NULL;
1117 object_property_set_int(OBJECT(dev), value, name, &errp);
59f971d4 1118 assert_no_error(errp);
ee6847d1
GH
1119}
1120
1121void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1122{
9b170e60
PB
1123 Error *errp = NULL;
1124 object_property_set_int(OBJECT(dev), value, name, &errp);
59f971d4 1125 assert_no_error(errp);
ee6847d1
GH
1126}
1127
316940b0
GH
1128void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1129{
9b170e60
PB
1130 Error *errp = NULL;
1131 object_property_set_int(OBJECT(dev), value, name, &errp);
59f971d4 1132 assert_no_error(errp);
316940b0
GH
1133}
1134
5a053d1f
BS
1135void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1136{
9b170e60
PB
1137 Error *errp = NULL;
1138 object_property_set_int(OBJECT(dev), value, name, &errp);
59f971d4 1139 assert_no_error(errp);
5a053d1f
BS
1140}
1141
3b25597b 1142void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
cc984673 1143{
9b170e60
PB
1144 Error *errp = NULL;
1145 object_property_set_str(OBJECT(dev), value, name, &errp);
59f971d4 1146 assert_no_error(errp);
cc984673
MA
1147}
1148
18846dee 1149int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
14b41872 1150{
9b170e60 1151 Error *errp = NULL;
0a54a0ce
PB
1152 const char *bdrv_name = value ? bdrv_get_device_name(value) : "";
1153 object_property_set_str(OBJECT(dev), bdrv_name,
9b170e60
PB
1154 name, &errp);
1155 if (errp) {
1156 qerror_report_err(errp);
1157 error_free(errp);
18846dee
MA
1158 return -1;
1159 }
18846dee 1160 return 0;
14b41872
GH
1161}
1162
18846dee
MA
1163void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value)
1164{
1165 if (qdev_prop_set_drive(dev, name, value) < 0) {
1166 exit(1);
1167 }
1168}
313feaab
GH
1169void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
1170{
9b170e60 1171 Error *errp = NULL;
0a54a0ce
PB
1172 assert(!value || value->label);
1173 object_property_set_str(OBJECT(dev),
1174 value ? value->label : "", name, &errp);
59f971d4 1175 assert_no_error(errp);
313feaab
GH
1176}
1177
2ef924b4
GH
1178void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value)
1179{
9b170e60 1180 Error *errp = NULL;
0a54a0ce
PB
1181 assert(!value || value->name);
1182 object_property_set_str(OBJECT(dev),
1183 value ? value->name : "", name, &errp);
59f971d4 1184 assert_no_error(errp);
2ef924b4
GH
1185}
1186
851bec09
GH
1187void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
1188{
9b170e60
PB
1189 Error *errp = NULL;
1190 object_property_set_int(OBJECT(dev), value ? value->id : -1, name, &errp);
59f971d4 1191 assert_no_error(errp);
851bec09
GH
1192}
1193
1503fff3
GH
1194void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
1195{
9b170e60
PB
1196 Error *errp = NULL;
1197 char str[2 * 6 + 5 + 1];
1198 snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1199 value[0], value[1], value[2], value[3], value[4], value[5]);
1200
1201 object_property_set_str(OBJECT(dev), str, name, &errp);
59f971d4 1202 assert_no_error(errp);
1503fff3
GH
1203}
1204
9b170e60 1205void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
4e4fa398 1206{
9b170e60
PB
1207 Property *prop;
1208 Error *errp = NULL;
1209
1210 prop = qdev_prop_find(dev, name);
1211 object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
1212 name, &errp);
59f971d4 1213 assert_no_error(errp);
4e4fa398
JK
1214}
1215
ee6847d1
GH
1216void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1217{
7a7aae21
PB
1218 Property *prop;
1219 void **ptr;
1220
1221 prop = qdev_prop_find(dev, name);
1222 assert(prop && prop->info == &qdev_prop_ptr);
1223 ptr = qdev_get_prop_ptr(dev, prop);
1224 *ptr = value;
ee6847d1
GH
1225}
1226
458fb679 1227static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
b6b61144 1228
25920d6a 1229static void qdev_prop_register_global(GlobalProperty *prop)
b6b61144 1230{
458fb679 1231 QTAILQ_INSERT_TAIL(&global_props, prop, next);
b6b61144
GH
1232}
1233
458fb679 1234void qdev_prop_register_global_list(GlobalProperty *props)
b6b61144 1235{
458fb679 1236 int i;
b6b61144 1237
458fb679
GH
1238 for (i = 0; props[i].driver != NULL; i++) {
1239 qdev_prop_register_global(props+i);
b6b61144 1240 }
458fb679
GH
1241}
1242
1243void qdev_prop_set_globals(DeviceState *dev)
1244{
bce54474
PB
1245 ObjectClass *class = object_get_class(OBJECT(dev));
1246
1247 do {
1248 GlobalProperty *prop;
1249 QTAILQ_FOREACH(prop, &global_props, next) {
1250 if (strcmp(object_class_get_name(class), prop->driver) != 0) {
1251 continue;
1252 }
1253 if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
1254 exit(1);
1255 }
b6b61144 1256 }
bce54474
PB
1257 class = object_class_get_parent(class);
1258 } while (class);
b6b61144 1259}
25920d6a
KW
1260
1261static int qdev_add_one_global(QemuOpts *opts, void *opaque)
1262{
1263 GlobalProperty *g;
1264
7267c094 1265 g = g_malloc0(sizeof(*g));
25920d6a
KW
1266 g->driver = qemu_opt_get(opts, "driver");
1267 g->property = qemu_opt_get(opts, "property");
1268 g->value = qemu_opt_get(opts, "value");
1269 qdev_prop_register_global(g);
1270 return 0;
1271}
1272
1273void qemu_add_globals(void)
1274{
3329f07b 1275 qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0);
25920d6a 1276}
This page took 0.67134 seconds and 4 git commands to generate.