qemu/hw/core/qdev-properties.c
<<
>>
Prefs
   1#include "qemu/osdep.h"
   2#include "net/net.h"
   3#include "hw/qdev.h"
   4#include "qapi/error.h"
   5#include "hw/pci/pci.h"
   6#include "qapi/qmp/qerror.h"
   7#include "qemu/error-report.h"
   8#include "sysemu/block-backend.h"
   9#include "hw/block/block.h"
  10#include "net/hub.h"
  11#include "qapi/visitor.h"
  12#include "sysemu/char.h"
  13
  14void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
  15                                  Error **errp)
  16{
  17    if (dev->id) {
  18        error_setg(errp, "Attempt to set property '%s' on device '%s' "
  19                   "(type '%s') after it was realized", name, dev->id,
  20                   object_get_typename(OBJECT(dev)));
  21    } else {
  22        error_setg(errp, "Attempt to set property '%s' on anonymous device "
  23                   "(type '%s') after it was realized", name,
  24                   object_get_typename(OBJECT(dev)));
  25    }
  26}
  27
  28void qdev_prop_allow_set_link_before_realize(Object *obj, const char *name,
  29                                             Object *val, Error **errp)
  30{
  31    DeviceState *dev = DEVICE(obj);
  32
  33    if (dev->realized) {
  34        error_setg(errp, "Attempt to set link property '%s' on device '%s' "
  35                   "(type '%s') after it was realized",
  36                   name, dev->id, object_get_typename(obj));
  37    }
  38}
  39
  40void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
  41{
  42    void *ptr = dev;
  43    ptr += prop->offset;
  44    return ptr;
  45}
  46
  47static void get_enum(Object *obj, Visitor *v, const char *name, void *opaque,
  48                     Error **errp)
  49{
  50    DeviceState *dev = DEVICE(obj);
  51    Property *prop = opaque;
  52    int *ptr = qdev_get_prop_ptr(dev, prop);
  53
  54    visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
  55}
  56
  57static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque,
  58                     Error **errp)
  59{
  60    DeviceState *dev = DEVICE(obj);
  61    Property *prop = opaque;
  62    int *ptr = qdev_get_prop_ptr(dev, prop);
  63
  64    if (dev->realized) {
  65        qdev_prop_set_after_realize(dev, name, errp);
  66        return;
  67    }
  68
  69    visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
  70}
  71
  72/* Bit */
  73
  74static uint32_t qdev_get_prop_mask(Property *prop)
  75{
  76    assert(prop->info == &qdev_prop_bit);
  77    return 0x1 << prop->bitnr;
  78}
  79
  80static void bit_prop_set(DeviceState *dev, Property *props, bool val)
  81{
  82    uint32_t *p = qdev_get_prop_ptr(dev, props);
  83    uint32_t mask = qdev_get_prop_mask(props);
  84    if (val) {
  85        *p |= mask;
  86    } else {
  87        *p &= ~mask;
  88    }
  89}
  90
  91static void prop_get_bit(Object *obj, Visitor *v, const char *name,
  92                         void *opaque, Error **errp)
  93{
  94    DeviceState *dev = DEVICE(obj);
  95    Property *prop = opaque;
  96    uint32_t *p = qdev_get_prop_ptr(dev, prop);
  97    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
  98
  99    visit_type_bool(v, name, &value, errp);
 100}
 101
 102static void prop_set_bit(Object *obj, Visitor *v, const char *name,
 103                         void *opaque, Error **errp)
 104{
 105    DeviceState *dev = DEVICE(obj);
 106    Property *prop = opaque;
 107    Error *local_err = NULL;
 108    bool value;
 109
 110    if (dev->realized) {
 111        qdev_prop_set_after_realize(dev, name, errp);
 112        return;
 113    }
 114
 115    visit_type_bool(v, name, &value, &local_err);
 116    if (local_err) {
 117        error_propagate(errp, local_err);
 118        return;
 119    }
 120    bit_prop_set(dev, prop, value);
 121}
 122
 123PropertyInfo qdev_prop_bit = {
 124    .name  = "bool",
 125    .description = "on/off",
 126    .get   = prop_get_bit,
 127    .set   = prop_set_bit,
 128};
 129
 130/* Bit64 */
 131
 132static uint64_t qdev_get_prop_mask64(Property *prop)
 133{
 134    assert(prop->info == &qdev_prop_bit64);
 135    return 0x1ull << prop->bitnr;
 136}
 137
 138static void bit64_prop_set(DeviceState *dev, Property *props, bool val)
 139{
 140    uint64_t *p = qdev_get_prop_ptr(dev, props);
 141    uint64_t mask = qdev_get_prop_mask64(props);
 142    if (val) {
 143        *p |= mask;
 144    } else {
 145        *p &= ~mask;
 146    }
 147}
 148
 149static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
 150                           void *opaque, Error **errp)
 151{
 152    DeviceState *dev = DEVICE(obj);
 153    Property *prop = opaque;
 154    uint64_t *p = qdev_get_prop_ptr(dev, prop);
 155    bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
 156
 157    visit_type_bool(v, name, &value, errp);
 158}
 159
 160static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
 161                           void *opaque, Error **errp)
 162{
 163    DeviceState *dev = DEVICE(obj);
 164    Property *prop = opaque;
 165    Error *local_err = NULL;
 166    bool value;
 167
 168    if (dev->realized) {
 169        qdev_prop_set_after_realize(dev, name, errp);
 170        return;
 171    }
 172
 173    visit_type_bool(v, name, &value, &local_err);
 174    if (local_err) {
 175        error_propagate(errp, local_err);
 176        return;
 177    }
 178    bit64_prop_set(dev, prop, value);
 179}
 180
 181PropertyInfo qdev_prop_bit64 = {
 182    .name  = "bool",
 183    .description = "on/off",
 184    .get   = prop_get_bit64,
 185    .set   = prop_set_bit64,
 186};
 187
 188/* --- bool --- */
 189
 190static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
 191                     Error **errp)
 192{
 193    DeviceState *dev = DEVICE(obj);
 194    Property *prop = opaque;
 195    bool *ptr = qdev_get_prop_ptr(dev, prop);
 196
 197    visit_type_bool(v, name, ptr, errp);
 198}
 199
 200static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
 201                     Error **errp)
 202{
 203    DeviceState *dev = DEVICE(obj);
 204    Property *prop = opaque;
 205    bool *ptr = qdev_get_prop_ptr(dev, prop);
 206
 207    if (dev->realized) {
 208        qdev_prop_set_after_realize(dev, name, errp);
 209        return;
 210    }
 211
 212    visit_type_bool(v, name, ptr, errp);
 213}
 214
 215PropertyInfo qdev_prop_bool = {
 216    .name  = "bool",
 217    .get   = get_bool,
 218    .set   = set_bool,
 219};
 220
 221/* --- 8bit integer --- */
 222
 223static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
 224                      Error **errp)
 225{
 226    DeviceState *dev = DEVICE(obj);
 227    Property *prop = opaque;
 228    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
 229
 230    visit_type_uint8(v, name, ptr, errp);
 231}
 232
 233static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
 234                      Error **errp)
 235{
 236    DeviceState *dev = DEVICE(obj);
 237    Property *prop = opaque;
 238    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
 239
 240    if (dev->realized) {
 241        qdev_prop_set_after_realize(dev, name, errp);
 242        return;
 243    }
 244
 245    visit_type_uint8(v, name, ptr, errp);
 246}
 247
 248PropertyInfo qdev_prop_uint8 = {
 249    .name  = "uint8",
 250    .get   = get_uint8,
 251    .set   = set_uint8,
 252};
 253
 254/* --- 16bit integer --- */
 255
 256static void get_uint16(Object *obj, Visitor *v, const char *name,
 257                       void *opaque, Error **errp)
 258{
 259    DeviceState *dev = DEVICE(obj);
 260    Property *prop = opaque;
 261    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
 262
 263    visit_type_uint16(v, name, ptr, errp);
 264}
 265
 266static void set_uint16(Object *obj, Visitor *v, const char *name,
 267                       void *opaque, Error **errp)
 268{
 269    DeviceState *dev = DEVICE(obj);
 270    Property *prop = opaque;
 271    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
 272
 273    if (dev->realized) {
 274        qdev_prop_set_after_realize(dev, name, errp);
 275        return;
 276    }
 277
 278    visit_type_uint16(v, name, ptr, errp);
 279}
 280
 281PropertyInfo qdev_prop_uint16 = {
 282    .name  = "uint16",
 283    .get   = get_uint16,
 284    .set   = set_uint16,
 285};
 286
 287/* --- 32bit integer --- */
 288
 289static void get_uint32(Object *obj, Visitor *v, const char *name,
 290                       void *opaque, Error **errp)
 291{
 292    DeviceState *dev = DEVICE(obj);
 293    Property *prop = opaque;
 294    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
 295
 296    visit_type_uint32(v, name, ptr, errp);
 297}
 298
 299static void set_uint32(Object *obj, Visitor *v, const char *name,
 300                       void *opaque, Error **errp)
 301{
 302    DeviceState *dev = DEVICE(obj);
 303    Property *prop = opaque;
 304    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
 305
 306    if (dev->realized) {
 307        qdev_prop_set_after_realize(dev, name, errp);
 308        return;
 309    }
 310
 311    visit_type_uint32(v, name, ptr, errp);
 312}
 313
 314static void get_int32(Object *obj, Visitor *v, const char *name, void *opaque,
 315                      Error **errp)
 316{
 317    DeviceState *dev = DEVICE(obj);
 318    Property *prop = opaque;
 319    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
 320
 321    visit_type_int32(v, name, ptr, errp);
 322}
 323
 324static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
 325                      Error **errp)
 326{
 327    DeviceState *dev = DEVICE(obj);
 328    Property *prop = opaque;
 329    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
 330
 331    if (dev->realized) {
 332        qdev_prop_set_after_realize(dev, name, errp);
 333        return;
 334    }
 335
 336    visit_type_int32(v, name, ptr, errp);
 337}
 338
 339PropertyInfo qdev_prop_uint32 = {
 340    .name  = "uint32",
 341    .get   = get_uint32,
 342    .set   = set_uint32,
 343};
 344
 345PropertyInfo qdev_prop_int32 = {
 346    .name  = "int32",
 347    .get   = get_int32,
 348    .set   = set_int32,
 349};
 350
 351/* --- 64bit integer --- */
 352
 353static void get_uint64(Object *obj, Visitor *v, const char *name,
 354                       void *opaque, Error **errp)
 355{
 356    DeviceState *dev = DEVICE(obj);
 357    Property *prop = opaque;
 358    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
 359
 360    visit_type_uint64(v, name, ptr, errp);
 361}
 362
 363static void set_uint64(Object *obj, Visitor *v, const char *name,
 364                       void *opaque, Error **errp)
 365{
 366    DeviceState *dev = DEVICE(obj);
 367    Property *prop = opaque;
 368    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
 369
 370    if (dev->realized) {
 371        qdev_prop_set_after_realize(dev, name, errp);
 372        return;
 373    }
 374
 375    visit_type_uint64(v, name, ptr, errp);
 376}
 377
 378PropertyInfo qdev_prop_uint64 = {
 379    .name  = "uint64",
 380    .get   = get_uint64,
 381    .set   = set_uint64,
 382};
 383
 384/* --- string --- */
 385
 386static void release_string(Object *obj, const char *name, void *opaque)
 387{
 388    Property *prop = opaque;
 389    g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
 390}
 391
 392static void get_string(Object *obj, Visitor *v, const char *name,
 393                       void *opaque, Error **errp)
 394{
 395    DeviceState *dev = DEVICE(obj);
 396    Property *prop = opaque;
 397    char **ptr = qdev_get_prop_ptr(dev, prop);
 398
 399    if (!*ptr) {
 400        char *str = (char *)"";
 401        visit_type_str(v, name, &str, errp);
 402    } else {
 403        visit_type_str(v, name, ptr, errp);
 404    }
 405}
 406
 407static void set_string(Object *obj, Visitor *v, const char *name,
 408                       void *opaque, Error **errp)
 409{
 410    DeviceState *dev = DEVICE(obj);
 411    Property *prop = opaque;
 412    char **ptr = qdev_get_prop_ptr(dev, prop);
 413    Error *local_err = NULL;
 414    char *str;
 415
 416    if (dev->realized) {
 417        qdev_prop_set_after_realize(dev, name, errp);
 418        return;
 419    }
 420
 421    visit_type_str(v, name, &str, &local_err);
 422    if (local_err) {
 423        error_propagate(errp, local_err);
 424        return;
 425    }
 426    g_free(*ptr);
 427    *ptr = str;
 428}
 429
 430PropertyInfo qdev_prop_string = {
 431    .name  = "str",
 432    .release = release_string,
 433    .get   = get_string,
 434    .set   = set_string,
 435};
 436
 437/* --- pointer --- */
 438
 439/* Not a proper property, just for dirty hacks.  TODO Remove it!  */
 440PropertyInfo qdev_prop_ptr = {
 441    .name  = "ptr",
 442};
 443
 444/* --- mac address --- */
 445
 446/*
 447 * accepted syntax versions:
 448 *   01:02:03:04:05:06
 449 *   01-02-03-04-05-06
 450 */
 451static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
 452                    Error **errp)
 453{
 454    DeviceState *dev = DEVICE(obj);
 455    Property *prop = opaque;
 456    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
 457    char buffer[2 * 6 + 5 + 1];
 458    char *p = buffer;
 459
 460    snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
 461             mac->a[0], mac->a[1], mac->a[2],
 462             mac->a[3], mac->a[4], mac->a[5]);
 463
 464    visit_type_str(v, name, &p, errp);
 465}
 466
 467static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
 468                    Error **errp)
 469{
 470    DeviceState *dev = DEVICE(obj);
 471    Property *prop = opaque;
 472    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
 473    Error *local_err = NULL;
 474    int i, pos;
 475    char *str, *p;
 476
 477    if (dev->realized) {
 478        qdev_prop_set_after_realize(dev, name, errp);
 479        return;
 480    }
 481
 482    visit_type_str(v, name, &str, &local_err);
 483    if (local_err) {
 484        error_propagate(errp, local_err);
 485        return;
 486    }
 487
 488    for (i = 0, pos = 0; i < 6; i++, pos += 3) {
 489        if (!qemu_isxdigit(str[pos])) {
 490            goto inval;
 491        }
 492        if (!qemu_isxdigit(str[pos+1])) {
 493            goto inval;
 494        }
 495        if (i == 5) {
 496            if (str[pos+2] != '\0') {
 497                goto inval;
 498            }
 499        } else {
 500            if (str[pos+2] != ':' && str[pos+2] != '-') {
 501                goto inval;
 502            }
 503        }
 504        mac->a[i] = strtol(str+pos, &p, 16);
 505    }
 506    g_free(str);
 507    return;
 508
 509inval:
 510    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
 511    g_free(str);
 512}
 513
 514PropertyInfo qdev_prop_macaddr = {
 515    .name  = "str",
 516    .description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56",
 517    .get   = get_mac,
 518    .set   = set_mac,
 519};
 520
 521/* --- on/off/auto --- */
 522
 523PropertyInfo qdev_prop_on_off_auto = {
 524    .name = "OnOffAuto",
 525    .description = "on/off/auto",
 526    .enum_table = OnOffAuto_lookup,
 527    .get = get_enum,
 528    .set = set_enum,
 529};
 530
 531/* --- lost tick policy --- */
 532
 533QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
 534
 535PropertyInfo qdev_prop_losttickpolicy = {
 536    .name  = "LostTickPolicy",
 537    .enum_table  = LostTickPolicy_lookup,
 538    .get   = get_enum,
 539    .set   = set_enum,
 540};
 541
 542/* --- BIOS CHS translation */
 543
 544QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
 545
 546PropertyInfo qdev_prop_bios_chs_trans = {
 547    .name = "BiosAtaTranslation",
 548    .description = "Logical CHS translation algorithm, "
 549                   "auto/none/lba/large/rechs",
 550    .enum_table = BiosAtaTranslation_lookup,
 551    .get = get_enum,
 552    .set = set_enum,
 553};
 554
 555/* --- FDC default drive types */
 556
 557PropertyInfo qdev_prop_fdc_drive_type = {
 558    .name = "FdcDriveType",
 559    .description = "FDC drive type, "
 560                   "144/288/120/none/auto",
 561    .enum_table = FloppyDriveType_lookup,
 562    .get = get_enum,
 563    .set = set_enum
 564};
 565
 566/* --- pci address --- */
 567
 568/*
 569 * bus-local address, i.e. "$slot" or "$slot.$fn"
 570 */
 571static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
 572                          void *opaque, Error **errp)
 573{
 574    DeviceState *dev = DEVICE(obj);
 575    Property *prop = opaque;
 576    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
 577    unsigned int slot, fn, n;
 578    Error *local_err = NULL;
 579    char *str;
 580
 581    if (dev->realized) {
 582        qdev_prop_set_after_realize(dev, name, errp);
 583        return;
 584    }
 585
 586    visit_type_str(v, name, &str, &local_err);
 587    if (local_err) {
 588        error_free(local_err);
 589        local_err = NULL;
 590        visit_type_int32(v, name, &value, &local_err);
 591        if (local_err) {
 592            error_propagate(errp, local_err);
 593        } else if (value < -1 || value > 255) {
 594            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
 595                       name ? name : "null", "pci_devfn");
 596        } else {
 597            *ptr = value;
 598        }
 599        return;
 600    }
 601
 602    if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
 603        fn = 0;
 604        if (sscanf(str, "%x%n", &slot, &n) != 1) {
 605            goto invalid;
 606        }
 607    }
 608    if (str[n] != '\0' || fn > 7 || slot > 31) {
 609        goto invalid;
 610    }
 611    *ptr = slot << 3 | fn;
 612    g_free(str);
 613    return;
 614
 615invalid:
 616    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
 617    g_free(str);
 618}
 619
 620static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest,
 621                           size_t len)
 622{
 623    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
 624
 625    if (*ptr == -1) {
 626        return snprintf(dest, len, "<unset>");
 627    } else {
 628        return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
 629    }
 630}
 631
 632PropertyInfo qdev_prop_pci_devfn = {
 633    .name  = "int32",
 634    .description = "Slot and optional function number, example: 06.0 or 06",
 635    .print = print_pci_devfn,
 636    .get   = get_int32,
 637    .set   = set_pci_devfn,
 638};
 639
 640/* --- blocksize --- */
 641
 642static void set_blocksize(Object *obj, Visitor *v, const char *name,
 643                          void *opaque, Error **errp)
 644{
 645    DeviceState *dev = DEVICE(obj);
 646    Property *prop = opaque;
 647    uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
 648    Error *local_err = NULL;
 649    const int64_t min = 512;
 650    const int64_t max = 32768;
 651
 652    if (dev->realized) {
 653        qdev_prop_set_after_realize(dev, name, errp);
 654        return;
 655    }
 656
 657    visit_type_uint16(v, name, &value, &local_err);
 658    if (local_err) {
 659        error_propagate(errp, local_err);
 660        return;
 661    }
 662    /* value of 0 means "unset" */
 663    if (value && (value < min || value > max)) {
 664        error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
 665                   dev->id ? : "", name, (int64_t)value, min, max);
 666        return;
 667    }
 668
 669    /* We rely on power-of-2 blocksizes for bitmasks */
 670    if ((value & (value - 1)) != 0) {
 671        error_setg(errp,
 672                  "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2",
 673                  dev->id ?: "", name, (int64_t)value);
 674        return;
 675    }
 676
 677    *ptr = value;
 678}
 679
 680PropertyInfo qdev_prop_blocksize = {
 681    .name  = "uint16",
 682    .description = "A power of two between 512 and 32768",
 683    .get   = get_uint16,
 684    .set   = set_blocksize,
 685};
 686
 687/* --- pci host address --- */
 688
 689static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
 690                                 void *opaque, Error **errp)
 691{
 692    DeviceState *dev = DEVICE(obj);
 693    Property *prop = opaque;
 694    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
 695    char buffer[] = "xxxx:xx:xx.x";
 696    char *p = buffer;
 697    int rc = 0;
 698
 699    rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d",
 700                  addr->domain, addr->bus, addr->slot, addr->function);
 701    assert(rc == sizeof(buffer) - 1);
 702
 703    visit_type_str(v, name, &p, errp);
 704}
 705
 706/*
 707 * Parse [<domain>:]<bus>:<slot>.<func>
 708 *   if <domain> is not supplied, it's assumed to be 0.
 709 */
 710static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
 711                                 void *opaque, Error **errp)
 712{
 713    DeviceState *dev = DEVICE(obj);
 714    Property *prop = opaque;
 715    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
 716    Error *local_err = NULL;
 717    char *str, *p;
 718    char *e;
 719    unsigned long val;
 720    unsigned long dom = 0, bus = 0;
 721    unsigned int slot = 0, func = 0;
 722
 723    if (dev->realized) {
 724        qdev_prop_set_after_realize(dev, name, errp);
 725        return;
 726    }
 727
 728    visit_type_str(v, name, &str, &local_err);
 729    if (local_err) {
 730        error_propagate(errp, local_err);
 731        return;
 732    }
 733
 734    p = str;
 735    val = strtoul(p, &e, 16);
 736    if (e == p || *e != ':') {
 737        goto inval;
 738    }
 739    bus = val;
 740
 741    p = e + 1;
 742    val = strtoul(p, &e, 16);
 743    if (e == p) {
 744        goto inval;
 745    }
 746    if (*e == ':') {
 747        dom = bus;
 748        bus = val;
 749        p = e + 1;
 750        val = strtoul(p, &e, 16);
 751        if (e == p) {
 752            goto inval;
 753        }
 754    }
 755    slot = val;
 756
 757    if (*e != '.') {
 758        goto inval;
 759    }
 760    p = e + 1;
 761    val = strtoul(p, &e, 10);
 762    if (e == p) {
 763        goto inval;
 764    }
 765    func = val;
 766
 767    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
 768        goto inval;
 769    }
 770
 771    if (*e) {
 772        goto inval;
 773    }
 774
 775    addr->domain = dom;
 776    addr->bus = bus;
 777    addr->slot = slot;
 778    addr->function = func;
 779
 780    g_free(str);
 781    return;
 782
 783inval:
 784    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
 785    g_free(str);
 786}
 787
 788PropertyInfo qdev_prop_pci_host_devaddr = {
 789    .name = "str",
 790    .description = "Address (bus/device/function) of "
 791                   "the host device, example: 04:10.0",
 792    .get = get_pci_host_devaddr,
 793    .set = set_pci_host_devaddr,
 794};
 795
 796/* --- support for array properties --- */
 797
 798/* Used as an opaque for the object properties we add for each
 799 * array element. Note that the struct Property must be first
 800 * in the struct so that a pointer to this works as the opaque
 801 * for the underlying element's property hooks as well as for
 802 * our own release callback.
 803 */
 804typedef struct {
 805    struct Property prop;
 806    char *propname;
 807    ObjectPropertyRelease *release;
 808} ArrayElementProperty;
 809
 810/* object property release callback for array element properties:
 811 * we call the underlying element's property release hook, and
 812 * then free the memory we allocated when we added the property.
 813 */
 814static void array_element_release(Object *obj, const char *name, void *opaque)
 815{
 816    ArrayElementProperty *p = opaque;
 817    if (p->release) {
 818        p->release(obj, name, opaque);
 819    }
 820    g_free(p->propname);
 821    g_free(p);
 822}
 823
 824static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
 825                              void *opaque, Error **errp)
 826{
 827    /* Setter for the property which defines the length of a
 828     * variable-sized property array. As well as actually setting the
 829     * array-length field in the device struct, we have to create the
 830     * array itself and dynamically add the corresponding properties.
 831     */
 832    DeviceState *dev = DEVICE(obj);
 833    Property *prop = opaque;
 834    uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
 835    void **arrayptr = (void *)dev + prop->arrayoffset;
 836    Error *local_err = NULL;
 837    void *eltptr;
 838    const char *arrayname;
 839    int i;
 840
 841    if (dev->realized) {
 842        qdev_prop_set_after_realize(dev, name, errp);
 843        return;
 844    }
 845    if (*alenptr) {
 846        error_setg(errp, "array size property %s may not be set more than once",
 847                   name);
 848        return;
 849    }
 850    visit_type_uint32(v, name, alenptr, &local_err);
 851    if (local_err) {
 852        error_propagate(errp, local_err);
 853        return;
 854    }
 855    if (!*alenptr) {
 856        return;
 857    }
 858
 859    /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
 860     * strip it off so we can get the name of the array itself.
 861     */
 862    assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
 863                   strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
 864    arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
 865
 866    /* Note that it is the responsibility of the individual device's deinit
 867     * to free the array proper.
 868     */
 869    *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
 870    for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
 871        char *propname = g_strdup_printf("%s[%d]", arrayname, i);
 872        ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
 873        arrayprop->release = prop->arrayinfo->release;
 874        arrayprop->propname = propname;
 875        arrayprop->prop.info = prop->arrayinfo;
 876        arrayprop->prop.name = propname;
 877        /* This ugly piece of pointer arithmetic sets up the offset so
 878         * that when the underlying get/set hooks call qdev_get_prop_ptr
 879         * they get the right answer despite the array element not actually
 880         * being inside the device struct.
 881         */
 882        arrayprop->prop.offset = eltptr - (void *)dev;
 883        assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
 884        object_property_add(obj, propname,
 885                            arrayprop->prop.info->name,
 886                            arrayprop->prop.info->get,
 887                            arrayprop->prop.info->set,
 888                            array_element_release,
 889                            arrayprop, &local_err);
 890        if (local_err) {
 891            error_propagate(errp, local_err);
 892            return;
 893        }
 894    }
 895}
 896
 897PropertyInfo qdev_prop_arraylen = {
 898    .name = "uint32",
 899    .get = get_uint32,
 900    .set = set_prop_arraylen,
 901};
 902
 903/* --- public helpers --- */
 904
 905static Property *qdev_prop_walk(Property *props, const char *name)
 906{
 907    if (!props) {
 908        return NULL;
 909    }
 910    while (props->name) {
 911        if (strcmp(props->name, name) == 0) {
 912            return props;
 913        }
 914        props++;
 915    }
 916    return NULL;
 917}
 918
 919static Property *qdev_prop_find(DeviceState *dev, const char *name)
 920{
 921    ObjectClass *class;
 922    Property *prop;
 923
 924    /* device properties */
 925    class = object_get_class(OBJECT(dev));
 926    do {
 927        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
 928        if (prop) {
 929            return prop;
 930        }
 931        class = object_class_get_parent(class);
 932    } while (class != object_class_by_name(TYPE_DEVICE));
 933
 934    return NULL;
 935}
 936
 937void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
 938                                    Property *prop, const char *value)
 939{
 940    switch (ret) {
 941    case -EEXIST:
 942        error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
 943                  object_get_typename(OBJECT(dev)), prop->name, value);
 944        break;
 945    default:
 946    case -EINVAL:
 947        error_setg(errp, QERR_PROPERTY_VALUE_BAD,
 948                   object_get_typename(OBJECT(dev)), prop->name, value);
 949        break;
 950    case -ENOENT:
 951        error_setg(errp, "Property '%s.%s' can't find value '%s'",
 952                  object_get_typename(OBJECT(dev)), prop->name, value);
 953        break;
 954    case 0:
 955        break;
 956    }
 957}
 958
 959void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
 960{
 961    object_property_set_bool(OBJECT(dev), value, name, &error_abort);
 962}
 963
 964void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
 965{
 966    object_property_set_int(OBJECT(dev), value, name, &error_abort);
 967}
 968
 969void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
 970{
 971    object_property_set_int(OBJECT(dev), value, name, &error_abort);
 972}
 973
 974void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
 975{
 976    object_property_set_int(OBJECT(dev), value, name, &error_abort);
 977}
 978
 979void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
 980{
 981    object_property_set_int(OBJECT(dev), value, name, &error_abort);
 982}
 983
 984void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
 985{
 986    object_property_set_int(OBJECT(dev), value, name, &error_abort);
 987}
 988
 989void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
 990{
 991    object_property_set_str(OBJECT(dev), value, name, &error_abort);
 992}
 993
 994void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
 995{
 996    char str[2 * 6 + 5 + 1];
 997    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
 998             value[0], value[1], value[2], value[3], value[4], value[5]);
 999
