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