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