aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2008-08-15 18:21:58 +0000
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2008-08-15 18:21:58 +0000
commit72c7b06cb7e0cfded2678d531c454fcac16c93c3 (patch)
tree060dc80ddef90c8e91c41ea01949e78f05e1a341
parent414f0dab0970795f043f2396fe9449f69b49b20c (diff)
Cancel IDE outstanding IO on device reset (Gleb Natapov)
Cancel AIO in IDE layer on device rest in order to be in deterministic state during next boot. Signed-off-by: Gleb Natapov <gleb@qumranet.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5011 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--hw/ide.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/hw/ide.c b/hw/ide.c
index f4243c49aa..6b14e8f961 100644
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -2844,6 +2844,23 @@ static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
}
}
+static void ide_dma_cancel(BMDMAState *bm)
+{
+ if (bm->status & BM_STATUS_DMAING) {
+ bm->status &= ~BM_STATUS_DMAING;
+ /* cancel DMA request */
+ bm->ide_if = NULL;
+ bm->dma_cb = NULL;
+ if (bm->aiocb) {
+#ifdef DEBUG_AIO
+ printf("aio_cancel\n");
+#endif
+ bdrv_aio_cancel(bm->aiocb);
+ bm->aiocb = NULL;
+ }
+ }
+}
+
static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
{
BMDMAState *bm = opaque;
@@ -2852,19 +2869,7 @@ static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
#endif
if (!(val & BM_CMD_START)) {
/* XXX: do it better */
- if (bm->status & BM_STATUS_DMAING) {
- bm->status &= ~BM_STATUS_DMAING;
- /* cancel DMA request */
- bm->ide_if = NULL;
- bm->dma_cb = NULL;
- if (bm->aiocb) {
-#ifdef DEBUG_AIO
- printf("aio_cancel\n");
-#endif
- bdrv_aio_cancel(bm->aiocb);
- bm->aiocb = NULL;
- }
- }
+ ide_dma_cancel(bm);
bm->cmd = val & 0x09;
} else {
if (!(bm->status & BM_STATUS_DMAING)) {
@@ -3188,9 +3193,14 @@ static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
return 0;
}
-static void piix3_reset(PCIIDEState *d)
+static void piix3_reset(void *opaque)
{
+ PCIIDEState *d = opaque;
uint8_t *pci_conf = d->dev.config;
+ int i;
+
+ for (i = 0; i < 2; i++)
+ ide_dma_cancel(&d->bmdma[i]);
pci_conf[0x04] = 0x00;
pci_conf[0x05] = 0x00;
@@ -3224,6 +3234,7 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
pci_conf[0x0e] = 0x00; // header_type
+ qemu_register_reset(piix3_reset, d);
piix3_reset(d);
pci_register_io_region((PCIDevice *)d, 4, 0x10,
@@ -3262,6 +3273,7 @@ void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
pci_conf[0x0e] = 0x00; // header_type
+ qemu_register_reset(piix3_reset, d);
piix3_reset(d);
pci_register_io_region((PCIDevice *)d, 4, 0x10,