Commit e965ffa7 authored by Stefan Hajnoczi's avatar Stefan Hajnoczi Committed by Kevin Wolf
Browse files

qdev: add qdev_add_vm_change_state_handler()



Children sometimes depend on their parent's vm change state handler
having completed.  Add a vm change state handler API for devices that
guarantees tree depth ordering.

Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent 60dbc5a1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ common-obj-$(CONFIG_SOFTMMU) += fw-path-provider.o
common-obj-y += irq.o
common-obj-y += hotplug.o
common-obj-$(CONFIG_SOFTMMU) += nmi.o
common-obj-$(CONFIG_SOFTMMU) += vm-change-state-handler.o

common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
common-obj-$(CONFIG_XILINX_AXI) += stream.o
+61 −0
Original line number Diff line number Diff line
/*
 *  qdev vm change state handlers
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License,
 *  or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "hw/qdev.h"

static int qdev_get_dev_tree_depth(DeviceState *dev)
{
    int depth;

    for (depth = 0; dev; depth++) {
        BusState *bus = dev->parent_bus;

        if (!bus) {
            break;
        }

        dev = bus->parent;
    }

    return depth;
}

/**
 * qdev_add_vm_change_state_handler:
 * @dev: the device that owns this handler
 * @cb: the callback function to be invoked
 * @opaque: user data passed to the callback function
 *
 * This function works like qemu_add_vm_change_state_handler() except callbacks
 * are invoked in qdev tree depth order.  Ordering is desirable when callbacks
 * of children depend on their parent's callback having completed first.
 *
 * For example, when qdev_add_vm_change_state_handler() is used, a host
 * controller's callback is invoked before the children on its bus when the VM
 * starts running.  The order is reversed when the VM stops running.
 *
 * Returns: an entry to be freed with qemu_del_vm_change_state_handler()
 */
VMChangeStateEntry *qdev_add_vm_change_state_handler(DeviceState *dev,
                                                     VMChangeStateHandler *cb,
                                                     void *opaque)
{
    int depth = qdev_get_dev_tree_depth(dev);

    return qemu_add_vm_change_state_handler_prio(cb, opaque, depth);
}
+5 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
#include "qom/object.h"
#include "hw/irq.h"
#include "hw/hotplug.h"
#include "sysemu/sysemu.h"

enum {
    DEV_NVECTORS_UNSPECIFIED = -1,
@@ -450,4 +451,8 @@ static inline bool qbus_is_hotpluggable(BusState *bus)
void device_listener_register(DeviceListener *listener);
void device_listener_unregister(DeviceListener *listener);

VMChangeStateEntry *qdev_add_vm_change_state_handler(DeviceState *dev,
                                                     VMChangeStateHandler *cb,
                                                     void *opaque);

#endif