1000    object_property_set_str(OBJECT(dev), str, name, &error_abort);
1001}
1002
1003void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1004{
1005    Property *prop;
1006
1007    prop = qdev_prop_find(dev, name);
1008    object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
1009                            name, &error_abort);
1010}
1011
1012void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1013{
1014    Property *prop;
1015    void **ptr;
1016
1017    prop = qdev_prop_find(dev, name);
1018    assert(prop && prop->info == &qdev_prop_ptr);
1019    ptr = qdev_get_prop_ptr(dev, prop);
1020    *ptr = value;
1021}
1022
1023static QTAILQ_HEAD(, GlobalProperty) global_props =
1024        QTAILQ_HEAD_INITIALIZER(global_props);
1025
1026void qdev_prop_register_global(GlobalProperty *prop)
1027{
1028    QTAILQ_INSERT_TAIL(&global_props, prop, next);
1029}
1030
1031void qdev_prop_register_global_list(GlobalProperty *props)
1032{
1033    int i;
1034
1035    for (i = 0; props[i].driver != NULL; i++) {
1036        qdev_prop_register_global(props+i);
1037    }
1038}
1039
1040int qdev_prop_check_globals(void)
1041{
1042    GlobalProperty *prop;
1043    int ret = 0;
1044
1045    QTAILQ_FOREACH(prop, &global_props, next) {
1046        ObjectClass *oc;
1047        DeviceClass *dc;
1048        if (prop->used) {
1049            continue;
1050        }
1051        if (!prop->user_provided) {
1052            continue;
1053        }
1054        oc = object_class_by_name(prop->driver);
1055        oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
1056        if (!oc) {
1057            error_report("Warning: global %s.%s has invalid class name",
1058                       prop->driver, prop->property);
1059            ret = 1;
1060            continue;
1061        }
1062        dc = DEVICE_CLASS(oc);
1063        if (!dc->hotpluggable && !prop->used) {
1064            error_report("Warning: global %s.%s=%s not used",
1065                       prop->driver, prop->property, prop->value);
1066            ret = 1;
1067            continue;
1068        }
1069    }
1070    return ret;
1071}
1072
1073static void qdev_prop_set_globals_for_type(DeviceState *dev,
1074                                const char *typename)
1075{
1076    GlobalProperty *prop;
1077
1078    QTAILQ_FOREACH(prop, &global_props, next) {
1079        Error *err = NULL;
1080
1081        if (strcmp(typename, prop->driver) != 0) {
1082            continue;
1083        }
1084        prop->used = true;
1085        object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
1086        if (err != NULL) {
1087            assert(prop->user_provided);
1088            error_reportf_err(err, "Warning: global %s.%s=%s ignored: ",
1089                              prop->driver, prop->property, prop->value);
1090            return;
1091        }
1092    }
1093}
1094
1095void qdev_prop_set_globals(DeviceState *dev)
1096{
1097    ObjectClass *class = object_get_class(OBJECT(dev));
1098
1099    do {
1100        qdev_prop_set_globals_for_type(dev, object_class_get_name(class));
1101        class = object_class_get_parent(class);
1102    } while (class);
1103}
1104
1105/* --- 64bit unsigned int 'size' type --- */
1106
1107static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
1108                     Error **errp)
1109{
1110    DeviceState *dev = DEVICE(obj);
1111    Property *prop = opaque;
1112    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1113
1114    visit_type_size(v, name, ptr, errp);
1115}
1116
1117static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
1118                     Error **errp)
1119{
1120    DeviceState *dev = DEVICE(obj);
1121    Property *prop = opaque;
1122    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1123
1124    visit_type_size(v, name, ptr, errp);
1125}
1126
1127PropertyInfo qdev_prop_size = {
1128    .name  = "size",
1129    .get = get_size,
1130    .set = set_size,
1131};
1132