aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2014-10-29 13:00:11 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2014-10-31 11:29:00 +0100
commit8d72db68fe7b45c7e01f815c4ac3e6c7ac0e26c1 (patch)
treee8c03878cd97adc6eab05dffb173e9f1df985f26 /hw
parent77bb6b171043d03f7e4f5212beaa4e6cb3fd6528 (diff)
megasas: Clear unit attention on initial reset
The EFI firmware doesn't handle unit attentions properly, so we need to clear the Power On/Reset unit attention upon initial reset. Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/scsi/megasas.c18
-rw-r--r--hw/scsi/scsi-bus.c2
2 files changed, 18 insertions, 2 deletions
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 58e29aed71..57d52885b7 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -2202,11 +2202,26 @@ static void megasas_soft_reset(MegasasState *s)
int i;
MegasasCmd *cmd;
- trace_megasas_reset();
+ trace_megasas_reset(s->fw_state);
for (i = 0; i < s->fw_cmds; i++) {
cmd = &s->frames[i];
megasas_abort_command(cmd);
}
+ if (s->fw_state == MFI_FWSTATE_READY) {
+ BusChild *kid;
+
+ /*
+ * The EFI firmware doesn't handle UA,
+ * so we need to clear the Power On/Reset UA
+ * after the initial reset.
+ */
+ QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
+ SCSIDevice *sdev = DO_UPCAST(SCSIDevice, qdev, kid->child);
+
+ sdev->unit_attention = SENSE_CODE(NO_SENSE);
+ scsi_device_unit_attention_reported(sdev);
+ }
+ }
megasas_reset_frames(s);
s->reply_queue_len = s->fw_cmds;
s->reply_queue_pa = 0;
@@ -2334,6 +2349,7 @@ static int megasas_scsi_init(PCIDevice *dev)
msix_vector_use(dev, 0);
}
+ s->fw_state = MFI_FWSTATE_READY;
if (!s->sas_addr) {
s->sas_addr = ((NAA_LOCALLY_ASSIGNED_ID << 24) |
IEEE_COMPANY_LOCALLY_ASSIGNED) << 36;
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 6fce8471d4..6376b88722 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -84,7 +84,7 @@ static SCSIRequest *scsi_device_alloc_req(SCSIDevice *s, uint32_t tag, uint32_t
return NULL;
}
-static void scsi_device_unit_attention_reported(SCSIDevice *s)
+void scsi_device_unit_attention_reported(SCSIDevice *s)
{
SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
if (sc->unit_attention_reported) {