From patchwork Thu Nov 18 14:47:50 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 72110 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B44A2B71A7 for ; Fri, 19 Nov 2010 02:04:32 +1100 (EST) Received: from localhost ([127.0.0.1]:50658 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PJ61I-0000s7-A3 for incoming@patchwork.ozlabs.org; Thu, 18 Nov 2010 10:03:28 -0500 Received: from [140.186.70.92] (port=35936 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PJ5jt-0001xi-BU for qemu-devel@nongnu.org; Thu, 18 Nov 2010 09:45:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PJ5jr-0001rg-Rz for qemu-devel@nongnu.org; Thu, 18 Nov 2010 09:45:29 -0500 Received: from cantor.suse.de ([195.135.220.2]:49175 helo=mx1.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PJ5jr-0001rP-JH for qemu-devel@nongnu.org; Thu, 18 Nov 2010 09:45:27 -0500 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id D9F5993EE3; Thu, 18 Nov 2010 15:45:26 +0100 (CET) Date: Thu, 18 Nov 2010 15:47:50 +0100 To: qemu-devel@nongnu.org User-Agent: Heirloom mailx 12.2 01/07/07 MIME-Version: 1.0 Message-Id: <20101118144750.9A528F90AB@ochil.suse.de> From: hare@suse.de (Hannes Reinecke) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 Cc: stefanha@gmail.com, nab@linux-iscsi.org, kraxel@redhat.com Subject: [Qemu-devel] [PATCH 15/16] scsi: Implement get_req_iov callback X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add callback to create a request with a predefined iovec. Signed-off-by: Hannes Reinecke --- hw/scsi-disk.c | 25 +++++++++++++++++++++---- hw/scsi-generic.c | 44 ++++++++++++++++++++++++++++++++++---------- hw/scsi.h | 2 ++ 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index f9b66ac..0f144f3 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -95,14 +95,30 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, return req; } +static SCSIRequest *scsi_new_request_iovec(SCSIDevice *d, uint32_t tag, + uint32_t lun, struct iovec *iov, int iov_num) +{ + SCSIRequest *req; + SCSIDiskReq *r; + + req = scsi_req_alloc(sizeof(SCSIDiskReq), d, tag, lun); + r = DO_UPCAST(SCSIDiskReq, req, req); + r->iov = iov; + r->iov_num = iov_num; + r->iov_buf = NULL; + return req; +} + static void scsi_remove_request(SCSIRequest *req) { SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); - qemu_vfree(r->iov); - r->iov = NULL; - qemu_vfree(r->iov_buf); - r->iov_buf = NULL; + if (r->iov_buf) { + qemu_vfree(r->iov); + r->iov = NULL; + qemu_vfree(r->iov_buf); + r->iov_buf = NULL; + } scsi_req_free(&r->req); } @@ -1217,6 +1233,7 @@ static SCSIDeviceInfo scsi_disk_info = { .init = scsi_disk_initfn, .destroy = scsi_destroy, .get_req = scsi_new_request, + .get_req_iov = scsi_new_request_iovec, .put_req = scsi_remove_request, .send_command = scsi_send_command, .read_data = scsi_read_data, diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index fa03337..13fa6f4 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -107,6 +107,25 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun) return req; } +static SCSIRequest *scsi_new_request_iovec(SCSIDevice *d, uint32_t tag, + uint32_t lun, struct iovec *iov, int iov_num) +{ + SCSIRequest *req; + SCSIGenericReq *r; + int i; + + req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun); + r = DO_UPCAST(SCSIGenericReq, req, req); + r->io_header.dxferp = iov; + r->io_header.iovec_count = iov_num; + r->io_header.dxfer_len = 0; + for (i = 0; i < iov_num; i++) + r->io_header.dxfer_len += iov[i].iov_len; + r->buf = NULL; + r->buflen = 0; + return req; +} + static void scsi_remove_request(SCSIRequest *req) { SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); @@ -176,8 +195,10 @@ static int execute_command(BlockDriverState *bdrv, r->io_header.interface_id = 'S'; r->io_header.dxfer_direction = direction; - r->io_header.dxferp = r->buf; - r->io_header.dxfer_len = r->buflen; + if (r->buf) { + r->io_header.dxferp = r->buf; + r->io_header.dxfer_len = r->buflen; + } r->io_header.cmdp = r->req.cmd.buf; r->io_header.cmd_len = r->req.cmd.len; r->io_header.mx_sb_len = sizeof(s->sensebuf); @@ -282,7 +303,7 @@ static int scsi_write_data(SCSIRequest *req) DPRINTF("scsi_write_data 0x%x\n", req->tag); - if (r->len == 0) { + if (r->len == 0 && r->io_header.dxfer_len == 0) { r->len = r->buflen; r->req.bus->complete(&r->req, SCSI_REASON_DATA, r->len); return 0; @@ -376,14 +397,16 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd) return 0; } - if (r->buflen != r->req.cmd.xfer) { - if (r->buf != NULL) - qemu_free(r->buf); - r->buf = qemu_malloc(r->req.cmd.xfer); - r->buflen = r->req.cmd.xfer; - } + if (!r->io_header.iovec_count) { + if (r->buflen != r->req.cmd.xfer) { + if (r->buf != NULL) + qemu_free(r->buf); + r->buf = qemu_malloc(r->req.cmd.xfer); + r->buflen = r->req.cmd.xfer; + } - memset(r->buf, 0, r->buflen); + memset(r->buf, 0, r->buflen); + } r->len = r->req.cmd.xfer; if (r->req.cmd.mode == SCSI_XFER_TO_DEV) { r->len = 0; @@ -553,6 +576,7 @@ static SCSIDeviceInfo scsi_generic_info = { .init = scsi_generic_initfn, .destroy = scsi_destroy, .get_req = scsi_new_request, + .get_req_iov = scsi_new_request_iovec, .put_req = scsi_remove_request, .send_command = scsi_send_command, .read_data = scsi_read_data, diff --git a/hw/scsi.h b/hw/scsi.h index 6c2540e..10594de 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -72,6 +72,8 @@ struct SCSIDeviceInfo { scsi_qdev_initfn init; void (*destroy)(SCSIDevice *s); SCSIRequest *(*get_req)(SCSIDevice *s, uint32_t tag, uint32_t lun); + SCSIRequest *(*get_req_iov)(SCSIDevice *s, uint32_t tag, uint32_t lun, + struct iovec *iov, int iov_num); void (*put_req)(SCSIRequest *req); int32_t (*send_command)(SCSIRequest *req, uint8_t *buf); void (*read_data)(SCSIRequest *req);