diff options
Diffstat (limited to 'hw/scsi')
| -rw-r--r-- | hw/scsi/megasas.c | 6 | ||||
| -rw-r--r-- | hw/scsi/scsi-generic.c | 10 | ||||
| -rw-r--r-- | hw/scsi/vhost-scsi-common.c | 27 |
3 files changed, 36 insertions, 7 deletions
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c index e90c00823a..e24c12d7ee 100644 --- a/hw/scsi/megasas.c +++ b/hw/scsi/megasas.c @@ -277,10 +277,10 @@ static int megasas_map_sgl(MegasasState *s, MegasasCmd *cmd, union mfi_sgl *sgl) cmd->flags = le16_to_cpu(cmd->frame->header.flags); iov_count = cmd->frame->header.sge_count; - if (iov_count > MEGASAS_MAX_SGE) { + if (!iov_count || iov_count > MEGASAS_MAX_SGE) { trace_megasas_iovec_sgl_overflow(cmd->index, iov_count, MEGASAS_MAX_SGE); - return iov_count; + return -1; } pci_dma_sglist_init(&cmd->qsg, PCI_DEVICE(s), iov_count); for (i = 0; i < iov_count; i++) { @@ -310,7 +310,7 @@ static int megasas_map_sgl(MegasasState *s, MegasasCmd *cmd, union mfi_sgl *sgl) return 0; unmap: qemu_sglist_destroy(&cmd->qsg); - return iov_count - i; + return -1; } /* diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index 86ed0a3822..2cb23ca891 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -162,7 +162,8 @@ static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s) } } - if (s->type == TYPE_DISK && (r->req.cmd.buf[1] & 0x01)) { + if ((s->type == TYPE_DISK || s->type == TYPE_ZBC) && + (r->req.cmd.buf[1] & 0x01)) { page = r->req.cmd.buf[2]; if (page == 0xb0) { uint32_t max_transfer = @@ -299,10 +300,11 @@ static void scsi_read_complete(void * opaque, int ret) } blk_set_guest_block_size(s->conf.blk, s->blocksize); - /* Patch MODE SENSE device specific parameters if the BDS is opened + /* + * Patch MODE SENSE device specific parameters if the BDS is opened * readonly. */ - if ((s->type == TYPE_DISK || s->type == TYPE_TAPE) && + if ((s->type == TYPE_DISK || s->type == TYPE_TAPE || s->type == TYPE_ZBC) && blk_is_read_only(s->conf.blk) && (r->req.cmd.buf[0] == MODE_SENSE || r->req.cmd.buf[0] == MODE_SENSE_10) && @@ -617,7 +619,7 @@ static void scsi_generic_read_device_identification(SCSIDevice *s) void scsi_generic_read_device_inquiry(SCSIDevice *s) { scsi_generic_read_device_identification(s); - if (s->type == TYPE_DISK) { + if (s->type == TYPE_DISK || s->type == TYPE_ZBC) { scsi_generic_set_vpd_bl_emulation(s); } else { s->needs_vpd_bl_emulation = false; diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c index 8ec49d7fef..767f827e55 100644 --- a/hw/scsi/vhost-scsi-common.c +++ b/hw/scsi/vhost-scsi-common.c @@ -32,6 +32,8 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc) BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); + VirtIOSCSICommon *vs = (VirtIOSCSICommon *)vsc; + if (!k->set_guest_notifiers) { error_report("binding does not support guest notifiers"); return -ENOSYS; @@ -49,6 +51,23 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc) } vsc->dev.acked_features = vdev->guest_features; + + assert(vsc->inflight == NULL); + vsc->inflight = g_new0(struct vhost_inflight, 1); + ret = vhost_dev_get_inflight(&vsc->dev, + vs->conf.virtqueue_size, + vsc->inflight); + if (ret < 0) { + error_report("Error get inflight: %d", -ret); + goto err_guest_notifiers; + } + + ret = vhost_dev_set_inflight(&vsc->dev, vsc->inflight); + if (ret < 0) { + error_report("Error set inflight: %d", -ret); + goto err_guest_notifiers; + } + ret = vhost_dev_start(&vsc->dev, vdev); if (ret < 0) { error_report("Error start vhost dev"); @@ -66,6 +85,9 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc) return ret; err_guest_notifiers: + g_free(vsc->inflight); + vsc->inflight = NULL; + k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false); err_host_notifiers: vhost_dev_disable_notifiers(&vsc->dev, vdev); @@ -89,6 +111,11 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc) } assert(ret >= 0); + if (vsc->inflight) { + vhost_dev_free_inflight(vsc->inflight); + vsc->inflight = NULL; + } + vhost_dev_disable_notifiers(&vsc->dev, vdev); } |