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