@@ -102,6 +102,8 @@ struct I6300State {
typedef struct I6300State I6300State;
+static void i6300esb_reset(DeviceState *dev);
+
/* This function is called when the watchdog has either been enabled
* (hence it starts counting down) or has been keep-alived.
*/
@@ -140,16 +142,6 @@ static void i6300esb_disable_timer(I6300State *d)
qemu_del_timer(d->timer);
}
-static void i6300esb_reset(I6300State *d)
-{
- /* XXX We should probably reset other parts of the state here,
- * but we should also reset our state on general machine reset
- * too. For now just disable the timer so it doesn't fire
- * again after the reboot.
- */
- i6300esb_disable_timer(d);
-}
-
/* This function is called when the watchdog expires. Note that
* the hardware has two timers, and so expiry happens in two stages.
* If d->stage == 1 then we perform the first stage action (usually,
@@ -181,7 +173,7 @@ static void i6300esb_timer_expired(void *vp)
if (d->reboot_enabled) {
d->previous_reboot_flag = 1;
watchdog_perform_action(); /* This reboots, exits, etc */
- i6300esb_reset(d);
+ i6300esb_reset(&d->dev.qdev);
}
/* In "free running mode" we start stage 1 again. */
@@ -394,17 +386,9 @@ static int i6300esb_init(PCIDevice *dev)
I6300State *d = DO_UPCAST(I6300State, dev, dev);
uint8_t *pci_conf;
- d->reboot_enabled = 1;
- d->clock_scale = CLOCK_SCALE_1KHZ;
- d->int_type = INT_TYPE_IRQ;
- d->free_run = 0;
- d->locked = 0;
- d->enabled = 0;
+ i6300esb_debug("watchdog init\n");
+
d->timer = qemu_new_timer(vm_clock, i6300esb_timer_expired, d);
- d->timer1_preload = 0xfffff;
- d->timer2_preload = 0xfffff;
- d->stage = 1;
- d->unlock_state = 0;
d->previous_reboot_flag = 0;
pci_conf = d->dev.config;
@@ -413,11 +397,33 @@ static int i6300esb_init(PCIDevice *dev)
pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER);
pci_register_bar(&d->dev, 0, 0x10,
- PCI_BASE_ADDRESS_SPACE_MEMORY, i6300esb_map);
+ PCI_BASE_ADDRESS_SPACE_MEMORY, i6300esb_map);
return 0;
}
+static void i6300esb_reset(DeviceState *dev)
+{
+ I6300State *d = DO_UPCAST(I6300State, dev.qdev, dev);
+
+ i6300esb_debug("watchdog reset\n");
+
+ /* NB: Don't change d->previous_reboot_flag in this function. */
+
+ d->reboot_enabled = 1;
+ d->clock_scale = CLOCK_SCALE_1KHZ;
+ d->int_type = INT_TYPE_IRQ;
+ d->free_run = 0;
+ d->locked = 0;
+ d->enabled = 0;
+ d->timer1_preload = 0xfffff;
+ d->timer2_preload = 0xfffff;
+ d->stage = 1;
+ d->unlock_state = 0;
+
+ i6300esb_disable_timer(d);
+}
+
static WatchdogTimerModel model = {
.wdt_name = "i6300esb",
.wdt_description = "Intel 6300ESB",
@@ -427,6 +433,7 @@ static PCIDeviceInfo i6300esb_info = {
.qdev.name = "i6300esb",
.qdev.size = sizeof(I6300State),
.qdev.vmsd = &vmstate_i6300esb,
+ .qdev.reset = i6300esb_reset,
.config_read = i6300esb_config_read,
.config_write = i6300esb_config_write,
.init = i6300esb_init,
@@ -97,6 +97,8 @@ static int wdt_ib700_init(ISADevice *dev)
{
IB700State *s = DO_UPCAST(IB700State, dev, dev);
+ ib700_debug("watchdog init\n");
+
s->timer = qemu_new_timer(vm_clock, ib700_timer_expired, s);
register_ioport_write(0x441, 2, 1, ib700_write_disable_reg, s);
register_ioport_write(0x443, 2, 1, ib700_write_enable_reg, s);
@@ -104,16 +106,26 @@ static int wdt_ib700_init(ISADevice *dev)
return 0;
}
+static void wdt_ib700_reset(DeviceState *dev)
+{
+ IB700State *s = DO_UPCAST(IB700State, dev.qdev, dev);
+
+ ib700_debug("watchdog reset\n");
+
+ qemu_del_timer(s->timer);
+}
+
static WatchdogTimerModel model = {
.wdt_name = "ib700",
.wdt_description = "iBASE 700",
};
static ISADeviceInfo wdt_ib700_info = {
- .qdev.name = "ib700",
- .qdev.size = sizeof(IB700State),
- .qdev.vmsd = &vmstate_ib700,
- .init = wdt_ib700_init,
+ .qdev.name = "ib700",
+ .qdev.size = sizeof(IB700State),
+ .qdev.vmsd = &vmstate_ib700,
+ .qdev.reset = wdt_ib700_reset,
+ .init = wdt_ib700_init,
};
static void wdt_ib700_register_devices(void)