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