qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH v4 12/18] virtio-scsi: Add basic request processing infrastructure
Date: Wed, 22 Feb 2012 15:33:50 +0100	[thread overview]
Message-ID: <1329921236-23461-13-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1329921236-23461-1-git-send-email-pbonzini@redhat.com>

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/virtio-scsi.c |  142 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 140 insertions(+), 2 deletions(-)

diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index a297fed..a9f883c 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -135,14 +135,152 @@ typedef struct {
     uint32_t cdb_size;
 } VirtIOSCSI;
 
+typedef struct VirtIOSCSIReq {
+    VirtIOSCSI *dev;
+    VirtQueue *vq;
+    VirtQueueElement elem;
+    QEMUSGList qsgl;
+    SCSIRequest *sreq;
+    union {
+        char                  *buf;
+        VirtIOSCSICmdReq      *cmd;
+        VirtIOSCSICtrlTMFReq  *tmf;
+        VirtIOSCSICtrlANReq   *an;
+    } req;
+    union {
+        char                  *buf;
+        VirtIOSCSICmdResp     *cmd;
+        VirtIOSCSICtrlTMFResp *tmf;
+        VirtIOSCSICtrlANResp  *an;
+        VirtIOSCSIEvent       *event;
+    } resp;
+} VirtIOSCSIReq;
+
+static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
+{
+    VirtIOSCSI *s = req->dev;
+    VirtQueue *vq = req->vq;
+    virtqueue_push(vq, &req->elem, req->qsgl.size + req->elem.in_sg[0].iov_len);
+    qemu_sglist_destroy(&req->qsgl);
+    if (req->sreq) {
+        req->sreq->hba_private = NULL;
+        scsi_req_unref(req->sreq);
+    }
+    g_free(req);
+    virtio_notify(&s->vdev, vq);
+}
+
+static void virtio_scsi_bad_req(void)
+{
+    error_report("wrong size for virtio-scsi headers");
+    exit(1);
+}
+
+static void qemu_sgl_init_external(QEMUSGList *qsgl, struct iovec *sg,
+                                   target_phys_addr_t *addr, int num)
+{
+    memset(qsgl, 0, sizeof(*qsgl));
+    while (num--) {
+        qemu_sglist_add(qsgl, *(addr++), (sg++)->iov_len);
+    }
+}
+
+static void virtio_scsi_parse_req(VirtIOSCSI *s, VirtQueue *vq,
+                                  VirtIOSCSIReq *req)
+{
+    assert(req->elem.out_num && req->elem.in_num);
+    req->vq = vq;
+    req->dev = s;
+    req->sreq = NULL;
+    req->req.buf = req->elem.out_sg[0].iov_base;
+    req->resp.buf = req->elem.in_sg[0].iov_base;
+
+    if (req->elem.out_num > 1) {
+        qemu_sgl_init_external(&req->qsgl, &req->elem.out_sg[1],
+                               &req->elem.out_addr[1],
+                               req->elem.out_num - 1);
+    } else {
+        qemu_sgl_init_external(&req->qsgl, &req->elem.in_sg[1],
+                               &req->elem.in_addr[1],
+                               req->elem.in_num - 1);
+    }
+}
+
+static VirtIOSCSIReq *virtio_scsi_pop_req(VirtIOSCSI *s, VirtQueue *vq)
+{
+    VirtIOSCSIReq *req;
+    req = g_malloc(sizeof(*req));
+    if (!virtqueue_pop(vq, &req->elem)) {
+        g_free(req);
+        return NULL;
+    }
+
+    virtio_scsi_parse_req(s, vq, req);
+    return req;
+}
+
+static void virtio_scsi_fail_ctrl_req(VirtIOSCSIReq *req)
+{
+    if (req->req.tmf->type == VIRTIO_SCSI_T_TMF) {
+        req->resp.tmf->response = VIRTIO_SCSI_S_FAILURE;
+    } else {
+        req->resp.an->response = VIRTIO_SCSI_S_FAILURE;
+    }
+
+    virtio_scsi_complete_req(req);
+}
+
 static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
 {
-    /* TODO */
+    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
+    VirtIOSCSIReq *req;
+
+    while ((req = virtio_scsi_pop_req(s, vq))) {
+        virtio_scsi_fail_ctrl_req(req);
+    }
+}
+
+static void virtio_scsi_fail_cmd_req(VirtIOSCSI *s, VirtIOSCSIReq *req)
+{
+    req->resp.cmd->response = VIRTIO_SCSI_S_FAILURE;
+    virtio_scsi_complete_req(req);
 }
 
 static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
 {
-    /* TODO */
+    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
+    VirtIOSCSIReq *req;
+
+    while ((req = virtio_scsi_pop_req(s, vq))) {
+        int out_size, in_size;
+        if (req->elem.out_num < 1 || req->elem.in_num < 1) {
+            virtio_scsi_bad_req();
+        }
+
+        out_size = req->elem.out_sg[0].iov_len;
+        in_size = req->elem.in_sg[0].iov_len;
+        if (out_size < sizeof(VirtIOSCSICmdReq) + s->cdb_size ||
+            in_size < sizeof(VirtIOSCSICmdResp) + s->sense_size) {
+            virtio_scsi_bad_req();
+        }
+
+        if (req->elem.out_num > 1 && req->elem.in_num > 1) {
+            virtio_scsi_fail_cmd_req(s, req);
+            continue;
+        }
+
+        req->resp.cmd->resid = 0;
+        req->resp.cmd->status_qualifier = 0;
+        req->resp.cmd->status = CHECK_CONDITION;
+        req->resp.cmd->sense_len = 4;
+        req->resp.cmd->sense[0] = 0xf0; /* Fixed format current sense */
+        req->resp.cmd->sense[1] = ILLEGAL_REQUEST;
+        req->resp.cmd->sense[2] = 0x20;
+        req->resp.cmd->sense[3] = 0x00;
+        req->resp.cmd->response = VIRTIO_SCSI_S_OK;
+
+        virtio_scsi_complete_req(req);
+    }
 }
 
 static void virtio_scsi_get_config(VirtIODevice *vdev,
-- 
1.7.7.6

  parent reply	other threads:[~2012-02-22 14:34 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-22 14:33 [Qemu-devel] [PULL v4 00/18] virtio-scsi driver Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 01/18] dma-helpers: make QEMUSGList target independent Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 02/18] dma-helpers: add dma_buf_read and dma_buf_write Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 03/18] dma-helpers: add accounting wrappers Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 04/18] ahci: use new DMA helpers Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 05/18] scsi: pass residual amount to command_complete Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 06/18] scsi: add scatter/gather functionality Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 07/18] scsi-disk: enable " Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 08/18] scsi: add SCSIDevice vmstate definitions Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 09/18] scsi-generic: add migration support Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 10/18] scsi-disk: " Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 11/18] virtio-scsi: Add virtio-scsi stub device Paolo Bonzini
2012-02-22 14:33 ` Paolo Bonzini [this message]
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 13/18] virtio-scsi: add basic SCSI bus operation Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 14/18] virtio-scsi: process control queue requests Paolo Bonzini
2012-02-24  7:54   ` Hu Tao
2012-02-24  8:56     ` Paolo Bonzini
2012-02-24 13:58     ` Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 15/18] virtio-scsi: add migration support Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 16/18] scsi: fix wrong return for target INQUIRY Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 17/18] scsi: fix searching for an empty id Paolo Bonzini
2012-02-22 14:33 ` [Qemu-devel] [PATCH v4 18/18] scsi-block: always use scsi_generic_ops for cache != none Paolo Bonzini
2012-02-24 16:34 ` [Qemu-devel] [PULL v4 00/18] virtio-scsi driver Anthony Liguori

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=1329921236-23461-13-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --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 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).