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