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