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 #include "qemu/units.h" 18 19 void qdev_prop_set_after_realize(DeviceState *dev, const char *name, 20 Error **errp) 21 { 22 if (dev->id) { 23 error_setg(errp, "Attempt to set property '%s' on device '%s' " 24 "(type '%s') after it was realized", name, dev->id, 25 object_get_typename(OBJECT(dev))); 26 } else { 27 error_setg(errp, "Attempt to set property '%s' on anonymous device " 28 "(type '%s') after it was realized", name, 29 object_get_typename(OBJECT(dev))); 30 } 31 } 32 33 void qdev_prop_allow_set_link_before_realize(const Object *obj, 34 const char *name, 35 Object *val, Error **errp) 36 { 37 DeviceState *dev = DEVICE(obj); 38 39 if (dev->realized) { 40 error_setg(errp, "Attempt to set link property '%s' on device '%s' " 41 "(type '%s') after it was realized", 42 name, dev->id, object_get_typename(obj)); 43 } 44 } 45 46 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop) 47 { 48 void *ptr = dev; 49 ptr += prop->offset; 50 return ptr; 51 } 52 53 static void get_enum(Object *obj, Visitor *v, const char *name, void *opaque, 54 Error **errp) 55 { 56 DeviceState *dev = DEVICE(obj); 57 Property *prop = opaque; 58 int *ptr = qdev_get_prop_ptr(dev, prop); 59 60 visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp); 61 } 62 63 static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque, 64 Error **errp) 65 { 66 DeviceState *dev = DEVICE(obj); 67 Property *prop = opaque; 68 int *ptr = qdev_get_prop_ptr(dev, prop); 69 70 if (dev->realized) { 71 qdev_prop_set_after_realize(dev, name, errp); 72 return; 73 } 74 75 visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp); 76 } 77 78 static void set_default_value_enum(ObjectProperty *op, const Property *prop) 79 { 80 object_property_set_default_str(op, 81 qapi_enum_lookup(prop->info->enum_table, prop->defval.i)); 82 } 83 84 /* Bit */ 85 86 static uint32_t qdev_get_prop_mask(Property *prop) 87 { 88 assert(prop->info == &qdev_prop_bit); 89 return 0x1 << prop->bitnr; 90 } 91 92 static 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 103 static 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 114 static 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 135 static void set_default_value_bool(ObjectProperty *op, const Property *prop) 136 { 137 object_property_set_default_bool(op, prop->defval.u); 138 } 139 140 const 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 150 static uint64_t qdev_get_prop_mask64(Property *prop) 151 { 152 assert(prop->info == &qdev_prop_bit64); 153 return 0x1ull << prop->bitnr; 154 } 155 156 static 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 167 static 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 178 static 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 199 const 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 209 static 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 219 static 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 234 const 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 243 static 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 253 static 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 268 static void set_default_value_int(ObjectProperty *op, const Property *prop) 269 { 270 object_property_set_default_int(op, prop->defval.i); 271 } 272 273 static void set_default_value_uint(ObjectProperty *op, const Property *prop) 274 { 275 object_property_set_default_uint(op, prop->defval.u); 276 } 277 278 const 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 287 static 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 297 static 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 312 const 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 321 static 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 331 static 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 346 static 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 356 static 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 371 const 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 378 const 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 387 static 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 397 static 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 412 static 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 422 static 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 437 const 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 444 const 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 453 static 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 459 static 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 474 static 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 497 const PropertyInfo qdev_prop_string = { 498 .name = "str", 499 .release = release_string, 500 .get = get_string, 501 .set = set_string, 502 }; 503 504 /* --- mac address --- */ 505 506 /* 507 * accepted syntax versions: 508 * 01:02:03:04:05:06 509 * 01-02-03-04-05-06 510 */ 511 static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque, 512 Error **errp) 513 { 514 DeviceState *dev = DEVICE(obj); 515 Property *prop = opaque; 516 MACAddr *mac = qdev_get_prop_ptr(dev, prop); 517 char buffer[2 * 6 + 5 + 1]; 518 char *p = buffer; 519 520 snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x", 521 mac->a[0], mac->a[1], mac->a[2], 522 mac->a[3], mac->a[4], mac->a[5]); 523 524 visit_type_str(v, name, &p, errp); 525 } 526 527 static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque, 528 Error **errp) 529 { 530 DeviceState *dev = DEVICE(obj); 531 Property *prop = opaque; 532 MACAddr *mac = qdev_get_prop_ptr(dev, prop); 533 Error *local_err = NULL; 534 int i, pos; 535 char *str, *p; 536 537 if (dev->realized) { 538 qdev_prop_set_after_realize(dev, name, errp); 539 return; 540 } 541 542 visit_type_str(v, name, &str, &local_err); 543 if (local_err) { 544 error_propagate(errp, local_err); 545 return; 546 } 547 548 for (i = 0, pos = 0; i < 6; i++, pos += 3) { 549 if (!qemu_isxdigit(str[pos])) { 550 goto inval; 551 } 552 if (!qemu_isxdigit(str[pos+1])) { 553 goto inval; 554 } 555 if (i == 5) { 556 if (str[pos+2] != '\0') { 557 goto inval; 558 } 559 } else { 560 if (str[pos+2] != ':' && str[pos+2] != '-') { 561 goto inval; 562 } 563 } 564 mac->a[i] = strtol(str+pos, &p, 16); 565 } 566 g_free(str); 567 return; 568 569 inval: 570 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 571 g_free(str); 572 } 573 574 const PropertyInfo qdev_prop_macaddr = { 575 .name = "str", 576 .description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56", 577 .get = get_mac, 578 .set = set_mac, 579 }; 580 581 /* --- on/off/auto --- */ 582 583 const PropertyInfo qdev_prop_on_off_auto = { 584 .name = "OnOffAuto", 585 .description = "on/off/auto", 586 .enum_table = &OnOffAuto_lookup, 587 .get = get_enum, 588 .set = set_enum, 589 .set_default_value = set_default_value_enum, 590 }; 591 592 /* --- lost tick policy --- */ 593 594 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int)); 595 596 const PropertyInfo qdev_prop_losttickpolicy = { 597 .name = "LostTickPolicy", 598 .enum_table = &LostTickPolicy_lookup, 599 .get = get_enum, 600 .set = set_enum, 601 .set_default_value = set_default_value_enum, 602 }; 603 604 /* --- Block device error handling policy --- */ 605 606 QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int)); 607 608 const PropertyInfo qdev_prop_blockdev_on_error = { 609 .name = "BlockdevOnError", 610 .description = "Error handling policy, " 611 "report/ignore/enospc/stop/auto", 612 .enum_table = &BlockdevOnError_lookup, 613 .get = get_enum, 614 .set = set_enum, 615 .set_default_value = set_default_value_enum, 616 }; 617 618 /* --- BIOS CHS translation */ 619 620 QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int)); 621 622 const PropertyInfo qdev_prop_bios_chs_trans = { 623 .name = "BiosAtaTranslation", 624 .description = "Logical CHS translation algorithm, " 625 "auto/none/lba/large/rechs", 626 .enum_table = &BiosAtaTranslation_lookup, 627 .get = get_enum, 628 .set = set_enum, 629 .set_default_value = set_default_value_enum, 630 }; 631 632 /* --- FDC default drive types */ 633 634 const PropertyInfo qdev_prop_fdc_drive_type = { 635 .name = "FdcDriveType", 636 .description = "FDC drive type, " 637 "144/288/120/none/auto", 638 .enum_table = &FloppyDriveType_lookup, 639 .get = get_enum, 640 .set = set_enum, 641 .set_default_value = set_default_value_enum, 642 }; 643 644 /* --- MultiFDCompression --- */ 645 646 const PropertyInfo qdev_prop_multifd_compression = { 647 .name = "MultiFDCompression", 648 .description = "multifd_compression values, " 649 "none/zlib/zstd", 650 .enum_table = &MultiFDCompression_lookup, 651 .get = get_enum, 652 .set = set_enum, 653 .set_default_value = set_default_value_enum, 654 }; 655 656 /* --- pci address --- */ 657 658 /* 659 * bus-local address, i.e. "$slot" or "$slot.$fn" 660 */ 661 static void set_pci_devfn(Object *obj, Visitor *v, const char *name, 662 void *opaque, Error **errp) 663 { 664 DeviceState *dev = DEVICE(obj); 665 Property *prop = opaque; 666 int32_t value, *ptr = qdev_get_prop_ptr(dev, prop); 667 unsigned int slot, fn, n; 668 Error *local_err = NULL; 669 char *str; 670 671 if (dev->realized) { 672 qdev_prop_set_after_realize(dev, name, errp); 673 return; 674 } 675 676 visit_type_str(v, name, &str, &local_err); 677 if (local_err) { 678 error_free(local_err); 679 local_err = NULL; 680 visit_type_int32(v, name, &value, &local_err); 681 if (local_err) { 682 error_propagate(errp, local_err); 683 } else if (value < -1 || value > 255) { 684 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 685 name ? name : "null", "pci_devfn"); 686 } else { 687 *ptr = value; 688 } 689 return; 690 } 691 692 if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) { 693 fn = 0; 694 if (sscanf(str, "%x%n", &slot, &n) != 1) { 695 goto invalid; 696 } 697 } 698 if (str[n] != '\0' || fn > 7 || slot > 31) { 699 goto invalid; 700 } 701 *ptr = slot << 3 | fn; 702 g_free(str); 703 return; 704 705 invalid: 706 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 707 g_free(str); 708 } 709 710 static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, 711 size_t len) 712 { 713 int32_t *ptr = qdev_get_prop_ptr(dev, prop); 714 715 if (*ptr == -1) { 716 return snprintf(dest, len, "<unset>"); 717 } else { 718 return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7); 719 } 720 } 721 722 const PropertyInfo qdev_prop_pci_devfn = { 723 .name = "int32", 724 .description = "Slot and optional function number, example: 06.0 or 06", 725 .print = print_pci_devfn, 726 .get = get_int32, 727 .set = set_pci_devfn, 728 .set_default_value = set_default_value_int, 729 }; 730 731 /* --- 32bit unsigned int 'size' type --- */ 732 733 static void get_size32(Object *obj, Visitor *v, const char *name, void *opaque, 734 Error **errp) 735 { 736 DeviceState *dev = DEVICE(obj); 737 Property *prop = opaque; 738 uint32_t *ptr = qdev_get_prop_ptr(dev, prop); 739 uint64_t value = *ptr; 740 741 visit_type_size(v, name, &value, errp); 742 } 743 744 static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque, 745 Error **errp) 746 { 747 DeviceState *dev = DEVICE(obj); 748 Property *prop = opaque; 749 uint32_t *ptr = qdev_get_prop_ptr(dev, prop); 750 uint64_t value; 751 Error *local_err = NULL; 752 753 if (dev->realized) { 754 qdev_prop_set_after_realize(dev, name, errp); 755 return; 756 } 757 758 visit_type_size(v, name, &value, &local_err); 759 if (local_err) { 760 error_propagate(errp, local_err); 761 return; 762 } 763 764 if (value > UINT32_MAX) { 765 error_setg(errp, 766 "Property %s.%s doesn't take value %" PRIu64 767 " (maximum: %u)", 768 dev->id ? : "", name, value, UINT32_MAX); 769 return; 770 } 771 772 *ptr = value; 773 } 774 775 const PropertyInfo qdev_prop_size32 = { 776 .name = "size", 777 .get = get_size32, 778 .set = set_size32, 779 .set_default_value = set_default_value_uint, 780 }; 781 782 /* --- blocksize --- */ 783 784 /* lower limit is sector size */ 785 #define MIN_BLOCK_SIZE 512 786 #define MIN_BLOCK_SIZE_STR "512 B" 787 /* 788 * upper limit is arbitrary, 2 MiB looks sufficient for all sensible uses, and 789 * matches qcow2 cluster size limit 790 */ 791 #define MAX_BLOCK_SIZE (2 * MiB) 792 #define MAX_BLOCK_SIZE_STR "2 MiB" 793 794 static void set_blocksize(Object *obj, Visitor *v, const char *name, 795 void *opaque, Error **errp) 796 { 797 DeviceState *dev = DEVICE(obj); 798 Property *prop = opaque; 799 uint32_t *ptr = qdev_get_prop_ptr(dev, prop); 800 uint64_t value; 801 Error *local_err = NULL; 802 803 if (dev->realized) { 804 qdev_prop_set_after_realize(dev, name, errp); 805 return; 806 } 807 808 visit_type_size(v, name, &value, &local_err); 809 if (local_err) { 810 error_propagate(errp, local_err); 811 return; 812 } 813 /* value of 0 means "unset" */ 814 if (value && (value < MIN_BLOCK_SIZE || value > MAX_BLOCK_SIZE)) { 815 error_setg(errp, 816 "Property %s.%s doesn't take value %" PRIu64 817 " (minimum: " MIN_BLOCK_SIZE_STR 818 ", maximum: " MAX_BLOCK_SIZE_STR ")", 819 dev->id ? : "", name, value); 820 return; 821 } 822 823 /* We rely on power-of-2 blocksizes for bitmasks */ 824 if ((value & (value - 1)) != 0) { 825 error_setg(errp, 826 "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2", 827 dev->id ?: "", name, (int64_t)value); 828 return; 829 } 830 831 *ptr = value; 832 } 833 834 const PropertyInfo qdev_prop_blocksize = { 835 .name = "size", 836 .description = "A power of two between " MIN_BLOCK_SIZE_STR 837 " and " MAX_BLOCK_SIZE_STR, 838 .get = get_size32, 839 .set = set_blocksize, 840 .set_default_value = set_default_value_uint, 841 }; 842 843 /* --- pci host address --- */ 844 845 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name, 846 void *opaque, Error **errp) 847 { 848 DeviceState *dev = DEVICE(obj); 849 Property *prop = opaque; 850 PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop); 851 char buffer[] = "ffff:ff:ff.f"; 852 char *p = buffer; 853 int rc = 0; 854 855 /* 856 * Catch "invalid" device reference from vfio-pci and allow the 857 * default buffer representing the non-existent device to be used. 858 */ 859 if (~addr->domain || ~addr->bus || ~addr->slot || ~addr->function) { 860 rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%0d", 861 addr->domain, addr->bus, addr->slot, addr->function); 862 assert(rc == sizeof(buffer) - 1); 863 } 864 865 visit_type_str(v, name, &p, errp); 866 } 867 868 /* 869 * Parse [<domain>:]<bus>:<slot>.<func> 870 * if <domain> is not supplied, it's assumed to be 0. 871 */ 872 static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name, 873 void *opaque, Error **errp) 874 { 875 DeviceState *dev = DEVICE(obj); 876 Property *prop = opaque; 877 PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop); 878 Error *local_err = NULL; 879 char *str, *p; 880 char *e; 881 unsigned long val; 882 unsigned long dom = 0, bus = 0; 883 unsigned int slot = 0, func = 0; 884 885 if (dev->realized) { 886 qdev_prop_set_after_realize(dev, name, errp); 887 return; 888 } 889 890 visit_type_str(v, name, &str, &local_err); 891 if (local_err) { 892 error_propagate(errp, local_err); 893 return; 894 } 895 896 p = str; 897 val = strtoul(p, &e, 16); 898 if (e == p || *e != ':') { 899 goto inval; 900 } 901 bus = val; 902 903 p = e + 1; 904 val = strtoul(p, &e, 16); 905 if (e == p) { 906 goto inval; 907 } 908 if (*e == ':') { 909 dom = bus; 910 bus = val; 911 p = e + 1; 912 val = strtoul(p, &e, 16); 913 if (e == p) { 914 goto inval; 915 } 916 } 917 slot = val; 918 919 if (*e != '.') { 920 goto inval; 921 } 922 p = e + 1; 923 val = strtoul(p, &e, 10); 924 if (e == p) { 925 goto inval; 926 } 927 func = val; 928 929 if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) { 930 goto inval; 931 } 932 933 if (*e) { 934 goto inval; 935 } 936 937 addr->domain = dom; 938 addr->bus = bus; 939 addr->slot = slot; 940 addr->function = func; 941 942 g_free(str); 943 return; 944 945 inval: 946 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 947 g_free(str); 948 } 949 950 const PropertyInfo qdev_prop_pci_host_devaddr = { 951 .name = "str", 952 .description = "Address (bus/device/function) of " 953 "the host device, example: 04:10.0", 954 .get = get_pci_host_devaddr, 955 .set = set_pci_host_devaddr, 956 }; 957 958 /* --- UUID --- */ 959 960 static void get_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 char buffer[UUID_FMT_LEN + 1]; 967 char *p = buffer; 968 969 qemu_uuid_unparse(uuid, buffer); 970 971 visit_type_str(v, name, &p, errp); 972 } 973 974 #define UUID_VALUE_AUTO "auto" 975 976 static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque, 977 Error **errp) 978 { 979 DeviceState *dev = DEVICE(obj); 980 Property *prop = opaque; 981 QemuUUID *uuid = qdev_get_prop_ptr(dev, prop); 982 Error *local_err = NULL; 983 char *str; 984 985 if (dev->realized) { 986 qdev_prop_set_after_realize(dev, name, errp); 987 return; 988 } 989 990 visit_type_str(v, name, &str, &local_err); 991 if (local_err) { 992 error_propagate(errp, local_err); 993 return; 994 } 995 996 if (!strcmp(str, UUID_VALUE_AUTO)) { 997 qemu_uuid_generate(uuid); 998 } else if (qemu_uuid_parse(str, uuid) < 0) { 999 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 1000 } 1001 g_free(str); 1002 } 1003 1004 static void set_default_uuid_auto(ObjectProperty *op, const Property *prop) 1005 { 1006 object_property_set_default_str(op, UUID_VALUE_AUTO); 1007 } 1008 1009 const PropertyInfo qdev_prop_uuid = { 1010 .name = "str", 1011 .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO 1012 "\" for random value (default)", 1013 .get = get_uuid, 1014 .set = set_uuid, 1015 .set_default_value = set_default_uuid_auto, 1016 }; 1017 1018 /* --- support for array properties --- */ 1019 1020 /* Used as an opaque for the object properties we add for each 1021 * array element. Note that the struct Property must be first 1022 * in the struct so that a pointer to this works as the opaque 1023 * for the underlying element's property hooks as well as for 1024 * our own release callback. 1025 */ 1026 typedef struct { 1027 struct Property prop; 1028 char *propname; 1029 ObjectPropertyRelease *release; 1030 } ArrayElementProperty; 1031 1032 /* object property release callback for array element properties: 1033 * we call the underlying element's property release hook, and 1034 * then free the memory we allocated when we added the property. 1035 */ 1036 static void array_element_release(Object *obj, const char *name, void *opaque) 1037 { 1038 ArrayElementProperty *p = opaque; 1039 if (p->release) { 1040 p->release(obj, name, opaque); 1041 } 1042 g_free(p->propname); 1043 g_free(p); 1044 } 1045 1046 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name, 1047 void *opaque, Error **errp) 1048 { 1049 /* Setter for the property which defines the length of a 1050 * variable-sized property array. As well as actually setting the 1051 * array-length field in the device struct, we have to create the 1052 * array itself and dynamically add the corresponding properties. 1053 */ 1054 DeviceState *dev = DEVICE(obj); 1055 Property *prop = opaque; 1056 uint32_t *alenptr = qdev_get_prop_ptr(dev, prop); 1057 void **arrayptr = (void *)dev + prop->arrayoffset; 1058 Error *local_err = NULL; 1059 void *eltptr; 1060 const char *arrayname; 1061 int i; 1062 1063 if (dev->realized) { 1064 qdev_prop_set_after_realize(dev, name, errp); 1065 return; 1066 } 1067 if (*alenptr) { 1068 error_setg(errp, "array size property %s may not be set more than once", 1069 name); 1070 return; 1071 } 1072 visit_type_uint32(v, name, alenptr, &local_err); 1073 if (local_err) { 1074 error_propagate(errp, local_err); 1075 return; 1076 } 1077 if (!*alenptr) { 1078 return; 1079 } 1080 1081 /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix; 1082 * strip it off so we can get the name of the array itself. 1083 */ 1084 assert(strncmp(name, PROP_ARRAY_LEN_PREFIX, 1085 strlen(PROP_ARRAY_LEN_PREFIX)) == 0); 1086 arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX); 1087 1088 /* Note that it is the responsibility of the individual device's deinit 1089 * to free the array proper. 1090 */ 1091 *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize); 1092 for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) { 1093 char *propname = g_strdup_printf("%s[%d]", arrayname, i); 1094 ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1); 1095 arrayprop->release = prop->arrayinfo->release; 1096 arrayprop->propname = propname; 1097 arrayprop->prop.info = prop->arrayinfo; 1098 arrayprop->prop.name = propname; 1099 /* This ugly piece of pointer arithmetic sets up the offset so 1100 * that when the underlying get/set hooks call qdev_get_prop_ptr 1101 * they get the right answer despite the array element not actually 1102 * being inside the device struct. 1103 */ 1104 arrayprop->prop.offset = eltptr - (void *)dev; 1105 assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr); 1106 object_property_add(obj, propname, 1107 arrayprop->prop.info->name, 1108 arrayprop->prop.info->get, 1109 arrayprop->prop.info->set, 1110 array_element_release, 1111 arrayprop); 1112 } 1113 } 1114 1115 const PropertyInfo qdev_prop_arraylen = { 1116 .name = "uint32", 1117 .get = get_uint32, 1118 .set = set_prop_arraylen, 1119 .set_default_value = set_default_value_uint, 1120 }; 1121 1122 /* --- public helpers --- */ 1123 1124 static Property *qdev_prop_walk(Property *props, const char *name) 1125 { 1126 if (!props) { 1127 return NULL; 1128 } 1129 while (props->name) { 1130 if (strcmp(props->name, name) == 0) { 1131 return props; 1132 } 1133 props++; 1134 } 1135 return NULL; 1136 } 1137 1138 static Property *qdev_prop_find(DeviceState *dev, const char *name) 1139 { 1140 ObjectClass *class; 1141 Property *prop; 1142 1143 /* device properties */ 1144 class = object_get_class(OBJECT(dev)); 1145 do { 1146 prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name); 1147 if (prop) { 1148 return prop; 1149 } 1150 class = object_class_get_parent(class); 1151 } while (class != object_class_by_name(TYPE_DEVICE)); 1152 1153 return NULL; 1154 } 1155 1156 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, 1157 Property *prop, const char *value) 1158 { 1159 switch (ret) { 1160 case -EEXIST: 1161 error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", 1162 object_get_typename(OBJECT(dev)), prop->name, value); 1163 break; 1164 default: 1165 case -EINVAL: 1166 error_setg(errp, QERR_PROPERTY_VALUE_BAD, 1167 object_get_typename(OBJECT(dev)), prop->name, value); 1168 break; 1169 case -ENOENT: 1170 error_setg(errp, "Property '%s.%s' can't find value '%s'", 1171 object_get_typename(OBJECT(dev)), prop->name, value); 1172 break; 1173 case 0: 1174 break; 1175 } 1176 } 1177 1178 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value) 1179 { 1180 object_property_set_bool(OBJECT(dev), value, name, &error_abort); 1181 } 1182 1183 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value) 1184 { 1185 object_property_set_int(OBJECT(dev), value, name, &error_abort); 1186 } 1187 1188 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value) 1189 { 1190 object_property_set_int(OBJECT(dev), value, name, &error_abort); 1191 } 1192 1193 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value) 1194 { 1195 object_property_set_int(OBJECT(dev), value, name, &error_abort); 1196 } 1197 1198 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value) 1199 { 1200 object_property_set_int(OBJECT(dev), value, name, &error_abort); 1201 } 1202 1203 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value) 1204 { 1205 object_property_set_int(OBJECT(dev), value, name, &error_abort); 1206 } 1207 1208 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value) 1209 { 1210 object_property_set_str(OBJECT(dev), value, name, &error_abort); 1211 } 1212 1213 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, 1214 const uint8_t *value) 1215 { 1216 char str[2 * 6 + 5 + 1]; 1217 snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", 1218 value[0], value[1], value[2], value[3], value[4], value[5]); 1219 1220 object_property_set_str(OBJECT(dev), str, name, &error_abort); 1221 } 1222 1223 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value) 1224 { 1225 Property *prop; 1226 1227 prop = qdev_prop_find(dev, name); 1228 object_property_set_str(OBJECT(dev), 1229 qapi_enum_lookup(prop->info->enum_table, value), 1230 name, &error_abort); 1231 } 1232 1233 static GPtrArray *global_props(void) 1234 { 1235 static GPtrArray *gp; 1236 1237 if (!gp) { 1238 gp = g_ptr_array_new(); 1239 } 1240 1241 return gp; 1242 } 1243 1244 void qdev_prop_register_global(GlobalProperty *prop) 1245 { 1246 g_ptr_array_add(global_props(), prop); 1247 } 1248 1249 const GlobalProperty *qdev_find_global_prop(DeviceState *dev, 1250 const char *name) 1251 { 1252 GPtrArray *props = global_props(); 1253 const GlobalProperty *p; 1254 int i; 1255 1256 for (i = 0; i < props->len; i++) { 1257 p = g_ptr_array_index(props, i); 1258 if (object_dynamic_cast(OBJECT(dev), p->driver) 1259 && !strcmp(p->property, name)) { 1260 return p; 1261 } 1262 } 1263 return NULL; 1264 } 1265 1266 int qdev_prop_check_globals(void) 1267 { 1268 int i, ret = 0; 1269 1270 for (i = 0; i < global_props()->len; i++) { 1271 GlobalProperty *prop; 1272 ObjectClass *oc; 1273 DeviceClass *dc; 1274 1275 prop = g_ptr_array_index(global_props(), i); 1276 if (prop->used) { 1277 continue; 1278 } 1279 oc = object_class_by_name(prop->driver); 1280 oc = object_class_dynamic_cast(oc, TYPE_DEVICE); 1281 if (!oc) { 1282 warn_report("global %s.%s has invalid class name", 1283 prop->driver, prop->property); 1284 ret = 1; 1285 continue; 1286 } 1287 dc = DEVICE_CLASS(oc); 1288 if (!dc->hotpluggable && !prop->used) { 1289 warn_report("global %s.%s=%s not used", 1290 prop->driver, prop->property, prop->value); 1291 ret = 1; 1292 continue; 1293 } 1294 } 1295 return ret; 1296 } 1297 1298 void qdev_prop_set_globals(DeviceState *dev) 1299 { 1300 object_apply_global_props(OBJECT(dev), global_props(), 1301 dev->hotplugged ? NULL : &error_fatal); 1302 } 1303 1304 /* --- 64bit unsigned int 'size' type --- */ 1305 1306 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque, 1307 Error **errp) 1308 { 1309 DeviceState *dev = DEVICE(obj); 1310 Property *prop = opaque; 1311 uint64_t *ptr = qdev_get_prop_ptr(dev, prop); 1312 1313 visit_type_size(v, name, ptr, errp); 1314 } 1315 1316 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque, 1317 Error **errp) 1318 { 1319 DeviceState *dev = DEVICE(obj); 1320 Property *prop = opaque; 1321 uint64_t *ptr = qdev_get_prop_ptr(dev, prop); 1322 1323 visit_type_size(v, name, ptr, errp); 1324 } 1325 1326 const PropertyInfo qdev_prop_size = { 1327 .name = "size", 1328 .get = get_size, 1329 .set = set_size, 1330 .set_default_value = set_default_value_uint, 1331 }; 1332 1333 /* --- object link property --- */ 1334 1335 static void create_link_property(ObjectClass *oc, Property *prop) 1336 { 1337 object_class_property_add_link(oc, prop->name, prop->link_type, 1338 prop->offset, 1339 qdev_prop_allow_set_link_before_realize, 1340 OBJ_PROP_LINK_STRONG); 1341 } 1342 1343 const PropertyInfo qdev_prop_link = { 1344 .name = "link", 1345 .create = create_link_property, 1346 }; 1347 1348 /* --- OffAutoPCIBAR off/auto/bar0/bar1/bar2/bar3/bar4/bar5 --- */ 1349 1350 const PropertyInfo qdev_prop_off_auto_pcibar = { 1351 .name = "OffAutoPCIBAR", 1352 .description = "off/auto/bar0/bar1/bar2/bar3/bar4/bar5", 1353 .enum_table = &OffAutoPCIBAR_lookup, 1354 .get = get_enum, 1355 .set = set_enum, 1356 .set_default_value = set_default_value_enum, 1357 }; 1358 1359 /* --- PCIELinkSpeed 2_5/5/8/16 -- */ 1360 1361 static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name, 1362 void *opaque, Error **errp) 1363 { 1364 DeviceState *dev = DEVICE(obj); 1365 Property *prop = opaque; 1366 PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop); 1367 int speed; 1368 1369 switch (*p) { 1370 case QEMU_PCI_EXP_LNK_2_5GT: 1371 speed = PCIE_LINK_SPEED_2_5; 1372 break; 1373 case QEMU_PCI_EXP_LNK_5GT: 1374 speed = PCIE_LINK_SPEED_5; 1375 break; 1376 case QEMU_PCI_EXP_LNK_8GT: 1377 speed = PCIE_LINK_SPEED_8; 1378 break; 1379 case QEMU_PCI_EXP_LNK_16GT: 1380 speed = PCIE_LINK_SPEED_16; 1381 break; 1382 default: 1383 /* Unreachable */ 1384 abort(); 1385 } 1386 1387 visit_type_enum(v, prop->name, &speed, prop->info->enum_table, errp); 1388 } 1389 1390 static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name, 1391 void *opaque, Error **errp) 1392 { 1393 DeviceState *dev = DEVICE(obj); 1394 Property *prop = opaque; 1395 PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop); 1396 int speed; 1397 Error *local_err = NULL; 1398 1399 if (dev->realized) { 1400 qdev_prop_set_after_realize(dev, name, errp); 1401 return; 1402 } 1403 1404 visit_type_enum(v, prop->name, &speed, prop->info->enum_table, &local_err); 1405 if (local_err) { 1406 error_propagate(errp, local_err); 1407 return; 1408 } 1409 1410 switch (speed) { 1411 case PCIE_LINK_SPEED_2_5: 1412 *p = QEMU_PCI_EXP_LNK_2_5GT; 1413 break; 1414 case PCIE_LINK_SPEED_5: 1415 *p = QEMU_PCI_EXP_LNK_5GT; 1416 break; 1417 case PCIE_LINK_SPEED_8: 1418 *p = QEMU_PCI_EXP_LNK_8GT; 1419 break; 1420 case PCIE_LINK_SPEED_16: 1421 *p = QEMU_PCI_EXP_LNK_16GT; 1422 break; 1423 default: 1424 /* Unreachable */ 1425 abort(); 1426 } 1427 } 1428 1429 const PropertyInfo qdev_prop_pcie_link_speed = { 1430 .name = "PCIELinkSpeed", 1431 .description = "2_5/5/8/16", 1432 .enum_table = &PCIELinkSpeed_lookup, 1433 .get = get_prop_pcielinkspeed, 1434 .set = set_prop_pcielinkspeed, 1435 .set_default_value = set_default_value_enum, 1436 }; 1437 1438 /* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */ 1439 1440 static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name, 1441 void *opaque, Error **errp) 1442 { 1443 DeviceState *dev = DEVICE(obj); 1444 Property *prop = opaque; 1445 PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop); 1446 int width; 1447 1448 switch (*p) { 1449 case QEMU_PCI_EXP_LNK_X1: 1450 width = PCIE_LINK_WIDTH_1; 1451 break; 1452 case QEMU_PCI_EXP_LNK_X2: 1453 width = PCIE_LINK_WIDTH_2; 1454 break; 1455 case QEMU_PCI_EXP_LNK_X4: 1456 width = PCIE_LINK_WIDTH_4; 1457 break; 1458 case QEMU_PCI_EXP_LNK_X8: 1459 width = PCIE_LINK_WIDTH_8; 1460 break; 1461 case QEMU_PCI_EXP_LNK_X12: 1462 width = PCIE_LINK_WIDTH_12; 1463 break; 1464 case QEMU_PCI_EXP_LNK_X16: 1465 width = PCIE_LINK_WIDTH_16; 1466 break; 1467 case QEMU_PCI_EXP_LNK_X32: 1468 width = PCIE_LINK_WIDTH_32; 1469 break; 1470 default: 1471 /* Unreachable */ 1472 abort(); 1473 } 1474 1475 visit_type_enum(v, prop->name, &width, prop->info->enum_table, errp); 1476 } 1477 1478 static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name, 1479 void *opaque, Error **errp) 1480 { 1481 DeviceState *dev = DEVICE(obj); 1482 Property *prop = opaque; 1483 PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop); 1484 int width; 1485 Error *local_err = NULL; 1486 1487 if (dev->realized) { 1488 qdev_prop_set_after_realize(dev, name, errp); 1489 return; 1490 } 1491 1492 visit_type_enum(v, prop->name, &width, prop->info->enum_table, &local_err); 1493 if (local_err) { 1494 error_propagate(errp, local_err); 1495 return; 1496 } 1497 1498 switch (width) { 1499 case PCIE_LINK_WIDTH_1: 1500 *p = QEMU_PCI_EXP_LNK_X1; 1501 break; 1502 case PCIE_LINK_WIDTH_2: 1503 *p = QEMU_PCI_EXP_LNK_X2; 1504 break; 1505 case PCIE_LINK_WIDTH_4: 1506 *p = QEMU_PCI_EXP_LNK_X4; 1507 break; 1508 case PCIE_LINK_WIDTH_8: 1509 *p = QEMU_PCI_EXP_LNK_X8; 1510 break; 1511 case PCIE_LINK_WIDTH_12: 1512 *p = QEMU_PCI_EXP_LNK_X12; 1513 break; 1514 case PCIE_LINK_WIDTH_16: 1515 *p = QEMU_PCI_EXP_LNK_X16; 1516 break; 1517 case PCIE_LINK_WIDTH_32: 1518 *p = QEMU_PCI_EXP_LNK_X32; 1519 break; 1520 default: 1521 /* Unreachable */ 1522 abort(); 1523 } 1524 } 1525 1526 const PropertyInfo qdev_prop_pcie_link_width = { 1527 .name = "PCIELinkWidth", 1528 .description = "1/2/4/8/12/16/32", 1529 .enum_table = &PCIELinkWidth_lookup, 1530 .get = get_prop_pcielinkwidth, 1531 .set = set_prop_pcielinkwidth, 1532 .set_default_value = set_default_value_enum, 1533 }; 1534