* [PATCH] hw/scsi/lsi53c895a: stop script on phase mismatch
@ 2024-03-02 21:44 Sven Schnelle
2024-03-02 22:53 ` Helge Deller
2024-03-04 7:57 ` Paolo Bonzini
0 siblings, 2 replies; 3+ messages in thread
From: Sven Schnelle @ 2024-03-02 21:44 UTC (permalink / raw)
To: Paolo Bonzini, Fam Zheng, qemu-devel; +Cc: deller, Sven Schnelle
Netbsd isn't happy with qemu lsi53c895a emulation:
cd0(esiop0:0:2:0): command with tag id 0 reset
esiop0: autoconfiguration error: phase mismatch without command
esiop0: autoconfiguration error: unhandled scsi interrupt, sist=0x80 sstat1=0x0 DSA=0x23a64b1 DSP=0x50
This is because lsi_bad_phase() triggers a phase mismatch, which
stops SCRIPT processing. However, after returning to
lsi_command_complete(), SCRIPT is restarted with lsi_resume_script().
Fix this by adding a return value to lsi_bad_phase(), and only resume
script processing when lsi_bad_phase() didn't trigger a host interrupt.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
hw/scsi/lsi53c895a.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 4ff9470381..59b88aff3f 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -573,8 +573,9 @@ static inline void lsi_set_phase(LSIState *s, int phase)
s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase;
}
-static void lsi_bad_phase(LSIState *s, int out, int new_phase)
+static int lsi_bad_phase(LSIState *s, int out, int new_phase)
{
+ int ret = 0;
/* Trigger a phase mismatch. */
if (s->ccntl0 & LSI_CCNTL0_ENPMJ) {
if ((s->ccntl0 & LSI_CCNTL0_PMJCTL)) {
@@ -587,8 +588,10 @@ static void lsi_bad_phase(LSIState *s, int out, int new_phase)
trace_lsi_bad_phase_interrupt();
lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
lsi_stop_script(s);
+ ret = 1;
}
lsi_set_phase(s, new_phase);
+ return ret;
}
@@ -792,7 +795,7 @@ static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
static void lsi_command_complete(SCSIRequest *req, size_t resid)
{
LSIState *s = LSI53C895A(req->bus->qbus.parent);
- int out;
+ int out, stop = 0;
out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
trace_lsi_command_complete(req->status);
@@ -800,7 +803,10 @@ static void lsi_command_complete(SCSIRequest *req, size_t resid)
s->command_complete = 2;
if (s->waiting && s->dbc != 0) {
/* Raise phase mismatch for short transfers. */
- lsi_bad_phase(s, out, PHASE_ST);
+ stop = lsi_bad_phase(s, out, PHASE_ST);
+ if (stop) {
+ s->waiting = 0;
+ }
} else {
lsi_set_phase(s, PHASE_ST);
}
@@ -810,7 +816,9 @@ static void lsi_command_complete(SCSIRequest *req, size_t resid)
lsi_request_free(s, s->current);
scsi_req_unref(req);
}
- lsi_resume_script(s);
+ if (!stop) {
+ lsi_resume_script(s);
+ }
}
/* Callback to indicate that the SCSI layer has completed a transfer. */
--
2.43.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] hw/scsi/lsi53c895a: stop script on phase mismatch
2024-03-02 21:44 [PATCH] hw/scsi/lsi53c895a: stop script on phase mismatch Sven Schnelle
@ 2024-03-02 22:53 ` Helge Deller
2024-03-04 7:57 ` Paolo Bonzini
1 sibling, 0 replies; 3+ messages in thread
From: Helge Deller @ 2024-03-02 22:53 UTC (permalink / raw)
To: Sven Schnelle, Paolo Bonzini, Fam Zheng, qemu-devel
On 3/2/24 22:44, Sven Schnelle wrote:
> Netbsd isn't happy with qemu lsi53c895a emulation:
>
> cd0(esiop0:0:2:0): command with tag id 0 reset
> esiop0: autoconfiguration error: phase mismatch without command
> esiop0: autoconfiguration error: unhandled scsi interrupt, sist=0x80 sstat1=0x0 DSA=0x23a64b1 DSP=0x50
>
> This is because lsi_bad_phase() triggers a phase mismatch, which
> stops SCRIPT processing. However, after returning to
> lsi_command_complete(), SCRIPT is restarted with lsi_resume_script().
> Fix this by adding a return value to lsi_bad_phase(), and only resume
> script processing when lsi_bad_phase() didn't trigger a host interrupt.
>
> Signed-off-by: Sven Schnelle <svens@stackframe.org>
Tested-by: Helge Deller <deller@gmx.de>
Helge
> ---
> hw/scsi/lsi53c895a.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
> index 4ff9470381..59b88aff3f 100644
> --- a/hw/scsi/lsi53c895a.c
> +++ b/hw/scsi/lsi53c895a.c
> @@ -573,8 +573,9 @@ static inline void lsi_set_phase(LSIState *s, int phase)
> s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase;
> }
>
> -static void lsi_bad_phase(LSIState *s, int out, int new_phase)
> +static int lsi_bad_phase(LSIState *s, int out, int new_phase)
> {
> + int ret = 0;
> /* Trigger a phase mismatch. */
> if (s->ccntl0 & LSI_CCNTL0_ENPMJ) {
> if ((s->ccntl0 & LSI_CCNTL0_PMJCTL)) {
> @@ -587,8 +588,10 @@ static void lsi_bad_phase(LSIState *s, int out, int new_phase)
> trace_lsi_bad_phase_interrupt();
> lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
> lsi_stop_script(s);
> + ret = 1;
> }
> lsi_set_phase(s, new_phase);
> + return ret;
> }
>
>
> @@ -792,7 +795,7 @@ static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
> static void lsi_command_complete(SCSIRequest *req, size_t resid)
> {
> LSIState *s = LSI53C895A(req->bus->qbus.parent);
> - int out;
> + int out, stop = 0;
>
> out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
> trace_lsi_command_complete(req->status);
> @@ -800,7 +803,10 @@ static void lsi_command_complete(SCSIRequest *req, size_t resid)
> s->command_complete = 2;
> if (s->waiting && s->dbc != 0) {
> /* Raise phase mismatch for short transfers. */
> - lsi_bad_phase(s, out, PHASE_ST);
> + stop = lsi_bad_phase(s, out, PHASE_ST);
> + if (stop) {
> + s->waiting = 0;
> + }
> } else {
> lsi_set_phase(s, PHASE_ST);
> }
> @@ -810,7 +816,9 @@ static void lsi_command_complete(SCSIRequest *req, size_t resid)
> lsi_request_free(s, s->current);
> scsi_req_unref(req);
> }
> - lsi_resume_script(s);
> + if (!stop) {
> + lsi_resume_script(s);
> + }
> }
>
> /* Callback to indicate that the SCSI layer has completed a transfer. */
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] hw/scsi/lsi53c895a: stop script on phase mismatch
2024-03-02 21:44 [PATCH] hw/scsi/lsi53c895a: stop script on phase mismatch Sven Schnelle
2024-03-02 22:53 ` Helge Deller
@ 2024-03-04 7:57 ` Paolo Bonzini
1 sibling, 0 replies; 3+ messages in thread
From: Paolo Bonzini @ 2024-03-04 7:57 UTC (permalink / raw)
To: Sven Schnelle; +Cc: Fam Zheng, qemu-devel, deller
Queued, thanks.
Paolo
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-03-04 7:58 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-02 21:44 [PATCH] hw/scsi/lsi53c895a: stop script on phase mismatch Sven Schnelle
2024-03-02 22:53 ` Helge Deller
2024-03-04 7:57 ` Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).