[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 31/36] hw/scsi/esp-pci: synchronise setting of DMA_STAT_DONE with
From: |
Philippe Mathieu-Daudé |
Subject: |
[PULL 31/36] hw/scsi/esp-pci: synchronise setting of DMA_STAT_DONE with ESP completion interrupt |
Date: |
Fri, 19 Jan 2024 12:35:00 +0100 |
From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
The setting of DMA_STAT_DONE at the end of a DMA transfer can be configured to
generate an interrupt, however the Linux driver manually checks for
DMA_STAT_DONE
being set and if it is, considers that a DMA transfer has completed.
If DMA_STAT_DONE is set but the ESP device isn't indicating an interrupt then
the Linux driver considers this to be a spurious interrupt. However this can
occur in QEMU as there is a delay between the end of DMA transfer where
DMA_STAT_DONE is set, and the ESP device raising its completion interrupt.
This appears to be an incorrect assumption in the Linux driver as the ESP and
PCI DMA interrupt sources are separate (and may not be raised exactly
together), however we can work around this by synchronising the setting of
DMA_STAT_DONE at the end of a DMA transfer with the ESP completion interrupt.
In conjunction with the previous commit Linux is now able to correctly boot
from an am53c974 PCI SCSI device on the hppa C3700 machine without emitting
"iget: checksum invalid" and "Spurious irq, sreg=10" errors.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Message-ID: <20240112131529.515642-4-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/scsi/esp-pci.c | 28 +++++++++++++---------------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c
index 15dc3c004d..875a49199d 100644
--- a/hw/scsi/esp-pci.c
+++ b/hw/scsi/esp-pci.c
@@ -93,6 +93,18 @@ static void esp_irq_handler(void *opaque, int irq_num, int
level)
if (level) {
pci->dma_regs[DMA_STAT] |= DMA_STAT_SCSIINT;
+
+ /*
+ * If raising the ESP IRQ to indicate end of DMA transfer, set
+ * DMA_STAT_DONE at the same time. In theory this should be done in
+ * esp_pci_dma_memory_rw(), however there is a delay between setting
+ * DMA_STAT_DONE and the ESP IRQ arriving which is visible to the
+ * guest that can cause confusion e.g. Linux
+ */
+ if ((pci->dma_regs[DMA_CMD] & DMA_CMD_MASK) == 0x3 &&
+ pci->dma_regs[DMA_WBC] == 0) {
+ pci->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
+ }
} else {
pci->dma_regs[DMA_STAT] &= ~DMA_STAT_SCSIINT;
}
@@ -306,9 +318,6 @@ static void esp_pci_dma_memory_rw(PCIESPState *pci, uint8_t
*buf, int len,
/* update status registers */
pci->dma_regs[DMA_WBC] -= len;
pci->dma_regs[DMA_WAC] += len;
- if (pci->dma_regs[DMA_WBC] == 0) {
- pci->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
- }
}
static void esp_pci_dma_memory_read(void *opaque, uint8_t *buf, int len)
@@ -363,24 +372,13 @@ static const VMStateDescription vmstate_esp_pci_scsi = {
}
};
-static void esp_pci_command_complete(SCSIRequest *req, size_t resid)
-{
- ESPState *s = req->hba_private;
- PCIESPState *pci = container_of(s, PCIESPState, esp);
-
- esp_command_complete(req, resid);
- pci->dma_regs[DMA_WBC] = 0;
- pci->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
- esp_pci_update_irq(pci);
-}
-
static const struct SCSIBusInfo esp_pci_scsi_info = {
.tcq = false,
.max_target = ESP_MAX_DEVS,
.max_lun = 7,
.transfer_data = esp_transfer_data,
- .complete = esp_pci_command_complete,
+ .complete = esp_command_complete,
.cancel = esp_request_cancelled,
};
--
2.41.0
- [PULL 21/36] system/replay: Restrict icount to system emulation, (continued)
- [PULL 21/36] system/replay: Restrict icount to system emulation, Philippe Mathieu-Daudé, 2024/01/19
- [PULL 22/36] system/watchpoint: Move TCG specific code to accel/tcg/, Philippe Mathieu-Daudé, 2024/01/19
- [PULL 23/36] cpus: Restrict 'start-powered-off' property to system emulation, Philippe Mathieu-Daudé, 2024/01/19
- [PULL 24/36] accel: Rename accel_init_ops_interfaces() to include 'system', Philippe Mathieu-Daudé, 2024/01/19
- [PULL 26/36] hw/s390x: Rename cpu_class_init() to include 'sclp', Philippe Mathieu-Daudé, 2024/01/19
- [PULL 25/36] hw/core/cpu: Rename cpu_class_init() to include 'common', Philippe Mathieu-Daudé, 2024/01/19
- [PULL 27/36] target/i386: Rename tcg_cpu_FOO() to include 'x86', Philippe Mathieu-Daudé, 2024/01/19
- [PULL 28/36] target/riscv: Rename tcg_cpu_FOO() to include 'riscv', Philippe Mathieu-Daudé, 2024/01/19
- [PULL 29/36] hw/scsi/esp-pci: use correct address register for PCI DMA transfers, Philippe Mathieu-Daudé, 2024/01/19
- [PULL 30/36] hw/scsi/esp-pci: generate PCI interrupt from separate ESP and PCI sources, Philippe Mathieu-Daudé, 2024/01/19
- [PULL 31/36] hw/scsi/esp-pci: synchronise setting of DMA_STAT_DONE with ESP completion interrupt,
Philippe Mathieu-Daudé <=
- [PULL 32/36] hw/scsi/esp-pci: set DMA_STAT_BCMBLT when BLAST command issued, Philippe Mathieu-Daudé, 2024/01/19
- [PULL 33/36] hw/elf_ops: Ignore loadable segments with zero size, Philippe Mathieu-Daudé, 2024/01/19
- [PULL 34/36] MAINTAINERS: Update Raphael Norwitz email, Philippe Mathieu-Daudé, 2024/01/19
- [PULL 35/36] MAINTAINERS: Update hw/core/cpu.c entry, Philippe Mathieu-Daudé, 2024/01/19
- [PULL 36/36] configure: Add linux header compile support for LoongArch, Philippe Mathieu-Daudé, 2024/01/19
- Re: [PULL 00/36] HW core patches for 2024-01-19, Peter Maydell, 2024/01/19