From patchwork Wed Jan 30 16:41:25 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 216944 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 184CE2C02F6 for ; Thu, 31 Jan 2013 07:53:07 +1100 (EST) Received: from localhost ([::1]:54443 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U0ajy-0000B8-NE for incoming@patchwork.ozlabs.org; Wed, 30 Jan 2013 11:42:26 -0500 Received: from eggs.gnu.org ([208.118.235.92]:60596) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U0ajJ-0006w7-4X for qemu-devel@nongnu.org; Wed, 30 Jan 2013 11:41:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U0ajG-0003k7-A8 for qemu-devel@nongnu.org; Wed, 30 Jan 2013 11:41:44 -0500 Received: from mail-qe0-f44.google.com ([209.85.128.44]:56248) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U0ajG-0003k2-4q for qemu-devel@nongnu.org; Wed, 30 Jan 2013 11:41:42 -0500 Received: by mail-qe0-f44.google.com with SMTP id a11so817649qen.3 for ; Wed, 30 Jan 2013 08:41:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:sender:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=Y0E30ur4BR4uSkYKudpgeEktIuyTOt/NwrYW3b45vFM=; b=wP0x2WTUSVatkS2+G29uf/4HVyWoghTtLxLJfkFdWVbLWwQNh8qYLXtc8XVEHce2ty unPlpl8R1t17g/lNqKXRyocE23qIc3ODE3Kp2iYd39k80PaLWtGpeycS7Vj8NvHxuR2P CWcuLGsOKtANwvEHvmFgH8L161r6KLcIS55JLRFkMlkEO5jLitDoeYvjCRZVmpg2giqi g5PkCUBIeMRQsF6QR/LLTo2Objh4yLVtSvltJDXlcRQlIP2YrFrINknBCgnim65321p4 +VDsy1Xz+Pup35TRcy4QZfnDSX6uiPXFLoR3B7pAcMiCIxhSvsWmHZQ1xfFhQts4ckMN gDvQ== X-Received: by 10.224.195.65 with SMTP id eb1mr5618394qab.83.1359564101604; Wed, 30 Jan 2013 08:41:41 -0800 (PST) Received: from yakj.usersys.redhat.com (93-34-179-137.ip50.fastwebnet.it. [93.34.179.137]) by mx.google.com with ESMTPS id df6sm1820861qab.6.2013.01.30.08.41.39 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 30 Jan 2013 08:41:40 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Wed, 30 Jan 2013 17:41:25 +0100 Message-Id: <1359564086-19705-4-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.1 In-Reply-To: <1359564086-19705-1-git-send-email-pbonzini@redhat.com> References: <1359564086-19705-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.128.44 Cc: asias@redhat.com, stefanha@linux.vnet.ibm.com, nab@linux-iscsi.org, mst@redhat.com Subject: [Qemu-devel] [PATCH 3/4] virtio-scsi: create VirtIOSCSICommon 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/virtio-scsi.c | 199 +++++++++++++-------------------------------------- hw/virtio-scsi.h | 127 ++++++++++++++++++++++++++++++++ include/qemu/osdep.h | 4 ++ 3 files changed, 180 insertions(+), 150 deletions(-) diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c index 0715865..363aba4 100644 --- a/hw/virtio-scsi.c +++ b/hw/virtio-scsi.c @@ -17,131 +17,12 @@ #include #include -#define VIRTIO_SCSI_VQ_SIZE 128 -#define VIRTIO_SCSI_CDB_SIZE 32 -#define VIRTIO_SCSI_SENSE_SIZE 96 -#define VIRTIO_SCSI_MAX_CHANNEL 0 -#define VIRTIO_SCSI_MAX_TARGET 255 -#define VIRTIO_SCSI_MAX_LUN 16383 - -/* Response codes */ -#define VIRTIO_SCSI_S_OK 0 -#define VIRTIO_SCSI_S_OVERRUN 1 -#define VIRTIO_SCSI_S_ABORTED 2 -#define VIRTIO_SCSI_S_BAD_TARGET 3 -#define VIRTIO_SCSI_S_RESET 4 -#define VIRTIO_SCSI_S_BUSY 5 -#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6 -#define VIRTIO_SCSI_S_TARGET_FAILURE 7 -#define VIRTIO_SCSI_S_NEXUS_FAILURE 8 -#define VIRTIO_SCSI_S_FAILURE 9 -#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10 -#define VIRTIO_SCSI_S_FUNCTION_REJECTED 11 -#define VIRTIO_SCSI_S_INCORRECT_LUN 12 - -/* Controlq type codes. */ -#define VIRTIO_SCSI_T_TMF 0 -#define VIRTIO_SCSI_T_AN_QUERY 1 -#define VIRTIO_SCSI_T_AN_SUBSCRIBE 2 - -/* Valid TMF subtypes. */ -#define VIRTIO_SCSI_T_TMF_ABORT_TASK 0 -#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1 -#define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2 -#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3 -#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4 -#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5 -#define VIRTIO_SCSI_T_TMF_QUERY_TASK 6 -#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7 - -/* Events. */ -#define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000 -#define VIRTIO_SCSI_T_NO_EVENT 0 -#define VIRTIO_SCSI_T_TRANSPORT_RESET 1 -#define VIRTIO_SCSI_T_ASYNC_NOTIFY 2 -#define VIRTIO_SCSI_T_PARAM_CHANGE 3 - -/* Reasons for transport reset event */ -#define VIRTIO_SCSI_EVT_RESET_HARD 0 -#define VIRTIO_SCSI_EVT_RESET_RESCAN 1 -#define VIRTIO_SCSI_EVT_RESET_REMOVED 2 - -/* SCSI command request, followed by data-out */ typedef struct { - uint8_t lun[8]; /* Logical Unit Number */ - uint64_t tag; /* Command identifier */ - uint8_t task_attr; /* Task attribute */ - uint8_t prio; - uint8_t crn; - uint8_t cdb[]; -} QEMU_PACKED VirtIOSCSICmdReq; - -/* Response, followed by sense data and data-in */ -typedef struct { - uint32_t sense_len; /* Sense data length */ - uint32_t resid; /* Residual bytes in data buffer */ - uint16_t status_qualifier; /* Status qualifier */ - uint8_t status; /* Command completion status */ - uint8_t response; /* Response values */ - uint8_t sense[]; -} QEMU_PACKED VirtIOSCSICmdResp; - -/* Task Management Request */ -typedef struct { - uint32_t type; - uint32_t subtype; - uint8_t lun[8]; - uint64_t tag; -} QEMU_PACKED VirtIOSCSICtrlTMFReq; - -typedef struct { - uint8_t response; -} QEMU_PACKED VirtIOSCSICtrlTMFResp; - -/* Asynchronous notification query/subscription */ -typedef struct { - uint32_t type; - uint8_t lun[8]; - uint32_t event_requested; -} QEMU_PACKED VirtIOSCSICtrlANReq; - -typedef struct { - uint32_t event_actual; - uint8_t response; -} QEMU_PACKED VirtIOSCSICtrlANResp; - -typedef struct { - uint32_t event; - uint8_t lun[8]; - uint32_t reason; -} QEMU_PACKED VirtIOSCSIEvent; - -typedef struct { - uint32_t num_queues; - uint32_t seg_max; - uint32_t max_sectors; - uint32_t cmd_per_lun; - uint32_t event_info_size; - uint32_t sense_size; - uint32_t cdb_size; - uint16_t max_channel; - uint16_t max_target; - uint32_t max_lun; -} QEMU_PACKED VirtIOSCSIConfig; - -typedef struct { - VirtIODevice vdev; - DeviceState *qdev; - VirtIOSCSIConf *conf; + VirtIOSCSICommon vs; SCSIBus bus; - uint32_t sense_size; - uint32_t cdb_size; int resetting; bool events_dropped; - VirtQueue *ctrl_vq; - VirtQueue *event_vq; - VirtQueue *cmd_vqs[0]; } VirtIOSCSI; typedef struct VirtIOSCSIReq { @@ -192,7 +73,7 @@ static void virtio_scsi_complete_req(VirtIOSCSIReq *req) scsi_req_unref(req->sreq); } g_free(req); - virtio_notify(&s->vdev, vq); + virtio_notify(&s->vs.vdev, vq); } static void virtio_scsi_bad_req(void) @@ -251,7 +132,7 @@ static void virtio_scsi_save_request(QEMUFile *f, SCSIRequest *sreq) VirtIOSCSIReq *req = sreq->hba_private; uint32_t n = virtio_queue_get_id(req->vq) - 2; - assert(n < req->dev->conf->num_queues); + assert(n < req->dev->vs.conf->num_queues); qemu_put_be32s(f, &n); qemu_put_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem)); } @@ -265,9 +146,9 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq) req = g_malloc(sizeof(*req)); qemu_get_be32s(f, &n); - assert(n < s->conf->num_queues); + assert(n < s->vs.conf->num_queues); qemu_get_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem)); - virtio_scsi_parse_req(s, s->cmd_vqs[n], req); + virtio_scsi_parse_req(s, s->vs.cmd_vqs[n], req); scsi_req_ref(sreq); req->sreq = sreq; @@ -482,8 +363,8 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq) 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) { + if (out_size < sizeof(VirtIOSCSICmdReq) + s->vs.cdb_size || + in_size < sizeof(VirtIOSCSICmdResp) + s->vs.sense_size) { virtio_scsi_bad_req(); } @@ -525,7 +406,7 @@ static void virtio_scsi_get_config(VirtIODevice *vdev, uint8_t *config) { VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config; - VirtIOSCSI *s = (VirtIOSCSI *)vdev; + VirtIOSCSICommon *s = (VirtIOSCSICommon *)vdev; stl_raw(&scsiconf->num_queues, s->conf->num_queues); stl_raw(&scsiconf->seg_max, 128 - 2); @@ -551,8 +432,8 @@ static void virtio_scsi_set_config(VirtIODevice *vdev, exit(1); } - s->sense_size = ldl_raw(&scsiconf->sense_size); - s->cdb_size = ldl_raw(&scsiconf->cdb_size); + s->vs.sense_size = ldl_raw(&scsiconf->sense_size); + s->vs.cdb_size = ldl_raw(&scsiconf->cdb_size); } static uint32_t virtio_scsi_get_features(VirtIODevice *vdev, @@ -569,8 +450,8 @@ static void virtio_scsi_reset(VirtIODevice *vdev) qbus_reset_all(&s->bus.qbus); s->resetting--; - s->sense_size = VIRTIO_SCSI_SENSE_SIZE; - s->cdb_size = VIRTIO_SCSI_CDB_SIZE; + s->vs.sense_size = VIRTIO_SCSI_SENSE_SIZE; + s->vs.cdb_size = VIRTIO_SCSI_CDB_SIZE; s->events_dropped = false; } @@ -580,7 +461,7 @@ static void virtio_scsi_reset(VirtIODevice *vdev) static void virtio_scsi_save(QEMUFile *f, void *opaque) { VirtIOSCSI *s = opaque; - virtio_save(&s->vdev, f); + virtio_save(&s->vs.vdev, f); } static int virtio_scsi_load(QEMUFile *f, void *opaque, int version_id) @@ -588,7 +469,7 @@ static int virtio_scsi_load(QEMUFile *f, void *opaque, int version_id) VirtIOSCSI *s = opaque; int ret; - ret = virtio_load(&s->vdev, f); + ret = virtio_load(&s->vs.vdev, f); if (ret) { return ret; } @@ -598,11 +479,11 @@ static int virtio_scsi_load(QEMUFile *f, void *opaque, int version_id) static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev, uint32_t event, uint32_t reason) { - VirtIOSCSIReq *req = virtio_scsi_pop_req(s, s->event_vq); + VirtIOSCSIReq *req = virtio_scsi_pop_req(s, s->vs.event_vq); VirtIOSCSIEvent *evt; int in_size; - if (!(s->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK)) { + if (!(s->vs.vdev.status & VIRTIO_CONFIG_S_DRIVER_OK)) { return; } @@ -657,7 +538,7 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense) { VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus); - if (((s->vdev.guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) && + if (((s->vs.vdev.guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) && dev->type != TYPE_ROM) { virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE, sense.asc | (sense.ascq << 8)); @@ -668,7 +549,7 @@ static void virtio_scsi_hotplug(SCSIBus *bus, SCSIDevice *dev) { VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus); - if ((s->vdev.guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) { + if ((s->vs.vdev.guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) { virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_RESCAN); } @@ -678,7 +559,7 @@ static void virtio_scsi_hot_unplug(SCSIBus *bus, SCSIDevice *dev) { VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus); - if ((s->vdev.guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) { + if ((s->vs.vdev.guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) { virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_REMOVED); } @@ -700,35 +581,53 @@ static struct SCSIBusInfo virtio_scsi_scsi_info = { .load_request = virtio_scsi_load_request, }; -VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf) +VirtIOSCSICommon *virtio_scsi_init_common(DeviceState *dev, VirtIOSCSIConf *proxyconf, + size_t sz) { - VirtIOSCSI *s; - static int virtio_scsi_id; - size_t sz; + VirtIOSCSICommon *s; int i; - sz = sizeof(VirtIOSCSI) + proxyconf->num_queues * sizeof(VirtQueue *); - s = (VirtIOSCSI *)virtio_common_init("virtio-scsi", VIRTIO_ID_SCSI, - sizeof(VirtIOSCSIConfig), sz); + /* Place the cmd_vqs array at the end of the block that the caller + * requested. Align the array properly, just in case. + */ + sz = ROUND_UP(sz, sizeof(void *)); + s = (VirtIOSCSICommon *) + virtio_common_init("virtio-scsi", VIRTIO_ID_SCSI, + sizeof(VirtIOSCSIConfig), + sz + sizeof(VirtQueue *) * proxyconf->num_queues); s->qdev = dev; s->conf = proxyconf; + s->sense_size = VIRTIO_SCSI_SENSE_SIZE; + s->cdb_size = VIRTIO_SCSI_CDB_SIZE; - /* TODO set up vdev function pointers */ s->vdev.get_config = virtio_scsi_get_config; - s->vdev.set_config = virtio_scsi_set_config; s->vdev.get_features = virtio_scsi_get_features; - s->vdev.reset = virtio_scsi_reset; s->ctrl_vq = virtio_add_queue(&s->vdev, VIRTIO_SCSI_VQ_SIZE, virtio_scsi_handle_ctrl); s->event_vq = virtio_add_queue(&s->vdev, VIRTIO_SCSI_VQ_SIZE, virtio_scsi_handle_event); + + s->cmd_vqs = (VirtQueue **) ((char *)s + sz); for (i = 0; i < s->conf->num_queues; i++) { s->cmd_vqs[i] = virtio_add_queue(&s->vdev, VIRTIO_SCSI_VQ_SIZE, virtio_scsi_handle_cmd); } + return s; +} + +VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf) +{ + VirtIOSCSI *s; + static int virtio_scsi_id; + + s = (VirtIOSCSI *)virtio_scsi_init_common(dev, proxyconf, sizeof(VirtIOSCSI)); + + s->vs.vdev.set_config = virtio_scsi_set_config; + s->vs.vdev.reset = virtio_scsi_reset; + scsi_bus_new(&s->bus, dev, &virtio_scsi_scsi_info); if (!dev->hotplugged) { scsi_bus_legacy_handle_cmdline(&s->bus); @@ -737,12 +636,12 @@ VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf) register_savevm(dev, "virtio-scsi", virtio_scsi_id++, 1, virtio_scsi_save, virtio_scsi_load, s); - return &s->vdev; + return &s->vs.vdev; } void virtio_scsi_exit(VirtIODevice *vdev) { VirtIOSCSI *s = (VirtIOSCSI *)vdev; - unregister_savevm(s->qdev, "virtio-scsi", s); + unregister_savevm(s->vs.qdev, "virtio-scsi", s); virtio_cleanup(vdev); } diff --git a/hw/virtio-scsi.h b/hw/virtio-scsi.h index 8d9d15f..b5d8a8c 100644 --- a/hw/virtio-scsi.h +++ b/hw/virtio-scsi.h @@ -25,12 +25,136 @@ #define VIRTIO_SCSI_F_HOTPLUG 1 #define VIRTIO_SCSI_F_CHANGE 2 +#define VIRTIO_SCSI_VQ_SIZE 128 +#define VIRTIO_SCSI_CDB_SIZE 32 +#define VIRTIO_SCSI_SENSE_SIZE 96 +#define VIRTIO_SCSI_MAX_CHANNEL 0 +#define VIRTIO_SCSI_MAX_TARGET 255 +#define VIRTIO_SCSI_MAX_LUN 16383 + +/* Response codes */ +#define VIRTIO_SCSI_S_OK 0 +#define VIRTIO_SCSI_S_OVERRUN 1 +#define VIRTIO_SCSI_S_ABORTED 2 +#define VIRTIO_SCSI_S_BAD_TARGET 3 +#define VIRTIO_SCSI_S_RESET 4 +#define VIRTIO_SCSI_S_BUSY 5 +#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6 +#define VIRTIO_SCSI_S_TARGET_FAILURE 7 +#define VIRTIO_SCSI_S_NEXUS_FAILURE 8 +#define VIRTIO_SCSI_S_FAILURE 9 +#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10 +#define VIRTIO_SCSI_S_FUNCTION_REJECTED 11 +#define VIRTIO_SCSI_S_INCORRECT_LUN 12 + +/* Controlq type codes. */ +#define VIRTIO_SCSI_T_TMF 0 +#define VIRTIO_SCSI_T_AN_QUERY 1 +#define VIRTIO_SCSI_T_AN_SUBSCRIBE 2 + +/* Valid TMF subtypes. */ +#define VIRTIO_SCSI_T_TMF_ABORT_TASK 0 +#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1 +#define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2 +#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3 +#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4 +#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5 +#define VIRTIO_SCSI_T_TMF_QUERY_TASK 6 +#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7 + +/* Events. */ +#define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000 +#define VIRTIO_SCSI_T_NO_EVENT 0 +#define VIRTIO_SCSI_T_TRANSPORT_RESET 1 +#define VIRTIO_SCSI_T_ASYNC_NOTIFY 2 +#define VIRTIO_SCSI_T_PARAM_CHANGE 3 + +/* Reasons for transport reset event */ +#define VIRTIO_SCSI_EVT_RESET_HARD 0 +#define VIRTIO_SCSI_EVT_RESET_RESCAN 1 +#define VIRTIO_SCSI_EVT_RESET_REMOVED 2 + +/* SCSI command request, followed by data-out */ +typedef struct { + uint8_t lun[8]; /* Logical Unit Number */ + uint64_t tag; /* Command identifier */ + uint8_t task_attr; /* Task attribute */ + uint8_t prio; + uint8_t crn; + uint8_t cdb[]; +} QEMU_PACKED VirtIOSCSICmdReq; + +/* Response, followed by sense data and data-in */ +typedef struct { + uint32_t sense_len; /* Sense data length */ + uint32_t resid; /* Residual bytes in data buffer */ + uint16_t status_qualifier; /* Status qualifier */ + uint8_t status; /* Command completion status */ + uint8_t response; /* Response values */ + uint8_t sense[]; +} QEMU_PACKED VirtIOSCSICmdResp; + +/* Task Management Request */ +typedef struct { + uint32_t type; + uint32_t subtype; + uint8_t lun[8]; + uint64_t tag; +} QEMU_PACKED VirtIOSCSICtrlTMFReq; + +typedef struct { + uint8_t response; +} QEMU_PACKED VirtIOSCSICtrlTMFResp; + +/* Asynchronous notification query/subscription */ +typedef struct { + uint32_t type; + uint8_t lun[8]; + uint32_t event_requested; +} QEMU_PACKED VirtIOSCSICtrlANReq; + +typedef struct { + uint32_t event_actual; + uint8_t response; +} QEMU_PACKED VirtIOSCSICtrlANResp; + +typedef struct { + uint32_t event; + uint8_t lun[8]; + uint32_t reason; +} QEMU_PACKED VirtIOSCSIEvent; + +typedef struct { + uint32_t num_queues; + uint32_t seg_max; + uint32_t max_sectors; + uint32_t cmd_per_lun; + uint32_t event_info_size; + uint32_t sense_size; + uint32_t cdb_size; + uint16_t max_channel; + uint16_t max_target; + uint32_t max_lun; +} QEMU_PACKED VirtIOSCSIConfig; + struct VirtIOSCSIConf { uint32_t num_queues; uint32_t max_sectors; uint32_t cmd_per_lun; }; +typedef struct VirtIOSCSICommon { + VirtIODevice vdev; + DeviceState *qdev; + VirtIOSCSIConf *conf; + + uint32_t sense_size; + uint32_t cdb_size; + VirtQueue *ctrl_vq; + VirtQueue *event_vq; + VirtQueue **cmd_vqs; +} VirtIOSCSICommon; + #define DEFINE_VIRTIO_SCSI_PROPERTIES(_state, _features_field, _conf_field) \ DEFINE_VIRTIO_COMMON_FEATURES(_state, _features_field), \ DEFINE_PROP_UINT32("num_queues", _state, _conf_field.num_queues, 1), \ @@ -39,4 +163,7 @@ struct VirtIOSCSIConf { DEFINE_PROP_BIT("hotplug", _state, _features_field, VIRTIO_SCSI_F_HOTPLUG, true), \ DEFINE_PROP_BIT("param_change", _state, _features_field, VIRTIO_SCSI_F_CHANGE, true) +VirtIOSCSICommon *virtio_scsi_init_common(DeviceState *dev, VirtIOSCSIConf *proxyconf, + size_t sz); + #endif /* _QEMU_VIRTIO_SCSI_H */ diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 87d3b9c..24ff6d0 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -60,6 +60,10 @@ typedef signed int int_fast16_t; #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif +#ifndef ROUND_UP +#define ROUND_UP(n,d) (((n) + (d) - 1) & -(d)) +#endif + #ifndef DIV_ROUND_UP #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) #endif