summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
authorMark Cave-Ayland2014-08-08 18:23:36 +0200
committerStefan Hajnoczi2014-08-15 19:03:13 +0200
commit271dddd133125ee00e347b154bb9d44e228929bb (patch)
tree8da779fffe762cc48994df30fc8d8bbbe1046c30 /hw
parentcmd646: allow MRDMODE interrupt status bits clearing from PCI config space (diff)
downloadqemu-271dddd133125ee00e347b154bb9d44e228929bb.tar.gz
qemu-271dddd133125ee00e347b154bb9d44e228929bb.tar.xz
qemu-271dddd133125ee00e347b154bb9d44e228929bb.zip
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>
Diffstat (limited to 'hw')
-rw-r--r--hw/ide/cmd646.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index b8dc4ab9ea..74d0deb6dd 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;