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