summaryrefslogtreecommitdiff
path: root/hw/ide
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2011-06-10 16:32:13 +0200
committerKevin Wolf <kwolf@redhat.com>2011-06-15 15:39:13 +0200
commitee752da74f5d07cf441f8d42455c4241d6051ae5 (patch)
tree9218f6575bf9f2e95aee51d98a10e56282c18772 /hw/ide
parentd353fb72f59cd0e1f67baf773e74719cda761a89 (diff)
ide: Clear error_status after restarting flush
Clearing the error status flag was missing for restarting flushes. Now that the error status is separate from the BM status register, we can simply set it to 0 after restarting the request. This ensures that we never forget to clear a bit. Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'hw/ide')
-rw-r--r--hw/ide/pci.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index c94037506..9f3050a15 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -189,6 +189,7 @@ static void bmdma_restart_bh(void *opaque)
BMDMAState *bm = opaque;
IDEBus *bus = bm->bus;
int is_read;
+ int error_status;
qemu_bh_delete(bm->bh);
bm->bh = NULL;
@@ -199,22 +200,25 @@ static void bmdma_restart_bh(void *opaque)
is_read = !!(bus->error_status & BM_STATUS_RETRY_READ);
- if (bus->error_status & BM_STATUS_DMA_RETRY) {
- if (bus->error_status & BM_STATUS_RETRY_TRIM) {
- bus->error_status &= ~BM_STATUS_RETRY_TRIM;
+ /* The error status must be cleared before resubmitting the request: The
+ * request may fail again, and this case can only be distinguished if the
+ * called function can set a new error status. */
+ error_status = bus->error_status;
+ bus->error_status = 0;
+
+ if (error_status & BM_STATUS_DMA_RETRY) {
+ if (error_status & BM_STATUS_RETRY_TRIM) {
bmdma_restart_dma(bm, IDE_DMA_TRIM);
} else {
- bus->error_status &= ~(BM_STATUS_DMA_RETRY | BM_STATUS_RETRY_READ);
bmdma_restart_dma(bm, is_read ? IDE_DMA_READ : IDE_DMA_WRITE);
}
- } else if (bus->error_status & BM_STATUS_PIO_RETRY) {
- bus->error_status &= ~(BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ);
+ } else if (error_status & BM_STATUS_PIO_RETRY) {
if (is_read) {
ide_sector_read(bmdma_active_if(bm));
} else {
ide_sector_write(bmdma_active_if(bm));
}
- } else if (bus->error_status & BM_STATUS_RETRY_FLUSH) {
+ } else if (error_status & BM_STATUS_RETRY_FLUSH) {
ide_flush_cache(bmdma_active_if(bm));
}
}