Message ID | 1414569232-21357-13-git-send-email-hare@suse.de |
---|---|
State | New |
Headers | show |
On 10/29/2014 08:53 AM, Hannes Reinecke wrote: > + > + /* > + * 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); > + SCSISense *ua; > + > + ua = &sdev->unit_attention; > + *ua = SENSE_CODE(NO_SENSE); Just sdev->unit_attention = SENSE_CODE(NO_SENSE)? > + sdev->sense_is_ua = false; Setting sense_is_ua is unnecessary, it refers to dev->sense rather than dev->unit_attention. Just assert(dev->sense_len == 0) if you care. You need this too: scsi_device_unit_attention_reported(sdev); Otherwise the state machine that reports CD-ROM media changes gets messed up. Paolo
On 10/29/2014 10:14 AM, Paolo Bonzini wrote: > > > On 10/29/2014 08:53 AM, Hannes Reinecke wrote: >> + >> + /* >> + * 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); >> + SCSISense *ua; >> + >> + ua = &sdev->unit_attention; >> + *ua = SENSE_CODE(NO_SENSE); > > Just sdev->unit_attention = SENSE_CODE(NO_SENSE)? > Ok. >> + sdev->sense_is_ua = false; > > Setting sense_is_ua is unnecessary, it refers to dev->sense rather than > dev->unit_attention. Just assert(dev->sense_len == 0) if you care. > > You need this too: > > scsi_device_unit_attention_reported(sdev); > > Otherwise the state machine that reports CD-ROM media changes gets > messed up. > yeah, this is all a bit ad-hoc. So I'll be fixing it up with the next round. Cheers, Hannes
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c index 56336b0..7a6c94f 100644 --- a/hw/scsi/megasas.c +++ b/hw/scsi/megasas.c @@ -2203,11 +2203,28 @@ 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); + SCSISense *ua; + + ua = &sdev->unit_attention; + *ua = SENSE_CODE(NO_SENSE); + sdev->sense_is_ua = false; + } + } megasas_reset_frames(s); s->reply_queue_len = s->fw_cmds; s->reply_queue_pa = 0; @@ -2335,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/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"
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> --- hw/scsi/megasas.c | 20 +++++++++++++++++++- trace-events | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-)