From patchwork Mon Feb 13 17:10:14 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 140955 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B332C1007D1 for ; Tue, 14 Feb 2012 05:18:14 +1100 (EST) Received: from localhost ([::1]:47747 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RwzRP-0004I5-8i for incoming@patchwork.ozlabs.org; Mon, 13 Feb 2012 12:11:51 -0500 Received: from eggs.gnu.org ([140.186.70.92]:41440) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RwzQf-0002wQ-4j for qemu-devel@nongnu.org; Mon, 13 Feb 2012 12:11:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RwzQY-0005Ci-7y for qemu-devel@nongnu.org; Mon, 13 Feb 2012 12:11:04 -0500 Received: from mail-pw0-f45.google.com ([209.85.160.45]:65375) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RwzQX-00057q-QU for qemu-devel@nongnu.org; Mon, 13 Feb 2012 12:10:58 -0500 Received: by mail-pw0-f45.google.com with SMTP id ro12so5449571pbb.4 for ; Mon, 13 Feb 2012 09:10:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=ObwuPOwVU36MSp95qv4gMG+Vl1SJABt9bcazoXtXml4=; b=Lk0fZxgkhMZq4xdyM1DKcycXsq/sWndsOVE7GzURr17OQs5E6PAspNmXJX/cT+t6S3 inEq76FC6Bz6T+gbRtS5qGtizMbGvmC63F9LkxirUhfPSMrFCmhuQCpfCQtTv2V+tvkA jvuQ/UnSYJ/wj85c4FH199tsu/Xj8rX1iEq7E= Received: by 10.68.230.6 with SMTP id su6mr49923038pbc.54.1329153057360; Mon, 13 Feb 2012 09:10:57 -0800 (PST) Received: from yakj.usersys.redhat.com (93-34-182-16.ip50.fastwebnet.it. [93.34.182.16]) by mx.google.com with ESMTPS id f1sm20940150pbq.15.2012.02.13.09.10.54 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 13 Feb 2012 09:10:56 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Mon, 13 Feb 2012 18:10:14 +0100 Message-Id: <1329153022-31159-8-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.7.6 In-Reply-To: <1329153022-31159-1-git-send-email-pbonzini@redhat.com> References: <1329153022-31159-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.160.45 Cc: kwolf@redhat.com, stefanha@gmail.com, christian.hoff@de.ibm.com, kvm@vger.kernel.org Subject: [Qemu-devel] [PATCH v3 07/15] scsi-disk: enable scatter/gather functionality X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Paolo Bonzini --- hw/scsi-bus.c | 1 + hw/scsi-disk.c | 63 ++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 69cb3fc..817aa49 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -87,6 +87,7 @@ static void scsi_dma_restart_bh(void *opaque) scsi_req_continue(req); break; case SCSI_XFER_NONE: + assert(!req->sg); scsi_req_dequeue(req); scsi_req_enqueue(req); break; diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 399e51e..0e4d6ad 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -38,6 +38,7 @@ do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0) #include "sysemu.h" #include "blockdev.h" #include "block_int.h" +#include "dma.h" #ifdef __linux #include @@ -123,6 +124,27 @@ 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; + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); + + bdrv_acct_done(s->qdev.conf.bs, &r->acct); + + if (ret) { + if (scsi_handle_rw_error(r, -ret)) { + goto done; + } + } + + r->sector += r->sector_count; + r->sector_count = 0; + scsi_req_complete(&r->req, GOOD); + +done: + scsi_req_unref(&r->req); +} + static void scsi_read_complete(void * opaque, int ret) { SCSIDiskReq *r = (SCSIDiskReq *)opaque; @@ -213,10 +235,17 @@ static void scsi_read_data(SCSIRequest *req) return; } - n = scsi_init_iovec(r); - bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); - r->req.aiocb = bdrv_aio_readv(s->qdev.conf.bs, r->sector, &r->qiov, n, - scsi_read_complete, r); + if (r->req.sg) { + dma_acct_start(s->qdev.conf.bs, &r->acct, r->req.sg, BDRV_ACCT_READ); + r->req.resid -= r->req.sg->size; + r->req.aiocb = dma_bdrv_read(s->qdev.conf.bs, r->req.sg, r->sector, + scsi_dma_complete, r); + } else { + n = scsi_init_iovec(r); + bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); + r->req.aiocb = bdrv_aio_readv(s->qdev.conf.bs, r->sector, &r->qiov, n, + scsi_read_complete, r); + } } /* @@ -315,18 +344,26 @@ static void scsi_write_data(SCSIRequest *req) return; } - n = r->qiov.size / 512; - if (n) { - if (s->tray_open) { - scsi_write_complete(r, -ENOMEDIUM); - return; - } + if (!r->req.sg && !r->qiov.size) { + /* Called for the first time. Ask the driver to send us more data. */ + scsi_write_complete(r, 0); + return; + } + if (s->tray_open) { + scsi_write_complete(r, -ENOMEDIUM); + return; + } + + if (r->req.sg) { + dma_acct_start(s->qdev.conf.bs, &r->acct, r->req.sg, BDRV_ACCT_WRITE); + r->req.resid -= r->req.sg->size; + r->req.aiocb = dma_bdrv_write(s->qdev.conf.bs, r->req.sg, r->sector, + scsi_dma_complete, r); + } else { + n = r->qiov.size / 512; bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE); r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, r->sector, &r->qiov, n, scsi_write_complete, r); - } else { - /* Called for the first time. Ask the driver to send us more data. */ - scsi_write_complete(r, 0); } }