diff options
author | Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> | 2014-08-08 17:23:36 +0100 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2014-08-15 18:03:13 +0100 |
commit | 271dddd133125ee00e347b154bb9d44e228929bb (patch) | |
tree | 8da779fffe762cc48994df30fc8d8bbbe1046c30 | |
parent | 1d113ef874c04486cf4ee2894b2ef84bf8d17543 (diff) | |
download | hqemu-271dddd133125ee00e347b154bb9d44e228929bb.zip hqemu-271dddd133125ee00e347b154bb9d44e228929bb.tar.gz |
cmd646: synchronise UDMA interrupt status with DMA interrupt status
Make sure that both registers are synchronised when being accessed through
PCI configuration space.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r-- | hw/ide/cmd646.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index b8dc4ab..74d0deb 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -146,6 +146,22 @@ static void cmd646_update_dma_interrupts(PCIDevice *pd) } } +static void cmd646_update_udma_interrupts(PCIDevice *pd) +{ + /* Sync UDMA interrupt status from DMA interrupt status */ + if (pd->config[CFR] & CFR_INTR_CH0) { + pd->config[MRDMODE] |= MRDMODE_INTR_CH0; + } else { + pd->config[MRDMODE] &= ~MRDMODE_INTR_CH0; + } + + if (pd->config[ARTTIM23] & ARTTIM23_INTR_CH1) { + pd->config[MRDMODE] |= MRDMODE_INTR_CH1; + } else { + pd->config[MRDMODE] &= ~MRDMODE_INTR_CH1; + } +} + static uint64_t bmdma_read(void *opaque, hwaddr addr, unsigned size) { @@ -296,6 +312,10 @@ static void cmd646_pci_config_write(PCIDevice *d, uint32_t addr, uint32_t val, for (i = addr; i < addr + l; i++) { switch (i) { + case CFR: + case ARTTIM23: + cmd646_update_udma_interrupts(d); + break; case MRDMODE: cmd646_update_dma_interrupts(d); break; @@ -322,6 +342,10 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev) } /* Set write-to-clear interrupt bits */ + dev->wmask[CFR] = 0x0; + dev->w1cmask[CFR] = CFR_INTR_CH0; + dev->wmask[ARTTIM23] = 0x0; + dev->w1cmask[ARTTIM23] = ARTTIM23_INTR_CH1; dev->wmask[MRDMODE] = 0x0; dev->w1cmask[MRDMODE] = MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1; |