From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33420) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XEtsN-0000wv-2H for qemu-devel@nongnu.org; Wed, 06 Aug 2014 01:35:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XEtsG-000112-Rk for qemu-devel@nongnu.org; Wed, 06 Aug 2014 01:35:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:64027) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XEtsG-00010y-KU for qemu-devel@nongnu.org; Wed, 06 Aug 2014 01:34:56 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s765YsM5008559 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 6 Aug 2014 01:34:55 -0400 From: Fam Zheng Date: Wed, 6 Aug 2014 13:35:00 +0800 Message-Id: <1407303308-4615-3-git-send-email-famz@redhat.com> In-Reply-To: <1407303308-4615-1-git-send-email-famz@redhat.com> References: <1407303308-4615-1-git-send-email-famz@redhat.com> Subject: [Qemu-devel] [RFC PATCH v2 02/10] virtio-scsi: Split virtio_scsi_handle_cmd_req from virtio_scsi_handle_cmd List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, pbonzini@redhat.com, stefanha@redhat.com This is the "common part" to handle one cmd request. Refactor out for later usage of dataplane iothread code. Signed-off-by: Fam Zheng --- hw/scsi/virtio-scsi.c | 107 ++++++++++++++++------------------------ include/hw/virtio/virtio-scsi.h | 26 ++++++++++ 2 files changed, 69 insertions(+), 64 deletions(-) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 0eb069a..bd5d789 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -21,31 +21,6 @@ #include #include "hw/virtio/virtio-access.h" -typedef struct VirtIOSCSIReq { - VirtIOSCSI *dev; - VirtQueue *vq; - VirtQueueElement elem; - QEMUSGList qsgl; - SCSIRequest *sreq; - size_t resp_size; - enum SCSIXferMode mode; - QEMUIOVector resp_iov; - union { - VirtIOSCSICmdResp cmd; - VirtIOSCSICtrlTMFResp tmf; - VirtIOSCSICtrlANResp an; - VirtIOSCSIEvent event; - } resp; - union { - struct { - VirtIOSCSICmdReq cmd; - uint8_t cdb[]; - } QEMU_PACKED; - VirtIOSCSICtrlTMFReq tmf; - VirtIOSCSICtrlANReq an; - } req; -} VirtIOSCSIReq; - QEMU_BUILD_BUG_ON(offsetof(VirtIOSCSIReq, req.cdb) != offsetof(VirtIOSCSIReq, req.cmd) + sizeof(VirtIOSCSICmdReq)); @@ -434,52 +409,56 @@ static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq *req) virtio_scsi_complete_cmd_req(req); } +void virtio_scsi_handle_cmd_req(VirtIOSCSI *s, VirtIOSCSIReq *req) +{ + VirtIOSCSICommon *vs = &s->parent_obj; + int n; + SCSIDevice *d; + int rc; + + rc = virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size, + sizeof(VirtIOSCSICmdResp) + vs->sense_size); + if (rc < 0) { + if (rc == -ENOTSUP) { + virtio_scsi_fail_cmd_req(req); + } else { + virtio_scsi_bad_req(); + } + return; + } + + d = virtio_scsi_device_find(s, req->req.cmd.lun); + if (!d) { + req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET; + virtio_scsi_complete_cmd_req(req); + return; + } + req->sreq = scsi_req_new(d, req->req.cmd.tag, + virtio_scsi_get_lun(req->req.cmd.lun), + req->req.cdb, req); + + if (req->sreq->cmd.mode != SCSI_XFER_NONE + && (req->sreq->cmd.mode != req->mode || + req->sreq->cmd.xfer > req->qsgl.size)) { + req->resp.cmd.response = VIRTIO_SCSI_S_OVERRUN; + virtio_scsi_complete_cmd_req(req); + return; + } + + n = scsi_req_enqueue(req->sreq); + if (n) { + scsi_req_continue(req->sreq); + } +} + static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq) { /* use non-QOM casts in the data path */ VirtIOSCSI *s = (VirtIOSCSI *)vdev; - VirtIOSCSICommon *vs = &s->parent_obj; - VirtIOSCSIReq *req; - int n; while ((req = virtio_scsi_pop_req(s, vq))) { - SCSIDevice *d; - int rc; - - rc = virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size, - sizeof(VirtIOSCSICmdResp) + vs->sense_size); - if (rc < 0) { - if (rc == -ENOTSUP) { - virtio_scsi_fail_cmd_req(req); - } else { - virtio_scsi_bad_req(); - } - continue; - } - - d = virtio_scsi_device_find(s, req->req.cmd.lun); - if (!d) { - req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET; - virtio_scsi_complete_cmd_req(req); - continue; - } - req->sreq = scsi_req_new(d, req->req.cmd.tag, - virtio_scsi_get_lun(req->req.cmd.lun), - req->req.cdb, req); - - if (req->sreq->cmd.mode != SCSI_XFER_NONE - && (req->sreq->cmd.mode != req->mode || - req->sreq->cmd.xfer > req->qsgl.size)) { - req->resp.cmd.response = VIRTIO_SCSI_S_OVERRUN; - virtio_scsi_complete_cmd_req(req); - continue; - } - - n = scsi_req_enqueue(req->sreq); - if (n) { - scsi_req_continue(req->sreq); - } + virtio_scsi_handle_cmd_req(s, req); } } diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index 188a2d9..7349936 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -172,6 +172,31 @@ typedef struct { bool events_dropped; } VirtIOSCSI; +typedef struct VirtIOSCSIReq { + VirtIOSCSI *dev; + VirtQueue *vq; + VirtQueueElement elem; + QEMUSGList qsgl; + SCSIRequest *sreq; + size_t resp_size; + enum SCSIXferMode mode; + QEMUIOVector resp_iov; + union { + VirtIOSCSICmdResp cmd; + VirtIOSCSICtrlTMFResp tmf; + VirtIOSCSICtrlANResp an; + VirtIOSCSIEvent event; + } resp; + union { + struct { + VirtIOSCSICmdReq cmd; + uint8_t cdb[]; + } QEMU_PACKED; + VirtIOSCSICtrlTMFReq tmf; + VirtIOSCSICtrlANReq an; + } req; +} VirtIOSCSIReq; + #define DEFINE_VIRTIO_SCSI_PROPERTIES(_state, _conf_field) \ DEFINE_PROP_UINT32("num_queues", _state, _conf_field.num_queues, 1), \ DEFINE_PROP_UINT32("max_sectors", _state, _conf_field.max_sectors, 0xFFFF),\ @@ -192,5 +217,6 @@ void virtio_scsi_common_realize(DeviceState *dev, Error **errp, HandleOutput cmd); void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp); +void virtio_scsi_handle_cmd_req(VirtIOSCSI *s, VirtIOSCSIReq *req); #endif /* _QEMU_VIRTIO_SCSI_H */ -- 2.0.3