@@ -311,6 +311,13 @@ static int qdev_reset_one(DeviceState *dev, void *opaque)
return 0;
}
+static int qdev_hot_reset_one(DeviceState *dev, void *opaque)
+{
+ device_hot_reset(dev);
+
+ return 0;
+}
+
static int qbus_reset_one(BusState *bus, void *opaque)
{
BusClass *bc = BUS_GET_CLASS(bus);
@@ -335,6 +342,11 @@ void qbus_reset_all(BusState *bus)
qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
}
+void qbus_hot_reset_all(BusState *bus)
+{
+ qbus_walk_children(bus, NULL, NULL, qdev_hot_reset_one, qbus_reset_one, NULL);
+}
+
void qbus_reset_all_fn(void *opaque)
{
BusState *bus = opaque;
@@ -1284,6 +1296,18 @@ void device_reset(DeviceState *dev)
}
}
+void device_hot_reset(DeviceState *dev)
+{
+ DeviceClass *klass = DEVICE_GET_CLASS(dev);
+
+ if (klass->hot_reset) {
+ klass->hot_reset(dev);
+ return;
+ }
+
+ device_reset(dev);
+}
+
Object *qdev_get_machine(void)
{
static Object *dev;
@@ -268,7 +268,7 @@ void pci_bridge_write_config(PCIDevice *d,
newctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL);
if (~oldctl & newctl & PCI_BRIDGE_CTL_BUS_RESET) {
/* Trigger hot reset on 0->1 transition. */
- qbus_reset_all(&s->sec_bus.qbus);
+ qbus_hot_reset_all(&s->sec_bus.qbus);
}
}
@@ -131,6 +131,7 @@ typedef struct DeviceClass {
/* callbacks */
void (*reset)(DeviceState *dev);
+ void (*hot_reset)(DeviceState *dev);
DeviceRealize realize;
DeviceUnrealize unrealize;
@@ -351,6 +352,7 @@ void qdev_reset_all_fn(void *opaque);
*/
void qbus_reset_all(BusState *bus);
void qbus_reset_all_fn(void *opaque);
+void qbus_hot_reset_all(BusState *bus);
/* This should go away once we get rid of the NULL bus hack */
BusState *sysbus_get_default(void);
@@ -372,6 +374,7 @@ void qdev_machine_init(void);
* Reset a single device (by calling the reset method).
*/
void device_reset(DeviceState *dev);
+void device_hot_reset(DeviceState *dev);
const struct VMStateDescription *qdev_get_vmsd(DeviceState *dev);