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