From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38790) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XjRvR-0000gW-BS for qemu-devel@nongnu.org; Wed, 29 Oct 2014 08:00:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XjRvI-0007pB-0K for qemu-devel@nongnu.org; Wed, 29 Oct 2014 08:00:29 -0400 Received: from cantor2.suse.de ([195.135.220.15]:34270 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XjRvH-0007oC-MH for qemu-devel@nongnu.org; Wed, 29 Oct 2014 08:00:19 -0400 From: Hannes Reinecke Date: Wed, 29 Oct 2014 13:00:11 +0100 Message-Id: <1414584016-25888-9-git-send-email-hare@suse.de> In-Reply-To: <1414584016-25888-1-git-send-email-hare@suse.de> References: <1414584016-25888-1-git-send-email-hare@suse.de> Subject: [Qemu-devel] [PATCH 08/13] megasas: Clear unit attention on initial reset List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Hannes Reinecke , Andreas Faerber , Nic Bellinger , Alexander Graf 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 --- hw/scsi/megasas.c | 18 +++++++++++++++++- hw/scsi/scsi-bus.c | 2 +- include/hw/scsi/scsi.h | 1 + trace-events | 2 +- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c index 13a49e8..53dda3d 100644 --- a/hw/scsi/megasas.c +++ b/hw/scsi/megasas.c @@ -2205,11 +2205,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; @@ -2337,6 +2352,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 919a86c..1f4d540 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -83,7 +83,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) { diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 4e9bbd1..268d4ad 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -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); diff --git a/trace-events b/trace-events index 69b95f5..11cfc44 100644 --- a/trace-events +++ b/trace-events @@ -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" -- 1.8.4.5