From: Evgeny Yakovlev <eyakov...@virtuozzo.com> The following sequence of tests discovered a problem in IDE emulation: 1. Send DMA write to IDE device 0 2. Send CMD_FLUSH_CACHE to same IDE device which will be failed by block layer using blkdebug script in tests/ide-test:test_retry_flush
When doing DMA request ide/core.c will set s->retry_unit to s->unit in ide_start_dma. When dma completes ide_set_inactive sets retry_unit to -1. After that ide_flush_cache runs and fails thanks to blkdebug. ide_flush_cb calls ide_handle_rw_error which asserts that s->retry_unit == s->unit. But s->retry_unit is still -1 after previous DMA completion and flush does not use anything related to retry. This patch restricts retry unit assertion only to ops that actually use retry logic. Signed-off-by: Evgeny Yakovlev <eyakov...@virtuozzo.com> Signed-off-by: Denis V. Lunev <d...@openvz.org> CC: Kevin Wolf <kw...@redhat.com> CC: Max Reitz <mre...@redhat.com> CC: Stefan Hajnoczi <stefa...@redhat.com> CC: Fam Zheng <f...@redhat.com> CC: John Snow <js...@redhat.com> --- hw/ide/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index 029f6b9..17f884b 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -779,7 +779,8 @@ int ide_handle_rw_error(IDEState *s, int error, int op) BlockErrorAction action = blk_get_error_action(s->blk, is_read, error); if (action == BLOCK_ERROR_ACTION_STOP) { - assert(s->bus->retry_unit == s->unit); + assert(!(IS_IDE_RETRY_DMA(op) || IS_IDE_RETRY_PIO(op)) + || s->bus->retry_unit == s->unit); s->bus->error_status = op; } else if (action == BLOCK_ERROR_ACTION_REPORT) { block_acct_failed(blk_get_stats(s->blk), &s->acct); -- 2.1.4