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