]> git.proxmox.com Git - mirror_qemu.git/commitdiff
megasas: Clear unit attention on initial reset
authorHannes Reinecke <hare@suse.de>
Wed, 29 Oct 2014 12:00:11 +0000 (13:00 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 31 Oct 2014 10:29:00 +0000 (11:29 +0100)
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>
hw/scsi/megasas.c
hw/scsi/scsi-bus.c
include/hw/scsi/scsi.h
trace-events

index 58e29aed715ece4083f00c87ef1b7d3ded91cd39..57d52885b7026bac027f192102931336a1a693d7 100644 (file)
@@ -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;
index 6fce8471d4fefd96f7661b8fac0dffcc703e8812..6376b88722e87d19d530832e4ec80aafd5f678de 100644 (file)
@@ -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) {
index fd48177fa6692d730476681d2f0257a1c38f8b82..f4aabfd0e790842335f10189a9b0f71f764d8038 100644 (file)
@@ -272,6 +272,7 @@ void scsi_req_retry(SCSIRequest *req);
 void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense);
 void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense);
 void scsi_device_report_change(SCSIDevice *dev, SCSISense sense);
+void scsi_device_unit_attention_reported(SCSIDevice *dev);
 int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
 SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun);
 
index cd149cb3f76fd89fae7191e941a76eed564e6ef1..2ceb8e426c16772a43cb3e2235a009741c082406 100644 (file)
@@ -754,7 +754,7 @@ megasas_dcmd_unsupported(int cmd, unsigned long size) "scmd %d: set properties l
 megasas_abort_frame(int cmd, int abort_cmd) "scmd %d: frame %x"
 megasas_abort_no_cmd(int cmd, uint64_t context) "scmd %d: no active command for frame context %" PRIx64 ""
 megasas_abort_invalid_context(int cmd, uint64_t context, int abort_cmd) "scmd %d: invalid frame context %" PRIx64 " for abort frame %x"
-megasas_reset(void) "Reset"
+megasas_reset(int fw_state) "firmware state %x"
 megasas_init(int sges, int cmds, const char *mode) "Using %d sges, %d cmds, %s mode"
 megasas_msix_raise(int vector) "vector %d"
 megasas_msi_raise(int vector) "vector %d"