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