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/* --- Block device error handling policy --- */
 543
 544QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int));
 545
 546PropertyInfo qdev_prop_blockdev_on_error = {
 547    .name = "BlockdevOnError",
 548    .description = "Error handling policy, "
 549                   "report/ignore/enospc/stop/auto",
 550    .enum_table = BlockdevOnError_lookup,
 551    .get = get_enum,
 552    .set = set_enum,
 553};
 554
 555/* --- BIOS CHS translation */
 556
 557QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
 558
 559PropertyInfo qdev_prop_bios_chs_trans = {
 560    .name = "BiosAtaTranslation",
 561    .description = "Logical CHS translation algorithm, "
 562                   "auto/none/lba/large/rechs",
 563    .enum_table = BiosAtaTranslation_lookup,
 564    .get = get_enum,
 565    .set = set_enum,
 566};
 567
 568/* --- FDC default drive types */
 569
 570PropertyInfo qdev_prop_fdc_drive_type = {
 571    .name = "FdcDriveType",
 572    .description = "FDC drive type, "
 573                   "144/288/120/none/auto",
 574    .enum_table = FloppyDriveType_lookup,
 575    .get = get_enum,
 576    .set = set_enum
 577};
 578
 579/* --- pci address --- */
 580
 581/*
 582 * bus-local address, i.e. "$slot" or "$slot.$fn"
 583 */
 584static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
 585                          void *opaque, Error **errp)
 586{
 587    DeviceState *dev = DEVICE(obj);
 588    Property *prop = opaque;
 589    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
 590    unsigned int slot, fn, n;
 591    Error *local_err = NULL;
 592    char *str;
 593
 594    if (dev->realized) {
 595        qdev_prop_set_after_realize(dev, name, errp);
 596        return;
 597    }
 598
 599    visit_type_str(v, name, &str, &local_err);
 600    if (local_err) {
 601        error_free(local_err);
 602        local_err = NULL;
 603        visit_type_int32(v, name, &value, &local_err);
 604        if (local_err) {
 605            error_propagate(errp, local_err);
 606        } else if (value < -1 || value > 255) {
 607            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
 608                       name ? name : "null", "pci_devfn");
 609        } else {
 610            *ptr = value;
 611        }
 612        return;
 613    }
 614
 615    if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
 616        fn = 0;
 617        if (sscanf(str, "%x%n", &slot, &n) != 1) {
 618            goto invalid;
 619        }
 620    }
 621    if (str[n] != '\0' || fn > 7 || slot > 31) {
 622        goto invalid;
 623    }
 624    *ptr = slot << 3 | fn;
 625    g_free(str);
 626    return;
 627
 628invalid:
 629    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
 630    g_free(str);
 631}
 632
 633static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest,
 634                           size_t len)
 635{
 636    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
 637
 638    if (*ptr == -1) {
 639        return snprintf(dest, len, "<unset>");
 640    } else {
 641        return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
 642    }
 643}
 644
 645PropertyInfo qdev_prop_pci_devfn = {
 646    .name  = "int32",
 647    .description = "Slot and optional function number, example: 06.0 or 06",
 648    .print = print_pci_devfn,
 649    .get   = get_int32,
 650    .set   = set_pci_devfn,
 651};
 652
 653/* --- blocksize --- */
 654
 655static void set_blocksize(Object *obj, Visitor *v, const char *name,
 656                          void *opaque, Error **errp)
 657{
 658    DeviceState *dev = DEVICE(obj);
 659    Property *prop = opaque;
 660    uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
 661    Error *local_err = NULL;
 662    const int64_t min = 512;
 663    const int64_t max = 32768;
 664
 665    if (dev->realized) {
 666        qdev_prop_set_after_realize(dev, name, errp);
 667        return;
 668    }
 669
 670    visit_type_uint16(v, name, &value, &local_err);
 671    if (local_err) {
 672        error_propagate(errp, local_err);
 673        return;
 674    }
 675    /* value of 0 means "unset" */
 676    if (value && (value < min || value > max)) {
 677        error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
 678                   dev->id ? : "", name, (int64_t)value, min, max);
 679        return;
 680    }
 681
 682    /* We rely on power-of-2 blocksizes for bitmasks */
 683    if ((value & (value - 1)) != 0) {
 684        error_setg(errp,
 685                  "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2",
 686                  dev->id ?: "", name, (int64_t)value);
 687        return;
 688    }
 689
 690    *ptr = value;
 691}
 692
 693PropertyInfo qdev_prop_blocksize = {
 694    .name  = "uint16",
 695    .description = "A power of two between 512 and 32768",
 696    .get   = get_uint16,
 697    .set   = set_blocksize,
 698};
 699
 700/* --- pci host address --- */
 701
 702static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
 703                                 void *opaque, Error **errp)
 704{
 705    DeviceState *dev = DEVICE(obj);
 706    Property *prop = opaque;
 707    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
 708    char buffer[] = "xxxx:xx:xx.x";
 709    char *p = buffer;
 710    int rc = 0;
 711
 712    rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d",
 713                  addr->domain, addr->bus, addr->slot, addr->function);
 714    assert(rc == sizeof(buffer) - 1);
 715
 716    visit_type_str(v, name, &p, errp);
 717}
 718
 719/*
 720 * Parse [<domain>:]<bus>:<slot>.<func>
 721 *   if <domain> is not supplied, it's assumed to be 0.
 722 */
 723static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
 724                                 void *opaque, Error **errp)
 725{
 726    DeviceState *dev = DEVICE(obj);
 727    Property *prop = opaque;
 728    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
 729    Error *local_err = NULL;
 730    char *str, *p;
 731    char *e;
 732    unsigned long val;
 733    unsigned long dom = 0, bus = 0;
 734    unsigned int slot = 0, func = 0;
 735
 736    if (dev->realized) {
 737        qdev_prop_set_after_realize(dev, name, errp);
 738        return;
 739    }
 740
 741    visit_type_str(v, name, &str, &local_err);
 742    if (local_err) {
 743        error_propagate(errp, local_err);
 744        return;
 745    }
 746
 747    p = str;
 748    val = strtoul(p, &e, 16);
 749    if (e == p || *e != ':') {
 750        goto inval;
 751    }
 752    bus = val;
 753
 754    p = e + 1;
 755    val = strtoul(p, &e, 16);
 756    if (e == p) {
 757        goto inval;
 758    }
 759    if (*e == ':') {
 760        dom = bus;
 761        bus = val;
 762        p = e + 1;
 763        val = strtoul(p, &e, 16);
 764        if (e == p) {
 765            goto inval;
 766        }
 767    }
 768    slot = val;
 769
 770    if (*e != '.') {
 771        goto inval;
 772    }
 773    p = e + 1;
 774    val = strtoul(p, &e, 10);
 775    if (e == p) {
 776        goto inval;
 777    }
 778    func = val;
 779
 780    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
 781        goto inval;
 782    }
 783
 784    if (*e) {
 785        goto inval;
 786    }
 787
 788    addr->domain = dom;
 789    addr->bus = bus;
 790    addr->slot = slot;
 791    addr->function = func;
 792
 793    g_free(str);
 794    return;
 795
 796inval:
 797    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
 798    g_free(str);
 799}
 800
 801PropertyInfo qdev_prop_pci_host_devaddr = {
 802    .name = "str",
 803    .description = "Address (bus/device/function) of "
 804                   "the host device, example: 04:10.0",
 805    .get = get_pci_host_devaddr,
 806    .set = set_pci_host_devaddr,
 807};
 808
 809/* --- support for array properties --- */
 810
 811/* Used as an opaque for the object properties we add for each
 812 * array element. Note that the struct Property must be first
 813 * in the struct so that a pointer to this works as the opaque
 814 * for the underlying element's property hooks as well as for
 815 * our own release callback.
 816 */
 817typedef struct {
 818    struct Property prop;
 819    char *propname;
 820    ObjectPropertyRelease *release;
 821} ArrayElementProperty;
 822
 823/* object property release callback for array element properties:
 824 * we call the underlying element's property release hook, and
 825 * then free the memory we allocated when we added the property.
 826 */
 827static void array_element_release(Object *obj, const char *name, void *opaque)
 828{
 829    ArrayElementProperty *p = opaque;
 830    if (p->release) {
 831        p->release(obj, name, opaque);
 832    }
 833    g_free(p->propname);
 834    g_free(p);
 835}
 836
 837static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
 838                              void *opaque, Error **errp)
 839{
 840    /* Setter for the property which defines the length of a
 841     * variable-sized property array. As well as actually setting the
 842     * array-length field in the device struct, we have to create the
 843     * array itself and dynamically add the corresponding properties.
 844     */
 845    DeviceState *dev = DEVICE(obj);
 846    Property *prop = opaque;
 847    uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
 848    void **arrayptr = (void *)dev + prop->arrayoffset;
 849    Error *local_err = NULL;
 850    void *eltptr;
 851    const char *arrayname;
 852    int i;
 853
 854    if (dev->realized) {
 855        qdev_prop_set_after_realize(dev, name, errp);
 856        return;
 857    }
 858    if (*alenptr) {
 859        error_setg(errp, "array size property %s may not be set more than once",
 860                   name);
 861        return;
 862    }
 863    visit_type_uint32(v, name, alenptr, &local_err);
 864    if (local_err) {
 865        error_propagate(errp, local_err);
 866        return;
 867    }
 868    if (!*alenptr) {
 869        return;
 870    }
 871
 872    /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
 873     * strip it off so we can get the name of the array itself.
 874     */
 875    assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
 876                   strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
 877    arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
 878
 879    /* Note that it is the responsibility of the individual device's deinit
 880     * to free the array proper.
 881     */
 882    *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
 883    for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
 884        char *propname = g_strdup_printf("%s[%d]", arrayname, i);
 885        ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
 886        arrayprop->release = prop->arrayinfo->release;
 887        arrayprop->propname = propname;
 888        arrayprop->prop.info = prop->arrayinfo;
 889        arrayprop->prop.name = propname;
 890        /* This ugly piece of pointer arithmetic sets up the offset so
 891         * that when the underlying get/set hooks call qdev_get_prop_ptr
 892         * they get the right answer despite the array element not actually
 893         * being inside the device struct.
 894         */
 895        arrayprop->prop.offset = eltptr - (void *)dev;
 896        assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
 897        object_property_add(obj, propname,
 898                            arrayprop->prop.info->name,
 899                            arrayprop->prop.info->get,
 900                            arrayprop->prop.info->set,
 901                            array_element_release,
 902                            arrayprop, &local_err);
 903        if (local_err) {
 904            error_propagate(errp, local_err);
 905            return;
 906        }
 907    }
 908}
 909
 910PropertyInfo qdev_prop_arraylen = {
 911    .name = "uint32",
 912    .get = get_uint32,
 913    .set = set_prop_arraylen,
 914};
 915
 916/* --- public helpers --- */
 917
 918static Property *qdev_prop_walk(Property *props, const char *name)
 919{
 920    if (!props) {
 921        return NULL;
 922    }
 923    while (props->name) {
 924        if (strcmp(props->name, name) == 0) {
 925            return props;
 926        }
 927        props++;
 928    }
 929    return NULL;
 930}
 931
 932static Property *qdev_prop_find(DeviceState *dev, const char *name)
 933{
 934    ObjectClass *class;
 935    Property *prop;
 936
 937    /* device properties */
 938    class = object_get_class(OBJECT(dev));
 939    do {
 940        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
 941        if (prop) {
 942            return prop;
 943        }
 944        class = object_class_get_parent(class);
 945    } while (class != object_class_by_name(TYPE_DEVICE));
 946
 947    return NULL;
 948}
 949
 950void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
 951                                    Property *prop, const char *value)
 952{
 953    switch (ret) {
 954    case -EEXIST:
 955        error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
 956                  object_get_typename(OBJECT(dev)), prop->name, value);
 957        break;
 958    default:
 959    case -EINVAL:
 960        error_setg(errp, QERR_PROPERTY_VALUE_BAD,
 961                   object_get_typename(OBJECT(dev)), prop->name, value);
 962        break;
 963    case -ENOENT:
 964        error_setg(errp, "Property '%s.%s' can't find value '%s'",
 965                  object_get_typename(OBJECT(dev)), prop->name, value);
 966        break;
 967    case 0:
 968        break;
 969    }
 970}
 971
 972void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
 973{
 974    object_property_set_bool(OBJECT(dev), value, name, &error_abort);
 975}
 976
 977void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
 978{
 979    object_property_set_int(OBJECT(dev), value, name, &error_abort);
 980}
 981
 982void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
 983{
 984    object_property_set_int(OBJECT(dev), value, name, &error_abort);
 985}
 986
 987void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
 988{
 989    object_property_set_int(OBJECT(dev), value, name, &error_abort);
 990}
 991
 992void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
 993{
 994    object_property_set_int(OBJECT(dev), value, name, &error_abort);
 995}
 996
 997void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
 998{
 999    object_property_set_int(OBJECT(dev), value, name, &error_abort);
1000}
1001
1002void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
1003{
1004    object_property_set_str(OBJECT(dev), value, name, &error_abort);
1005}
1006
1007void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
1008{
1009    char str[2 * 6 + 5 + 1];
1010    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1011             value[0], value[1], value[2], value[3], value[4], value[5]);
1012
1013    object_property_set_str(OBJECT(dev), str, name, &error_abort);
1014}
1015
1016void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1017{
1018    Property *prop;
1019
1020    prop = qdev_prop_find(dev, name);
1021    object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
1022                            name, &error_abort);
1023}
1024
1025void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1026{
1027    Property *prop;
1028    void **ptr;
1029
1030    prop = qdev_prop_find(dev, name);
1031    assert(prop && prop->info == &qdev_prop_ptr);
1032    ptr = qdev_get_prop_ptr(dev, prop);
1033    *ptr = value;
1034}
1035
1036static GList *global_props;
1037
1038void qdev_prop_register_global(GlobalProperty *prop)
1039{
1040    global_props = g_list_append(global_props, prop);
1041}
1042
1043void qdev_prop_register_global_list(GlobalProperty *props)
1044{
1045    int i;
1046
1047    for (i = 0; props[i].driver != NULL; i++) {
1048        qdev_prop_register_global(props+i);
1049    }
1050}
1051
1052int qdev_prop_check_globals(void)
1053{
1054    GList *l;
1055    int ret = 0;
1056
1057    for (l = global_props; l; l = l->next) {
1058        GlobalProperty *prop = l->data;
1059        ObjectClass *oc;
1060        DeviceClass *dc;
1061        if (prop->used) {
1062            continue;
1063        }
1064        if (!prop->user_provided) {
1065            continue;
1066        }
1067        oc = object_class_by_name(prop->driver);
1068        oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
1069        if (!oc) {
1070            error_report("Warning: global %s.%s has invalid class name",
1071                       prop->driver, prop->property);
1072            ret = 1;
1073            continue;
1074        }
1075        dc = DEVICE_CLASS(oc);
1076        if (!dc->hotpluggable && !prop->used) {
1077            error_report("Warning: global %s.%s=%s not used",
1078                       prop->driver, prop->property, prop->value);
1079            ret = 1;
1080            continue;
1081        }
1082    }
1083    return ret;
1084}
1085
1086static void qdev_prop_set_globals_for_type(DeviceState *dev,
1087                                           const char *typename)
1088{
1089    GList *l;
1090
1091    for (l = global_props; l; l = l->next) {
1092        GlobalProperty *prop = l->data;
1093        Error *err = NULL;
1094
1095        if (strcmp(typename, prop->driver) != 0) {
1096            continue;
1097        }
1098        prop->used = true;
1099        object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
1100        if (err != NULL) {
1101            error_prepend(&err, "can't apply global %s.%s=%s: ",
1102                          prop->driver, prop->property, prop->value);
1103            if (!dev->hotplugged && prop->errp) {
1104                error_propagate(prop->errp, err);
1105            } else {
1106                assert(prop->user_provided);
1107                error_reportf_err(err, "Warning: ");
1108            }
1109        }
1110    }
1111}
1112
1113void qdev_prop_set_globals(DeviceState *dev)
1114{
1115    ObjectClass *class = object_get_class(OBJECT(dev));
1116
1117    do {
1118        qdev_prop_set_globals_for_type(dev, object_class_get_name(class));
1119        class = object_class_get_parent(class);
1120    } while (class);
1121}
1122
1123/* --- 64bit unsigned int 'size' type --- */
1124
1125static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
1126                     Error **errp)
1127{
1128    DeviceState *dev = DEVICE(obj);
1129    Property *prop = opaque;
1130    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1131
1132    visit_type_size(v, name, ptr, errp);
1133}
1134
1135static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
1136                     Error **errp)
1137{
1138    DeviceState *dev = DEVICE(obj);
1139    Property *prop = opaque;
1140    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1141
1142    visit_type_size(v, name, ptr, errp);
1143}
1144
1145PropertyInfo qdev_prop_size = {
1146    .name  = "size",
1147    .get = get_size,
1148    .set = set_size,
1149};
1150