|
|
1.1.1.2 root 1: #include "net.h"
1.1 root 2: #include "qdev.h"
1.1.1.3 root 3: #include "qerror.h"
1.1.1.4 root 4: #include "blockdev.h"
1.1 root 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:
1.1.1.3 root 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 (!strncasecmp(str, "on", 2))
44: bit_prop_set(dev, prop, true);
45: else if (!strncasecmp(str, "off", 3))
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: {
1.1.1.5 root 54: uint32_t *p = qdev_get_prop_ptr(dev, prop);
1.1.1.3 root 55: return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
56: }
57:
58: PropertyInfo qdev_prop_bit = {
59: .name = "on/off",
60: .type = PROP_TYPE_BIT,
61: .size = sizeof(uint32_t),
62: .parse = parse_bit,
63: .print = print_bit,
64: };
65:
1.1.1.2 root 66: /* --- 8bit integer --- */
67:
68: static int parse_uint8(DeviceState *dev, Property *prop, const char *str)
69: {
70: uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
1.1.1.3 root 71: char *end;
1.1.1.2 root 72:
73: /* accept both hex and decimal */
1.1.1.3 root 74: *ptr = strtoul(str, &end, 0);
75: if ((*end != '\0') || (end == str)) {
76: return -EINVAL;
77: }
78:
1.1.1.2 root 79: return 0;
80: }
81:
82: static int print_uint8(DeviceState *dev, Property *prop, char *dest, size_t len)
83: {
84: uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
85: return snprintf(dest, len, "%" PRIu8, *ptr);
86: }
87:
88: PropertyInfo qdev_prop_uint8 = {
89: .name = "uint8",
90: .type = PROP_TYPE_UINT8,
91: .size = sizeof(uint8_t),
92: .parse = parse_uint8,
93: .print = print_uint8,
94: };
95:
1.1.1.6 ! root 96: /* --- 8bit hex value --- */
! 97:
! 98: static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
! 99: {
! 100: uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
! 101: char *end;
! 102:
! 103: *ptr = strtoul(str, &end, 16);
! 104: if ((*end != '\0') || (end == str)) {
! 105: return -EINVAL;
! 106: }
! 107:
! 108: return 0;
! 109: }
! 110:
! 111: static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
! 112: {
! 113: uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
! 114: return snprintf(dest, len, "0x%" PRIx8, *ptr);
! 115: }
! 116:
! 117: PropertyInfo qdev_prop_hex8 = {
! 118: .name = "hex8",
! 119: .type = PROP_TYPE_UINT8,
! 120: .size = sizeof(uint8_t),
! 121: .parse = parse_hex8,
! 122: .print = print_hex8,
! 123: };
! 124:
1.1 root 125: /* --- 16bit integer --- */
126:
127: static int parse_uint16(DeviceState *dev, Property *prop, const char *str)
128: {
129: uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
1.1.1.3 root 130: char *end;
1.1 root 131:
132: /* accept both hex and decimal */
1.1.1.3 root 133: *ptr = strtoul(str, &end, 0);
134: if ((*end != '\0') || (end == str)) {
135: return -EINVAL;
136: }
137:
1.1 root 138: return 0;
139: }
140:
141: static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len)
142: {
143: uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
144: return snprintf(dest, len, "%" PRIu16, *ptr);
145: }
146:
147: PropertyInfo qdev_prop_uint16 = {
148: .name = "uint16",
149: .type = PROP_TYPE_UINT16,
150: .size = sizeof(uint16_t),
151: .parse = parse_uint16,
152: .print = print_uint16,
153: };
154:
155: /* --- 32bit integer --- */
156:
157: static int parse_uint32(DeviceState *dev, Property *prop, const char *str)
158: {
159: uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
1.1.1.3 root 160: char *end;
1.1 root 161:
162: /* accept both hex and decimal */
1.1.1.3 root 163: *ptr = strtoul(str, &end, 0);
164: if ((*end != '\0') || (end == str)) {
165: return -EINVAL;
166: }
167:
1.1 root 168: return 0;
169: }
170:
171: static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len)
172: {
173: uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
174: return snprintf(dest, len, "%" PRIu32, *ptr);
175: }
176:
177: PropertyInfo qdev_prop_uint32 = {
178: .name = "uint32",
179: .type = PROP_TYPE_UINT32,
180: .size = sizeof(uint32_t),
181: .parse = parse_uint32,
182: .print = print_uint32,
183: };
184:
1.1.1.2 root 185: static int parse_int32(DeviceState *dev, Property *prop, const char *str)
186: {
187: int32_t *ptr = qdev_get_prop_ptr(dev, prop);
1.1.1.3 root 188: char *end;
189:
190: *ptr = strtol(str, &end, 10);
191: if ((*end != '\0') || (end == str)) {
192: return -EINVAL;
193: }
1.1.1.2 root 194:
195: return 0;
196: }
197:
198: static int print_int32(DeviceState *dev, Property *prop, char *dest, size_t len)
199: {
200: int32_t *ptr = qdev_get_prop_ptr(dev, prop);
201: return snprintf(dest, len, "%" PRId32, *ptr);
202: }
203:
204: PropertyInfo qdev_prop_int32 = {
205: .name = "int32",
206: .type = PROP_TYPE_INT32,
207: .size = sizeof(int32_t),
208: .parse = parse_int32,
209: .print = print_int32,
210: };
211:
1.1 root 212: /* --- 32bit hex value --- */
213:
214: static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
215: {
216: uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
1.1.1.3 root 217: char *end;
218:
219: *ptr = strtoul(str, &end, 16);
220: if ((*end != '\0') || (end == str)) {
221: return -EINVAL;
222: }
1.1 root 223:
224: return 0;
225: }
226:
227: static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
228: {
229: uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
230: return snprintf(dest, len, "0x%" PRIx32, *ptr);
231: }
232:
233: PropertyInfo qdev_prop_hex32 = {
234: .name = "hex32",
235: .type = PROP_TYPE_UINT32,
236: .size = sizeof(uint32_t),
237: .parse = parse_hex32,
238: .print = print_hex32,
239: };
240:
1.1.1.2 root 241: /* --- 64bit integer --- */
242:
243: static int parse_uint64(DeviceState *dev, Property *prop, const char *str)
244: {
245: uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1.1.1.3 root 246: char *end;
1.1.1.2 root 247:
248: /* accept both hex and decimal */
1.1.1.3 root 249: *ptr = strtoull(str, &end, 0);
250: if ((*end != '\0') || (end == str)) {
251: return -EINVAL;
252: }
253:
1.1.1.2 root 254: return 0;
255: }
256:
257: static int print_uint64(DeviceState *dev, Property *prop, char *dest, size_t len)
258: {
259: uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
260: return snprintf(dest, len, "%" PRIu64, *ptr);
261: }
262:
263: PropertyInfo qdev_prop_uint64 = {
264: .name = "uint64",
265: .type = PROP_TYPE_UINT64,
266: .size = sizeof(uint64_t),
267: .parse = parse_uint64,
268: .print = print_uint64,
269: };
270:
271: /* --- 64bit hex value --- */
272:
273: static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
274: {
275: uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1.1.1.3 root 276: char *end;
277:
278: *ptr = strtoull(str, &end, 16);
279: if ((*end != '\0') || (end == str)) {
280: return -EINVAL;
281: }
1.1.1.2 root 282:
283: return 0;
284: }
285:
286: static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
287: {
288: uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
289: return snprintf(dest, len, "0x%" PRIx64, *ptr);
290: }
291:
292: PropertyInfo qdev_prop_hex64 = {
293: .name = "hex64",
294: .type = PROP_TYPE_UINT64,
295: .size = sizeof(uint64_t),
296: .parse = parse_hex64,
297: .print = print_hex64,
298: };
299:
300: /* --- string --- */
301:
302: static int parse_string(DeviceState *dev, Property *prop, const char *str)
303: {
304: char **ptr = qdev_get_prop_ptr(dev, prop);
305:
306: if (*ptr)
1.1.1.6 ! root 307: g_free(*ptr);
! 308: *ptr = g_strdup(str);
1.1.1.2 root 309: return 0;
310: }
311:
1.1.1.3 root 312: static void free_string(DeviceState *dev, Property *prop)
313: {
1.1.1.6 ! root 314: g_free(*(char **)qdev_get_prop_ptr(dev, prop));
1.1.1.3 root 315: }
316:
1.1.1.2 root 317: static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
318: {
319: char **ptr = qdev_get_prop_ptr(dev, prop);
320: if (!*ptr)
321: return snprintf(dest, len, "<null>");
322: return snprintf(dest, len, "\"%s\"", *ptr);
323: }
324:
325: PropertyInfo qdev_prop_string = {
326: .name = "string",
327: .type = PROP_TYPE_STRING,
328: .size = sizeof(char*),
329: .parse = parse_string,
330: .print = print_string,
1.1.1.3 root 331: .free = free_string,
1.1.1.2 root 332: };
333:
334: /* --- drive --- */
335:
336: static int parse_drive(DeviceState *dev, Property *prop, const char *str)
337: {
1.1.1.3 root 338: BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
339: BlockDriverState *bs;
1.1.1.2 root 340:
1.1.1.3 root 341: bs = bdrv_find(str);
342: if (bs == NULL)
343: return -ENOENT;
1.1.1.6 ! root 344: if (bdrv_attach_dev(bs, dev) < 0)
1.1.1.3 root 345: return -EEXIST;
346: *ptr = bs;
1.1.1.2 root 347: return 0;
348: }
349:
1.1.1.3 root 350: static void free_drive(DeviceState *dev, Property *prop)
351: {
352: BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
353:
354: if (*ptr) {
1.1.1.6 ! root 355: bdrv_detach_dev(*ptr, dev);
1.1.1.3 root 356: blockdev_auto_del(*ptr);
357: }
358: }
359:
1.1.1.2 root 360: static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len)
361: {
1.1.1.3 root 362: BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
363: return snprintf(dest, len, "%s",
364: *ptr ? bdrv_get_device_name(*ptr) : "<null>");
1.1.1.2 root 365: }
366:
367: PropertyInfo qdev_prop_drive = {
368: .name = "drive",
369: .type = PROP_TYPE_DRIVE,
1.1.1.3 root 370: .size = sizeof(BlockDriverState *),
1.1.1.2 root 371: .parse = parse_drive,
372: .print = print_drive,
1.1.1.3 root 373: .free = free_drive,
1.1.1.2 root 374: };
375:
376: /* --- character device --- */
377:
378: static int parse_chr(DeviceState *dev, Property *prop, const char *str)
379: {
380: CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
381:
382: *ptr = qemu_chr_find(str);
1.1.1.5 root 383: if (*ptr == NULL) {
1.1.1.3 root 384: return -ENOENT;
1.1.1.5 root 385: }
386: if ((*ptr)->avail_connections < 1) {
387: return -EEXIST;
388: }
389: --(*ptr)->avail_connections;
1.1.1.2 root 390: return 0;
391: }
392:
393: static int print_chr(DeviceState *dev, Property *prop, char *dest, size_t len)
394: {
395: CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
396:
397: if (*ptr && (*ptr)->label) {
398: return snprintf(dest, len, "%s", (*ptr)->label);
399: } else {
400: return snprintf(dest, len, "<null>");
401: }
402: }
403:
404: PropertyInfo qdev_prop_chr = {
405: .name = "chr",
406: .type = PROP_TYPE_CHR,
407: .size = sizeof(CharDriverState*),
408: .parse = parse_chr,
409: .print = print_chr,
410: };
411:
412: /* --- netdev device --- */
413:
414: static int parse_netdev(DeviceState *dev, Property *prop, const char *str)
415: {
416: VLANClientState **ptr = qdev_get_prop_ptr(dev, prop);
417:
418: *ptr = qemu_find_netdev(str);
419: if (*ptr == NULL)
1.1.1.3 root 420: return -ENOENT;
421: if ((*ptr)->peer) {
422: return -EEXIST;
423: }
1.1.1.2 root 424: return 0;
425: }
426:
427: static int print_netdev(DeviceState *dev, Property *prop, char *dest, size_t len)
428: {
429: VLANClientState **ptr = qdev_get_prop_ptr(dev, prop);
430:
431: if (*ptr && (*ptr)->name) {
432: return snprintf(dest, len, "%s", (*ptr)->name);
433: } else {
434: return snprintf(dest, len, "<null>");
435: }
436: }
437:
438: PropertyInfo qdev_prop_netdev = {
439: .name = "netdev",
440: .type = PROP_TYPE_NETDEV,
441: .size = sizeof(VLANClientState*),
442: .parse = parse_netdev,
443: .print = print_netdev,
444: };
445:
446: /* --- vlan --- */
447:
448: static int parse_vlan(DeviceState *dev, Property *prop, const char *str)
449: {
450: VLANState **ptr = qdev_get_prop_ptr(dev, prop);
451: int id;
452:
453: if (sscanf(str, "%d", &id) != 1)
1.1.1.3 root 454: return -EINVAL;
1.1.1.2 root 455: *ptr = qemu_find_vlan(id, 1);
456: if (*ptr == NULL)
1.1.1.3 root 457: return -ENOENT;
1.1.1.2 root 458: return 0;
459: }
460:
461: static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
462: {
463: VLANState **ptr = qdev_get_prop_ptr(dev, prop);
464:
465: if (*ptr) {
466: return snprintf(dest, len, "%d", (*ptr)->id);
467: } else {
468: return snprintf(dest, len, "<null>");
469: }
470: }
471:
472: PropertyInfo qdev_prop_vlan = {
473: .name = "vlan",
474: .type = PROP_TYPE_VLAN,
475: .size = sizeof(VLANClientState*),
476: .parse = parse_vlan,
477: .print = print_vlan,
478: };
479:
1.1 root 480: /* --- pointer --- */
481:
1.1.1.3 root 482: /* Not a proper property, just for dirty hacks. TODO Remove it! */
1.1 root 483: PropertyInfo qdev_prop_ptr = {
484: .name = "ptr",
485: .type = PROP_TYPE_PTR,
486: .size = sizeof(void*),
487: };
488:
489: /* --- mac address --- */
490:
491: /*
492: * accepted syntax versions:
493: * 01:02:03:04:05:06
494: * 01-02-03-04-05-06
495: */
496: static int parse_mac(DeviceState *dev, Property *prop, const char *str)
497: {
1.1.1.2 root 498: MACAddr *mac = qdev_get_prop_ptr(dev, prop);
1.1 root 499: int i, pos;
500: char *p;
501:
502: for (i = 0, pos = 0; i < 6; i++, pos += 3) {
503: if (!qemu_isxdigit(str[pos]))
1.1.1.3 root 504: return -EINVAL;
1.1 root 505: if (!qemu_isxdigit(str[pos+1]))
1.1.1.3 root 506: return -EINVAL;
1.1.1.2 root 507: if (i == 5) {
508: if (str[pos+2] != '\0')
1.1.1.3 root 509: return -EINVAL;
1.1.1.2 root 510: } else {
511: if (str[pos+2] != ':' && str[pos+2] != '-')
1.1.1.3 root 512: return -EINVAL;
1.1.1.2 root 513: }
514: mac->a[i] = strtol(str+pos, &p, 16);
1.1 root 515: }
516: return 0;
517: }
518:
519: static int print_mac(DeviceState *dev, Property *prop, char *dest, size_t len)
520: {
1.1.1.2 root 521: MACAddr *mac = qdev_get_prop_ptr(dev, prop);
522:
1.1 root 523: return snprintf(dest, len, "%02x:%02x:%02x:%02x:%02x:%02x",
1.1.1.2 root 524: mac->a[0], mac->a[1], mac->a[2],
525: mac->a[3], mac->a[4], mac->a[5]);
1.1 root 526: }
527:
528: PropertyInfo qdev_prop_macaddr = {
1.1.1.2 root 529: .name = "macaddr",
1.1 root 530: .type = PROP_TYPE_MACADDR,
1.1.1.2 root 531: .size = sizeof(MACAddr),
1.1 root 532: .parse = parse_mac,
533: .print = print_mac,
534: };
535:
1.1.1.2 root 536: /* --- pci address --- */
537:
538: /*
539: * bus-local address, i.e. "$slot" or "$slot.$fn"
540: */
541: static int parse_pci_devfn(DeviceState *dev, Property *prop, const char *str)
542: {
543: uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
544: unsigned int slot, fn, n;
545:
546: if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
547: fn = 0;
548: if (sscanf(str, "%x%n", &slot, &n) != 1) {
1.1.1.3 root 549: return -EINVAL;
1.1.1.2 root 550: }
551: }
552: if (str[n] != '\0')
1.1.1.3 root 553: return -EINVAL;
1.1.1.2 root 554: if (fn > 7)
1.1.1.3 root 555: return -EINVAL;
1.1.1.6 ! root 556: if (slot > 31)
! 557: return -EINVAL;
1.1.1.2 root 558: *ptr = slot << 3 | fn;
559: return 0;
560: }
561:
562: static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
563: {
564: uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
565:
566: if (*ptr == -1) {
567: return snprintf(dest, len, "<unset>");
568: } else {
569: return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
570: }
571: }
572:
573: PropertyInfo qdev_prop_pci_devfn = {
574: .name = "pci-devfn",
575: .type = PROP_TYPE_UINT32,
576: .size = sizeof(uint32_t),
577: .parse = parse_pci_devfn,
578: .print = print_pci_devfn,
579: };
580:
1.1 root 581: /* --- public helpers --- */
582:
583: static Property *qdev_prop_walk(Property *props, const char *name)
584: {
585: if (!props)
586: return NULL;
587: while (props->name) {
588: if (strcmp(props->name, name) == 0)
589: return props;
590: props++;
591: }
592: return NULL;
593: }
594:
595: static Property *qdev_prop_find(DeviceState *dev, const char *name)
596: {
597: Property *prop;
598:
599: /* device properties */
600: prop = qdev_prop_walk(dev->info->props, name);
601: if (prop)
602: return prop;
603:
604: /* bus properties */
605: prop = qdev_prop_walk(dev->parent_bus->info->props, name);
606: if (prop)
607: return prop;
608:
609: return NULL;
610: }
611:
1.1.1.2 root 612: int qdev_prop_exists(DeviceState *dev, const char *name)
613: {
614: return qdev_prop_find(dev, name) ? true : false;
615: }
616:
1.1 root 617: int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
618: {
619: Property *prop;
1.1.1.3 root 620: int ret;
1.1 root 621:
622: prop = qdev_prop_find(dev, name);
1.1.1.3 root 623: /*
624: * TODO Properties without a parse method are just for dirty
625: * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
626: * marked for removal. The test !prop->info->parse should be
627: * removed along with it.
628: */
629: if (!prop || !prop->info->parse) {
630: qerror_report(QERR_PROPERTY_NOT_FOUND, dev->info->name, name);
631: return -1;
632: }
633: ret = prop->info->parse(dev, prop, value);
634: if (ret < 0) {
635: switch (ret) {
636: case -EEXIST:
637: qerror_report(QERR_PROPERTY_VALUE_IN_USE,
638: dev->info->name, name, value);
639: break;
640: default:
641: case -EINVAL:
642: qerror_report(QERR_PROPERTY_VALUE_BAD,
643: dev->info->name, name, value);
644: break;
645: case -ENOENT:
646: qerror_report(QERR_PROPERTY_VALUE_NOT_FOUND,
647: dev->info->name, name, value);
648: break;
649: }
1.1.1.2 root 650: return -1;
651: }
652: return 0;
1.1 root 653: }
654:
655: void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
656: {
657: Property *prop;
658:
659: prop = qdev_prop_find(dev, name);
660: if (!prop) {
661: fprintf(stderr, "%s: property \"%s.%s\" not found\n",
662: __FUNCTION__, dev->info->name, name);
663: abort();
664: }
665: if (prop->info->type != type) {
666: fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n",
667: __FUNCTION__, dev->info->name, name);
668: abort();
669: }
1.1.1.3 root 670: qdev_prop_cpy(dev, prop, src);
671: }
672:
673: void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
674: {
675: qdev_prop_set(dev, name, &value, PROP_TYPE_BIT);
1.1 root 676: }
677:
1.1.1.2 root 678: void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
679: {
680: qdev_prop_set(dev, name, &value, PROP_TYPE_UINT8);
681: }
682:
1.1 root 683: void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
684: {
685: qdev_prop_set(dev, name, &value, PROP_TYPE_UINT16);
686: }
687:
688: void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
689: {
690: qdev_prop_set(dev, name, &value, PROP_TYPE_UINT32);
691: }
692:
1.1.1.2 root 693: void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
694: {
695: qdev_prop_set(dev, name, &value, PROP_TYPE_INT32);
696: }
697:
698: void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
699: {
700: qdev_prop_set(dev, name, &value, PROP_TYPE_UINT64);
701: }
702:
1.1.1.3 root 703: void qdev_prop_set_string(DeviceState *dev, const char *name, char *value)
704: {
705: qdev_prop_set(dev, name, &value, PROP_TYPE_STRING);
706: }
707:
708: int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
1.1.1.2 root 709: {
1.1.1.3 root 710: int res;
711:
1.1.1.6 ! root 712: res = bdrv_attach_dev(value, dev);
1.1.1.3 root 713: if (res < 0) {
714: error_report("Can't attach drive %s to %s.%s: %s",
715: bdrv_get_device_name(value),
716: dev->id ? dev->id : dev->info->name,
717: name, strerror(-res));
718: return -1;
719: }
1.1.1.2 root 720: qdev_prop_set(dev, name, &value, PROP_TYPE_DRIVE);
1.1.1.3 root 721: return 0;
1.1.1.2 root 722: }
723:
1.1.1.3 root 724: void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value)
725: {
726: if (qdev_prop_set_drive(dev, name, value) < 0) {
727: exit(1);
728: }
729: }
1.1.1.2 root 730: void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
731: {
732: qdev_prop_set(dev, name, &value, PROP_TYPE_CHR);
733: }
734:
735: void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value)
736: {
737: qdev_prop_set(dev, name, &value, PROP_TYPE_NETDEV);
738: }
739:
740: void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
741: {
742: qdev_prop_set(dev, name, &value, PROP_TYPE_VLAN);
743: }
744:
745: void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
746: {
747: qdev_prop_set(dev, name, value, PROP_TYPE_MACADDR);
748: }
749:
1.1 root 750: void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
751: {
752: qdev_prop_set(dev, name, &value, PROP_TYPE_PTR);
753: }
754:
755: void qdev_prop_set_defaults(DeviceState *dev, Property *props)
756: {
757: if (!props)
758: return;
759: while (props->name) {
760: if (props->defval) {
1.1.1.3 root 761: qdev_prop_cpy(dev, props, props->defval);
1.1 root 762: }
763: props++;
764: }
765: }
766:
1.1.1.2 root 767: static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
1.1 root 768:
1.1.1.3 root 769: static void qdev_prop_register_global(GlobalProperty *prop)
1.1 root 770: {
1.1.1.2 root 771: QTAILQ_INSERT_TAIL(&global_props, prop, next);
1.1 root 772: }
773:
1.1.1.2 root 774: void qdev_prop_register_global_list(GlobalProperty *props)
1.1 root 775: {
1.1.1.2 root 776: int i;
1.1 root 777:
1.1.1.2 root 778: for (i = 0; props[i].driver != NULL; i++) {
779: qdev_prop_register_global(props+i);
1.1 root 780: }
1.1.1.2 root 781: }
782:
783: void qdev_prop_set_globals(DeviceState *dev)
784: {
785: GlobalProperty *prop;
786:
787: QTAILQ_FOREACH(prop, &global_props, next) {
788: if (strcmp(dev->info->name, prop->driver) != 0 &&
789: strcmp(dev->info->bus_info->name, prop->driver) != 0) {
1.1 root 790: continue;
791: }
792: if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
1.1.1.2 root 793: exit(1);
1.1 root 794: }
795: }
796: }
1.1.1.3 root 797:
798: static int qdev_add_one_global(QemuOpts *opts, void *opaque)
799: {
800: GlobalProperty *g;
801:
1.1.1.6 ! root 802: g = g_malloc0(sizeof(*g));
1.1.1.3 root 803: g->driver = qemu_opt_get(opts, "driver");
804: g->property = qemu_opt_get(opts, "property");
805: g->value = qemu_opt_get(opts, "value");
806: qdev_prop_register_global(g);
807: return 0;
808: }
809:
810: void qemu_add_globals(void)
811: {
1.1.1.4 root 812: qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0);
1.1.1.3 root 813: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.