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