summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/scsi/scsi-disk.c17
-rw-r--r--hw/scsi/scsi-generic.c8
-rw-r--r--hw/scsi/vhost-scsi.c2
3 files changed, 21 insertions, 6 deletions
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index c8d2a99593..74e6a14c29 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -61,8 +61,9 @@ typedef struct SCSIDiskReq {
BlockAcctCookie acct;
} SCSIDiskReq;
-#define SCSI_DISK_F_REMOVABLE 0
-#define SCSI_DISK_F_DPOFUA 1
+#define SCSI_DISK_F_REMOVABLE 0
+#define SCSI_DISK_F_DPOFUA 1
+#define SCSI_DISK_F_NO_REMOVABLE_DEVOPS 2
struct SCSIDiskState
{
@@ -1984,6 +1985,9 @@ static void scsi_disk_reset(DeviceState *dev)
nb_sectors--;
}
s->qdev.max_lba = nb_sectors;
+ /* reset tray statuses */
+ s->tray_locked = 0;
+ s->tray_open = 0;
}
static void scsi_destroy(SCSIDevice *dev)
@@ -2107,7 +2111,8 @@ static int scsi_initfn(SCSIDevice *dev)
return -1;
}
- if (s->features & (1 << SCSI_DISK_F_REMOVABLE)) {
+ if ((s->features & (1 << SCSI_DISK_F_REMOVABLE)) &&
+ !(s->features & (1 << SCSI_DISK_F_NO_REMOVABLE_DEVOPS))) {
bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_disk_removable_block_ops, s);
} else {
bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_disk_block_ops, s);
@@ -2319,6 +2324,12 @@ static int scsi_block_initfn(SCSIDevice *dev)
} else {
s->qdev.blocksize = 512;
}
+
+ /* Makes the scsi-block device not removable by using HMP and QMP eject
+ * command.
+ */
+ s->features |= (1 << SCSI_DISK_F_NO_REMOVABLE_DEVOPS);
+
return scsi_initfn(&s->qdev);
}
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 2a9a561127..8f195bec00 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -174,6 +174,9 @@ static int execute_command(BlockDriverState *bdrv,
r->io_header.flags |= SG_FLAG_DIRECT_IO;
r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
+ if (r->req.aiocb == NULL) {
+ return -EIO;
+ }
return 0;
}
@@ -198,9 +201,10 @@ static void scsi_read_complete(void * opaque, int ret)
scsi_command_complete(r, 0);
} else {
/* Snoop READ CAPACITY output to set the blocksize. */
- if (r->req.cmd.buf[0] == READ_CAPACITY_10) {
+ if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
+ (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
s->blocksize = ldl_be_p(&r->buf[4]);
- s->max_lba = ldl_be_p(&r->buf[0]);
+ s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
} else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
(r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
s->blocksize = ldl_be_p(&r->buf[8]);
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index d7a1c33183..785e93f545 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -123,7 +123,7 @@ static void vhost_scsi_stop(VHostSCSI *s)
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
int ret = 0;
- if (!k->set_guest_notifiers) {
+ if (k->set_guest_notifiers) {
ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
if (ret < 0) {
error_report("vhost guest notifier cleanup failed: %d\n", ret);