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