From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:53629) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qp1Vk-000564-WD for qemu-devel@nongnu.org; Thu, 04 Aug 2011 13:15:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Qp1Vi-0001Pe-EW for qemu-devel@nongnu.org; Thu, 04 Aug 2011 13:15:08 -0400 Received: from mail-ww0-f53.google.com ([74.125.82.53]:54032) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qp1Vi-0001K2-2t for qemu-devel@nongnu.org; Thu, 04 Aug 2011 13:15:06 -0400 Received: by mail-ww0-f53.google.com with SMTP id 26so1933653wwf.10 for ; Thu, 04 Aug 2011 10:15:05 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Thu, 4 Aug 2011 19:14:48 +0200 Message-Id: <1312478089-806-11-git-send-email-pbonzini@redhat.com> In-Reply-To: <1312478089-806-1-git-send-email-pbonzini@redhat.com> References: <1312478089-806-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 10/10] scsi-disk: enable scatter/gather functionality List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Signed-off-by: Paolo Bonzini --- hw/scsi-disk.c | 52 +++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 41 insertions(+), 11 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 509407f..81117d2 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -37,6 +37,7 @@ do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0) #include "scsi-defs.h" #include "sysemu.h" #include "blockdev.h" +#include "dma.h" #define SCSI_DMA_BUF_SIZE 131072 #define SCSI_MAX_INQUIRY_LEN 256 @@ -123,6 +124,25 @@ static uint32_t scsi_init_iovec(SCSIDiskReq *r) return r->qiov.size / 512; } +static void scsi_dma_complete(void *opaque, int ret) +{ + SCSIDiskReq *r = (SCSIDiskReq *)opaque; + + r->req.resid = qemu_sglist_get_resid(r->req.sg); + r->req.aiocb = NULL; + if (ret) { + int is_read = (r->req.cmd.mode == SCSI_XFER_FROM_DEV); + int retry = is_read ? SCSI_REQ_STATUS_RETRY_READ : SCSI_REQ_STATUS_RETRY_WRITE; + if (scsi_handle_rw_error(r, -ret, retry)) { + return; + } + } + + r->sector += r->sector_count; + r->sector_count = 0; + scsi_req_complete(&r->req, GOOD); +} + static void scsi_read_complete(void * opaque, int ret) { SCSIDiskReq *r = (SCSIDiskReq *)opaque; @@ -174,9 +194,14 @@ static void scsi_read_data(SCSIRequest *req) return; } - n = scsi_init_iovec(r); - r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n, - scsi_read_complete, r); + if (r->req.sg) { + r->req.aiocb = dma_bdrv_read(s->bs, r->req.sg, r->sector, + scsi_dma_complete, r); + } else { + n = scsi_init_iovec(r); + r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n, + scsi_read_complete, r); + } if (r->req.aiocb == NULL) { scsi_read_complete(r, -EIO); } @@ -258,16 +283,21 @@ static void scsi_write_data(SCSIRequest *req) return; } - n = r->qiov.size / 512; - if (n) { + if (r->req.sg) { + r->req.aiocb = dma_bdrv_write(s->bs, r->req.sg, r->sector, + scsi_dma_complete, r); + } else { + n = r->qiov.size / 512; + if (!n) { + /* Called for the first time. Ask the driver to send us more data. */ + scsi_write_complete(r, 0); + return; + } r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n, scsi_write_complete, r); - if (r->req.aiocb == NULL) { - scsi_write_complete(r, -ENOMEM); - } - } else { - /* Called for the first time. Ask the driver to send us more data. */ - scsi_write_complete(r, 0); + } + if (r->req.aiocb == NULL) { + scsi_write_complete(r, -ENOMEM); } } -- 1.7.6