diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2010-10-26 09:50:58 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2010-10-26 09:50:58 -0500 |
commit | 21bcc5907f4c4a8acffcda8b6662710784cba388 (patch) | |
tree | 0eed92970495fef0729139bd1e8bbe22983e3177 /hw | |
parent | 758c309f0a5cb52441a1ee015566cf9cd96fa933 (diff) | |
parent | 8c269b542c5bbbcd74c1664959b223d941a2893b (diff) | |
download | qemu-21bcc5907f4c4a8acffcda8b6662710784cba388.zip qemu-21bcc5907f4c4a8acffcda8b6662710784cba388.tar.gz qemu-21bcc5907f4c4a8acffcda8b6662710784cba388.tar.bz2 |
Merge remote branch 'kwolf/for-anthony' into staging
Diffstat (limited to 'hw')
-rw-r--r-- | hw/ide/core.c | 28 | ||||
-rw-r--r-- | hw/ide/internal.h | 3 | ||||
-rw-r--r-- | hw/virtio-blk.c | 8 |
3 files changed, 30 insertions, 9 deletions
diff --git a/hw/ide/core.c b/hw/ide/core.c index 06b6e14..bc3e916 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -65,6 +65,7 @@ static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb); static void ide_dma_restart(IDEState *s, int is_read); static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret); static int ide_handle_rw_error(IDEState *s, int error, int op); +static void ide_flush_cache(IDEState *s); static void padstr(char *str, const char *src, int len) { @@ -146,8 +147,8 @@ static void ide_identify(IDEState *s) put_le16(p + 68, 120); put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */ put_le16(p + 81, 0x16); /* conforms to ata5 */ - /* 14=NOP supported, 0=SMART supported */ - put_le16(p + 82, (1 << 14) | 1); + /* 14=NOP supported, 5=WCACHE supported, 0=SMART supported */ + put_le16(p + 82, (1 << 14) | (1 << 5) | 1); /* 13=flush_cache_ext,12=flush_cache,10=lba48 */ put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10)); /* 14=set to 1, 1=SMART self test, 0=SMART error logging */ @@ -688,6 +689,8 @@ static void ide_dma_restart_bh(void *opaque) } else { ide_sector_write(bmdma_active_if(bm)); } + } else if (bm->status & BM_STATUS_RETRY_FLUSH) { + ide_flush_cache(bmdma_active_if(bm)); } } @@ -795,12 +798,26 @@ static void ide_flush_cb(void *opaque, int ret) { IDEState *s = opaque; - /* XXX: how do we signal I/O errors here? */ + if (ret < 0) { + /* XXX: What sector number to set here? */ + if (ide_handle_rw_error(s, -ret, BM_STATUS_RETRY_FLUSH)) { + return; + } + } s->status = READY_STAT | SEEK_STAT; ide_set_irq(s->bus); } +static void ide_flush_cache(IDEState *s) +{ + if (s->bs) { + bdrv_aio_flush(s->bs, ide_flush_cb, s); + } else { + ide_flush_cb(s, 0); + } +} + static inline void cpu_to_ube16(uint8_t *buf, int val) { buf[0] = val >> 8; @@ -2031,10 +2048,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) break; case WIN_FLUSH_CACHE: case WIN_FLUSH_CACHE_EXT: - if (s->bs) - bdrv_aio_flush(s->bs, ide_flush_cb, s); - else - ide_flush_cb(s, 0); + ide_flush_cache(s); break; case WIN_STANDBY: case WIN_STANDBY2: diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 4165543..d652e06 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -472,7 +472,8 @@ struct IDEDeviceInfo { #define BM_STATUS_INT 0x04 #define BM_STATUS_DMA_RETRY 0x08 #define BM_STATUS_PIO_RETRY 0x10 -#define BM_STATUS_RETRY_READ 0x20 +#define BM_STATUS_RETRY_READ 0x20 +#define BM_STATUS_RETRY_FLUSH 0x40 #define BM_CMD_START 0x01 #define BM_CMD_READ 0x08 diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index a1df26d..dbe20707 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -106,7 +106,13 @@ static void virtio_blk_flush_complete(void *opaque, int ret) { VirtIOBlockReq *req = opaque; - virtio_blk_req_complete(req, ret ? VIRTIO_BLK_S_IOERR : VIRTIO_BLK_S_OK); + if (ret) { + if (virtio_blk_handle_rw_error(req, -ret, 0)) { + return; + } + } + + virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); } static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s) |