qdev-properties.c (26992B)
1#include "qemu/osdep.h" 2#include "hw/qdev-properties.h" 3#include "qapi/error.h" 4#include "qapi/qapi-types-misc.h" 5#include "qapi/qmp/qerror.h" 6#include "qemu/ctype.h" 7#include "qemu/error-report.h" 8#include "qapi/visitor.h" 9#include "qemu/units.h" 10#include "qemu/cutils.h" 11#include "qdev-prop-internal.h" 12 13void qdev_prop_set_after_realize(DeviceState *dev, const char *name, 14 Error **errp) 15{ 16 if (dev->id) { 17 error_setg(errp, "Attempt to set property '%s' on device '%s' " 18 "(type '%s') after it was realized", name, dev->id, 19 object_get_typename(OBJECT(dev))); 20 } else { 21 error_setg(errp, "Attempt to set property '%s' on anonymous device " 22 "(type '%s') after it was realized", name, 23 object_get_typename(OBJECT(dev))); 24 } 25} 26 27/* returns: true if property is allowed to be set, false otherwise */ 28static bool qdev_prop_allow_set(Object *obj, const char *name, 29 const PropertyInfo *info, Error **errp) 30{ 31 DeviceState *dev = DEVICE(obj); 32 33 if (dev->realized && !info->realized_set_allowed) { 34 qdev_prop_set_after_realize(dev, name, errp); 35 return false; 36 } 37 return true; 38} 39 40void qdev_prop_allow_set_link_before_realize(const Object *obj, 41 const char *name, 42 Object *val, Error **errp) 43{ 44 DeviceState *dev = DEVICE(obj); 45 46 if (dev->realized) { 47 error_setg(errp, "Attempt to set link property '%s' on device '%s' " 48 "(type '%s') after it was realized", 49 name, dev->id, object_get_typename(obj)); 50 } 51} 52 53void *object_field_prop_ptr(Object *obj, Property *prop) 54{ 55 void *ptr = obj; 56 ptr += prop->offset; 57 return ptr; 58} 59 60static void field_prop_get(Object *obj, Visitor *v, const char *name, 61 void *opaque, Error **errp) 62{ 63 Property *prop = opaque; 64 return prop->info->get(obj, v, name, opaque, errp); 65} 66 67/** 68 * field_prop_getter: Return getter function to be used for property 69 * 70 * Return value can be NULL if @info has no getter function. 71 */ 72static ObjectPropertyAccessor *field_prop_getter(const PropertyInfo *info) 73{ 74 return info->get ? field_prop_get : NULL; 75} 76 77static void field_prop_set(Object *obj, Visitor *v, const char *name, 78 void *opaque, Error **errp) 79{ 80 Property *prop = opaque; 81 82 if (!qdev_prop_allow_set(obj, name, prop->info, errp)) { 83 return; 84 } 85 86 return prop->info->set(obj, v, name, opaque, errp); 87} 88 89/** 90 * field_prop_setter: Return setter function to be used for property 91 * 92 * Return value can be NULL if @info has not setter function. 93 */ 94static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info) 95{ 96 return info->set ? field_prop_set : NULL; 97} 98 99void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name, 100 void *opaque, Error **errp) 101{ 102 Property *prop = opaque; 103 int *ptr = object_field_prop_ptr(obj, prop); 104 105 visit_type_enum(v, name, ptr, prop->info->enum_table, errp); 106} 107 108void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name, 109 void *opaque, Error **errp) 110{ 111 Property *prop = opaque; 112 int *ptr = object_field_prop_ptr(obj, prop); 113 114 visit_type_enum(v, name, ptr, prop->info->enum_table, errp); 115} 116 117void qdev_propinfo_set_default_value_enum(ObjectProperty *op, 118 const Property *prop) 119{ 120 object_property_set_default_str(op, 121 qapi_enum_lookup(prop->info->enum_table, prop->defval.i)); 122} 123 124const PropertyInfo qdev_prop_enum = { 125 .name = "enum", 126 .get = qdev_propinfo_get_enum, 127 .set = qdev_propinfo_set_enum, 128 .set_default_value = qdev_propinfo_set_default_value_enum, 129}; 130 131/* Bit */ 132 133static uint32_t qdev_get_prop_mask(Property *prop) 134{ 135 assert(prop->info == &qdev_prop_bit); 136 return 0x1 << prop->bitnr; 137} 138 139static void bit_prop_set(Object *obj, Property *props, bool val) 140{ 141 uint32_t *p = object_field_prop_ptr(obj, props); 142 uint32_t mask = qdev_get_prop_mask(props); 143 if (val) { 144 *p |= mask; 145 } else { 146 *p &= ~mask; 147 } 148} 149 150static void prop_get_bit(Object *obj, Visitor *v, const char *name, 151 void *opaque, Error **errp) 152{ 153 Property *prop = opaque; 154 uint32_t *p = object_field_prop_ptr(obj, prop); 155 bool value = (*p & qdev_get_prop_mask(prop)) != 0; 156 157 visit_type_bool(v, name, &value, errp); 158} 159 160static void prop_set_bit(Object *obj, Visitor *v, const char *name, 161 void *opaque, Error **errp) 162{ 163 Property *prop = opaque; 164 bool value; 165 166 if (!visit_type_bool(v, name, &value, errp)) { 167 return; 168 } 169 bit_prop_set(obj, prop, value); 170} 171 172static void set_default_value_bool(ObjectProperty *op, const Property *prop) 173{ 174 object_property_set_default_bool(op, prop->defval.u); 175} 176 177const PropertyInfo qdev_prop_bit = { 178 .name = "bool", 179 .description = "on/off", 180 .get = prop_get_bit, 181 .set = prop_set_bit, 182 .set_default_value = set_default_value_bool, 183}; 184 185/* Bit64 */ 186 187static uint64_t qdev_get_prop_mask64(Property *prop) 188{ 189 assert(prop->info == &qdev_prop_bit64); 190 return 0x1ull << prop->bitnr; 191} 192 193static void bit64_prop_set(Object *obj, Property *props, bool val) 194{ 195 uint64_t *p = object_field_prop_ptr(obj, props); 196 uint64_t mask = qdev_get_prop_mask64(props); 197 if (val) { 198 *p |= mask; 199 } else { 200 *p &= ~mask; 201 } 202} 203 204static void prop_get_bit64(Object *obj, Visitor *v, const char *name, 205 void *opaque, Error **errp) 206{ 207 Property *prop = opaque; 208 uint64_t *p = object_field_prop_ptr(obj, prop); 209 bool value = (*p & qdev_get_prop_mask64(prop)) != 0; 210 211 visit_type_bool(v, name, &value, errp); 212} 213 214static void prop_set_bit64(Object *obj, Visitor *v, const char *name, 215 void *opaque, Error **errp) 216{ 217 Property *prop = opaque; 218 bool value; 219 220 if (!visit_type_bool(v, name, &value, errp)) { 221 return; 222 } 223 bit64_prop_set(obj, prop, value); 224} 225 226const PropertyInfo qdev_prop_bit64 = { 227 .name = "bool", 228 .description = "on/off", 229 .get = prop_get_bit64, 230 .set = prop_set_bit64, 231 .set_default_value = set_default_value_bool, 232}; 233 234/* --- bool --- */ 235 236static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque, 237 Error **errp) 238{ 239 Property *prop = opaque; 240 bool *ptr = object_field_prop_ptr(obj, prop); 241 242 visit_type_bool(v, name, ptr, errp); 243} 244 245static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque, 246 Error **errp) 247{ 248 Property *prop = opaque; 249 bool *ptr = object_field_prop_ptr(obj, prop); 250 251 visit_type_bool(v, name, ptr, errp); 252} 253 254const PropertyInfo qdev_prop_bool = { 255 .name = "bool", 256 .get = get_bool, 257 .set = set_bool, 258 .set_default_value = set_default_value_bool, 259}; 260 261/* --- 8bit integer --- */ 262 263static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque, 264 Error **errp) 265{ 266 Property *prop = opaque; 267 uint8_t *ptr = object_field_prop_ptr(obj, prop); 268 269 visit_type_uint8(v, name, ptr, errp); 270} 271 272static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque, 273 Error **errp) 274{ 275 Property *prop = opaque; 276 uint8_t *ptr = object_field_prop_ptr(obj, prop); 277 278 visit_type_uint8(v, name, ptr, errp); 279} 280 281void qdev_propinfo_set_default_value_int(ObjectProperty *op, 282 const Property *prop) 283{ 284 object_property_set_default_int(op, prop->defval.i); 285} 286 287void qdev_propinfo_set_default_value_uint(ObjectProperty *op, 288 const Property *prop) 289{ 290 object_property_set_default_uint(op, prop->defval.u); 291} 292 293const PropertyInfo qdev_prop_uint8 = { 294 .name = "uint8", 295 .get = get_uint8, 296 .set = set_uint8, 297 .set_default_value = qdev_propinfo_set_default_value_uint, 298}; 299 300/* --- 16bit integer --- */ 301 302static void get_uint16(Object *obj, Visitor *v, const char *name, 303 void *opaque, Error **errp) 304{ 305 Property *prop = opaque; 306 uint16_t *ptr = object_field_prop_ptr(obj, prop); 307 308 visit_type_uint16(v, name, ptr, errp); 309} 310 311static void set_uint16(Object *obj, Visitor *v, const char *name, 312 void *opaque, Error **errp) 313{ 314 Property *prop = opaque; 315 uint16_t *ptr = object_field_prop_ptr(obj, prop); 316 317 visit_type_uint16(v, name, ptr, errp); 318} 319 320const PropertyInfo qdev_prop_uint16 = { 321 .name = "uint16", 322 .get = get_uint16, 323 .set = set_uint16, 324 .set_default_value = qdev_propinfo_set_default_value_uint, 325}; 326 327/* --- 32bit integer --- */ 328 329static void get_uint32(Object *obj, Visitor *v, const char *name, 330 void *opaque, Error **errp) 331{ 332 Property *prop = opaque; 333 uint32_t *ptr = object_field_prop_ptr(obj, prop); 334 335 visit_type_uint32(v, name, ptr, errp); 336} 337 338static void set_uint32(Object *obj, Visitor *v, const char *name, 339 void *opaque, Error **errp) 340{ 341 Property *prop = opaque; 342 uint32_t *ptr = object_field_prop_ptr(obj, prop); 343 344 visit_type_uint32(v, name, ptr, errp); 345} 346 347void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name, 348 void *opaque, Error **errp) 349{ 350 Property *prop = opaque; 351 int32_t *ptr = object_field_prop_ptr(obj, 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 Property *prop = opaque; 360 int32_t *ptr = object_field_prop_ptr(obj, prop); 361 362 visit_type_int32(v, name, ptr, errp); 363} 364 365const PropertyInfo qdev_prop_uint32 = { 366 .name = "uint32", 367 .get = get_uint32, 368 .set = set_uint32, 369 .set_default_value = qdev_propinfo_set_default_value_uint, 370}; 371 372const PropertyInfo qdev_prop_int32 = { 373 .name = "int32", 374 .get = qdev_propinfo_get_int32, 375 .set = set_int32, 376 .set_default_value = qdev_propinfo_set_default_value_int, 377}; 378 379/* --- 64bit integer --- */ 380 381static void get_uint64(Object *obj, Visitor *v, const char *name, 382 void *opaque, Error **errp) 383{ 384 Property *prop = opaque; 385 uint64_t *ptr = object_field_prop_ptr(obj, prop); 386 387 visit_type_uint64(v, name, ptr, errp); 388} 389 390static void set_uint64(Object *obj, Visitor *v, const char *name, 391 void *opaque, Error **errp) 392{ 393 Property *prop = opaque; 394 uint64_t *ptr = object_field_prop_ptr(obj, prop); 395 396 visit_type_uint64(v, name, ptr, errp); 397} 398 399static void get_int64(Object *obj, Visitor *v, const char *name, 400 void *opaque, Error **errp) 401{ 402 Property *prop = opaque; 403 int64_t *ptr = object_field_prop_ptr(obj, prop); 404 405 visit_type_int64(v, name, ptr, errp); 406} 407 408static void set_int64(Object *obj, Visitor *v, const char *name, 409 void *opaque, Error **errp) 410{ 411 Property *prop = opaque; 412 int64_t *ptr = object_field_prop_ptr(obj, prop); 413 414 visit_type_int64(v, name, ptr, errp); 415} 416 417const PropertyInfo qdev_prop_uint64 = { 418 .name = "uint64", 419 .get = get_uint64, 420 .set = set_uint64, 421 .set_default_value = qdev_propinfo_set_default_value_uint, 422}; 423 424const PropertyInfo qdev_prop_int64 = { 425 .name = "int64", 426 .get = get_int64, 427 .set = set_int64, 428 .set_default_value = qdev_propinfo_set_default_value_int, 429}; 430 431/* --- string --- */ 432 433static void release_string(Object *obj, const char *name, void *opaque) 434{ 435 Property *prop = opaque; 436 g_free(*(char **)object_field_prop_ptr(obj, prop)); 437} 438 439static void get_string(Object *obj, Visitor *v, const char *name, 440 void *opaque, Error **errp) 441{ 442 Property *prop = opaque; 443 char **ptr = object_field_prop_ptr(obj, prop); 444 445 if (!*ptr) { 446 char *str = (char *)""; 447 visit_type_str(v, name, &str, errp); 448 } else { 449 visit_type_str(v, name, ptr, errp); 450 } 451} 452 453static void set_string(Object *obj, Visitor *v, const char *name, 454 void *opaque, Error **errp) 455{ 456 Property *prop = opaque; 457 char **ptr = object_field_prop_ptr(obj, prop); 458 char *str; 459 460 if (!visit_type_str(v, name, &str, errp)) { 461 return; 462 } 463 g_free(*ptr); 464 *ptr = str; 465} 466 467const PropertyInfo qdev_prop_string = { 468 .name = "str", 469 .release = release_string, 470 .get = get_string, 471 .set = set_string, 472}; 473 474/* --- on/off/auto --- */ 475 476const PropertyInfo qdev_prop_on_off_auto = { 477 .name = "OnOffAuto", 478 .description = "on/off/auto", 479 .enum_table = &OnOffAuto_lookup, 480 .get = qdev_propinfo_get_enum, 481 .set = qdev_propinfo_set_enum, 482 .set_default_value = qdev_propinfo_set_default_value_enum, 483}; 484 485/* --- 32bit unsigned int 'size' type --- */ 486 487void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name, 488 void *opaque, Error **errp) 489{ 490 Property *prop = opaque; 491 uint32_t *ptr = object_field_prop_ptr(obj, prop); 492 uint64_t value = *ptr; 493 494 visit_type_size(v, name, &value, errp); 495} 496 497static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque, 498 Error **errp) 499{ 500 Property *prop = opaque; 501 uint32_t *ptr = object_field_prop_ptr(obj, prop); 502 uint64_t value; 503 504 if (!visit_type_size(v, name, &value, errp)) { 505 return; 506 } 507 508 if (value > UINT32_MAX) { 509 error_setg(errp, 510 "Property %s.%s doesn't take value %" PRIu64 511 " (maximum: %u)", 512 object_get_typename(obj), name, value, UINT32_MAX); 513 return; 514 } 515 516 *ptr = value; 517} 518 519const PropertyInfo qdev_prop_size32 = { 520 .name = "size", 521 .get = qdev_propinfo_get_size32, 522 .set = set_size32, 523 .set_default_value = qdev_propinfo_set_default_value_uint, 524}; 525 526/* --- support for array properties --- */ 527 528/* Used as an opaque for the object properties we add for each 529 * array element. Note that the struct Property must be first 530 * in the struct so that a pointer to this works as the opaque 531 * for the underlying element's property hooks as well as for 532 * our own release callback. 533 */ 534typedef struct { 535 struct Property prop; 536 char *propname; 537 ObjectPropertyRelease *release; 538} ArrayElementProperty; 539 540/* object property release callback for array element properties: 541 * we call the underlying element's property release hook, and 542 * then free the memory we allocated when we added the property. 543 */ 544static void array_element_release(Object *obj, const char *name, void *opaque) 545{ 546 ArrayElementProperty *p = opaque; 547 if (p->release) { 548 p->release(obj, name, opaque); 549 } 550 g_free(p->propname); 551 g_free(p); 552} 553 554static void set_prop_arraylen(Object *obj, Visitor *v, const char *name, 555 void *opaque, Error **errp) 556{ 557 /* Setter for the property which defines the length of a 558 * variable-sized property array. As well as actually setting the 559 * array-length field in the device struct, we have to create the 560 * array itself and dynamically add the corresponding properties. 561 */ 562 Property *prop = opaque; 563 uint32_t *alenptr = object_field_prop_ptr(obj, prop); 564 void **arrayptr = (void *)obj + prop->arrayoffset; 565 void *eltptr; 566 const char *arrayname; 567 int i; 568 569 if (*alenptr) { 570 error_setg(errp, "array size property %s may not be set more than once", 571 name); 572 return; 573 } 574 if (!visit_type_uint32(v, name, alenptr, errp)) { 575 return; 576 } 577 if (!*alenptr) { 578 return; 579 } 580 581 /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix; 582 * strip it off so we can get the name of the array itself. 583 */ 584 assert(strncmp(name, PROP_ARRAY_LEN_PREFIX, 585 strlen(PROP_ARRAY_LEN_PREFIX)) == 0); 586 arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX); 587 588 /* Note that it is the responsibility of the individual device's deinit 589 * to free the array proper. 590 */ 591 *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize); 592 for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) { 593 char *propname = g_strdup_printf("%s[%d]", arrayname, i); 594 ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1); 595 arrayprop->release = prop->arrayinfo->release; 596 arrayprop->propname = propname; 597 arrayprop->prop.info = prop->arrayinfo; 598 arrayprop->prop.name = propname; 599 /* This ugly piece of pointer arithmetic sets up the offset so 600 * that when the underlying get/set hooks call qdev_get_prop_ptr 601 * they get the right answer despite the array element not actually 602 * being inside the device struct. 603 */ 604 arrayprop->prop.offset = eltptr - (void *)obj; 605 assert(object_field_prop_ptr(obj, &arrayprop->prop) == eltptr); 606 object_property_add(obj, propname, 607 arrayprop->prop.info->name, 608 field_prop_getter(arrayprop->prop.info), 609 field_prop_setter(arrayprop->prop.info), 610 array_element_release, 611 arrayprop); 612 } 613} 614 615const PropertyInfo qdev_prop_arraylen = { 616 .name = "uint32", 617 .get = get_uint32, 618 .set = set_prop_arraylen, 619 .set_default_value = qdev_propinfo_set_default_value_uint, 620}; 621 622/* --- public helpers --- */ 623 624static Property *qdev_prop_walk(Property *props, const char *name) 625{ 626 if (!props) { 627 return NULL; 628 } 629 while (props->name) { 630 if (strcmp(props->name, name) == 0) { 631 return props; 632 } 633 props++; 634 } 635 return NULL; 636} 637 638static Property *qdev_prop_find(DeviceState *dev, const char *name) 639{ 640 ObjectClass *class; 641 Property *prop; 642 643 /* device properties */ 644 class = object_get_class(OBJECT(dev)); 645 do { 646 prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name); 647 if (prop) { 648 return prop; 649 } 650 class = object_class_get_parent(class); 651 } while (class != object_class_by_name(TYPE_DEVICE)); 652 653 return NULL; 654} 655 656void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj, 657 const char *name, const char *value) 658{ 659 switch (ret) { 660 case -EEXIST: 661 error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", 662 object_get_typename(obj), name, value); 663 break; 664 default: 665 case -EINVAL: 666 error_setg(errp, QERR_PROPERTY_VALUE_BAD, 667 object_get_typename(obj), name, value); 668 break; 669 case -ENOENT: 670 error_setg(errp, "Property '%s.%s' can't find value '%s'", 671 object_get_typename(obj), name, value); 672 break; 673 case 0: 674 break; 675 } 676} 677 678void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value) 679{ 680 object_property_set_bool(OBJECT(dev), name, value, &error_abort); 681} 682 683void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value) 684{ 685 object_property_set_int(OBJECT(dev), name, value, &error_abort); 686} 687 688void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value) 689{ 690 object_property_set_int(OBJECT(dev), name, value, &error_abort); 691} 692 693void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value) 694{ 695 object_property_set_int(OBJECT(dev), name, value, &error_abort); 696} 697 698void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value) 699{ 700 object_property_set_int(OBJECT(dev), name, value, &error_abort); 701} 702 703void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value) 704{ 705 object_property_set_int(OBJECT(dev), name, value, &error_abort); 706} 707 708void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value) 709{ 710 object_property_set_str(OBJECT(dev), name, value, &error_abort); 711} 712 713void qdev_prop_set_enum(DeviceState *dev, const char *name, int value) 714{ 715 Property *prop; 716 717 prop = qdev_prop_find(dev, name); 718 object_property_set_str(OBJECT(dev), name, 719 qapi_enum_lookup(prop->info->enum_table, value), 720 &error_abort); 721} 722 723static GPtrArray *global_props(void) 724{ 725 static GPtrArray *gp; 726 727 if (!gp) { 728 gp = g_ptr_array_new(); 729 } 730 731 return gp; 732} 733 734void qdev_prop_register_global(GlobalProperty *prop) 735{ 736 g_ptr_array_add(global_props(), prop); 737} 738 739const GlobalProperty *qdev_find_global_prop(Object *obj, 740 const char *name) 741{ 742 GPtrArray *props = global_props(); 743 const GlobalProperty *p; 744 int i; 745 746 for (i = 0; i < props->len; i++) { 747 p = g_ptr_array_index(props, i); 748 if (object_dynamic_cast(obj, p->driver) 749 && !strcmp(p->property, name)) { 750 return p; 751 } 752 } 753 return NULL; 754} 755 756int qdev_prop_check_globals(void) 757{ 758 int i, ret = 0; 759 760 for (i = 0; i < global_props()->len; i++) { 761 GlobalProperty *prop; 762 ObjectClass *oc; 763 DeviceClass *dc; 764 765 prop = g_ptr_array_index(global_props(), i); 766 if (prop->used) { 767 continue; 768 } 769 oc = object_class_by_name(prop->driver); 770 oc = object_class_dynamic_cast(oc, TYPE_DEVICE); 771 if (!oc) { 772 warn_report("global %s.%s has invalid class name", 773 prop->driver, prop->property); 774 ret = 1; 775 continue; 776 } 777 dc = DEVICE_CLASS(oc); 778 if (!dc->hotpluggable && !prop->used) { 779 warn_report("global %s.%s=%s not used", 780 prop->driver, prop->property, prop->value); 781 ret = 1; 782 continue; 783 } 784 } 785 return ret; 786} 787 788void qdev_prop_set_globals(DeviceState *dev) 789{ 790 object_apply_global_props(OBJECT(dev), global_props(), 791 dev->hotplugged ? NULL : &error_fatal); 792} 793 794/* --- 64bit unsigned int 'size' type --- */ 795 796static void get_size(Object *obj, Visitor *v, const char *name, void *opaque, 797 Error **errp) 798{ 799 Property *prop = opaque; 800 uint64_t *ptr = object_field_prop_ptr(obj, prop); 801 802 visit_type_size(v, name, ptr, errp); 803} 804 805static void set_size(Object *obj, Visitor *v, const char *name, void *opaque, 806 Error **errp) 807{ 808 Property *prop = opaque; 809 uint64_t *ptr = object_field_prop_ptr(obj, prop); 810 811 visit_type_size(v, name, ptr, errp); 812} 813 814const PropertyInfo qdev_prop_size = { 815 .name = "size", 816 .get = get_size, 817 .set = set_size, 818 .set_default_value = qdev_propinfo_set_default_value_uint, 819}; 820 821/* --- object link property --- */ 822 823static ObjectProperty *create_link_property(ObjectClass *oc, const char *name, 824 Property *prop) 825{ 826 return object_class_property_add_link(oc, name, prop->link_type, 827 prop->offset, 828 qdev_prop_allow_set_link_before_realize, 829 OBJ_PROP_LINK_STRONG); 830} 831 832const PropertyInfo qdev_prop_link = { 833 .name = "link", 834 .create = create_link_property, 835}; 836 837void qdev_property_add_static(DeviceState *dev, Property *prop) 838{ 839 Object *obj = OBJECT(dev); 840 ObjectProperty *op; 841 842 assert(!prop->info->create); 843 844 op = object_property_add(obj, prop->name, prop->info->name, 845 field_prop_getter(prop->info), 846 field_prop_setter(prop->info), 847 prop->info->release, 848 prop); 849 850 object_property_set_description(obj, prop->name, 851 prop->info->description); 852 853 if (prop->set_default) { 854 prop->info->set_default_value(op, prop); 855 if (op->init) { 856 op->init(obj, op); 857 } 858 } 859} 860 861static void qdev_class_add_property(DeviceClass *klass, const char *name, 862 Property *prop) 863{ 864 ObjectClass *oc = OBJECT_CLASS(klass); 865 ObjectProperty *op; 866 867 if (prop->info->create) { 868 op = prop->info->create(oc, name, prop); 869 } else { 870 op = object_class_property_add(oc, 871 name, prop->info->name, 872 field_prop_getter(prop->info), 873 field_prop_setter(prop->info), 874 prop->info->release, 875 prop); 876 } 877 if (prop->set_default) { 878 prop->info->set_default_value(op, prop); 879 } 880 object_class_property_set_description(oc, name, prop->info->description); 881} 882 883/** 884 * Legacy property handling 885 */ 886 887static void qdev_get_legacy_property(Object *obj, Visitor *v, 888 const char *name, void *opaque, 889 Error **errp) 890{ 891 Property *prop = opaque; 892 893 char buffer[1024]; 894 char *ptr = buffer; 895 896 prop->info->print(obj, prop, buffer, sizeof(buffer)); 897 visit_type_str(v, name, &ptr, errp); 898} 899 900/** 901 * qdev_class_add_legacy_property: 902 * @dev: Device to add the property to. 903 * @prop: The qdev property definition. 904 * 905 * Add a legacy QOM property to @dev for qdev property @prop. 906 * 907 * Legacy properties are string versions of QOM properties. The format of 908 * the string depends on the property type. Legacy properties are only 909 * needed for "info qtree". 910 * 911 * Do not use this in new code! QOM Properties added through this interface 912 * will be given names in the "legacy" namespace. 913 */ 914static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop) 915{ 916 g_autofree char *name = NULL; 917 918 /* Register pointer properties as legacy properties */ 919 if (!prop->info->print && prop->info->get) { 920 return; 921 } 922 923 name = g_strdup_printf("legacy-%s", prop->name); 924 object_class_property_add(OBJECT_CLASS(dc), name, "str", 925 prop->info->print ? qdev_get_legacy_property : prop->info->get, 926 NULL, NULL, prop); 927} 928 929void device_class_set_props(DeviceClass *dc, Property *props) 930{ 931 Property *prop; 932 933 dc->props_ = props; 934 for (prop = props; prop && prop->name; prop++) { 935 qdev_class_add_legacy_property(dc, prop); 936 qdev_class_add_property(dc, prop->name, prop); 937 } 938} 939 940void qdev_alias_all_properties(DeviceState *target, Object *source) 941{ 942 ObjectClass *class; 943 Property *prop; 944 945 class = object_get_class(OBJECT(target)); 946 do { 947 DeviceClass *dc = DEVICE_CLASS(class); 948 949 for (prop = dc->props_; prop && prop->name; prop++) { 950 object_property_add_alias(source, prop->name, 951 OBJECT(target), prop->name); 952 } 953 class = object_class_get_parent(class); 954 } while (class != object_class_by_name(TYPE_DEVICE)); 955}