1 #include "qemu/osdep.h" 2 #include "net/net.h" 3 #include "hw/qdev.h" 4 #include "qapi/qmp/qerror.h" 5 #include "qemu/error-report.h" 6 #include "sysemu/block-backend.h" 7 #include "hw/block/block.h" 8 #include "net/hub.h" 9 #include "qapi/visitor.h" 10 #include "sysemu/char.h" 11 12 void qdev_prop_set_after_realize(DeviceState *dev, const char *name, 13 Error **errp) 14 { 15 if (dev->id) { 16 error_setg(errp, "Attempt to set property '%s' on device '%s' " 17 "(type '%s') after it was realized", name, dev->id, 18 object_get_typename(OBJECT(dev))); 19 } else { 20 error_setg(errp, "Attempt to set property '%s' on anonymous device " 21 "(type '%s') after it was realized", name, 22 object_get_typename(OBJECT(dev))); 23 } 24 } 25 26 void qdev_prop_allow_set_link_before_realize(Object *obj, const char *name, 27 Object *val, Error **errp) 28 { 29 DeviceState *dev = DEVICE(obj); 30 31 if (dev->realized) { 32 error_setg(errp, "Attempt to set link property '%s' on device '%s' " 33 "(type '%s') after it was realized", 34 name, dev->id, object_get_typename(obj)); 35 } 36 } 37 38 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop) 39 { 40 void *ptr = dev; 41 ptr += prop->offset; 42 return ptr; 43 } 44 45 static void get_enum(Object *obj, Visitor *v, const char *name, void *opaque, 46 Error **errp) 47 { 48 DeviceState *dev = DEVICE(obj); 49 Property *prop = opaque; 50 int *ptr = qdev_get_prop_ptr(dev, prop); 51 52 visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp); 53 } 54 55 static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque, 56 Error **errp) 57 { 58 DeviceState *dev = DEVICE(obj); 59 Property *prop = opaque; 60 int *ptr = qdev_get_prop_ptr(dev, prop); 61 62 if (dev->realized) { 63 qdev_prop_set_after_realize(dev, name, errp); 64 return; 65 } 66 67 visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp); 68 } 69 70 /* Bit */ 71 72 static uint32_t qdev_get_prop_mask(Property *prop) 73 { 74 assert(prop->info == &qdev_prop_bit); 75 return 0x1 << prop->bitnr; 76 } 77 78 static void bit_prop_set(DeviceState *dev, Property *props, bool val) 79 { 80 uint32_t *p = qdev_get_prop_ptr(dev, props); 81 uint32_t mask = qdev_get_prop_mask(props); 82 if (val) { 83 *p |= mask; 84 } else { 85 *p &= ~mask; 86 } 87 } 88 89 static void prop_get_bit(Object *obj, Visitor *v, const char *name, 90 void *opaque, Error **errp) 91 { 92 DeviceState *dev = DEVICE(obj); 93 Property *prop = opaque; 94 uint32_t *p = qdev_get_prop_ptr(dev, prop); 95 bool value = (*p & qdev_get_prop_mask(prop)) != 0; 96 97 visit_type_bool(v, name, &value, errp); 98 } 99 100 static void prop_set_bit(Object *obj, Visitor *v, const char *name, 101 void *opaque, Error **errp) 102 { 103 DeviceState *dev = DEVICE(obj); 104 Property *prop = opaque; 105 Error *local_err = NULL; 106 bool value; 107 108 if (dev->realized) { 109 qdev_prop_set_after_realize(dev, name, errp); 110 return; 111 } 112 113 visit_type_bool(v, name, &value, &local_err); 114 if (local_err) { 115 error_propagate(errp, local_err); 116 return; 117 } 118 bit_prop_set(dev, prop, value); 119 } 120 121 PropertyInfo qdev_prop_bit = { 122 .name = "bool", 123 .description = "on/off", 124 .get = prop_get_bit, 125 .set = prop_set_bit, 126 }; 127 128 /* Bit64 */ 129 130 static uint64_t qdev_get_prop_mask64(Property *prop) 131 { 132 assert(prop->info == &qdev_prop_bit64); 133 return 0x1ull << prop->bitnr; 134 } 135 136 static void bit64_prop_set(DeviceState *dev, Property *props, bool val) 137 { 138 uint64_t *p = qdev_get_prop_ptr(dev, props); 139 uint64_t mask = qdev_get_prop_mask64(props); 140 if (val) { 141 *p |= mask; 142 } else { 143 *p &= ~mask; 144 } 145 } 146 147 static void prop_get_bit64(Object *obj, Visitor *v, const char *name, 148 void *opaque, Error **errp) 149 { 150 DeviceState *dev = DEVICE(obj); 151 Property *prop = opaque; 152 uint64_t *p = qdev_get_prop_ptr(dev, prop); 153 bool value = (*p & qdev_get_prop_mask64(prop)) != 0; 154 155 visit_type_bool(v, name, &value, errp); 156 } 157 158 static void prop_set_bit64(Object *obj, Visitor *v, const char *name, 159 void *opaque, Error **errp) 160 { 161 DeviceState *dev = DEVICE(obj); 162 Property *prop = opaque; 163 Error *local_err = NULL; 164 bool value; 165 166 if (dev->realized) { 167 qdev_prop_set_after_realize(dev, name, errp); 168 return; 169 } 170 171 visit_type_bool(v, name, &value, &local_err); 172 if (local_err) { 173 error_propagate(errp, local_err); 174 return; 175 } 176 bit64_prop_set(dev, prop, value); 177 } 178 179 PropertyInfo qdev_prop_bit64 = { 180 .name = "bool", 181 .description = "on/off", 182 .get = prop_get_bit64, 183 .set = prop_set_bit64, 184 }; 185 186 /* --- bool --- */ 187 188 static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque, 189 Error **errp) 190 { 191 DeviceState *dev = DEVICE(obj); 192 Property *prop = opaque; 193 bool *ptr = qdev_get_prop_ptr(dev, prop); 194 195 visit_type_bool(v, name, ptr, errp); 196 } 197 198 static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque, 199 Error **errp) 200 { 201 DeviceState *dev = DEVICE(obj); 202 Property *prop = opaque; 203 bool *ptr = qdev_get_prop_ptr(dev, prop); 204 205 if (dev->realized) { 206 qdev_prop_set_after_realize(dev, name, errp); 207 return; 208 } 209 210 visit_type_bool(v, name, ptr, errp); 211 } 212 213 PropertyInfo qdev_prop_bool = { 214 .name = "bool", 215 .get = get_bool, 216 .set = set_bool, 217 }; 218 219 /* --- 8bit integer --- */ 220 221 static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque, 222 Error **errp) 223 { 224 DeviceState *dev = DEVICE(obj); 225 Property *prop = opaque; 226 uint8_t *ptr = qdev_get_prop_ptr(dev, prop); 227 228 visit_type_uint8(v, name, ptr, errp); 229 } 230 231 static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque, 232 Error **errp) 233 { 234 DeviceState *dev = DEVICE(obj); 235 Property *prop = opaque; 236 uint8_t *ptr = qdev_get_prop_ptr(dev, prop); 237 238 if (dev->realized) { 239 qdev_prop_set_after_realize(dev, name, errp); 240 return; 241 } 242 243 visit_type_uint8(v, name, ptr, errp); 244 } 245 246 PropertyInfo qdev_prop_uint8 = { 247 .name = "uint8", 248 .get = get_uint8, 249 .set = set_uint8, 250 }; 251 252 /* --- 16bit integer --- */ 253 254 static void get_uint16(Object *obj, Visitor *v, const char *name, 255 void *opaque, Error **errp) 256 { 257 DeviceState *dev = DEVICE(obj); 258 Property *prop = opaque; 259 uint16_t *ptr = qdev_get_prop_ptr(dev, prop); 260 261 visit_type_uint16(v, name, ptr, errp); 262 } 263 264 static void set_uint16(Object *obj, Visitor *v, const char *name, 265 void *opaque, Error **errp) 266 { 267 DeviceState *dev = DEVICE(obj); 268 Property *prop = opaque; 269 uint16_t *ptr = qdev_get_prop_ptr(dev, prop); 270 271 if (dev->realized) { 272 qdev_prop_set_after_realize(dev, name, errp); 273 return; 274 } 275 276 visit_type_uint16(v, name, ptr, errp); 277 } 278 279 PropertyInfo qdev_prop_uint16 = { 280 .name = "uint16", 281 .get = get_uint16, 282 .set = set_uint16, 283 }; 284 285 /* --- 32bit integer --- */ 286 287 static void get_uint32(Object *obj, Visitor *v, const char *name, 288 void *opaque, Error **errp) 289 { 290 DeviceState *dev = DEVICE(obj); 291 Property *prop = opaque; 292 uint32_t *ptr = qdev_get_prop_ptr(dev, prop); 293 294 visit_type_uint32(v, name, ptr, errp); 295 } 296 297 static void set_uint32(Object *obj, Visitor *v, const char *name, 298 void *opaque, Error **errp) 299 { 300 DeviceState *dev = DEVICE(obj); 301 Property *prop = opaque; 302 uint32_t *ptr = qdev_get_prop_ptr(dev, prop); 303 304 if (dev->realized) { 305 qdev_prop_set_after_realize(dev, name, errp); 306 return; 307 } 308 309 visit_type_uint32(v, name, ptr, errp); 310 } 311 312 static void get_int32(Object *obj, Visitor *v, const char *name, void *opaque, 313 Error **errp) 314 { 315 DeviceState *dev = DEVICE(obj); 316 Property *prop = opaque; 317 int32_t *ptr = qdev_get_prop_ptr(dev, prop); 318 319 visit_type_int32(v, name, ptr, errp); 320 } 321 322 static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque, 323 Error **errp) 324 { 325 DeviceState *dev = DEVICE(obj); 326 Property *prop = opaque; 327 int32_t *ptr = qdev_get_prop_ptr(dev, prop); 328 329 if (dev->realized) { 330 qdev_prop_set_after_realize(dev, name, errp); 331 return; 332 } 333 334 visit_type_int32(v, name, ptr, errp); 335 } 336 337 PropertyInfo qdev_prop_uint32 = { 338 .name = "uint32", 339 .get = get_uint32, 340 .set = set_uint32, 341 }; 342 343 PropertyInfo qdev_prop_int32 = { 344 .name = "int32", 345 .get = get_int32, 346 .set = set_int32, 347 }; 348 349 /* --- 64bit integer --- */ 350 351 static void get_uint64(Object *obj, Visitor *v, const char *name, 352 void *opaque, Error **errp) 353 { 354 DeviceState *dev = DEVICE(obj); 355 Property *prop = opaque; 356 uint64_t *ptr = qdev_get_prop_ptr(dev, prop); 357 358 visit_type_uint64(v, name, ptr, errp); 359 } 360 361 static void set_uint64(Object *obj, Visitor *v, const char *name, 362 void *opaque, Error **errp) 363 { 364 DeviceState *dev = DEVICE(obj); 365 Property *prop = opaque; 366 uint64_t *ptr = qdev_get_prop_ptr(dev, prop); 367 368 if (dev->realized) { 369 qdev_prop_set_after_realize(dev, name, errp); 370 return; 371 } 372 373 visit_type_uint64(v, name, ptr, errp); 374 } 375 376 PropertyInfo qdev_prop_uint64 = { 377 .name = "uint64", 378 .get = get_uint64, 379 .set = set_uint64, 380 }; 381 382 /* --- string --- */ 383 384 static void release_string(Object *obj, const char *name, void *opaque) 385 { 386 Property *prop = opaque; 387 g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop)); 388 } 389 390 static void get_string(Object *obj, Visitor *v, const char *name, 391 void *opaque, Error **errp) 392 { 393 DeviceState *dev = DEVICE(obj); 394 Property *prop = opaque; 395 char **ptr = qdev_get_prop_ptr(dev, prop); 396 397 if (!*ptr) { 398 char *str = (char *)""; 399 visit_type_str(v, name, &str, errp); 400 } else { 401 visit_type_str(v, name, ptr, errp); 402 } 403 } 404 405 static void set_string(Object *obj, Visitor *v, const char *name, 406 void *opaque, Error **errp) 407 { 408 DeviceState *dev = DEVICE(obj); 409 Property *prop = opaque; 410 char **ptr = qdev_get_prop_ptr(dev, prop); 411 Error *local_err = NULL; 412 char *str; 413 414 if (dev->realized) { 415 qdev_prop_set_after_realize(dev, name, errp); 416 return; 417 } 418 419 visit_type_str(v, name, &str, &local_err); 420 if (local_err) { 421 error_propagate(errp, local_err); 422 return; 423 } 424 g_free(*ptr); 425 *ptr = str; 426 } 427 428 PropertyInfo qdev_prop_string = { 429 .name = "str", 430 .release = release_string, 431 .get = get_string, 432 .set = set_string, 433 }; 434 435 /* --- pointer --- */ 436 437 /* Not a proper property, just for dirty hacks. TODO Remove it! */ 438 PropertyInfo qdev_prop_ptr = { 439 .name = "ptr", 440 }; 441 442 /* --- mac address --- */ 443 444 /* 445 * accepted syntax versions: 446 * 01:02:03:04:05:06 447 * 01-02-03-04-05-06 448 */ 449 static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque, 450 Error **errp) 451 { 452 DeviceState *dev = DEVICE(obj); 453 Property *prop = opaque; 454 MACAddr *mac = qdev_get_prop_ptr(dev, prop); 455 char buffer[2 * 6 + 5 + 1]; 456 char *p = buffer; 457 458 snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x", 459 mac->a[0], mac->a[1], mac->a[2], 460 mac->a[3], mac->a[4], mac->a[5]); 461 462 visit_type_str(v, name, &p, errp); 463 } 464 465 static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque, 466 Error **errp) 467 { 468 DeviceState *dev = DEVICE(obj); 469 Property *prop = opaque; 470 MACAddr *mac = qdev_get_prop_ptr(dev, prop); 471 Error *local_err = NULL; 472 int i, pos; 473 char *str, *p; 474 475 if (dev->realized) { 476 qdev_prop_set_after_realize(dev, name, errp); 477 return; 478 } 479 480 visit_type_str(v, name, &str, &local_err); 481 if (local_err) { 482 error_propagate(errp, local_err); 483 return; 484 } 485 486 for (i = 0, pos = 0; i < 6; i++, pos += 3) { 487 if (!qemu_isxdigit(str[pos])) { 488 goto inval; 489 } 490 if (!qemu_isxdigit(str[pos+1])) { 491 goto inval; 492 } 493 if (i == 5) { 494 if (str[pos+2] != '\0') { 495 goto inval; 496 } 497 } else { 498 if (str[pos+2] != ':' && str[pos+2] != '-') { 499 goto inval; 500 } 501 } 502 mac->a[i] = strtol(str+pos, &p, 16); 503 } 504 g_free(str); 505 return; 506 507 inval: 508 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 509 g_free(str); 510 } 511 512 PropertyInfo qdev_prop_macaddr = { 513 .name = "str", 514 .description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56", 515 .get = get_mac, 516 .set = set_mac, 517 }; 518 519 /* --- on/off/auto --- */ 520 521 PropertyInfo qdev_prop_on_off_auto = { 522 .name = "OnOffAuto", 523 .description = "on/off/auto", 524 .enum_table = OnOffAuto_lookup, 525 .get = get_enum, 526 .set = set_enum, 527 }; 528 529 /* --- lost tick policy --- */ 530 531 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int)); 532 533 PropertyInfo qdev_prop_losttickpolicy = { 534 .name = "LostTickPolicy", 535 .enum_table = LostTickPolicy_lookup, 536 .get = get_enum, 537 .set = set_enum, 538 }; 539 540 /* --- BIOS CHS translation */ 541 542 QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int)); 543 544 PropertyInfo qdev_prop_bios_chs_trans = { 545 .name = "BiosAtaTranslation", 546 .description = "Logical CHS translation algorithm, " 547 "auto/none/lba/large/rechs", 548 .enum_table = BiosAtaTranslation_lookup, 549 .get = get_enum, 550 .set = set_enum, 551 }; 552 553 /* --- FDC default drive types */ 554 555 PropertyInfo qdev_prop_fdc_drive_type = { 556 .name = "FdcDriveType", 557 .description = "FDC drive type, " 558 "144/288/120/none/auto", 559 .enum_table = FloppyDriveType_lookup, 560 .get = get_enum, 561 .set = set_enum 562 }; 563 564 /* --- pci address --- */ 565 566 /* 567 * bus-local address, i.e. "$slot" or "$slot.$fn" 568 */ 569 static void set_pci_devfn(Object *obj, Visitor *v, const char *name, 570 void *opaque, Error **errp) 571 { 572 DeviceState *dev = DEVICE(obj); 573 Property *prop = opaque; 574 int32_t value, *ptr = qdev_get_prop_ptr(dev, prop); 575 unsigned int slot, fn, n; 576 Error *local_err = NULL; 577 char *str; 578 579 if (dev->realized) { 580 qdev_prop_set_after_realize(dev, name, errp); 581 return; 582 } 583 584 visit_type_str(v, name, &str, &local_err); 585 if (local_err) { 586 error_free(local_err); 587 local_err = NULL; 588 visit_type_int32(v, name, &value, &local_err); 589 if (local_err) { 590 error_propagate(errp, local_err); 591 } else if (value < -1 || value > 255) { 592 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 593 name ? name : "null", "pci_devfn"); 594 } else { 595 *ptr = value; 596 } 597 return; 598 } 599 600 if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) { 601 fn = 0; 602 if (sscanf(str, "%x%n", &slot, &n) != 1) { 603 goto invalid; 604 } 605 } 606 if (str[n] != '\0' || fn > 7 || slot > 31) { 607 goto invalid; 608 } 609 *ptr = slot << 3 | fn; 610 g_free(str); 611 return; 612 613 invalid: 614 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 615 g_free(str); 616 } 617 618 static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, 619 size_t len) 620 { 621 int32_t *ptr = qdev_get_prop_ptr(dev, prop); 622 623 if (*ptr == -1) { 624 return snprintf(dest, len, "<unset>"); 625 } else { 626 return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7); 627 } 628 } 629 630 PropertyInfo qdev_prop_pci_devfn = { 631 .name = "int32", 632 .description = "Slot and optional function number, example: 06.0 or 06", 633 .print = print_pci_devfn, 634 .get = get_int32, 635 .set = set_pci_devfn, 636 }; 637 638 /* --- blocksize --- */ 639 640 static void set_blocksize(Object *obj, Visitor *v, const char *name, 641 void *opaque, Error **errp) 642 { 643 DeviceState *dev = DEVICE(obj); 644 Property *prop = opaque; 645 uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop); 646 Error *local_err = NULL; 647 const int64_t min = 512; 648 const int64_t max = 32768; 649 650 if (dev->realized) { 651 qdev_prop_set_after_realize(dev, name, errp); 652 return; 653 } 654 655 visit_type_uint16(v, name, &value, &local_err); 656 if (local_err) { 657 error_propagate(errp, local_err); 658 return; 659 } 660 /* value of 0 means "unset" */ 661 if (value && (value < min || value > max)) { 662 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, 663 dev->id ? : "", name, (int64_t)value, min, max); 664 return; 665 } 666 667 /* We rely on power-of-2 blocksizes for bitmasks */ 668 if ((value & (value - 1)) != 0) { 669 error_setg(errp, 670 "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2", 671 dev->id ?: "", name, (int64_t)value); 672 return; 673 } 674 675 *ptr = value; 676 } 677 678 PropertyInfo qdev_prop_blocksize = { 679 .name = "uint16", 680 .description = "A power of two between 512 and 32768", 681 .get = get_uint16, 682 .set = set_blocksize, 683 }; 684 685 /* --- pci host address --- */ 686 687 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name, 688 void *opaque, Error **errp) 689 { 690 DeviceState *dev = DEVICE(obj); 691 Property *prop = opaque; 692 PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop); 693 char buffer[] = "xxxx:xx:xx.x"; 694 char *p = buffer; 695 int rc = 0; 696 697 rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d", 698 addr->domain, addr->bus, addr->slot, addr->function); 699 assert(rc == sizeof(buffer) - 1); 700 701 visit_type_str(v, name, &p, errp); 702 } 703 704 /* 705 * Parse [<domain>:]<bus>:<slot>.<func> 706 * if <domain> is not supplied, it's assumed to be 0. 707 */ 708 static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name, 709 void *opaque, Error **errp) 710 { 711 DeviceState *dev = DEVICE(obj); 712 Property *prop = opaque; 713 PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop); 714 Error *local_err = NULL; 715 char *str, *p; 716 char *e; 717 unsigned long val; 718 unsigned long dom = 0, bus = 0; 719 unsigned int slot = 0, func = 0; 720 721 if (dev->realized) { 722 qdev_prop_set_after_realize(dev, name, errp); 723 return; 724 } 725 726 visit_type_str(v, name, &str, &local_err); 727 if (local_err) { 728 error_propagate(errp, local_err); 729 return; 730 } 731 732 p = str; 733 val = strtoul(p, &e, 16); 734 if (e == p || *e != ':') { 735 goto inval; 736 } 737 bus = val; 738 739 p = e + 1; 740 val = strtoul(p, &e, 16); 741 if (e == p) { 742 goto inval; 743 } 744 if (*e == ':') { 745 dom = bus; 746 bus = val; 747 p = e + 1; 748 val = strtoul(p, &e, 16); 749 if (e == p) { 750 goto inval; 751 } 752 } 753 slot = val; 754 755 if (*e != '.') { 756 goto inval; 757 } 758 p = e + 1; 759 val = strtoul(p, &e, 10); 760 if (e == p) { 761 goto inval; 762 } 763 func = val; 764 765 if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) { 766 goto inval; 767 } 768 769 if (*e) { 770 goto inval; 771 } 772 773 addr->domain = dom; 774 addr->bus = bus; 775 addr->slot = slot; 776 addr->function = func; 777 778 g_free(str); 779 return; 780 781 inval: 782 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 783 g_free(str); 784 } 785 786 PropertyInfo qdev_prop_pci_host_devaddr = { 787 .name = "str", 788 .description = "Address (bus/device/function) of " 789 "the host device, example: 04:10.0", 790 .get = get_pci_host_devaddr, 791 .set = set_pci_host_devaddr, 792 }; 793 794 /* --- support for array properties --- */ 795 796 /* Used as an opaque for the object properties we add for each 797 * array element. Note that the struct Property must be first 798 * in the struct so that a pointer to this works as the opaque 799 * for the underlying element's property hooks as well as for 800 * our own release callback. 801 */ 802 typedef struct { 803 struct Property prop; 804 char *propname; 805 ObjectPropertyRelease *release; 806 } ArrayElementProperty; 807 808 /* object property release callback for array element properties: 809 * we call the underlying element's property release hook, and 810 * then free the memory we allocated when we added the property. 811 */ 812 static void array_element_release(Object *obj, const char *name, void *opaque) 813 { 814 ArrayElementProperty *p = opaque; 815 if (p->release) { 816 p->release(obj, name, opaque); 817 } 818 g_free(p->propname); 819 g_free(p); 820 } 821 822 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name, 823 void *opaque, Error **errp) 824 { 825 /* Setter for the property which defines the length of a 826 * variable-sized property array. As well as actually setting the 827 * array-length field in the device struct, we have to create the 828 * array itself and dynamically add the corresponding properties. 829 */ 830 DeviceState *dev = DEVICE(obj); 831 Property *prop = opaque; 832 uint32_t *alenptr = qdev_get_prop_ptr(dev, prop); 833 void **arrayptr = (void *)dev + prop->arrayoffset; 834 Error *local_err = NULL; 835 void *eltptr; 836 const char *arrayname; 837 int i; 838 839 if (dev->realized) { 840 qdev_prop_set_after_realize(dev, name, errp); 841 return; 842 } 843 if (*alenptr) { 844 error_setg(errp, "array size property %s may not be set more than once", 845 name); 846 return; 847 } 848 visit_type_uint32(v, name, alenptr, &local_err); 849 if (local_err) { 850 error_propagate(errp, local_err); 851 return; 852 } 853 if (!*alenptr) { 854 return; 855 } 856 857 /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix; 858 * strip it off so we can get the name of the array itself. 859 */ 860 assert(strncmp(name, PROP_ARRAY_LEN_PREFIX, 861 strlen(PROP_ARRAY_LEN_PREFIX)) == 0); 862 arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX); 863 864 /* Note that it is the responsibility of the individual device's deinit 865 * to free the array proper. 866 */ 867 *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize); 868 for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) { 869 char *propname = g_strdup_printf("%s[%d]", arrayname, i); 870 ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1); 871 arrayprop->release = prop->arrayinfo->release; 872 arrayprop->propname = propname; 873 arrayprop->prop.info = prop->arrayinfo; 874 arrayprop->prop.name = propname; 875 /* This ugly piece of pointer arithmetic sets up the offset so 876 * that when the underlying get/set hooks call qdev_get_prop_ptr 877 * they get the right answer despite the array element not actually 878 * being inside the device struct. 879 */ 880 arrayprop->prop.offset = eltptr - (void *)dev; 881 assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr); 882 object_property_add(obj, propname, 883 arrayprop->prop.info->name, 884 arrayprop->prop.info->get, 885 arrayprop->prop.info->set, 886 array_element_release, 887 arrayprop, &local_err); 888 if (local_err) { 889 error_propagate(errp, local_err); 890 return; 891 } 892 } 893 } 894 895 PropertyInfo qdev_prop_arraylen = { 896 .name = "uint32", 897 .get = get_uint32, 898 .set = set_prop_arraylen, 899 }; 900 901 /* --- public helpers --- */ 902 903 static Property *qdev_prop_walk(Property *props, const char *name) 904 { 905 if (!props) { 906 return NULL; 907 } 908 while (props->name) { 909 if (strcmp(props->name, name) == 0) { 910 return props; 911 } 912 props++; 913 } 914 return NULL; 915 } 916 917 static Property *qdev_prop_find(DeviceState *dev, const char *name) 918 { 919 ObjectClass *class; 920 Property *prop; 921 922 /* device properties */ 923 class = object_get_class(OBJECT(dev)); 924 do { 925 prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name); 926 if (prop) { 927 return prop; 928 } 929 class = object_class_get_parent(class); 930 } while (class != object_class_by_name(TYPE_DEVICE)); 931 932 return NULL; 933 } 934 935 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, 936 Property *prop, const char *value) 937 { 938 switch (ret) { 939 case -EEXIST: 940 error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", 941 object_get_typename(OBJECT(dev)), prop->name, value); 942 break; 943 default: 944 case -EINVAL: 945 error_setg(errp, QERR_PROPERTY_VALUE_BAD, 946 object_get_typename(OBJECT(dev)), prop->name, value); 947 break; 948 case -ENOENT: 949 error_setg(errp, "Property '%s.%s' can't find value '%s'", 950 object_get_typename(OBJECT(dev)), prop->name, value); 951 break; 952 case 0: 953 break; 954 } 955 } 956 957 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value) 958 { 959 object_property_set_bool(OBJECT(dev), value, name, &error_abort); 960 } 961 962 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value) 963 { 964 object_property_set_int(OBJECT(dev), value, name, &error_abort); 965 } 966 967 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value) 968 { 969 object_property_set_int(OBJECT(dev), value, name, &error_abort); 970 } 971 972 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value) 973 { 974 object_property_set_int(OBJECT(dev), value, name, &error_abort); 975 } 976 977 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value) 978 { 979 object_property_set_int(OBJECT(dev), value, name, &error_abort); 980 } 981 982 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value) 983 { 984 object_property_set_int(OBJECT(dev), value, name, &error_abort); 985 } 986 987 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value) 988 { 989 object_property_set_str(OBJECT(dev), value, name, &error_abort); 990 } 991 992 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value) 993 { 994 char str[2 * 6 + 5 + 1]; 995 snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", 996 value[0], value[1], value[2], value[3], value[4], value[5]); 997 998 object_property_set_str(OBJECT(dev), str, name, &error_abort); 999 } 1000 1001 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value) 1002 { 1003 Property *prop; 1004 1005 prop = qdev_prop_find(dev, name); 1006 object_property_set_str(OBJECT(dev), prop->info->enum_table[value], 1007 name, &error_abort); 1008 } 1009 1010 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value) 1011 { 1012 Property *prop; 1013 void **ptr; 1014 1015 prop = qdev_prop_find(dev, name); 1016 assert(prop && prop->info == &qdev_prop_ptr); 1017 ptr = qdev_get_prop_ptr(dev, prop); 1018 *ptr = value; 1019 } 1020 1021 static QTAILQ_HEAD(, GlobalProperty) global_props = 1022 QTAILQ_HEAD_INITIALIZER(global_props); 1023 1024 void qdev_prop_register_global(GlobalProperty *prop) 1025 { 1026 QTAILQ_INSERT_TAIL(&global_props, prop, next); 1027 } 1028 1029 void qdev_prop_register_global_list(GlobalProperty *props) 1030 { 1031 int i; 1032 1033 for (i = 0; props[i].driver != NULL; i++) { 1034 qdev_prop_register_global(props+i); 1035 } 1036 } 1037 1038 int qdev_prop_check_globals(void) 1039 { 1040 GlobalProperty *prop; 1041 int ret = 0; 1042 1043 QTAILQ_FOREACH(prop, &global_props, next) { 1044 ObjectClass *oc; 1045 DeviceClass *dc; 1046 if (prop->used) { 1047 continue; 1048 } 1049 if (!prop->user_provided) { 1050 continue; 1051 } 1052 oc = object_class_by_name(prop->driver); 1053 oc = object_class_dynamic_cast(oc, TYPE_DEVICE); 1054 if (!oc) { 1055 error_report("Warning: global %s.%s has invalid class name", 1056 prop->driver, prop->property); 1057 ret = 1; 1058 continue; 1059 } 1060 dc = DEVICE_CLASS(oc); 1061 if (!dc->hotpluggable && !prop->used) { 1062 error_report("Warning: global %s.%s=%s not used", 1063 prop->driver, prop->property, prop->value); 1064 ret = 1; 1065 continue; 1066 } 1067 } 1068 return ret; 1069 } 1070 1071 static void qdev_prop_set_globals_for_type(DeviceState *dev, 1072 const char *typename) 1073 { 1074 GlobalProperty *prop; 1075 1076 QTAILQ_FOREACH(prop, &global_props, next) { 1077 Error *err = NULL; 1078 1079 if (strcmp(typename, prop->driver) != 0) { 1080 continue; 1081 } 1082 prop->used = true; 1083 object_property_parse(OBJECT(dev), prop->value, prop->property, &err); 1084 if (err != NULL) { 1085 assert(prop->user_provided); 1086 error_reportf_err(err, "Warning: global %s.%s=%s ignored: ", 1087 prop->driver, prop->property, prop->value); 1088 return; 1089 } 1090 } 1091 } 1092 1093 void qdev_prop_set_globals(DeviceState *dev) 1094 { 1095 ObjectClass *class = object_get_class(OBJECT(dev)); 1096 1097 do { 1098 qdev_prop_set_globals_for_type(dev, object_class_get_name(class)); 1099 class = object_class_get_parent(class); 1100 } while (class); 1101 } 1102 1103 /* --- 64bit unsigned int 'size' type --- */ 1104 1105 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque, 1106 Error **errp) 1107 { 1108 DeviceState *dev = DEVICE(obj); 1109 Property *prop = opaque; 1110 uint64_t *ptr = qdev_get_prop_ptr(dev, prop); 1111 1112 visit_type_size(v, name, ptr, errp); 1113 } 1114 1115 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque, 1116 Error **errp) 1117 { 1118 DeviceState *dev = DEVICE(obj); 1119 Property *prop = opaque; 1120 uint64_t *ptr = qdev_get_prop_ptr(dev, prop); 1121 1122 visit_type_size(v, name, ptr, errp); 1123 } 1124 1125 PropertyInfo qdev_prop_size = { 1126 .name = "size", 1127 .get = get_size, 1128 .set = set_size, 1129 }; 1130