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 /* --- lost tick policy --- */ 520 521 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int)); 522 523 PropertyInfo qdev_prop_losttickpolicy = { 524 .name = "LostTickPolicy", 525 .enum_table = LostTickPolicy_lookup, 526 .get = get_enum, 527 .set = set_enum, 528 }; 529 530 /* --- BIOS CHS translation */ 531 532 QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int)); 533 534 PropertyInfo qdev_prop_bios_chs_trans = { 535 .name = "BiosAtaTranslation", 536 .description = "Logical CHS translation algorithm, " 537 "auto/none/lba/large/rechs", 538 .enum_table = BiosAtaTranslation_lookup, 539 .get = get_enum, 540 .set = set_enum, 541 }; 542 543 /* --- FDC default drive types */ 544 545 PropertyInfo qdev_prop_fdc_drive_type = { 546 .name = "FdcDriveType", 547 .description = "FDC drive type, " 548 "144/288/120/none/auto", 549 .enum_table = FloppyDriveType_lookup, 550 .get = get_enum, 551 .set = set_enum 552 }; 553 554 /* --- pci address --- */ 555 556 /* 557 * bus-local address, i.e. "$slot" or "$slot.$fn" 558 */ 559 static void set_pci_devfn(Object *obj, Visitor *v, const char *name, 560 void *opaque, Error **errp) 561 { 562 DeviceState *dev = DEVICE(obj); 563 Property *prop = opaque; 564 int32_t value, *ptr = qdev_get_prop_ptr(dev, prop); 565 unsigned int slot, fn, n; 566 Error *local_err = NULL; 567 char *str; 568 569 if (dev->realized) { 570 qdev_prop_set_after_realize(dev, name, errp); 571 return; 572 } 573 574 visit_type_str(v, name, &str, &local_err); 575 if (local_err) { 576 error_free(local_err); 577 local_err = NULL; 578 visit_type_int32(v, name, &value, &local_err); 579 if (local_err) { 580 error_propagate(errp, local_err); 581 } else if (value < -1 || value > 255) { 582 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 583 name ? name : "null", "pci_devfn"); 584 } else { 585 *ptr = value; 586 } 587 return; 588 } 589 590 if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) { 591 fn = 0; 592 if (sscanf(str, "%x%n", &slot, &n) != 1) { 593 goto invalid; 594 } 595 } 596 if (str[n] != '\0' || fn > 7 || slot > 31) { 597 goto invalid; 598 } 599 *ptr = slot << 3 | fn; 600 g_free(str); 601 return; 602 603 invalid: 604 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 605 g_free(str); 606 } 607 608 static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, 609 size_t len) 610 { 611 int32_t *ptr = qdev_get_prop_ptr(dev, prop); 612 613 if (*ptr == -1) { 614 return snprintf(dest, len, "<unset>"); 615 } else { 616 return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7); 617 } 618 } 619 620 PropertyInfo qdev_prop_pci_devfn = { 621 .name = "int32", 622 .description = "Slot and optional function number, example: 06.0 or 06", 623 .print = print_pci_devfn, 624 .get = get_int32, 625 .set = set_pci_devfn, 626 }; 627 628 /* --- blocksize --- */ 629 630 static void set_blocksize(Object *obj, Visitor *v, const char *name, 631 void *opaque, Error **errp) 632 { 633 DeviceState *dev = DEVICE(obj); 634 Property *prop = opaque; 635 uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop); 636 Error *local_err = NULL; 637 const int64_t min = 512; 638 const int64_t max = 32768; 639 640 if (dev->realized) { 641 qdev_prop_set_after_realize(dev, name, errp); 642 return; 643 } 644 645 visit_type_uint16(v, name, &value, &local_err); 646 if (local_err) { 647 error_propagate(errp, local_err); 648 return; 649 } 650 /* value of 0 means "unset" */ 651 if (value && (value < min || value > max)) { 652 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, 653 dev->id ? : "", name, (int64_t)value, min, max); 654 return; 655 } 656 657 /* We rely on power-of-2 blocksizes for bitmasks */ 658 if ((value & (value - 1)) != 0) { 659 error_setg(errp, 660 "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2", 661 dev->id ?: "", name, (int64_t)value); 662 return; 663 } 664 665 *ptr = value; 666 } 667 668 PropertyInfo qdev_prop_blocksize = { 669 .name = "uint16", 670 .description = "A power of two between 512 and 32768", 671 .get = get_uint16, 672 .set = set_blocksize, 673 }; 674 675 /* --- pci host address --- */ 676 677 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name, 678 void *opaque, Error **errp) 679 { 680 DeviceState *dev = DEVICE(obj); 681 Property *prop = opaque; 682 PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop); 683 char buffer[] = "xxxx:xx:xx.x"; 684 char *p = buffer; 685 int rc = 0; 686 687 rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d", 688 addr->domain, addr->bus, addr->slot, addr->function); 689 assert(rc == sizeof(buffer) - 1); 690 691 visit_type_str(v, name, &p, errp); 692 } 693 694 /* 695 * Parse [<domain>:]<bus>:<slot>.<func> 696 * if <domain> is not supplied, it's assumed to be 0. 697 */ 698 static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name, 699 void *opaque, Error **errp) 700 { 701 DeviceState *dev = DEVICE(obj); 702 Property *prop = opaque; 703 PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop); 704 Error *local_err = NULL; 705 char *str, *p; 706 char *e; 707 unsigned long val; 708 unsigned long dom = 0, bus = 0; 709 unsigned int slot = 0, func = 0; 710 711 if (dev->realized) { 712 qdev_prop_set_after_realize(dev, name, errp); 713 return; 714 } 715 716 visit_type_str(v, name, &str, &local_err); 717 if (local_err) { 718 error_propagate(errp, local_err); 719 return; 720 } 721 722 p = str; 723 val = strtoul(p, &e, 16); 724 if (e == p || *e != ':') { 725 goto inval; 726 } 727 bus = val; 728 729 p = e + 1; 730 val = strtoul(p, &e, 16); 731 if (e == p) { 732 goto inval; 733 } 734 if (*e == ':') { 735 dom = bus; 736 bus = val; 737 p = e + 1; 738 val = strtoul(p, &e, 16); 739 if (e == p) { 740 goto inval; 741 } 742 } 743 slot = val; 744 745 if (*e != '.') { 746 goto inval; 747 } 748 p = e + 1; 749 val = strtoul(p, &e, 10); 750 if (e == p) { 751 goto inval; 752 } 753 func = val; 754 755 if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) { 756 goto inval; 757 } 758 759 if (*e) { 760 goto inval; 761 } 762 763 addr->domain = dom; 764 addr->bus = bus; 765 addr->slot = slot; 766 addr->function = func; 767 768 g_free(str); 769 return; 770 771 inval: 772 error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); 773 g_free(str); 774 } 775 776 PropertyInfo qdev_prop_pci_host_devaddr = { 777 .name = "str", 778 .description = "Address (bus/device/function) of " 779 "the host device, example: 04:10.0", 780 .get = get_pci_host_devaddr, 781 .set = set_pci_host_devaddr, 782 }; 783 784 /* --- support for array properties --- */ 785 786 /* Used as an opaque for the object properties we add for each 787 * array element. Note that the struct Property must be first 788 * in the struct so that a pointer to this works as the opaque 789 * for the underlying element's property hooks as well as for 790 * our own release callback. 791 */ 792 typedef struct { 793 struct Property prop; 794 char *propname; 795 ObjectPropertyRelease *release; 796 } ArrayElementProperty; 797 798 /* object property release callback for array element properties: 799 * we call the underlying element's property release hook, and 800 * then free the memory we allocated when we added the property. 801 */ 802 static void array_element_release(Object *obj, const char *name, void *opaque) 803 { 804 ArrayElementProperty *p = opaque; 805 if (p->release) { 806 p->release(obj, name, opaque); 807 } 808 g_free(p->propname); 809 g_free(p); 810 } 811 812 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name, 813 void *opaque, Error **errp) 814 { 815 /* Setter for the property which defines the length of a 816 * variable-sized property array. As well as actually setting the 817 * array-length field in the device struct, we have to create the 818 * array itself and dynamically add the corresponding properties. 819 */ 820 DeviceState *dev = DEVICE(obj); 821 Property *prop = opaque; 822 uint32_t *alenptr = qdev_get_prop_ptr(dev, prop); 823 void **arrayptr = (void *)dev + prop->arrayoffset; 824 Error *local_err = NULL; 825 void *eltptr; 826 const char *arrayname; 827 int i; 828 829 if (dev->realized) { 830 qdev_prop_set_after_realize(dev, name, errp); 831 return; 832 } 833 if (*alenptr) { 834 error_setg(errp, "array size property %s may not be set more than once", 835 name); 836 return; 837 } 838 visit_type_uint32(v, name, alenptr, &local_err); 839 if (local_err) { 840 error_propagate(errp, local_err); 841 return; 842 } 843 if (!*alenptr) { 844 return; 845 } 846 847 /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix; 848 * strip it off so we can get the name of the array itself. 849 */ 850 assert(strncmp(name, PROP_ARRAY_LEN_PREFIX, 851 strlen(PROP_ARRAY_LEN_PREFIX)) == 0); 852 arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX); 853 854 /* Note that it is the responsibility of the individual device's deinit 855 * to free the array proper. 856 */ 857 *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize); 858 for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) { 859 char *propname = g_strdup_printf("%s[%d]", arrayname, i); 860 ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1); 861 arrayprop->release = prop->arrayinfo->release; 862 arrayprop->propname = propname; 863 arrayprop->prop.info = prop->arrayinfo; 864 arrayprop->prop.name = propname; 865 /* This ugly piece of pointer arithmetic sets up the offset so 866 * that when the underlying get/set hooks call qdev_get_prop_ptr 867 * they get the right answer despite the array element not actually 868 * being inside the device struct. 869 */ 870 arrayprop->prop.offset = eltptr - (void *)dev; 871 assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr); 872 object_property_add(obj, propname, 873 arrayprop->prop.info->name, 874 arrayprop->prop.info->get, 875 arrayprop->prop.info->set, 876 array_element_release, 877 arrayprop, &local_err); 878 if (local_err) { 879 error_propagate(errp, local_err); 880 return; 881 } 882 } 883 } 884 885 PropertyInfo qdev_prop_arraylen = { 886 .name = "uint32", 887 .get = get_uint32, 888 .set = set_prop_arraylen, 889 }; 890 891 /* --- public helpers --- */ 892 893 static Property *qdev_prop_walk(Property *props, const char *name) 894 { 895 if (!props) { 896 return NULL; 897 } 898 while (props->name) { 899 if (strcmp(props->name, name) == 0) { 900 return props; 901 } 902 props++; 903 } 904 return NULL; 905 } 906 907 static Property *qdev_prop_find(DeviceState *dev, const char *name) 908 { 909 ObjectClass *class; 910 Property *prop; 911 912 /* device properties */ 913 class = object_get_class(OBJECT(dev)); 914 do { 915 prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name); 916 if (prop) { 917 return prop; 918 } 919 class = object_class_get_parent(class); 920 } while (class != object_class_by_name(TYPE_DEVICE)); 921 922 return NULL; 923 } 924 925 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, 926 Property *prop, const char *value) 927 { 928 switch (ret) { 929 case -EEXIST: 930 error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", 931 object_get_typename(OBJECT(dev)), prop->name, value); 932 break; 933 default: 934 case -EINVAL: 935 error_setg(errp, QERR_PROPERTY_VALUE_BAD, 936 object_get_typename(OBJECT(dev)), prop->name, value); 937 break; 938 case -ENOENT: 939 error_setg(errp, "Property '%s.%s' can't find value '%s'", 940 object_get_typename(OBJECT(dev)), prop->name, value); 941 break; 942 case 0: 943 break; 944 } 945 } 946 947 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value) 948 { 949 object_property_set_bool(OBJECT(dev), value, name, &error_abort); 950 } 951 952 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value) 953 { 954 object_property_set_int(OBJECT(dev), value, name, &error_abort); 955 } 956 957 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value) 958 { 959 object_property_set_int(OBJECT(dev), value, name, &error_abort); 960 } 961 962 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value) 963 { 964 object_property_set_int(OBJECT(dev), value, name, &error_abort); 965 } 966 967 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value) 968 { 969 object_property_set_int(OBJECT(dev), value, name, &error_abort); 970 } 971 972 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value) 973 { 974 object_property_set_int(OBJECT(dev), value, name, &error_abort); 975 } 976 977 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value) 978 { 979 object_property_set_str(OBJECT(dev), value, name, &error_abort); 980 } 981 982 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value) 983 { 984 char str[2 * 6 + 5 + 1]; 985 snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", 986 value[0], value[1], value[2], value[3], value[4], value[5]); 987 988 object_property_set_str(OBJECT(dev), str, name, &error_abort); 989 } 990 991 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value) 992 { 993 Property *prop; 994 995 prop = qdev_prop_find(dev, name); 996 object_property_set_str(OBJECT(dev), prop->info->enum_table[value], 997 name, &error_abort); 998 } 999 1000 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value) 1001 { 1002 Property *prop; 1003 void **ptr; 1004 1005 prop = qdev_prop_find(dev, name); 1006 assert(prop && prop->info == &qdev_prop_ptr); 1007 ptr = qdev_get_prop_ptr(dev, prop); 1008 *ptr = value; 1009 } 1010 1011 static QTAILQ_HEAD(, GlobalProperty) global_props = 1012 QTAILQ_HEAD_INITIALIZER(global_props); 1013 1014 void qdev_prop_register_global(GlobalProperty *prop) 1015 { 1016 QTAILQ_INSERT_TAIL(&global_props, prop, next); 1017 } 1018 1019 void qdev_prop_register_global_list(GlobalProperty *props) 1020 { 1021 int i; 1022 1023 for (i = 0; props[i].driver != NULL; i++) { 1024 qdev_prop_register_global(props+i); 1025 } 1026 } 1027 1028 int qdev_prop_check_globals(void) 1029 { 1030 GlobalProperty *prop; 1031 int ret = 0; 1032 1033 QTAILQ_FOREACH(prop, &global_props, next) { 1034 ObjectClass *oc; 1035 DeviceClass *dc; 1036 if (prop->used) { 1037 continue; 1038 } 1039 if (!prop->user_provided) { 1040 continue; 1041 } 1042 oc = object_class_by_name(prop->driver); 1043 oc = object_class_dynamic_cast(oc, TYPE_DEVICE); 1044 if (!oc) { 1045 error_report("Warning: global %s.%s has invalid class name", 1046 prop->driver, prop->property); 1047 ret = 1; 1048 continue; 1049 } 1050 dc = DEVICE_CLASS(oc); 1051 if (!dc->hotpluggable && !prop->used) { 1052 error_report("Warning: global %s.%s=%s not used", 1053 prop->driver, prop->property, prop->value); 1054 ret = 1; 1055 continue; 1056 } 1057 } 1058 return ret; 1059 } 1060 1061 static void qdev_prop_set_globals_for_type(DeviceState *dev, 1062 const char *typename) 1063 { 1064 GlobalProperty *prop; 1065 1066 QTAILQ_FOREACH(prop, &global_props, next) { 1067 Error *err = NULL; 1068 1069 if (strcmp(typename, prop->driver) != 0) { 1070 continue; 1071 } 1072 prop->used = true; 1073 object_property_parse(OBJECT(dev), prop->value, prop->property, &err); 1074 if (err != NULL) { 1075 assert(prop->user_provided); 1076 error_reportf_err(err, "Warning: global %s.%s=%s ignored: ", 1077 prop->driver, prop->property, prop->value); 1078 return; 1079 } 1080 } 1081 } 1082 1083 void qdev_prop_set_globals(DeviceState *dev) 1084 { 1085 ObjectClass *class = object_get_class(OBJECT(dev)); 1086 1087 do { 1088 qdev_prop_set_globals_for_type(dev, object_class_get_name(class)); 1089 class = object_class_get_parent(class); 1090 } while (class); 1091 } 1092 1093 /* --- 64bit unsigned int 'size' type --- */ 1094 1095 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque, 1096 Error **errp) 1097 { 1098 DeviceState *dev = DEVICE(obj); 1099 Property *prop = opaque; 1100 uint64_t *ptr = qdev_get_prop_ptr(dev, prop); 1101 1102 visit_type_size(v, name, ptr, errp); 1103 } 1104 1105 static void set_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 PropertyInfo qdev_prop_size = { 1116 .name = "size", 1117 .get = get_size, 1118 .set = set_size, 1119 }; 1120