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