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