aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVenu Busireddy <venu.busireddy@oracle.com>2022-10-06 14:49:46 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2022-10-13 23:38:33 +0200
commit8cc5583abe6419e7faaebc9fbd109f34f4c850f2 (patch)
tree337bcecff7c0ab0523fe847506633ef857d78a7c
parent2ba341b3694cf3cff7b8a1df4cc765900d5c4f60 (diff)
downloadqemu-8cc5583abe6419e7faaebc9fbd109f34f4c850f2.zip
qemu-8cc5583abe6419e7faaebc9fbd109f34f4c850f2.tar.gz
qemu-8cc5583abe6419e7faaebc9fbd109f34f4c850f2.tar.bz2
virtio-scsi: Send "REPORTED LUNS CHANGED" sense data upon disk hotplug events
Section 5.6.6.3 of VirtIO specification states, "Events will also be reported via sense codes..." However, no sense data is sent when VIRTIO_SCSI_EVT_RESET_RESCAN or VIRTIO_SCSI_EVT_RESET_REMOVED events are reported (when disk hotplug/hotunplug events occur). SCSI layer on Solaris depends on this sense data, and hence does not handle disk hotplug/hotunplug events. When the disk inventory changes, use the bus unit attention mechanism to return a CHECK_CONDITION status with sense data of 0x06/0x3F/0x0E (sense code REPORTED_LUNS_CHANGED). The first device on the bus to execute a command successfully will report and consume the unit attention status. Signed-off-by: Venu Busireddy <venu.busireddy@oracle.com> Message-Id: <20221006194946.24134-1-venu.busireddy@oracle.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--hw/scsi/scsi-bus.c18
-rw-r--r--hw/scsi/virtio-scsi.c2
-rw-r--r--include/hw/scsi/scsi.h1
3 files changed, 21 insertions, 0 deletions
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 4403717..ceceafb 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -1616,6 +1616,24 @@ static int scsi_ua_precedence(SCSISense sense)
return (sense.asc << 8) | sense.ascq;
}
+void scsi_bus_set_ua(SCSIBus *bus, SCSISense sense)
+{
+ int prec1, prec2;
+ if (sense.key != UNIT_ATTENTION) {
+ return;
+ }
+
+ /*
+ * Override a pre-existing unit attention condition, except for a more
+ * important reset condition.
+ */
+ prec1 = scsi_ua_precedence(bus->unit_attention);
+ prec2 = scsi_ua_precedence(sense);
+ if (prec2 < prec1) {
+ bus->unit_attention = sense;
+ }
+}
+
void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense)
{
int prec1, prec2;
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 41f2a56..cf2721a 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -956,6 +956,7 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
virtio_scsi_push_event(s, sd,
VIRTIO_SCSI_T_TRANSPORT_RESET,
VIRTIO_SCSI_EVT_RESET_RESCAN);
+ scsi_bus_set_ua(&s->bus, SENSE_CODE(REPORTED_LUNS_CHANGED));
virtio_scsi_release(s);
}
}
@@ -973,6 +974,7 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
virtio_scsi_push_event(s, sd,
VIRTIO_SCSI_T_TRANSPORT_RESET,
VIRTIO_SCSI_EVT_RESET_REMOVED);
+ scsi_bus_set_ua(&s->bus, SENSE_CODE(REPORTED_LUNS_CHANGED));
virtio_scsi_release(s);
}
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 0011034..3b1b3d2 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -186,6 +186,7 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
BlockdevOnError rerror,
BlockdevOnError werror,
const char *serial, Error **errp);
+void scsi_bus_set_ua(SCSIBus *bus, SCSISense sense);
void scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
void scsi_legacy_handle_cmdline(void);