1 /* 2 * Dynamic device configuration and creation. 3 * 4 * Copyright (c) 2009 CodeSourcery 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 /* The theory here is that it should be possible to create a machine without 21 knowledge of specific devices. Historically board init routines have 22 passed a bunch of arguments to each device, requiring the board know 23 exactly which device it is dealing with. This file provides an abstract 24 API for device configuration and initialization. Devices will generally 25 inherit from a particular bus (e.g. PCI or I2C) rather than 26 this API directly. */ 27 28 #include "qemu/osdep.h" 29 #include "qapi/error.h" 30 #include "qapi/qapi-events-qdev.h" 31 #include "qapi/qmp/qdict.h" 32 #include "qapi/visitor.h" 33 #include "qemu/error-report.h" 34 #include "qemu/option.h" 35 #include "hw/irq.h" 36 #include "hw/qdev-properties.h" 37 #include "hw/boards.h" 38 #include "hw/sysbus.h" 39 #include "hw/qdev-clock.h" 40 #include "migration/vmstate.h" 41 #include "trace.h" 42 43 static bool qdev_hot_added = false; 44 bool qdev_hot_removed = false; 45 46 const VMStateDescription *qdev_get_vmsd(DeviceState *dev) 47 { 48 DeviceClass *dc = DEVICE_GET_CLASS(dev); 49 return dc->vmsd; 50 } 51 52 static void bus_free_bus_child(BusChild *kid) 53 { 54 object_unref(OBJECT(kid->child)); 55 g_free(kid); 56 } 57 58 static void bus_remove_child(BusState *bus, DeviceState *child) 59 { 60 BusChild *kid; 61 62 QTAILQ_FOREACH(kid, &bus->children, sibling) { 63 if (kid->child == child) { 64 char name[32]; 65 66 snprintf(name, sizeof(name), "child[%d]", kid->index); 67 QTAILQ_REMOVE_RCU(&bus->children, kid, sibling); 68 69 bus->num_children--; 70 71 /* This gives back ownership of kid->child back to us. */ 72 object_property_del(OBJECT(bus), name); 73 74 /* free the bus kid, when it is safe to do so*/ 75 call_rcu(kid, bus_free_bus_child, rcu); 76 break; 77 } 78 } 79 } 80 81 static void bus_add_child(BusState *bus, DeviceState *child) 82 { 83 char name[32]; 84 BusChild *kid = g_malloc0(sizeof(*kid)); 85 86 bus->num_children++; 87 kid->index = bus->max_index++; 88 kid->child = child; 89 object_ref(OBJECT(kid->child)); 90 91 QTAILQ_INSERT_HEAD_RCU(&bus->children, kid, sibling); 92 93 /* This transfers ownership of kid->child to the property. */ 94 snprintf(name, sizeof(name), "child[%d]", kid->index); 95 object_property_add_link(OBJECT(bus), name, 96 object_get_typename(OBJECT(child)), 97 (Object **)&kid->child, 98 NULL, /* read-only property */ 99 0); 100 } 101 102 static bool bus_check_address(BusState *bus, DeviceState *child, Error **errp) 103 { 104 BusClass *bc = BUS_GET_CLASS(bus); 105 return !bc->check_address || bc->check_address(bus, child, errp); 106 } 107 108 bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp) 109 { 110 BusState *old_parent_bus = dev->parent_bus; 111 DeviceClass *dc = DEVICE_GET_CLASS(dev); 112 113 assert(dc->bus_type && object_dynamic_cast(OBJECT(bus), dc->bus_type)); 114 115 if (!bus_check_address(bus, dev, errp)) { 116 return false; 117 } 118 119 if (old_parent_bus) { 120 trace_qdev_update_parent_bus(dev, object_get_typename(OBJECT(dev)), 121 old_parent_bus, object_get_typename(OBJECT(old_parent_bus)), 122 OBJECT(bus), object_get_typename(OBJECT(bus))); 123 /* 124 * Keep a reference to the device while it's not plugged into 125 * any bus, to avoid it potentially evaporating when it is 126 * dereffed in bus_remove_child(). 127 * Also keep the ref of the parent bus until the end, so that 128 * we can safely call resettable_change_parent() below. 129 */ 130 object_ref(OBJECT(dev)); 131 bus_remove_child(dev->parent_bus, dev); 132 } 133 dev->parent_bus = bus; 134 object_ref(OBJECT(bus)); 135 bus_add_child(bus, dev); 136 if (dev->realized) { 137 resettable_change_parent(OBJECT(dev), OBJECT(bus), 138 OBJECT(old_parent_bus)); 139 } 140 if (old_parent_bus) { 141 object_unref(OBJECT(old_parent_bus)); 142 object_unref(OBJECT(dev)); 143 } 144 return true; 145 } 146 147 DeviceState *qdev_new(const char *name) 148 { 149 return DEVICE(object_new(name)); 150 } 151 152 DeviceState *qdev_try_new(const char *name) 153 { 154 ObjectClass *oc = module_object_class_by_name(name); 155 if (!oc) { 156 return NULL; 157 } 158 return DEVICE(object_new_with_class(oc)); 159 } 160 161 static QTAILQ_HEAD(, DeviceListener) device_listeners 162 = QTAILQ_HEAD_INITIALIZER(device_listeners); 163 164 enum ListenerDirection { Forward, Reverse }; 165 166 #define DEVICE_LISTENER_CALL(_callback, _direction, _args...) \ 167 do { \ 168 DeviceListener *_listener; \ 169 \ 170 switch (_direction) { \ 171 case Forward: \ 172 QTAILQ_FOREACH(_listener, &device_listeners, link) { \ 173 if (_listener->_callback) { \ 174 _listener->_callback(_listener, ##_args); \ 175 } \ 176 } \ 177 break; \ 178 case Reverse: \ 179 QTAILQ_FOREACH_REVERSE(_listener, &device_listeners, \ 180 link) { \ 181 if (_listener->_callback) { \ 182 _listener->_callback(_listener, ##_args); \ 183 } \ 184 } \ 185 break; \ 186 default: \ 187 abort(); \ 188 } \ 189 } while (0) 190 191 static int device_listener_add(DeviceState *dev, void *opaque) 192 { 193 DEVICE_LISTENER_CALL(realize, Forward, dev); 194 195 return 0; 196 } 197 198 void device_listener_register(DeviceListener *listener) 199 { 200 QTAILQ_INSERT_TAIL(&device_listeners, listener, link); 201 202 qbus_walk_children(sysbus_get_default(), NULL, NULL, device_listener_add, 203 NULL, NULL); 204 } 205 206 void device_listener_unregister(DeviceListener *listener) 207 { 208 QTAILQ_REMOVE(&device_listeners, listener, link); 209 } 210 211 bool qdev_should_hide_device(const QDict *opts, bool from_json, Error **errp) 212 { 213 ERRP_GUARD(); 214 DeviceListener *listener; 215 216 QTAILQ_FOREACH(listener, &device_listeners, link) { 217 if (listener->hide_device) { 218 if (listener->hide_device(listener, opts, from_json, errp)) { 219 return true; 220 } else if (*errp) { 221 return false; 222 } 223 } 224 } 225 226 return false; 227 } 228 229 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id, 230 int required_for_version) 231 { 232 assert(!dev->realized); 233 dev->instance_id_alias = alias_id; 234 dev->alias_required_for_version = required_for_version; 235 } 236 237 void device_cold_reset(DeviceState *dev) 238 { 239 resettable_reset(OBJECT(dev), RESET_TYPE_COLD); 240 } 241 242 bool device_is_in_reset(DeviceState *dev) 243 { 244 return resettable_is_in_reset(OBJECT(dev)); 245 } 246 247 static ResettableState *device_get_reset_state(Object *obj) 248 { 249 DeviceState *dev = DEVICE(obj); 250 return &dev->reset; 251 } 252 253 static void device_reset_child_foreach(Object *obj, ResettableChildCallback cb, 254 void *opaque, ResetType type) 255 { 256 DeviceState *dev = DEVICE(obj); 257 BusState *bus; 258 259 QLIST_FOREACH(bus, &dev->child_bus, sibling) { 260 cb(OBJECT(bus), opaque, type); 261 } 262 } 263 264 bool qdev_realize(DeviceState *dev, BusState *bus, Error **errp) 265 { 266 assert(!dev->realized && !dev->parent_bus); 267 268 if (bus) { 269 if (!qdev_set_parent_bus(dev, bus, errp)) { 270 return false; 271 } 272 } else { 273 assert(!DEVICE_GET_CLASS(dev)->bus_type); 274 } 275 276 return object_property_set_bool(OBJECT(dev), "realized", true, errp); 277 } 278 279 bool qdev_realize_and_unref(DeviceState *dev, BusState *bus, Error **errp) 280 { 281 bool ret; 282 283 ret = qdev_realize(dev, bus, errp); 284 object_unref(OBJECT(dev)); 285 return ret; 286 } 287 288 void qdev_unrealize(DeviceState *dev) 289 { 290 object_property_set_bool(OBJECT(dev), "realized", false, &error_abort); 291 } 292 293 static int qdev_assert_realized_properly_cb(Object *obj, void *opaque) 294 { 295 DeviceState *dev = DEVICE(object_dynamic_cast(obj, TYPE_DEVICE)); 296 DeviceClass *dc; 297 298 if (dev) { 299 dc = DEVICE_GET_CLASS(dev); 300 assert(dev->realized); 301 assert(dev->parent_bus || !dc->bus_type); 302 } 303 return 0; 304 } 305 306 void qdev_assert_realized_properly(void) 307 { 308 object_child_foreach_recursive(object_get_root(), 309 qdev_assert_realized_properly_cb, NULL); 310 } 311 312 bool qdev_machine_modified(void) 313 { 314 return qdev_hot_added || qdev_hot_removed; 315 } 316 317 BusState *qdev_get_parent_bus(const DeviceState *dev) 318 { 319 return dev->parent_bus; 320 } 321 322 BusState *qdev_get_child_bus(DeviceState *dev, const char *name) 323 { 324 BusState *bus; 325 Object *child = object_resolve_path_component(OBJECT(dev), name); 326 327 bus = (BusState *)object_dynamic_cast(child, TYPE_BUS); 328 if (bus) { 329 return bus; 330 } 331 332 QLIST_FOREACH(bus, &dev->child_bus, sibling) { 333 if (strcmp(name, bus->name) == 0) { 334 return bus; 335 } 336 } 337 return NULL; 338 } 339 340 int qdev_walk_children(DeviceState *dev, 341 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn, 342 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn, 343 void *opaque) 344 { 345 BusState *bus; 346 int err; 347 348 if (pre_devfn) { 349 err = pre_devfn(dev, opaque); 350 if (err) { 351 return err; 352 } 353 } 354 355 QLIST_FOREACH(bus, &dev->child_bus, sibling) { 356 err = qbus_walk_children(bus, pre_devfn, pre_busfn, 357 post_devfn, post_busfn, opaque); 358 if (err < 0) { 359 return err; 360 } 361 } 362 363 if (post_devfn) { 364 err = post_devfn(dev, opaque); 365 if (err) { 366 return err; 367 } 368 } 369 370 return 0; 371 } 372 373 DeviceState *qdev_find_recursive(BusState *bus, const char *id) 374 { 375 BusChild *kid; 376 DeviceState *ret; 377 BusState *child; 378 379 WITH_RCU_READ_LOCK_GUARD() { 380 QTAILQ_FOREACH_RCU(kid, &bus->children, sibling) { 381 DeviceState *dev = kid->child; 382 383 if (dev->id && strcmp(dev->id, id) == 0) { 384 return dev; 385 } 386 387 QLIST_FOREACH(child, &dev->child_bus, sibling) { 388 ret = qdev_find_recursive(child, id); 389 if (ret) { 390 return ret; 391 } 392 } 393 } 394 } 395 return NULL; 396 } 397 398 char *qdev_get_dev_path(DeviceState *dev) 399 { 400 BusClass *bc; 401 402 if (!dev || !dev->parent_bus) { 403 return NULL; 404 } 405 406 bc = BUS_GET_CLASS(dev->parent_bus); 407 if (bc->get_dev_path) { 408 return bc->get_dev_path(dev); 409 } 410 411 return NULL; 412 } 413 414 void qdev_add_unplug_blocker(DeviceState *dev, Error *reason) 415 { 416 dev->unplug_blockers = g_slist_prepend(dev->unplug_blockers, reason); 417 } 418 419 void qdev_del_unplug_blocker(DeviceState *dev, Error *reason) 420 { 421 dev->unplug_blockers = g_slist_remove(dev->unplug_blockers, reason); 422 } 423 424 bool qdev_unplug_blocked(DeviceState *dev, Error **errp) 425 { 426 if (dev->unplug_blockers) { 427 error_propagate(errp, error_copy(dev->unplug_blockers->data)); 428 return true; 429 } 430 431 return false; 432 } 433 434 static bool device_get_realized(Object *obj, Error **errp) 435 { 436 DeviceState *dev = DEVICE(obj); 437 return dev->realized; 438 } 439 440 static bool check_only_migratable(Object *obj, Error **errp) 441 { 442 DeviceClass *dc = DEVICE_GET_CLASS(obj); 443 444 if (!vmstate_check_only_migratable(dc->vmsd)) { 445 error_setg(errp, "Device %s is not migratable, but " 446 "--only-migratable was specified", 447 object_get_typename(obj)); 448 return false; 449 } 450 451 return true; 452 } 453 454 static void device_set_realized(Object *obj, bool value, Error **errp) 455 { 456 DeviceState *dev = DEVICE(obj); 457 DeviceClass *dc = DEVICE_GET_CLASS(dev); 458 HotplugHandler *hotplug_ctrl; 459 BusState *bus; 460 NamedClockList *ncl; 461 Error *local_err = NULL; 462 bool unattached_parent = false; 463 static int unattached_count; 464 465 if (dev->hotplugged && !dc->hotpluggable) { 466 error_setg(errp, "Device '%s' does not support hotplugging", 467 object_get_typename(obj)); 468 return; 469 } 470 471 if (value && !dev->realized) { 472 if (!check_only_migratable(obj, errp)) { 473 goto fail; 474 } 475 476 if (!obj->parent) { 477 gchar *name = g_strdup_printf("device[%d]", unattached_count++); 478 479 object_property_add_child(container_get(qdev_get_machine(), 480 "/unattached"), 481 name, obj); 482 unattached_parent = true; 483 g_free(name); 484 } 485 486 hotplug_ctrl = qdev_get_hotplug_handler(dev); 487 if (hotplug_ctrl) { 488 hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err); 489 if (local_err != NULL) { 490 goto fail; 491 } 492 } 493 494 if (dc->realize) { 495 dc->realize(dev, &local_err); 496 if (local_err != NULL) { 497 goto fail; 498 } 499 } 500 501 DEVICE_LISTENER_CALL(realize, Forward, dev); 502 503 /* 504 * always free/re-initialize here since the value cannot be cleaned up 505 * in device_unrealize due to its usage later on in the unplug path 506 */ 507 g_free(dev->canonical_path); 508 dev->canonical_path = object_get_canonical_path(OBJECT(dev)); 509 QLIST_FOREACH(ncl, &dev->clocks, node) { 510 if (ncl->alias) { 511 continue; 512 } else { 513 clock_setup_canonical_path(ncl->clock); 514 } 515 } 516 517 if (qdev_get_vmsd(dev)) { 518 if (vmstate_register_with_alias_id(VMSTATE_IF(dev), 519 VMSTATE_INSTANCE_ID_ANY, 520 qdev_get_vmsd(dev), dev, 521 dev->instance_id_alias, 522 dev->alias_required_for_version, 523 &local_err) < 0) { 524 goto post_realize_fail; 525 } 526 } 527 528 /* 529 * Clear the reset state, in case the object was previously unrealized 530 * with a dirty state. 531 */ 532 resettable_state_clear(&dev->reset); 533 534 QLIST_FOREACH(bus, &dev->child_bus, sibling) { 535 if (!qbus_realize(bus, errp)) { 536 goto child_realize_fail; 537 } 538 } 539 if (dev->hotplugged) { 540 /* 541 * Reset the device, as well as its subtree which, at this point, 542 * should be realized too. 543 */ 544 resettable_assert_reset(OBJECT(dev), RESET_TYPE_COLD); 545 resettable_change_parent(OBJECT(dev), OBJECT(dev->parent_bus), 546 NULL); 547 resettable_release_reset(OBJECT(dev), RESET_TYPE_COLD); 548 } 549 dev->pending_deleted_event = false; 550 551 if (hotplug_ctrl) { 552 hotplug_handler_plug(hotplug_ctrl, dev, &local_err); 553 if (local_err != NULL) { 554 goto child_realize_fail; 555 } 556 } 557 558 qatomic_store_release(&dev->realized, value); 559 560 } else if (!value && dev->realized) { 561 562 /* 563 * Change the value so that any concurrent users are aware 564 * that the device is going to be unrealized 565 * 566 * TODO: change .realized property to enum that states 567 * each phase of the device realization/unrealization 568 */ 569 570 qatomic_set(&dev->realized, value); 571 /* 572 * Ensure that concurrent users see this update prior to 573 * any other changes done by unrealize. 574 */ 575 smp_wmb(); 576 577 QLIST_FOREACH(bus, &dev->child_bus, sibling) { 578 qbus_unrealize(bus); 579 } 580 if (qdev_get_vmsd(dev)) { 581 vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev); 582 } 583 if (dc->unrealize) { 584 dc->unrealize(dev); 585 } 586 dev->pending_deleted_event = true; 587 DEVICE_LISTENER_CALL(unrealize, Reverse, dev); 588 } 589 590 assert(local_err == NULL); 591 return; 592 593 child_realize_fail: 594 QLIST_FOREACH(bus, &dev->child_bus, sibling) { 595 qbus_unrealize(bus); 596 } 597 598 if (qdev_get_vmsd(dev)) { 599 vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev); 600 } 601 602 post_realize_fail: 603 g_free(dev->canonical_path); 604 dev->canonical_path = NULL; 605 if (dc->unrealize) { 606 dc->unrealize(dev); 607 } 608 609 fail: 610 error_propagate(errp, local_err); 611 if (unattached_parent) { 612 /* 613 * Beware, this doesn't just revert 614 * object_property_add_child(), it also runs bus_remove()! 615 */ 616 object_unparent(OBJECT(dev)); 617 unattached_count--; 618 } 619 } 620 621 static bool device_get_hotpluggable(Object *obj, Error **errp) 622 { 623 DeviceClass *dc = DEVICE_GET_CLASS(obj); 624 DeviceState *dev = DEVICE(obj); 625 626 return dc->hotpluggable && (dev->parent_bus == NULL || 627 qbus_is_hotpluggable(dev->parent_bus)); 628 } 629 630 static bool device_get_hotplugged(Object *obj, Error **errp) 631 { 632 DeviceState *dev = DEVICE(obj); 633 634 return dev->hotplugged; 635 } 636 637 static void device_initfn(Object *obj) 638 { 639 DeviceState *dev = DEVICE(obj); 640 641 if (phase_check(PHASE_MACHINE_READY)) { 642 dev->hotplugged = 1; 643 qdev_hot_added = true; 644 } 645 646 dev->instance_id_alias = -1; 647 dev->realized = false; 648 dev->allow_unplug_during_migration = false; 649 650 QLIST_INIT(&dev->gpios); 651 QLIST_INIT(&dev->clocks); 652 } 653 654 static void device_post_init(Object *obj) 655 { 656 /* 657 * Note: ordered so that the user's global properties take 658 * precedence. 659 */ 660 object_apply_compat_props(obj); 661 qdev_prop_set_globals(DEVICE(obj)); 662 } 663 664 /* Unlink device from bus and free the structure. */ 665 static void device_finalize(Object *obj) 666 { 667 NamedGPIOList *ngl, *next; 668 669 DeviceState *dev = DEVICE(obj); 670 671 g_assert(!dev->unplug_blockers); 672 673 QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) { 674 QLIST_REMOVE(ngl, node); 675 qemu_free_irqs(ngl->in, ngl->num_in); 676 g_free(ngl->name); 677 g_free(ngl); 678 /* ngl->out irqs are owned by the other end and should not be freed 679 * here 680 */ 681 } 682 683 qdev_finalize_clocklist(dev); 684 685 /* Only send event if the device had been completely realized */ 686 if (dev->pending_deleted_event) { 687 g_assert(dev->canonical_path); 688 689 qapi_event_send_device_deleted(dev->id, dev->canonical_path); 690 g_free(dev->canonical_path); 691 dev->canonical_path = NULL; 692 } 693 694 qobject_unref(dev->opts); 695 g_free(dev->id); 696 } 697 698 static void device_class_base_init(ObjectClass *class, void *data) 699 { 700 DeviceClass *klass = DEVICE_CLASS(class); 701 702 /* We explicitly look up properties in the superclasses, 703 * so do not propagate them to the subclasses. 704 */ 705 klass->props_ = NULL; 706 } 707 708 static void device_unparent(Object *obj) 709 { 710 DeviceState *dev = DEVICE(obj); 711 BusState *bus; 712 713 if (dev->realized) { 714 qdev_unrealize(dev); 715 } 716 while (dev->num_child_bus) { 717 bus = QLIST_FIRST(&dev->child_bus); 718 object_unparent(OBJECT(bus)); 719 } 720 if (dev->parent_bus) { 721 bus_remove_child(dev->parent_bus, dev); 722 object_unref(OBJECT(dev->parent_bus)); 723 dev->parent_bus = NULL; 724 } 725 } 726 727 static char * 728 device_vmstate_if_get_id(VMStateIf *obj) 729 { 730 DeviceState *dev = DEVICE(obj); 731 732 return qdev_get_dev_path(dev); 733 } 734 735 static void device_class_init(ObjectClass *class, void *data) 736 { 737 DeviceClass *dc = DEVICE_CLASS(class); 738 VMStateIfClass *vc = VMSTATE_IF_CLASS(class); 739 ResettableClass *rc = RESETTABLE_CLASS(class); 740 741 class->unparent = device_unparent; 742 743 /* by default all devices were considered as hotpluggable, 744 * so with intent to check it in generic qdev_unplug() / 745 * device_set_realized() functions make every device 746 * hotpluggable. Devices that shouldn't be hotpluggable, 747 * should override it in their class_init() 748 */ 749 dc->hotpluggable = true; 750 dc->user_creatable = true; 751 vc->get_id = device_vmstate_if_get_id; 752 rc->get_state = device_get_reset_state; 753 rc->child_foreach = device_reset_child_foreach; 754 755 /* 756 * A NULL legacy_reset implies a three-phase reset device. Devices can 757 * only be reset using three-phase aware mechanisms, but we still support 758 * for transitional purposes leaf classes which set the old legacy_reset 759 * method via device_class_set_legacy_reset(). 760 */ 761 dc->legacy_reset = NULL; 762 763 object_class_property_add_bool(class, "realized", 764 device_get_realized, device_set_realized); 765 object_class_property_add_bool(class, "hotpluggable", 766 device_get_hotpluggable, NULL); 767 object_class_property_add_bool(class, "hotplugged", 768 device_get_hotplugged, NULL); 769 object_class_property_add_link(class, "parent_bus", TYPE_BUS, 770 offsetof(DeviceState, parent_bus), NULL, 0); 771 } 772 773 static void do_legacy_reset(Object *obj, ResetType type) 774 { 775 DeviceClass *dc = DEVICE_GET_CLASS(obj); 776 777 dc->legacy_reset(DEVICE(obj)); 778 } 779 780 void device_class_set_legacy_reset(DeviceClass *dc, DeviceReset dev_reset) 781 { 782 /* 783 * A legacy DeviceClass::reset has identical semantics to the 784 * three-phase "hold" method, with no "enter" or "exit" 785 * behaviour. Classes that use this legacy function must be leaf 786 * classes that do not chain up to their parent class reset. 787 * There is no mechanism for resetting a device that does not 788 * use the three-phase APIs, so the only place which calls 789 * the legacy_reset hook is do_legacy_reset(). 790 */ 791 ResettableClass *rc = RESETTABLE_CLASS(dc); 792 793 rc->phases.enter = NULL; 794 rc->phases.hold = do_legacy_reset; 795 rc->phases.exit = NULL; 796 dc->legacy_reset = dev_reset; 797 } 798 799 void device_class_set_parent_realize(DeviceClass *dc, 800 DeviceRealize dev_realize, 801 DeviceRealize *parent_realize) 802 { 803 *parent_realize = dc->realize; 804 dc->realize = dev_realize; 805 } 806 807 void device_class_set_parent_unrealize(DeviceClass *dc, 808 DeviceUnrealize dev_unrealize, 809 DeviceUnrealize *parent_unrealize) 810 { 811 *parent_unrealize = dc->unrealize; 812 dc->unrealize = dev_unrealize; 813 } 814 815 Object *qdev_get_machine(void) 816 { 817 static Object *dev; 818 819 if (dev == NULL) { 820 dev = container_get(object_get_root(), "/machine"); 821 } 822 823 return dev; 824 } 825 826 char *qdev_get_human_name(DeviceState *dev) 827 { 828 g_assert(dev != NULL); 829 830 return dev->id ? 831 g_strdup(dev->id) : object_get_canonical_path(OBJECT(dev)); 832 } 833 834 static MachineInitPhase machine_phase; 835 836 bool phase_check(MachineInitPhase phase) 837 { 838 return machine_phase >= phase; 839 } 840 841 void phase_advance(MachineInitPhase phase) 842 { 843 assert(machine_phase == phase - 1); 844 machine_phase = phase; 845 } 846 847 static const TypeInfo device_type_info = { 848 .name = TYPE_DEVICE, 849 .parent = TYPE_OBJECT, 850 .instance_size = sizeof(DeviceState), 851 .instance_init = device_initfn, 852 .instance_post_init = device_post_init, 853 .instance_finalize = device_finalize, 854 .class_base_init = device_class_base_init, 855 .class_init = device_class_init, 856 .abstract = true, 857 .class_size = sizeof(DeviceClass), 858 .interfaces = (InterfaceInfo[]) { 859 { TYPE_VMSTATE_IF }, 860 { TYPE_RESETTABLE_INTERFACE }, 861 { } 862 } 863 }; 864 865 static void qdev_register_types(void) 866 { 867 type_register_static(&device_type_info); 868 } 869 870 type_init(qdev_register_types) 871