1e965ffa7SStefan Hajnoczi /* 2e965ffa7SStefan Hajnoczi * qdev vm change state handlers 3e965ffa7SStefan Hajnoczi * 4e965ffa7SStefan Hajnoczi * This program is free software; you can redistribute it and/or modify 5e965ffa7SStefan Hajnoczi * it under the terms of the GNU General Public License as published by 6e965ffa7SStefan Hajnoczi * the Free Software Foundation; either version 2 of the License, 7e965ffa7SStefan Hajnoczi * or (at your option) any later version. 8e965ffa7SStefan Hajnoczi * 9e965ffa7SStefan Hajnoczi * This program is distributed in the hope that it will be useful, 10e965ffa7SStefan Hajnoczi * but WITHOUT ANY WARRANTY; without even the implied warranty of 11e965ffa7SStefan Hajnoczi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12e965ffa7SStefan Hajnoczi * GNU General Public License for more details. 13e965ffa7SStefan Hajnoczi * 14e965ffa7SStefan Hajnoczi * You should have received a copy of the GNU General Public License 15e965ffa7SStefan Hajnoczi * along with this program; if not, see <http://www.gnu.org/licenses/>. 16e965ffa7SStefan Hajnoczi */ 17e965ffa7SStefan Hajnoczi 18e965ffa7SStefan Hajnoczi #include "qemu/osdep.h" 19*a27bd6c7SMarkus Armbruster #include "hw/qdev-core.h" 20e965ffa7SStefan Hajnoczi 21e965ffa7SStefan Hajnoczi static int qdev_get_dev_tree_depth(DeviceState *dev) 22e965ffa7SStefan Hajnoczi { 23e965ffa7SStefan Hajnoczi int depth; 24e965ffa7SStefan Hajnoczi 25e965ffa7SStefan Hajnoczi for (depth = 0; dev; depth++) { 26e965ffa7SStefan Hajnoczi BusState *bus = dev->parent_bus; 27e965ffa7SStefan Hajnoczi 28e965ffa7SStefan Hajnoczi if (!bus) { 29e965ffa7SStefan Hajnoczi break; 30e965ffa7SStefan Hajnoczi } 31e965ffa7SStefan Hajnoczi 32e965ffa7SStefan Hajnoczi dev = bus->parent; 33e965ffa7SStefan Hajnoczi } 34e965ffa7SStefan Hajnoczi 35e965ffa7SStefan Hajnoczi return depth; 36e965ffa7SStefan Hajnoczi } 37e965ffa7SStefan Hajnoczi 38e965ffa7SStefan Hajnoczi /** 39e965ffa7SStefan Hajnoczi * qdev_add_vm_change_state_handler: 40e965ffa7SStefan Hajnoczi * @dev: the device that owns this handler 41e965ffa7SStefan Hajnoczi * @cb: the callback function to be invoked 42e965ffa7SStefan Hajnoczi * @opaque: user data passed to the callback function 43e965ffa7SStefan Hajnoczi * 44e965ffa7SStefan Hajnoczi * This function works like qemu_add_vm_change_state_handler() except callbacks 45e965ffa7SStefan Hajnoczi * are invoked in qdev tree depth order. Ordering is desirable when callbacks 46e965ffa7SStefan Hajnoczi * of children depend on their parent's callback having completed first. 47e965ffa7SStefan Hajnoczi * 48e965ffa7SStefan Hajnoczi * For example, when qdev_add_vm_change_state_handler() is used, a host 49e965ffa7SStefan Hajnoczi * controller's callback is invoked before the children on its bus when the VM 50e965ffa7SStefan Hajnoczi * starts running. The order is reversed when the VM stops running. 51e965ffa7SStefan Hajnoczi * 52e965ffa7SStefan Hajnoczi * Returns: an entry to be freed with qemu_del_vm_change_state_handler() 53e965ffa7SStefan Hajnoczi */ 54e965ffa7SStefan Hajnoczi VMChangeStateEntry *qdev_add_vm_change_state_handler(DeviceState *dev, 55e965ffa7SStefan Hajnoczi VMChangeStateHandler *cb, 56e965ffa7SStefan Hajnoczi void *opaque) 57e965ffa7SStefan Hajnoczi { 58e965ffa7SStefan Hajnoczi int depth = qdev_get_dev_tree_depth(dev); 59e965ffa7SStefan Hajnoczi 60e965ffa7SStefan Hajnoczi return qemu_add_vm_change_state_handler_prio(cb, opaque, depth); 61e965ffa7SStefan Hajnoczi } 62