qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Hannes Reinecke <hare@suse.de>
To: qemu-devel@nongnu.org
Cc: stefanha@gmail.com, nab@linux-iscsi.org, kraxel@redhat.com
Subject: [Qemu-devel] [PATCH 13/15] scsi: Implement alloc_req_iov callback
Date: Wed, 24 Nov 2010 12:16:08 +0100	[thread overview]
Message-ID: <1290597370-21365-14-git-send-email-hare@suse.de> (raw)
In-Reply-To: <1290597370-21365-1-git-send-email-hare@suse.de>

Add callback to create a request with a predefined iovec.
This is required for drivers which can use the iovec
of a command directly.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 hw/scsi-disk.c    |   25 +++++++++++++++++++++----
 hw/scsi-generic.c |   44 +++++++++++++++++++++++++++++++++-----------
 hw/scsi.h         |    2 ++
 3 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 68b8667..67f93a5 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -96,14 +96,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_free(r->iov);
-    r->iov = NULL;
-    qemu_vfree(r->iov_buf);
-    r->iov_buf = NULL;
+    if (r->iov_buf) {
+        qemu_free(r->iov);
+        r->iov = NULL;
+        qemu_vfree(r->iov_buf);
+        r->iov_buf = NULL;
+    }
     scsi_req_free(&r->req);
 }
 
@@ -1220,6 +1236,7 @@ static SCSIDeviceInfo scsi_disk_info = {
     .init         = scsi_disk_initfn,
     .destroy      = scsi_destroy,
     .alloc_req    = scsi_new_request,
+    .alloc_req_iov = scsi_new_request_iovec,
     .free_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 949b4cc..8c99e9e 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -108,6 +108,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);
@@ -180,8 +199,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);
@@ -287,7 +308,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;
@@ -369,8 +390,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
 #endif
 
     if (r->req.cmd.xfer == 0) {
-        if (r->buf != NULL)
-            qemu_free(r->buf);
+        qemu_free(r->buf);
         r->buflen = 0;
         r->buf = NULL;
         ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
@@ -381,14 +401,15 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
         return 0;
     }
 
-    if (r->buflen != r->req.cmd.xfer) {
-        if (r->buf != NULL)
+    if (!r->io_header.iovec_count) {
+        if (r->buflen != r->req.cmd.xfer) {
             qemu_free(r->buf);
-        r->buf = qemu_malloc(r->req.cmd.xfer);
-        r->buflen = r->req.cmd.xfer;
-    }
+            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;
@@ -561,6 +582,7 @@ static SCSIDeviceInfo scsi_generic_info = {
     .init         = scsi_generic_initfn,
     .destroy      = scsi_destroy,
     .alloc_req    = scsi_new_request,
+    .alloc_req_iov  = scsi_new_request_iovec,
     .free_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 cc96f85..063154d 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -72,6 +72,8 @@ struct SCSIDeviceInfo {
     scsi_qdev_initfn init;
     void (*destroy)(SCSIDevice *s);
     SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun);
+    SCSIRequest *(*alloc_req_iov)(SCSIDevice *s, uint32_t tag, uint32_t lun,
+                                  struct iovec *iov, int iov_num);
     void (*free_req)(SCSIRequest *req);
     int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
     void (*read_data)(SCSIRequest *req);
-- 
1.6.0.2

  parent reply	other threads:[~2010-11-24 11:13 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-24 11:15 [Qemu-devel] [PATCH 00/15] Megasas HBA emulation and SCSI update v.3 Hannes Reinecke
2010-11-24 11:15 ` [Qemu-devel] [PATCH 01/15] scsi: Increase the number of possible devices Hannes Reinecke
2010-11-24 11:15 ` [Qemu-devel] [PATCH 02/15] scsi: Return SAM status codes Hannes Reinecke
2010-11-24 16:51   ` Christoph Hellwig
2010-11-24 11:15 ` [Qemu-devel] [PATCH 03/15] scsi: INQUIRY VPD fixes Hannes Reinecke
2010-11-24 11:15 ` [Qemu-devel] [PATCH 04/15] scsi: Move sense handling into the driver Hannes Reinecke
2010-11-24 11:16 ` [Qemu-devel] [PATCH 05/15] scsi-disk: Remove duplicate cdb parsing Hannes Reinecke
2010-11-24 11:16 ` [Qemu-devel] [PATCH 06/15] scsi: Update sense code handling Hannes Reinecke
2010-11-25 14:33   ` Kevin Wolf
2010-12-21 11:56     ` Hannes Reinecke
2010-11-24 11:16 ` [Qemu-devel] [PATCH 07/15] lsi53c895a: Rename 'sense' to 'status' Hannes Reinecke
2010-11-24 11:16 ` [Qemu-devel] [PATCH 08/15] scsi-disk: Allocate iovec dynamically Hannes Reinecke
2010-11-24 11:16 ` [Qemu-devel] [PATCH 09/15] scsi: Use 'SCSIRequest' directly Hannes Reinecke
2010-11-24 11:16 ` [Qemu-devel] [PATCH 10/15] scsi-disk: add data direction checking Hannes Reinecke
2010-11-24 11:16 ` [Qemu-devel] [PATCH 11/15] Remove 'bus' argument from SCSI command completion callbacks Hannes Reinecke
2010-11-24 11:16 ` [Qemu-devel] [PATCH 12/15] scsi: Implement 'get_sense' callback Hannes Reinecke
2010-11-24 11:16 ` Hannes Reinecke [this message]
2010-11-24 16:52   ` [Qemu-devel] [PATCH 13/15] scsi: Implement alloc_req_iov callback Christoph Hellwig
2010-11-25  8:53     ` Hannes Reinecke
2010-11-25 15:29       ` Christoph Hellwig
2010-11-25 16:21         ` Hannes Reinecke
2010-11-26  0:06           ` Paul Brook
2010-11-24 11:16 ` [Qemu-devel] [PATCH 14/15] megasas: LSI Megaraid SAS emulation Hannes Reinecke
2010-11-25 14:36   ` [Qemu-devel] " Stefan Hajnoczi
2010-11-25 14:50     ` Hannes Reinecke
2010-11-25 14:52       ` Stefan Hajnoczi
2010-11-25 20:47   ` Sebastian Herbszt
2010-12-21 12:06     ` Hannes Reinecke
2010-11-24 11:16 ` [Qemu-devel] [PATCH 15/15] Make SCSI HBA configurable Hannes Reinecke
2010-11-24 16:50 ` [Qemu-devel] [PATCH 00/15] Megasas HBA emulation and SCSI update v.3 Christoph Hellwig
2010-12-10 22:14   ` [Qemu-devel] " Paolo Bonzini
2010-12-13  7:32     ` Hannes Reinecke
2010-12-16  1:45       ` Benjamin Herrenschmidt
2010-12-16  1:48         ` Benjamin Herrenschmidt
2010-12-16  8:34         ` Stefan Hajnoczi
2010-12-16 14:58         ` Kevin Wolf
2010-12-20 14:59 ` [Qemu-devel] " Christoph Hellwig
2010-12-20 15:25   ` Hannes Reinecke

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=1290597370-21365-14-git-send-email-hare@suse.de \
    --to=hare@suse.de \
    --cc=kraxel@redhat.com \
    --cc=nab@linux-iscsi.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@gmail.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).