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 13 void 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 */ 28 static bool qdev_prop_allow_set(Object *obj, const char *name, 29 Error **errp) 30 { 31 DeviceState *dev = DEVICE(obj); 32 33 if (dev->realized) { 34 qdev_prop_set_after_realize(dev, name, errp); 35 return false; 36 } 37 return true; 38 } 39 40 void 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 53 void *object_field_prop_ptr(Object *obj, Property *prop) 54 { 55 void *ptr = obj; 56 ptr += prop->offset; 57 return ptr; 58 } 59 60 static 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 */ 72 static ObjectPropertyAccessor *field_prop_getter(const PropertyInfo *info) 73 { 74 return info->get ? field_prop_get : NULL; 75 } 76 77 static 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, 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 */ 94 static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info) 95 { 96 return info->set ? field_prop_set : NULL; 97 } 98 99 void 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 108 void 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 117 void 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 124 const 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 133 static uint32_t qdev_get_prop_mask(Property *prop) 134 { 135 assert(prop->info == &qdev_prop_bit); 136 return 0x1 << prop->bitnr; 137 } 138 139 static 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 150 static 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 160 static 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 172 static void set_default_value_bool(ObjectProperty *op, const Property *prop) 173 { 174 object_property_set_default_bool(op, prop->defval.u); 175 } 176 177 const 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 187 static uint64_t qdev_get_prop_mask64(Property *prop) 188 { 189 assert(prop->info == &qdev_prop_bit64); 190 return 0x1ull << prop->bitnr; 191 } 192 193 static 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 204 static 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 214 static 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 226 const 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 236 static 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 245 static 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 254 const 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 263 static 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 272 static 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 281 void 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 287 void 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 293 const 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 302 static 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 311 static 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 320 const 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 329 static 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 338 static 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 347 void 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 356 static 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 365 const 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 372 const 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 381 static 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 390 static 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 399 static 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 408 static 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 417 const 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 424 const 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 433 static 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 439 static 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 453 static 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 467 const 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 476 const 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 487 void 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 497 static 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 519 const 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 */ 534 typedef 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 */ 544 static 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 554 static 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 615 const 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 624 static 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 638 static 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 656 void 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 678 void 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 683 void 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 688 void 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 693 void 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 698 void 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 703 void 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 708 void 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 713 void 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 723 static 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 734 void qdev_prop_register_global(GlobalProperty *prop) 735 { 736 g_ptr_array_add(global_props(), prop); 737 } 738 739 const 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 756 int 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 788 void 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 796 static 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 805 static 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 814 const 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 823 static 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 832 const PropertyInfo qdev_prop_link = { 833 .name = "link", 834 .create = create_link_property, 835 }; 836 837 void 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 861 static 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 887 static 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 */ 914 static 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 929 void 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 940 void 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 } 956