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[] = "ffff:ff:ff.f";
 709    char *p = buffer;
 710    int rc = 0;
 711
 712    /*
 713     * Catch "invalid" device reference from vfio-pci and allow the
 714     * default buffer representing the non-existant device to be used.
 715     */
 716    if (~addr->domain || ~addr->bus || ~addr->slot || ~addr->function) {
 717        rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%0d",
 718                      addr->domain, addr->bus, addr->slot, addr->function);
 719        assert(rc == sizeof(buffer) - 1);
 720    }
 721
 722    visit_type_str(v, name, &p, errp);
 723}
 724
 725/*
 726 * Parse [<domain>:]<bus>:<slot>.<func>
 727 *   if <domain> is not supplied, it's assumed to be 0.
 728 */
 729static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
 730                                 void *opaque, Error **errp)
 731{
 732    DeviceState *dev = DEVICE(obj);
 733    Property *prop = opaque;
 734    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
 735    Error *local_err = NULL;
 736    char *str, *p;
 737    char *e;
 738    unsigned long val;
 739    unsigned long dom = 0, bus = 0;
 740    unsigned int slot = 0, func = 0;
 741
 742    if (dev->realized) {
 743        qdev_prop_set_after_realize(dev, name, errp);
 744        return;
 745    }
 746
 747    visit_type_str(v, name, &str, &local_err);
 748    if (local_err) {
 749        error_propagate(errp, local_err);
 750        return;
 751    }
 752
 753    p = str;
 754    val = strtoul(p, &e, 16);
 755    if (e == p || *e != ':') {
 756        goto inval;
 757    }
 758    bus = val;
 759
 760    p = e + 1;
 761    val = strtoul(p, &e, 16);
 762    if (e == p) {
 763        goto inval;
 764    }
 765    if (*e == ':') {
 766        dom = bus;
 767        bus = val;
 768        p = e + 1;
 769        val = strtoul(p, &e, 16);
 770        if (e == p) {
 771            goto inval;
 772        }
 773    }
 774    slot = val;
 775
 776    if (*e != '.') {
 777        goto inval;
 778    }
 779    p = e + 1;
 780    val = strtoul(p, &e, 10);
 781    if (e == p) {
 782        goto inval;
 783    }
 784    func = val;
 785
 786    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
 787        goto inval;
 788    }
 789
 790    if (*e) {
 791        goto inval;
 792    }
 793
 794    addr->domain = dom;
 795    addr->bus = bus;
 796    addr->slot = slot;
 797    addr->function = func;
 798
 799    g_free(str);
 800    return;
 801
 802inval:
 803    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
 804    g_free(str);
 805}
 806
 807PropertyInfo qdev_prop_pci_host_devaddr = {
 808    .name = "str",
 809    .description = "Address (bus/device/function) of "
 810                   "the host device, example: 04:10.0",
 811    .get = get_pci_host_devaddr,
 812    .set = set_pci_host_devaddr,
 813};
 814
 815/* --- support for array properties --- */
 816
 817/* Used as an opaque for the object properties we add for each
 818 * array element. Note that the struct Property must be first
 819 * in the struct so that a pointer to this works as the opaque
 820 * for the underlying element's property hooks as well as for
 821 * our own release callback.
 822 */
 823typedef struct {
 824    struct Property prop;
 825    char *propname;
 826    ObjectPropertyRelease *release;
 827} ArrayElementProperty;
 828
 829/* object property release callback for array element properties:
 830 * we call the underlying element's property release hook, and
 831 * then free the memory we allocated when we added the property.
 832 */
 833static void array_element_release(Object *obj, const char *name, void *opaque)
 834{
 835    ArrayElementProperty *p = opaque;
 836    if (p->release) {
 837        p->release(obj, name, opaque);
 838    }
 839    g_free(p->propname);
 840    g_free(p);
 841}
 842
 843static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
 844                              void *opaque, Error **errp)
 845{
 846    /* Setter for the property which defines the length of a
 847     * variable-sized property array. As well as actually setting the
 848     * array-length field in the device struct, we have to create the
 849     * array itself and dynamically add the corresponding properties.
 850     */
 851    DeviceState *dev = DEVICE(obj);
 852    Property *prop = opaque;
 853    uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
 854    void **arrayptr = (void *)dev + prop->arrayoffset;
 855    Error *local_err = NULL;
 856    void *eltptr;
 857    const char *arrayname;
 858    int i;
 859
 860    if (dev->realized) {
 861        qdev_prop_set_after_realize(dev, name, errp);
 862        return;
 863    }
 864    if (*alenptr) {
 865        error_setg(errp, "array size property %s may not be set more than once",
 866                   name);
 867        return;
 868    }
 869    visit_type_uint32(v, name, alenptr, &local_err);
 870    if (local_err) {
 871        error_propagate(errp, local_err);
 872        return;
 873    }
 874    if (!*alenptr) {
 875        return;
 876    }
 877
 878    /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
 879     * strip it off so we can get the name of the array itself.
 880     */
 881    assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
 882                   strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
 883    arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
 884
 885    /* Note that it is the responsibility of the individual device's deinit
 886     * to free the array proper.
 887     */
 888    *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
 889    for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
 890        char *propname = g_strdup_printf("%s[%d]", arrayname, i);
 891        ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
 892        arrayprop->release = prop->arrayinfo->release;
 893        arrayprop->propname = propname;
 894        arrayprop->prop.info = prop->arrayinfo;
 895        arrayprop->prop.name = propname;
 896        /* This ugly piece of pointer arithmetic sets up the offset so
 897         * that when the underlying get/set hooks call qdev_get_prop_ptr
 898         * they get the right answer despite the array element not actually
 899         * being inside the device struct.
 900         */
 901        arrayprop->prop.offset = eltptr - (void *)dev;
 902        assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
 903        object_property_add(obj, propname,
 904                            arrayprop->prop.info->name,
 905                            arrayprop->prop.info->get,
 906                            arrayprop->prop.info->set,
 907                            array_element_release,
 908                            arrayprop, &local_err);
 909        if (local_err) {
 910            error_propagate(errp, local_err);
 911            return;
 912        }
 913    }
 914}
 915
 916PropertyInfo qdev_prop_arraylen = {
 917    .name = "uint32",
 918    .get = get_uint32,
 919    .set = set_prop_arraylen,
 920};
 921
 922/* --- public helpers --- */
 923
 924static Property *qdev_prop_walk(Property *props, const char *name)
 925{
 926    if (!props) {
 927        return NULL;
 928    }
 929    while (props->name) {
 930        if (strcmp(props->name, name) == 0) {
 931            return props;
 932        }
 933        props++;
 934    }
 935    return NULL;
 936}
 937
 938static Property *qdev_prop_find(DeviceState *dev, const char *name)
 939{
 940    ObjectClass *class;
 941    Property *prop;
 942
 943    /* device properties */
 944    class = object_get_class(OBJECT(dev));
 945    do {
 946        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
 947        if (prop) {
 948            return prop;
 949        }
 950        class = object_class_get_parent(class);
 951    } while (class != object_class_by_name(TYPE_DEVICE));
 952
 953    return NULL;
 954}
 955
 956void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
 957                                    Property *prop, const char *value)
 958{
 959    switch (ret) {
 960    case -EEXIST:
 961        error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
 962                  object_get_typename(OBJECT(dev)), prop->name, value);
 963        break;
 964    default:
 965    case -EINVAL:
 966        error_setg(errp, QERR_PROPERTY_VALUE_BAD,
 967                   object_get_typename(OBJECT(dev)), prop->name, value);
 968        break;
 969    case -ENOENT:
 970        error_setg(errp, "Property '%s.%s' can't find value '%s'",
 971                  object_get_typename(OBJECT(dev)), prop->name, value);
 972        break;
 973    case 0:
 974        break;
 975    }
 976}
 977
 978void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
 979{
 980    object_property_set_bool(OBJECT(dev), value, name, &error_abort);
 981}
 982
 983void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
 984{
 985    object_property_set_int(OBJECT(dev), value, name, &error_abort);
 986}
 987
 988void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
 989{
 990    object_property_set_int(OBJECT(dev), value, name, &error_abort);
 991}
 992
 993void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
 994{
 995    object_property_set_int(OBJECT(dev), value, name, &error_abort);
 996}
 997
 998void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
 999{
1000    object_property_set_int(OBJECT(dev), value, name, &error_abort);
1001}
1002
1003void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1004{
1005    object_property_set_int(OBJECT(dev), value, name, &error_abort);
1006}
1007
1008void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
1009{
1010    object_property_set_str(OBJECT(dev), value, name, &error_abort);
1011}
1012
1013void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
1014{
1015    char str[2 * 6 + 5 + 1];
1016    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1017             value[0], value[1], value[2], value[3], value[4], value[5]);
1018
1019    object_property_set_str(OBJECT(dev), str, name, &error_abort);
1020}
1021
1022void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1023{
1024    Property *prop;
1025
1026    prop = qdev_prop_find(dev, name);
1027    object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
1028                            name, &error_abort);
1029}
1030
1031void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1032{
1033    Property *prop;
1034    void **ptr;
1035
1036    prop = qdev_prop_find(dev, name);
1037    assert(prop && prop->info == &qdev_prop_ptr);
1038    ptr = qdev_get_prop_ptr(dev, prop);
1039    *ptr = value;
1040}
1041
1042static GList *global_props;
1043
1044void qdev_prop_register_global(GlobalProperty *prop)
1045{
1046    global_props = g_list_append(global_props, prop);
1047}
1048
1049void qdev_prop_register_global_list(GlobalProperty *props)
1050{
1051    int i;
1052
1053    for (i = 0; props[i].driver != NULL; i++) {
1054        qdev_prop_register_global(props+i);
1055    }
1056}
1057
1058int qdev_prop_check_globals(void)
1059{
1060    GList *l;
1061    int ret = 0;
1062
1063    for (l = global_props; l; l = l->next) {
1064        GlobalProperty *prop = l->data;
1065        ObjectClass *oc;
1066        DeviceClass *dc;
1067        if (prop->used) {
1068            continue;
1069        }
1070        if (!prop->user_provided) {
1071            continue;
1072        }
1073        oc = object_class_by_name(prop->driver);
1074        oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
1075        if (!oc) {
1076            error_report("Warning: global %s.%s has invalid class name",
1077                       prop->driver, prop->property);
1078            ret = 1;
1079            continue;
1080        }
1081        dc = DEVICE_CLASS(oc);
1082        if (!dc->hotpluggable && !prop->used) {
1083            error_report("Warning: global %s.%s=%s not used",
1084                       prop->driver, prop->property, prop->value);
1085            ret = 1;
1086            continue;
1087        }
1088    }
1089    return ret;
1090}
1091
1092static void qdev_prop_set_globals_for_type(DeviceState *dev,
1093                                           const char *typename)
1094{
1095    GList *l;
1096
1097    for (l = global_props; l; l = l->next) {
1098        GlobalProperty *prop = l->data;
1099        Error *err = NULL;
1100
1101        if (strcmp(typename, prop->driver) != 0) {
1102            continue;
1103        }
1104        prop->used = true;
1105        object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
1106        if (err != NULL) {
1107            error_prepend(&err, "can't apply global %s.%s=%s: ",
1108                          prop->driver, prop->property, prop->value);
1109            if (!dev->hotplugged && prop->errp) {
1110                error_propagate(prop->errp, err);
1111            } else {
1112                assert(prop->user_provided);
1113                error_reportf_err(err, "Warning: ");
1114            }
1115        }
1116    }
1117}
1118
1119void qdev_prop_set_globals(DeviceState *dev)
1120{
1121    ObjectClass *class = object_get_class(OBJECT(dev));
1122
1123    do {
1124        qdev_prop_set_globals_for_type(dev, object_class_get_name(class));
1125        class = object_class_get_parent(class);
1126    } while (class);
1127}
1128
1129/* --- 64bit unsigned int 'size' type --- */
1130
1131static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
1132                     Error **errp)
1133{
1134    DeviceState *dev = DEVICE(obj);
1135    Property *prop = opaque;
1136    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1137
1138    visit_type_size(v, name, ptr, errp);
1139}
1140
1141static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
1142                     Error **errp)
1143{
1144    DeviceState *dev = DEVICE(obj);
1145    Property *prop = opaque;
1146    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1147
1148    visit_type_size(v, name, ptr, errp);
1149}
1150
1151PropertyInfo qdev_prop_size = {
1152    .name  = "size",
1153    .get = get_size,
1154    .set = set_size,
1155};
1156