All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@lst.de>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 4/7] ide: factor dma handling helpers
Date: Fri, 10 Dec 2010 16:01:15 +0100	[thread overview]
Message-ID: <20101210150115.GD31114@lst.de> (raw)
In-Reply-To: <20101210150038.GA30990@lst.de>

The DMA I/O path is duplicated between read and write commands, and
support for the TRIM command would add another copy.  Factor the
code into common helpers using the s->is_read flag added for the
macio ATA controller, and the newly added dma_bdrv_io function.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: qemu/hw/ide/core.c
===================================================================
--- qemu.orig/hw/ide/core.c	2010-12-10 11:17:57.328254648 +0100
+++ qemu/hw/ide/core.c	2010-12-10 11:35:23.164005731 +0100
@@ -61,7 +61,8 @@ static inline int media_is_cd(IDEState *
     return (media_present(s) && s->nb_sectors <= CD_MAX_SECTORS);
 }
 
-static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
+static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb,
+       DMAIOFunc *io_func);
 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);
@@ -568,7 +569,7 @@ static int dma_buf_rw(BMDMAState *bm, in
     return 1;
 }
 
-static void ide_read_dma_cb(void *opaque, int ret)
+static void ide_dma_cb(void *opaque, int ret)
 {
     BMDMAState *bm = opaque;
     IDEState *s = bmdma_active_if(bm);
@@ -576,9 +577,12 @@ static void ide_read_dma_cb(void *opaque
     int64_t sector_num;
 
     if (ret < 0) {
-        if (ide_handle_rw_error(s, -ret,
-            BM_STATUS_DMA_RETRY | BM_STATUS_RETRY_READ))
-        {
+        int op = BM_STATUS_DMA_RETRY;
+
+        if (s->is_read)
+            op |= BM_STATUS_RETRY_READ;
+
+        if (ide_handle_rw_error(s, -ret, op)) {
             return;
         }
     }
@@ -586,7 +590,7 @@ static void ide_read_dma_cb(void *opaque
     n = s->io_buffer_size >> 9;
     sector_num = ide_get_sector(s);
     if (n > 0) {
-        dma_buf_commit(s, 1);
+        dma_buf_commit(s, s->is_read);
         sector_num += n;
         ide_set_sector(s, sector_num);
         s->nsector -= n;
@@ -596,32 +600,39 @@ static void ide_read_dma_cb(void *opaque
     if (s->nsector == 0) {
         s->status = READY_STAT | SEEK_STAT;
         ide_set_irq(s->bus);
-    eot:
-        bm->status |= BM_STATUS_INT;
-        ide_dma_set_inactive(bm);
-        return;
+        goto eot;
     }
 
     /* launch next transfer */
     n = s->nsector;
-    s->io_buffer_index = 0;
+    if (s->is_read)
+        s->io_buffer_index = 0;
     s->io_buffer_size = n * 512;
-    if (dma_buf_prepare(bm, 1) == 0)
+    if (dma_buf_prepare(bm, s->is_read) == 0)
         goto eot;
+
 #ifdef DEBUG_AIO
-    printf("aio_read: sector_num=%" PRId64 " n=%d\n", sector_num, n);
+    printf("ide_dma_cb: read: %d sector_num=%" PRId64 " n=%d\n",
+           s->is_read, sector_num, n);
 #endif
-    bm->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, ide_read_dma_cb, bm);
-    ide_dma_submit_check(s, ide_read_dma_cb, bm);
+
+    bm->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num, bm->io_func,
+                            ide_dma_cb, bm, !s->is_read);
+    ide_dma_submit_check(s, ide_dma_cb, bm);
+    return;
+
+eot:
+    bm->status |= BM_STATUS_INT;
+    ide_dma_set_inactive(bm);
 }
 
-static void ide_sector_read_dma(IDEState *s)
+static void ide_sector_dma(IDEState *s, DMAIOFunc *io_func, bool is_read)
 {
     s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
     s->io_buffer_index = 0;
     s->io_buffer_size = 0;
-    s->is_read = 1;
-    ide_dma_start(s, ide_read_dma_cb);
+    s->is_read = is_read;
+    ide_dma_start(s, ide_dma_cb, io_func);
 }
 
 static void ide_sector_write_timer_cb(void *opaque)
@@ -714,58 +725,6 @@ void ide_dma_restart_cb(void *opaque, in
     }
 }
 
-static void ide_write_dma_cb(void *opaque, int ret)
-{
-    BMDMAState *bm = opaque;
-    IDEState *s = bmdma_active_if(bm);
-    int n;
-    int64_t sector_num;
-
-    if (ret < 0) {
-        if (ide_handle_rw_error(s, -ret,  BM_STATUS_DMA_RETRY))
-            return;
-    }
-
-    n = s->io_buffer_size >> 9;
-    sector_num = ide_get_sector(s);
-    if (n > 0) {
-        dma_buf_commit(s, 0);
-        sector_num += n;
-        ide_set_sector(s, sector_num);
-        s->nsector -= n;
-    }
-
-    /* end of transfer ? */
-    if (s->nsector == 0) {
-        s->status = READY_STAT | SEEK_STAT;
-        ide_set_irq(s->bus);
-    eot:
-        bm->status |= BM_STATUS_INT;
-        ide_dma_set_inactive(bm);
-        return;
-    }
-
-    n = s->nsector;
-    s->io_buffer_size = n * 512;
-    /* launch next transfer */
-    if (dma_buf_prepare(bm, 0) == 0)
-        goto eot;
-#ifdef DEBUG_AIO
-    printf("aio_write: sector_num=%" PRId64 " n=%d\n", sector_num, n);
-#endif
-    bm->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num, ide_write_dma_cb, bm);
-    ide_dma_submit_check(s, ide_write_dma_cb, bm);
-}
-
-static void ide_sector_write_dma(IDEState *s)
-{
-    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
-    s->io_buffer_index = 0;
-    s->io_buffer_size = 0;
-    s->is_read = 0;
-    ide_dma_start(s, ide_write_dma_cb);
-}
-
 void ide_atapi_cmd_ok(IDEState *s)
 {
     s->error = 0;
@@ -1003,7 +962,7 @@ static void ide_atapi_cmd_reply(IDEState
 
     if (s->atapi_dma) {
     	s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
-	ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
+	ide_dma_start(s, ide_atapi_cmd_read_dma_cb, NULL);
     } else {
     	s->status = READY_STAT | SEEK_STAT;
     	ide_atapi_cmd_reply_end(s);
@@ -1111,7 +1070,7 @@ static void ide_atapi_cmd_read_dma(IDESt
 
     /* XXX: check if BUSY_STAT should be set */
     s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
-    ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
+    ide_dma_start(s, ide_atapi_cmd_read_dma_cb, NULL);
 }
 
 static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
@@ -1968,7 +1927,7 @@ void ide_ioport_write(void *opaque, uint
             if (!s->bs)
                 goto abort_cmd;
 	    ide_cmd_lba48_transform(s, lba48);
-            ide_sector_read_dma(s);
+            ide_sector_dma(s, bdrv_aio_readv, 1);
             break;
 	case WIN_WRITEDMA_EXT:
 	    lba48 = 1;
@@ -1977,7 +1936,7 @@ void ide_ioport_write(void *opaque, uint
             if (!s->bs)
                 goto abort_cmd;
 	    ide_cmd_lba48_transform(s, lba48);
-            ide_sector_write_dma(s);
+            ide_sector_dma(s, bdrv_aio_writev, 0);
             s->media_changed = 1;
             break;
         case WIN_READ_NATIVE_MAX_EXT:
@@ -2912,13 +2871,15 @@ const VMStateDescription vmstate_ide_bus
 /***********************************************************/
 /* PCI IDE definitions */
 
-static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
+static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb,
+       DMAIOFunc *io_func)
 {
     BMDMAState *bm = s->bus->bmdma;
     if(!bm)
         return;
     bm->unit = s->unit;
     bm->dma_cb = dma_cb;
+    bm->io_func = io_func;
     bm->cur_prd_last = 0;
     bm->cur_prd_addr = 0;
     bm->cur_prd_len = 0;
@@ -2936,15 +2897,11 @@ static void ide_dma_restart(IDEState *s,
     s->io_buffer_index = 0;
     s->io_buffer_size = 0;
     s->nsector = bm->nsector;
+    s->is_read = is_read;
     bm->cur_addr = bm->addr;
 
-    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);
+    bm->dma_cb = ide_dma_cb;
+    ide_dma_start(s, bm->dma_cb, bm->io_func);
 }
 
 void ide_dma_cancel(BMDMAState *bm)
Index: qemu/hw/ide/internal.h
===================================================================
--- qemu.orig/hw/ide/internal.h	2010-12-10 11:17:57.348254927 +0100
+++ qemu/hw/ide/internal.h	2010-12-10 11:33:41.444006150 +0100
@@ -433,7 +433,6 @@ struct IDEState {
     uint32_t mdata_size;
     uint8_t *mdata_storage;
     int media_changed;
-    /* for pmac */
     int is_read;
     /* SMART */
     uint8_t smart_enabled;
@@ -493,6 +492,7 @@ struct BMDMAState {
     uint8_t unit;
     BlockDriverCompletionFunc *dma_cb;
     BlockDriverAIOCB *aiocb;
+    DMAIOFunc *io_func;
     struct iovec iov;
     QEMUIOVector qiov;
     int64_t sector_num;
Index: qemu/hw/ide/macio.c
===================================================================
--- qemu.orig/hw/ide/macio.c	2010-12-10 11:17:57.357254927 +0100
+++ qemu/hw/ide/macio.c	2010-12-10 11:19:00.936260584 +0100
@@ -146,12 +146,8 @@ static void pmac_ide_transfer_cb(void *o
     io->addr += io->len;
     io->len = 0;
 
-    if (s->is_read)
-        m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num,
-		                 pmac_ide_transfer_cb, io);
-    else
-        m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num,
-		                  pmac_ide_transfer_cb, io);
+    m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num, s->io_func,
+		           pmac_ide_transfer_cb, io, !s->is_read);
     if (!m->aiocb)
         pmac_ide_transfer_cb(io, -1);
 }

  parent reply	other threads:[~2010-12-10 15:01 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-10 15:00 [Qemu-devel] ]PATCH 0/7] add TRIM/UNMAP support, v3 Christoph Hellwig
2010-12-10 15:00 ` [Qemu-devel] [PATCH 1/7] block: add discard support Christoph Hellwig
2010-12-10 15:00 ` [Qemu-devel] [PATCH 2/7] scsi-disk: support WRITE SAME (16) with unmap bit Christoph Hellwig
2010-12-16 15:48   ` Kevin Wolf
2010-12-16 16:41     ` Christoph Hellwig
2010-12-10 15:01 ` [Qemu-devel] [PATCH 3/7] make dma_bdrv_io available to drivers Christoph Hellwig
2010-12-10 15:01 ` Christoph Hellwig [this message]
2010-12-10 15:01 ` [Qemu-devel] [PATCH 5/7] ide: also reset io_buffer_index for writes Christoph Hellwig
2010-12-10 15:01 ` [Qemu-devel] [PATCH 6/7] ide: add TRIM support Christoph Hellwig
2010-12-10 15:01 ` [Qemu-devel] [PATCH 7/7] raw-posix: add discard support Christoph Hellwig
2010-12-12 15:28 ` [Qemu-devel] ]PATCH 0/7] add TRIM/UNMAP support, v3 Stefan Hajnoczi
2010-12-13 15:45   ` Christoph Hellwig
2010-12-16 15:43 ` Kevin Wolf
2010-12-16 16:42   ` Christoph Hellwig
2010-12-16 18:36 ` [Qemu-devel] Re: [PATCH 0/3] add TRIM/UNMAP support, v4 Christoph Hellwig
2010-12-16 18:36   ` [Qemu-devel] [PATCH 1/3] block: add discard support Christoph Hellwig
2010-12-16 18:36   ` [Qemu-devel] [PATCH 2/3] scsi-disk: support WRITE SAME (16) with unmap bit Christoph Hellwig
2010-12-16 18:36   ` [Qemu-devel] [PATCH 3/3] raw-posix: add discard support Christoph Hellwig
2010-12-17 10:32     ` Kevin Wolf
2010-12-17 10:41       ` [Qemu-devel] [PATCH v5] " Christoph Hellwig
2010-12-17 10:53         ` [Qemu-devel] " 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=20101210150115.GD31114@lst.de \
    --to=hch@lst.de \
    --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.