aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2010-10-26 09:50:58 -0500
committerAnthony Liguori <aliguori@us.ibm.com>2010-10-26 09:50:58 -0500
commit21bcc5907f4c4a8acffcda8b6662710784cba388 (patch)
tree0eed92970495fef0729139bd1e8bbe22983e3177 /hw
parent758c309f0a5cb52441a1ee015566cf9cd96fa933 (diff)
parent8c269b542c5bbbcd74c1664959b223d941a2893b (diff)
downloadqemu-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.c28
-rw-r--r--hw/ide/internal.h3
-rw-r--r--hw/virtio-blk.c8
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)