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