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