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