diff options
author | Kevin Wolf <kwolf@redhat.com> | 2011-06-10 16:32:13 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2011-06-15 15:39:13 +0200 |
commit | ee752da74f5d07cf441f8d42455c4241d6051ae5 (patch) | |
tree | 9218f6575bf9f2e95aee51d98a10e56282c18772 /hw/ide | |
parent | d353fb72f59cd0e1f67baf773e74719cda761a89 (diff) | |
download | qemu-ee752da74f5d07cf441f8d42455c4241d6051ae5.zip qemu-ee752da74f5d07cf441f8d42455c4241d6051ae5.tar.gz qemu-ee752da74f5d07cf441f8d42455c4241d6051ae5.tar.bz2 |
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.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/hw/ide/pci.c b/hw/ide/pci.c index c940375..9f3050a 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)); } } |