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