mirror of
https://git.proxmox.com/git/pve-qemu
synced 2025-08-24 11:17:51 +00:00

In particular, the i386 patches fix an issue that was newly introduced in 7.2.10 and the LSI patches improve the reentrancy fix. The others also sounded relevant and nice to have. Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
86 lines
3.1 KiB
Diff
86 lines
3.1 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Sven Schnelle <svens@stackframe.org>
|
|
Date: Wed, 10 Apr 2024 08:43:29 +0300
|
|
Subject: [PATCH] hw/scsi/lsi53c895a: stop script on phase mismatch
|
|
|
|
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>
|
|
Message-ID: <20240302214453.2071388-1-svens@stackframe.org>
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
(cherry picked from commit a9198b3132d81a6bfc9fdbf6f3d3a514c2864674)
|
|
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
|
|
---
|
|
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 ca619ed564..905f5ef237 100644
|
|
--- a/hw/scsi/lsi53c895a.c
|
|
+++ b/hw/scsi/lsi53c895a.c
|
|
@@ -570,8 +570,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)) {
|
|
@@ -584,8 +585,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;
|
|
}
|
|
|
|
|
|
@@ -789,7 +792,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);
|
|
@@ -797,7 +800,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);
|
|
}
|
|
@@ -807,7 +813,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. */
|