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