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