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