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 *qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 **)qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 = qdev_get_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 DeviceState *dev = DEVICE(obj); 563 Property *prop = opaque; 564 uint32_t *alenptr = qdev_get_prop_ptr(obj, prop); 565 void **arrayptr = (void *)dev + prop->arrayoffset; 566 void *eltptr; 567 const char *arrayname; 568 int i; 569 570 if (*alenptr) { 571 error_setg(errp, "array size property %s may not be set more than once", 572 name); 573 return; 574 } 575 if (!visit_type_uint32(v, name, alenptr, errp)) { 576 return; 577 } 578 if (!*alenptr) { 579 return; 580 } 581 582 /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix; 583 * strip it off so we can get the name of the array itself. 584 */ 585 assert(strncmp(name, PROP_ARRAY_LEN_PREFIX, 586 strlen(PROP_ARRAY_LEN_PREFIX)) == 0); 587 arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX); 588 589 /* Note that it is the responsibility of the individual device's deinit 590 * to free the array proper. 591 */ 592 *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize); 593 for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) { 594 char *propname = g_strdup_printf("%s[%d]", arrayname, i); 595 ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1); 596 arrayprop->release = prop->arrayinfo->release; 597 arrayprop->propname = propname; 598 arrayprop->prop.info = prop->arrayinfo; 599 arrayprop->prop.name = propname; 600 /* This ugly piece of pointer arithmetic sets up the offset so 601 * that when the underlying get/set hooks call qdev_get_prop_ptr 602 * they get the right answer despite the array element not actually 603 * being inside the device struct. 604 */ 605 arrayprop->prop.offset = eltptr - (void *)dev; 606 assert(qdev_get_prop_ptr(obj, &arrayprop->prop) == eltptr); 607 object_property_add(obj, propname, 608 arrayprop->prop.info->name, 609 field_prop_getter(arrayprop->prop.info), 610 field_prop_setter(arrayprop->prop.info), 611 array_element_release, 612 arrayprop); 613 } 614 } 615 616 const PropertyInfo qdev_prop_arraylen = { 617 .name = "uint32", 618 .get = get_uint32, 619 .set = set_prop_arraylen, 620 .set_default_value = qdev_propinfo_set_default_value_uint, 621 }; 622 623 /* --- public helpers --- */ 624 625 static Property *qdev_prop_walk(Property *props, const char *name) 626 { 627 if (!props) { 628 return NULL; 629 } 630 while (props->name) { 631 if (strcmp(props->name, name) == 0) { 632 return props; 633 } 634 props++; 635 } 636 return NULL; 637 } 638 639 static Property *qdev_prop_find(DeviceState *dev, const char *name) 640 { 641 ObjectClass *class; 642 Property *prop; 643 644 /* device properties */ 645 class = object_get_class(OBJECT(dev)); 646 do { 647 prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name); 648 if (prop) { 649 return prop; 650 } 651 class = object_class_get_parent(class); 652 } while (class != object_class_by_name(TYPE_DEVICE)); 653 654 return NULL; 655 } 656 657 void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj, 658 const char *name, const char *value) 659 { 660 switch (ret) { 661 case -EEXIST: 662 error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", 663 object_get_typename(obj), name, value); 664 break; 665 default: 666 case -EINVAL: 667 error_setg(errp, QERR_PROPERTY_VALUE_BAD, 668 object_get_typename(obj), name, value); 669 break; 670 case -ENOENT: 671 error_setg(errp, "Property '%s.%s' can't find value '%s'", 672 object_get_typename(obj), name, value); 673 break; 674 case 0: 675 break; 676 } 677 } 678 679 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value) 680 { 681 object_property_set_bool(OBJECT(dev), name, value, &error_abort); 682 } 683 684 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value) 685 { 686 object_property_set_int(OBJECT(dev), name, value, &error_abort); 687 } 688 689 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value) 690 { 691 object_property_set_int(OBJECT(dev), name, value, &error_abort); 692 } 693 694 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value) 695 { 696 object_property_set_int(OBJECT(dev), name, value, &error_abort); 697 } 698 699 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value) 700 { 701 object_property_set_int(OBJECT(dev), name, value, &error_abort); 702 } 703 704 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value) 705 { 706 object_property_set_int(OBJECT(dev), name, value, &error_abort); 707 } 708 709 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value) 710 { 711 object_property_set_str(OBJECT(dev), name, value, &error_abort); 712 } 713 714 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value) 715 { 716 Property *prop; 717 718 prop = qdev_prop_find(dev, name); 719 object_property_set_str(OBJECT(dev), name, 720 qapi_enum_lookup(prop->info->enum_table, value), 721 &error_abort); 722 } 723 724 static GPtrArray *global_props(void) 725 { 726 static GPtrArray *gp; 727 728 if (!gp) { 729 gp = g_ptr_array_new(); 730 } 731 732 return gp; 733 } 734 735 void qdev_prop_register_global(GlobalProperty *prop) 736 { 737 g_ptr_array_add(global_props(), prop); 738 } 739 740 const GlobalProperty *qdev_find_global_prop(Object *obj, 741 const char *name) 742 { 743 GPtrArray *props = global_props(); 744 const GlobalProperty *p; 745 int i; 746 747 for (i = 0; i < props->len; i++) { 748 p = g_ptr_array_index(props, i); 749 if (object_dynamic_cast(obj, p->driver) 750 && !strcmp(p->property, name)) { 751 return p; 752 } 753 } 754 return NULL; 755 } 756 757 int qdev_prop_check_globals(void) 758 { 759 int i, ret = 0; 760 761 for (i = 0; i < global_props()->len; i++) { 762 GlobalProperty *prop; 763 ObjectClass *oc; 764 DeviceClass *dc; 765 766 prop = g_ptr_array_index(global_props(), i); 767 if (prop->used) { 768 continue; 769 } 770 oc = object_class_by_name(prop->driver); 771 oc = object_class_dynamic_cast(oc, TYPE_DEVICE); 772 if (!oc) { 773 warn_report("global %s.%s has invalid class name", 774 prop->driver, prop->property); 775 ret = 1; 776 continue; 777 } 778 dc = DEVICE_CLASS(oc); 779 if (!dc->hotpluggable && !prop->used) { 780 warn_report("global %s.%s=%s not used", 781 prop->driver, prop->property, prop->value); 782 ret = 1; 783 continue; 784 } 785 } 786 return ret; 787 } 788 789 void qdev_prop_set_globals(DeviceState *dev) 790 { 791 object_apply_global_props(OBJECT(dev), global_props(), 792 dev->hotplugged ? NULL : &error_fatal); 793 } 794 795 /* --- 64bit unsigned int 'size' type --- */ 796 797 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque, 798 Error **errp) 799 { 800 Property *prop = opaque; 801 uint64_t *ptr = qdev_get_prop_ptr(obj, prop); 802 803 visit_type_size(v, name, ptr, errp); 804 } 805 806 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque, 807 Error **errp) 808 { 809 Property *prop = opaque; 810 uint64_t *ptr = qdev_get_prop_ptr(obj, prop); 811 812 visit_type_size(v, name, ptr, errp); 813 } 814 815 const PropertyInfo qdev_prop_size = { 816 .name = "size", 817 .get = get_size, 818 .set = set_size, 819 .set_default_value = qdev_propinfo_set_default_value_uint, 820 }; 821 822 /* --- object link property --- */ 823 824 static ObjectProperty *create_link_property(ObjectClass *oc, const char *name, 825 Property *prop) 826 { 827 return object_class_property_add_link(oc, name, prop->link_type, 828 prop->offset, 829 qdev_prop_allow_set_link_before_realize, 830 OBJ_PROP_LINK_STRONG); 831 } 832 833 const PropertyInfo qdev_prop_link = { 834 .name = "link", 835 .create = create_link_property, 836 }; 837 838 void qdev_property_add_static(DeviceState *dev, Property *prop) 839 { 840 Object *obj = OBJECT(dev); 841 ObjectProperty *op; 842 843 assert(!prop->info->create); 844 845 op = object_property_add(obj, prop->name, prop->info->name, 846 field_prop_getter(prop->info), 847 field_prop_setter(prop->info), 848 prop->info->release, 849 prop); 850 851 object_property_set_description(obj, prop->name, 852 prop->info->description); 853 854 if (prop->set_default) { 855 prop->info->set_default_value(op, prop); 856 if (op->init) { 857 op->init(obj, op); 858 } 859 } 860 } 861 862 static void qdev_class_add_property(DeviceClass *klass, const char *name, 863 Property *prop) 864 { 865 ObjectClass *oc = OBJECT_CLASS(klass); 866 867 if (prop->info->create) { 868 prop->info->create(oc, name, prop); 869 } else { 870 ObjectProperty *op; 871 872 op = object_class_property_add(oc, 873 name, prop->info->name, 874 field_prop_getter(prop->info), 875 field_prop_setter(prop->info), 876 prop->info->release, 877 prop); 878 if (prop->set_default) { 879 prop->info->set_default_value(op, prop); 880 } 881 } 882 object_class_property_set_description(oc, name, 883 prop->info->description); 884 } 885 886 /** 887 * Legacy property handling 888 */ 889 890 static void qdev_get_legacy_property(Object *obj, Visitor *v, 891 const char *name, void *opaque, 892 Error **errp) 893 { 894 Property *prop = opaque; 895 896 char buffer[1024]; 897 char *ptr = buffer; 898 899 prop->info->print(obj, prop, buffer, sizeof(buffer)); 900 visit_type_str(v, name, &ptr, errp); 901 } 902 903 /** 904 * qdev_class_add_legacy_property: 905 * @dev: Device to add the property to. 906 * @prop: The qdev property definition. 907 * 908 * Add a legacy QOM property to @dev for qdev property @prop. 909 * 910 * Legacy properties are string versions of QOM properties. The format of 911 * the string depends on the property type. Legacy properties are only 912 * needed for "info qtree". 913 * 914 * Do not use this in new code! QOM Properties added through this interface 915 * will be given names in the "legacy" namespace. 916 */ 917 static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop) 918 { 919 g_autofree char *name = NULL; 920 921 /* Register pointer properties as legacy properties */ 922 if (!prop->info->print && prop->info->get) { 923 return; 924 } 925 926 name = g_strdup_printf("legacy-%s", prop->name); 927 object_class_property_add(OBJECT_CLASS(dc), name, "str", 928 prop->info->print ? qdev_get_legacy_property : prop->info->get, 929 NULL, NULL, prop); 930 } 931 932 void device_class_set_props(DeviceClass *dc, Property *props) 933 { 934 Property *prop; 935 936 dc->props_ = props; 937 for (prop = props; prop && prop->name; prop++) { 938 qdev_class_add_legacy_property(dc, prop); 939 qdev_class_add_property(dc, prop->name, prop); 940 } 941 } 942 943 void qdev_alias_all_properties(DeviceState *target, Object *source) 944 { 945 ObjectClass *class; 946 Property *prop; 947 948 class = object_get_class(OBJECT(target)); 949 do { 950 DeviceClass *dc = DEVICE_CLASS(class); 951 952 for (prop = dc->props_; prop && prop->name; prop++) { 953 object_property_add_alias(source, prop->name, 954 OBJECT(target), prop->name); 955 } 956 class = object_class_get_parent(class); 957 } while (class != object_class_by_name(TYPE_DEVICE)); 958 } 959