All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>
Subject: [Qemu-devel] [PATCH 3/4] ide: Implement rerror option
Date: Fri, 27 Nov 2009 13:25:38 +0100	[thread overview]
Message-ID: <1259324739-6805-4-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1259324739-6805-1-git-send-email-kwolf@redhat.com>

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/core.c     |   54 ++++++++++++++++++++++++++++++++++++----------------
 hw/ide/internal.h |    1 +
 vl.c              |    2 +-
 3 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 49bbdcd..a5b00ae 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -61,8 +61,9 @@ static inline int media_is_cd(IDEState *s)
 }
 
 static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
-static void ide_dma_restart(IDEState *s);
+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 padstr(char *str, const char *src, int len)
 {
@@ -407,8 +408,11 @@ static void ide_sector_read(IDEState *s)
             n = s->req_nb_sectors;
         ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
         if (ret != 0) {
-            ide_rw_error(s);
-            return;
+            if (ide_handle_rw_error(s, -ret,
+                BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ))
+            {
+                return;
+            }
         }
         ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
         ide_set_irq(s->bus);
@@ -471,9 +475,10 @@ void ide_dma_error(IDEState *s)
     ide_set_irq(s->bus);
 }
 
-static int ide_handle_write_error(IDEState *s, int error, int op)
+static int ide_handle_rw_error(IDEState *s, int error, int op)
 {
-    BlockInterfaceErrorAction action = drive_get_on_error(s->bs, 0);
+    int is_read = (op & BM_STATUS_RETRY_READ);
+    BlockInterfaceErrorAction action = drive_get_on_error(s->bs, is_read);
 
     if (action == BLOCK_ERR_IGNORE)
         return 0;
@@ -484,7 +489,7 @@ static int ide_handle_write_error(IDEState *s, int error, int op)
         s->bus->bmdma->status |= op;
         vm_stop(0);
     } else {
-        if (op == BM_STATUS_DMA_RETRY) {
+        if (op & BM_STATUS_DMA_RETRY) {
             dma_buf_commit(s, 0);
             ide_dma_error(s);
         } else {
@@ -551,9 +556,11 @@ static void ide_read_dma_cb(void *opaque, int ret)
     int64_t sector_num;
 
     if (ret < 0) {
-        dma_buf_commit(s, 1);
-	ide_dma_error(s);
-	return;
+        if (ide_handle_rw_error(s, -ret,
+            BM_STATUS_DMA_RETRY | BM_STATUS_RETRY_READ))
+        {
+            return;
+        }
     }
 
     n = s->io_buffer_size >> 9;
@@ -622,7 +629,7 @@ static void ide_sector_write(IDEState *s)
     ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
 
     if (ret != 0) {
-        if (ide_handle_write_error(s, -ret, BM_STATUS_PIO_RETRY))
+        if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY))
             return;
     }
 
@@ -658,16 +665,23 @@ static void ide_sector_write(IDEState *s)
 static void ide_dma_restart_bh(void *opaque)
 {
     BMDMAState *bm = opaque;
+    int is_read;
 
     qemu_bh_delete(bm->bh);
     bm->bh = NULL;
 
+    is_read = !!(bm->status & BM_STATUS_RETRY_READ);
+
     if (bm->status & BM_STATUS_DMA_RETRY) {
-        bm->status &= ~BM_STATUS_DMA_RETRY;
-        ide_dma_restart(bmdma_active_if(bm));
+        bm->status &= ~(BM_STATUS_DMA_RETRY | BM_STATUS_RETRY_READ);
+        ide_dma_restart(bmdma_active_if(bm), is_read);
     } else if (bm->status & BM_STATUS_PIO_RETRY) {
-        bm->status &= ~BM_STATUS_PIO_RETRY;
-        ide_sector_write(bmdma_active_if(bm));
+        bm->status &= ~(BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ);
+        if (is_read) {
+            ide_sector_read(bmdma_active_if(bm));
+        } else {
+            ide_sector_write(bmdma_active_if(bm));
+        }
     }
 }
 
@@ -692,7 +706,7 @@ static void ide_write_dma_cb(void *opaque, int ret)
     int64_t sector_num;
 
     if (ret < 0) {
-        if (ide_handle_write_error(s, -ret,  BM_STATUS_DMA_RETRY))
+        if (ide_handle_rw_error(s, -ret,  BM_STATUS_DMA_RETRY))
             return;
     }
 
@@ -2715,7 +2729,7 @@ static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
     }
 }
 
-static void ide_dma_restart(IDEState *s)
+static void ide_dma_restart(IDEState *s, int is_read)
 {
     BMDMAState *bm = s->bus->bmdma;
     ide_set_sector(s, bm->sector_num);
@@ -2723,7 +2737,13 @@ static void ide_dma_restart(IDEState *s)
     s->io_buffer_size = 0;
     s->nsector = bm->nsector;
     bm->cur_addr = bm->addr;
-    bm->dma_cb = ide_write_dma_cb;
+
+    if (is_read) {
+        bm->dma_cb = ide_read_dma_cb;
+    } else {
+        bm->dma_cb = ide_write_dma_cb;
+    }
+
     ide_dma_start(s, bm->dma_cb);
 }
 
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 567616e..f937daa 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -464,6 +464,7 @@ 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_CMD_START     0x01
 #define BM_CMD_READ      0x08
diff --git a/vl.c b/vl.c
index 5b5dc60..0136d16 100644
--- a/vl.c
+++ b/vl.c
@@ -2199,7 +2199,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
 
     on_read_error = BLOCK_ERR_REPORT;
     if ((buf = qemu_opt_get(opts, "rerror")) != NULL) {
-        if (1) {
+        if (type != IF_IDE) {
             fprintf(stderr, "rerror is no supported by this format\n");
             return NULL;
         }
-- 
1.6.2.5

  parent reply	other threads:[~2009-11-27 12:26 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-27 12:25 [Qemu-devel] [PATCH 0/4] rerror option for -drive Kevin Wolf
2009-11-27 12:25 ` [Qemu-devel] [PATCH 1/4] Rename DriveInfo.onerror to on_write_error Kevin Wolf
2009-11-29 10:46   ` Gleb Natapov
2009-12-03 19:55     ` Anthony Liguori
2009-12-04  8:18       ` Kevin Wolf
2009-11-27 12:25 ` [Qemu-devel] [PATCH 2/4] Introduce rerror option for drives Kevin Wolf
2009-11-27 12:25 ` Kevin Wolf [this message]
2009-11-27 12:25 ` [Qemu-devel] [PATCH 4/4] virtio-blk: Implement rerror option Kevin Wolf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1259324739-6805-4-git-send-email-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.