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 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 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, 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 */ 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 static void set_uint64_checkmask(Object *obj, Visitor *v, const char *name, 432 void *opaque, Error **errp) 433 { 434 Property *prop = opaque; 435 uint64_t *ptr = object_field_prop_ptr(obj, prop); 436 437 visit_type_uint64(v, name, ptr, errp); 438 if (*ptr & ~prop->bitmask) { 439 error_setg(errp, "Property value for '%s' has bits outside mask '0x%" PRIx64 "'", 440 name, prop->bitmask); 441 } 442 } 443 444 const PropertyInfo qdev_prop_uint64_checkmask = { 445 .name = "uint64", 446 .get = get_uint64, 447 .set = set_uint64_checkmask, 448 }; 449 450 /* --- string --- */ 451 452 static void release_string(Object *obj, const char *name, void *opaque) 453 { 454 Property *prop = opaque; 455 g_free(*(char **)object_field_prop_ptr(obj, prop)); 456 } 457 458 static void get_string(Object *obj, Visitor *v, const char *name, 459 void *opaque, Error **errp) 460 { 461 Property *prop = opaque; 462 char **ptr = object_field_prop_ptr(obj, prop); 463 464 if (!*ptr) { 465 char *str = (char *)""; 466 visit_type_str(v, name, &str, errp); 467 } else { 468 visit_type_str(v, name, ptr, errp); 469 } 470 } 471 472 static void set_string(Object *obj, Visitor *v, const char *name, 473 void *opaque, Error **errp) 474 { 475 Property *prop = opaque; 476 char **ptr = object_field_prop_ptr(obj, prop); 477 char *str; 478 479 if (!visit_type_str(v, name, &str, errp)) { 480 return; 481 } 482 g_free(*ptr); 483 *ptr = str; 484 } 485 486 const PropertyInfo qdev_prop_string = { 487 .name = "str", 488 .release = release_string, 489 .get = get_string, 490 .set = set_string, 491 }; 492 493 /* --- on/off/auto --- */ 494 495 const PropertyInfo qdev_prop_on_off_auto = { 496 .name = "OnOffAuto", 497 .description = "on/off/auto", 498 .enum_table = &OnOffAuto_lookup, 499 .get = qdev_propinfo_get_enum, 500 .set = qdev_propinfo_set_enum, 501 .set_default_value = qdev_propinfo_set_default_value_enum, 502 }; 503 504 /* --- 32bit unsigned int 'size' type --- */ 505 506 void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name, 507 void *opaque, Error **errp) 508 { 509 Property *prop = opaque; 510 uint32_t *ptr = object_field_prop_ptr(obj, prop); 511 uint64_t value = *ptr; 512 513 visit_type_size(v, name, &value, errp); 514 } 515 516 static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque, 517 Error **errp) 518 { 519 Property *prop = opaque; 520 uint32_t *ptr = object_field_prop_ptr(obj, prop); 521 uint64_t value; 522 523 if (!visit_type_size(v, name, &value, errp)) { 524 return; 525 } 526 527 if (value > UINT32_MAX) { 528 error_setg(errp, 529 "Property %s.%s doesn't take value %" PRIu64 530 " (maximum: %u)", 531 object_get_typename(obj), name, value, UINT32_MAX); 532 return; 533 } 534 535 *ptr = value; 536 } 537 538 const PropertyInfo qdev_prop_size32 = { 539 .name = "size", 540 .get = qdev_propinfo_get_size32, 541 .set = set_size32, 542 .set_default_value = qdev_propinfo_set_default_value_uint, 543 }; 544 545 /* --- support for array properties --- */ 546 547 /* Used as an opaque for the object properties we add for each 548 * array element. Note that the struct Property must be first 549 * in the struct so that a pointer to this works as the opaque 550 * for the underlying element's property hooks as well as for 551 * our own release callback. 552 */ 553 typedef struct { 554 struct Property prop; 555 char *propname; 556 ObjectPropertyRelease *release; 557 } ArrayElementProperty; 558 559 /* object property release callback for array element properties: 560 * we call the underlying element's property release hook, and 561 * then free the memory we allocated when we added the property. 562 */ 563 static void array_element_release(Object *obj, const char *name, void *opaque) 564 { 565 ArrayElementProperty *p = opaque; 566 if (p->release) { 567 p->release(obj, name, opaque); 568 } 569 g_free(p->propname); 570 g_free(p); 571 } 572 573 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name, 574 void *opaque, Error **errp) 575 { 576 /* Setter for the property which defines the length of a 577 * variable-sized property array. As well as actually setting the 578 * array-length field in the device struct, we have to create the 579 * array itself and dynamically add the corresponding properties. 580 */ 581 Property *prop = opaque; 582 uint32_t *alenptr = object_field_prop_ptr(obj, prop); 583 void **arrayptr = (void *)obj + prop->arrayoffset; 584 void *eltptr; 585 const char *arrayname; 586 int i; 587 588 if (*alenptr) { 589 error_setg(errp, "array size property %s may not be set more than once", 590 name); 591 return; 592 } 593 if (!visit_type_uint32(v, name, alenptr, errp)) { 594 return; 595 } 596 if (!*alenptr) { 597 return; 598 } 599 600 /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix; 601 * strip it off so we can get the name of the array itself. 602 */ 603 assert(strncmp(name, PROP_ARRAY_LEN_PREFIX, 604 strlen(PROP_ARRAY_LEN_PREFIX)) == 0); 605 arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX); 606 607 /* Note that it is the responsibility of the individual device's deinit 608 * to free the array proper. 609 */ 610 *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize); 611 for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) { 612 char *propname = g_strdup_printf("%s[%d]", arrayname, i); 613 ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1); 614 arrayprop->release = prop->arrayinfo->release; 615 arrayprop->propname = propname; 616 arrayprop->prop.info = prop->arrayinfo; 617 arrayprop->prop.name = propname; 618 /* This ugly piece of pointer arithmetic sets up the offset so 619 * that when the underlying get/set hooks call qdev_get_prop_ptr 620 * they get the right answer despite the array element not actually 621 * being inside the device struct. 622 */ 623 arrayprop->prop.offset = eltptr - (void *)obj; 624 assert(object_field_prop_ptr(obj, &arrayprop->prop) == eltptr); 625 object_property_add(obj, propname, 626 arrayprop->prop.info->name, 627 field_prop_getter(arrayprop->prop.info), 628 field_prop_setter(arrayprop->prop.info), 629 array_element_release, 630 arrayprop); 631 } 632 } 633 634 const PropertyInfo qdev_prop_arraylen = { 635 .name = "uint32", 636 .get = get_uint32, 637 .set = set_prop_arraylen, 638 .set_default_value = qdev_propinfo_set_default_value_uint, 639 }; 640 641 /* --- public helpers --- */ 642 643 static Property *qdev_prop_walk(Property *props, const char *name) 644 { 645 if (!props) { 646 return NULL; 647 } 648 while (props->name) { 649 if (strcmp(props->name, name) == 0) { 650 return props; 651 } 652 props++; 653 } 654 return NULL; 655 } 656 657 static Property *qdev_prop_find(DeviceState *dev, const char *name) 658 { 659 ObjectClass *class; 660 Property *prop; 661 662 /* device properties */ 663 class = object_get_class(OBJECT(dev)); 664 do { 665 prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name); 666 if (prop) { 667 return prop; 668 } 669 class = object_class_get_parent(class); 670 } while (class != object_class_by_name(TYPE_DEVICE)); 671 672 return NULL; 673 } 674 675 void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj, 676 const char *name, const char *value) 677 { 678 switch (ret) { 679 case -EEXIST: 680 error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", 681 object_get_typename(obj), name, value); 682 break; 683 default: 684 case -EINVAL: 685 error_setg(errp, QERR_PROPERTY_VALUE_BAD, 686 object_get_typename(obj), name, value); 687 break; 688 case -ENOENT: 689 error_setg(errp, "Property '%s.%s' can't find value '%s'", 690 object_get_typename(obj), name, value); 691 break; 692 case 0: 693 break; 694 } 695 } 696 697 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value) 698 { 699 object_property_set_bool(OBJECT(dev), name, value, &error_abort); 700 } 701 702 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value) 703 { 704 object_property_set_int(OBJECT(dev), name, value, &error_abort); 705 } 706 707 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value) 708 { 709 object_property_set_int(OBJECT(dev), name, value, &error_abort); 710 } 711 712 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value) 713 { 714 object_property_set_int(OBJECT(dev), name, value, &error_abort); 715 } 716 717 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value) 718 { 719 object_property_set_int(OBJECT(dev), name, value, &error_abort); 720 } 721 722 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value) 723 { 724 object_property_set_int(OBJECT(dev), name, value, &error_abort); 725 } 726 727 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value) 728 { 729 object_property_set_str(OBJECT(dev), name, value, &error_abort); 730 } 731 732 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value) 733 { 734 Property *prop; 735 736 prop = qdev_prop_find(dev, name); 737 object_property_set_str(OBJECT(dev), name, 738 qapi_enum_lookup(prop->info->enum_table, value), 739 &error_abort); 740 } 741 742 static GPtrArray *global_props(void) 743 { 744 static GPtrArray *gp; 745 746 if (!gp) { 747 gp = g_ptr_array_new(); 748 } 749 750 return gp; 751 } 752 753 void qdev_prop_register_global(GlobalProperty *prop) 754 { 755 g_ptr_array_add(global_props(), prop); 756 } 757 758 const GlobalProperty *qdev_find_global_prop(Object *obj, 759 const char *name) 760 { 761 GPtrArray *props = global_props(); 762 const GlobalProperty *p; 763 int i; 764 765 for (i = 0; i < props->len; i++) { 766 p = g_ptr_array_index(props, i); 767 if (object_dynamic_cast(obj, p->driver) 768 && !strcmp(p->property, name)) { 769 return p; 770 } 771 } 772 return NULL; 773 } 774 775 int qdev_prop_check_globals(void) 776 { 777 int i, ret = 0; 778 779 for (i = 0; i < global_props()->len; i++) { 780 GlobalProperty *prop; 781 ObjectClass *oc; 782 DeviceClass *dc; 783 784 prop = g_ptr_array_index(global_props(), i); 785 if (prop->used) { 786 continue; 787 } 788 oc = object_class_by_name(prop->driver); 789 oc = object_class_dynamic_cast(oc, TYPE_DEVICE); 790 if (!oc) { 791 warn_report("global %s.%s has invalid class name", 792 prop->driver, prop->property); 793 ret = 1; 794 continue; 795 } 796 dc = DEVICE_CLASS(oc); 797 if (!dc->hotpluggable && !prop->used) { 798 warn_report("global %s.%s=%s not used", 799 prop->driver, prop->property, prop->value); 800 ret = 1; 801 continue; 802 } 803 } 804 return ret; 805 } 806 807 void qdev_prop_set_globals(DeviceState *dev) 808 { 809 object_apply_global_props(OBJECT(dev), global_props(), 810 dev->hotplugged ? NULL : &error_fatal); 811 } 812 813 /* --- 64bit unsigned int 'size' type --- */ 814 815 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque, 816 Error **errp) 817 { 818 Property *prop = opaque; 819 uint64_t *ptr = object_field_prop_ptr(obj, prop); 820 821 visit_type_size(v, name, ptr, errp); 822 } 823 824 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque, 825 Error **errp) 826 { 827 Property *prop = opaque; 828 uint64_t *ptr = object_field_prop_ptr(obj, prop); 829 830 visit_type_size(v, name, ptr, errp); 831 } 832 833 const PropertyInfo qdev_prop_size = { 834 .name = "size", 835 .get = get_size, 836 .set = set_size, 837 .set_default_value = qdev_propinfo_set_default_value_uint, 838 }; 839 840 /* --- object link property --- */ 841 842 static ObjectProperty *create_link_property(ObjectClass *oc, const char *name, 843 Property *prop) 844 { 845 return object_class_property_add_link(oc, name, prop->link_type, 846 prop->offset, 847 qdev_prop_allow_set_link_before_realize, 848 OBJ_PROP_LINK_STRONG); 849 } 850 851 const PropertyInfo qdev_prop_link = { 852 .name = "link", 853 .create = create_link_property, 854 }; 855 856 void qdev_property_add_static(DeviceState *dev, Property *prop) 857 { 858 Object *obj = OBJECT(dev); 859 ObjectProperty *op; 860 861 assert(!prop->info->create); 862 863 op = object_property_add(obj, prop->name, prop->info->name, 864 field_prop_getter(prop->info), 865 field_prop_setter(prop->info), 866 prop->info->release, 867 prop); 868 869 object_property_set_description(obj, prop->name, 870 prop->info->description); 871 872 if (prop->set_default) { 873 prop->info->set_default_value(op, prop); 874 if (op->init) { 875 op->init(obj, op); 876 } 877 } 878 } 879 880 static void qdev_class_add_property(DeviceClass *klass, const char *name, 881 Property *prop) 882 { 883 ObjectClass *oc = OBJECT_CLASS(klass); 884 ObjectProperty *op; 885 886 if (prop->info->create) { 887 op = prop->info->create(oc, name, prop); 888 } else { 889 op = object_class_property_add(oc, 890 name, prop->info->name, 891 field_prop_getter(prop->info), 892 field_prop_setter(prop->info), 893 prop->info->release, 894 prop); 895 } 896 if (prop->set_default) { 897 prop->info->set_default_value(op, prop); 898 } 899 object_class_property_set_description(oc, name, prop->info->description); 900 } 901 902 /** 903 * Legacy property handling 904 */ 905 906 static void qdev_get_legacy_property(Object *obj, Visitor *v, 907 const char *name, void *opaque, 908 Error **errp) 909 { 910 Property *prop = opaque; 911 912 char buffer[1024]; 913 char *ptr = buffer; 914 915 prop->info->print(obj, prop, buffer, sizeof(buffer)); 916 visit_type_str(v, name, &ptr, errp); 917 } 918 919 /** 920 * qdev_class_add_legacy_property: 921 * @dev: Device to add the property to. 922 * @prop: The qdev property definition. 923 * 924 * Add a legacy QOM property to @dev for qdev property @prop. 925 * 926 * Legacy properties are string versions of QOM properties. The format of 927 * the string depends on the property type. Legacy properties are only 928 * needed for "info qtree". 929 * 930 * Do not use this in new code! QOM Properties added through this interface 931 * will be given names in the "legacy" namespace. 932 */ 933 static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop) 934 { 935 g_autofree char *name = NULL; 936 937 /* Register pointer properties as legacy properties */ 938 if (!prop->info->print && prop->info->get) { 939 return; 940 } 941 942 name = g_strdup_printf("legacy-%s", prop->name); 943 object_class_property_add(OBJECT_CLASS(dc), name, "str", 944 prop->info->print ? qdev_get_legacy_property : prop->info->get, 945 NULL, NULL, prop); 946 } 947 948 void device_class_set_props(DeviceClass *dc, Property *props) 949 { 950 Property *prop; 951 952 dc->props_ = props; 953 for (prop = props; prop && prop->name; prop++) { 954 qdev_class_add_legacy_property(dc, prop); 955 qdev_class_add_property(dc, prop->name, prop); 956 } 957 } 958 959 void qdev_alias_all_properties(DeviceState *target, Object *source) 960 { 961 ObjectClass *class; 962 Property *prop; 963 964 class = object_get_class(OBJECT(target)); 965 do { 966 DeviceClass *dc = DEVICE_CLASS(class); 967 968 for (prop = dc->props_; prop && prop->name; prop++) { 969 object_property_add_alias(source, prop->name, 970 OBJECT(target), prop->name); 971 } 972 class = object_class_get_parent(class); 973 } while (class != object_class_by_name(TYPE_DEVICE)); 974 } 975