summaryrefslogtreecommitdiffstats
path: root/hw/scsi/esp.c
diff options
context:
space:
mode:
authorPeter Maydell2019-01-11 16:46:09 +0100
committerPeter Maydell2019-01-11 16:46:09 +0100
commit15bede554162dda822cd762c689edb6fa32b6e3b (patch)
treeba397197336b06e020d9c5b403471e9d82d19c63 /hw/scsi/esp.c
parentMerge remote-tracking branch 'remotes/ehabkost/tags/machine-next-pull-request... (diff)
parentavoid TABs in files that only contain a few (diff)
downloadqemu-15bede554162dda822cd762c689edb6fa32b6e3b.tar.gz
qemu-15bede554162dda822cd762c689edb6fa32b6e3b.tar.xz
qemu-15bede554162dda822cd762c689edb6fa32b6e3b.zip
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* HAX support for Linux hosts (Alejandro) * esp bugfixes (Guenter) * Windows build cleanup (Marc-André) * checkpatch logic improvements (Paolo) * coalesced range bugfix (Paolo) * switch testsuite to TAP (Paolo) * QTAILQ rewrite (Paolo) * block/iscsi.c cancellation fixes (Stefan) * improve selection of the default accelerator (Thomas) # gpg: Signature made Fri 11 Jan 2019 14:47:40 GMT # gpg: using RSA key BFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (34 commits) avoid TABs in files that only contain a few remove space-tab sequences scripts: add script to convert multiline comments into 4-line format hw/watchdog/wdt_i6300esb: remove a unnecessary comment checkpatch: warn about qemu/queue.h head structs that are not typedef-ed qemu/queue.h: simplify reverse access to QTAILQ qemu/queue.h: reimplement QTAILQ without pointer-to-pointers qemu/queue.h: remove Q_TAILQ_{HEAD,ENTRY} qemu/queue.h: typedef QTAILQ heads qemu/queue.h: leave head structs anonymous unless necessary vfio: make vfio_address_spaces static qemu/queue.h: do not access tqe_prev directly test: replace gtester with a TAP driver test: execute g_test_run when tests are skipped qga: drop < Vista compatibility build-sys: build with Vista API by default build-sys: move windows defines in osdep.h header build-sys: don't include windows.h, osdep.h does it scsi: esp: Defer command completion until previous interrupts have been handled esp-pci: Fix status register write erase control ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/scsi/esp.c')
-rw-r--r--hw/scsi/esp.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 630d923623..ca8b36c0c5 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -286,11 +286,8 @@ static void esp_do_dma(ESPState *s)
esp_dma_done(s);
}
-void esp_command_complete(SCSIRequest *req, uint32_t status,
- size_t resid)
+static void esp_report_command_complete(ESPState *s, uint32_t status)
{
- ESPState *s = req->hba_private;
-
trace_esp_command_complete();
if (s->ti_size != 0) {
trace_esp_command_complete_unexpected();
@@ -311,6 +308,23 @@ void esp_command_complete(SCSIRequest *req, uint32_t status,
}
}
+void esp_command_complete(SCSIRequest *req, uint32_t status,
+ size_t resid)
+{
+ ESPState *s = req->hba_private;
+
+ if (s->rregs[ESP_RSTAT] & STAT_INT) {
+ /* Defer handling command complete until the previous
+ * interrupt has been handled.
+ */
+ trace_esp_command_complete_deferred();
+ s->deferred_status = status;
+ s->deferred_complete = true;
+ return;
+ }
+ esp_report_command_complete(s, status);
+}
+
void esp_transfer_data(SCSIRequest *req, uint32_t len)
{
ESPState *s = req->hba_private;
@@ -422,7 +436,10 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
s->rregs[ESP_RSTAT] &= ~STAT_TC;
s->rregs[ESP_RSEQ] = SEQ_CD;
esp_lower_irq(s);
-
+ if (s->deferred_complete) {
+ esp_report_command_complete(s, s->deferred_status);
+ s->deferred_complete = false;
+ }
return old_val;
case ESP_TCHI:
/* Return the unique id if the value has never been written */
@@ -582,6 +599,8 @@ const VMStateDescription vmstate_esp = {
VMSTATE_UINT32(ti_wptr, ESPState),
VMSTATE_BUFFER(ti_buf, ESPState),
VMSTATE_UINT32(status, ESPState),
+ VMSTATE_UINT32(deferred_status, ESPState),
+ VMSTATE_BOOL(deferred_complete, ESPState),
VMSTATE_UINT32(dma, ESPState),
VMSTATE_PARTIAL_BUFFER(cmdbuf, ESPState, 16),
VMSTATE_BUFFER_START_MIDDLE_V(cmdbuf, ESPState, 16, 4),
@@ -671,8 +690,8 @@ static void sysbus_esp_hard_reset(DeviceState *dev)
static const VMStateDescription vmstate_sysbus_esp_scsi = {
.name = "sysbusespscsi",
- .version_id = 0,
- .minimum_version_id = 0,
+ .version_id = 1,
+ .minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_STRUCT(esp, SysBusESPState, 0, vmstate_esp, ESPState),
VMSTATE_END_OF_LIST()