diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2019-01-11 15:46:09 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2019-01-11 15:46:09 +0000 |
| commit | 15bede554162dda822cd762c689edb6fa32b6e3b (patch) | |
| tree | ba397197336b06e020d9c5b403471e9d82d19c63 /hw/scsi | |
| parent | e53f7796fbe71a5c7c24ffebf04b4aa9a759da36 (diff) | |
| parent | 7d37435bd5801bb49e1c4b550fedd1c5fe143131 (diff) | |
| download | focaccia-qemu-15bede554162dda822cd762c689edb6fa32b6e3b.tar.gz focaccia-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')
| -rw-r--r-- | hw/scsi/esp-pci.c | 10 | ||||
| -rw-r--r-- | hw/scsi/esp.c | 33 | ||||
| -rw-r--r-- | hw/scsi/lsi53c895a.c | 6 | ||||
| -rw-r--r-- | hw/scsi/scsi-bus.c | 2 | ||||
| -rw-r--r-- | hw/scsi/trace-events | 1 |
5 files changed, 36 insertions, 16 deletions
diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c index 419fc668ac..6b0bbb9b7f 100644 --- a/hw/scsi/esp-pci.c +++ b/hw/scsi/esp-pci.c @@ -59,7 +59,7 @@ #define DMA_STAT_SCSIINT 0x10 #define DMA_STAT_BCMBLT 0x20 -#define SBAC_STATUS 0x1000 +#define SBAC_STATUS (1 << 24) typedef struct PCIESPState { /*< private >*/ @@ -136,7 +136,7 @@ static void esp_pci_dma_write(PCIESPState *pci, uint32_t saddr, uint32_t val) pci->dma_regs[saddr] = val; break; case DMA_STAT: - if (!(pci->sbac & SBAC_STATUS)) { + if (pci->sbac & SBAC_STATUS) { /* clear some bits on write */ uint32_t mask = DMA_STAT_ERROR | DMA_STAT_ABORT | DMA_STAT_DONE; pci->dma_regs[DMA_STAT] &= ~(val & mask); @@ -157,7 +157,7 @@ static uint32_t esp_pci_dma_read(PCIESPState *pci, uint32_t saddr) if (pci->esp.rregs[ESP_RSTAT] & STAT_INT) { val |= DMA_STAT_SCSIINT; } - if (pci->sbac & SBAC_STATUS) { + if (!(pci->sbac & SBAC_STATUS)) { pci->dma_regs[DMA_STAT] &= ~(DMA_STAT_ERROR | DMA_STAT_ABORT | DMA_STAT_DONE); } @@ -313,8 +313,8 @@ static void esp_pci_hard_reset(DeviceState *dev) static const VMStateDescription vmstate_esp_pci_scsi = { .name = "pciespscsi", - .version_id = 0, - .minimum_version_id = 0, + .version_id = 1, + .minimum_version_id = 1, .fields = (VMStateField[]) { VMSTATE_PCI_DEVICE(parent_obj, PCIESPState), VMSTATE_BUFFER_UNSAFE(dma_regs, PCIESPState, 0, 8 * sizeof(uint32_t)), 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() diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index 52a38933b6..89def1421f 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -1850,7 +1850,7 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val) break; case 0x0a: case 0x0b: /* Openserver writes to these readonly registers on startup */ - return; + return; case 0x0c: case 0x0d: case 0x0e: case 0x0f: /* Linux writes to these readonly registers on startup. */ return; @@ -1884,8 +1884,8 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val) /* nothing to do */ break; case 0x1a: /* CTEST2 */ - s->ctest2 = val & LSI_CTEST2_PCICIE; - break; + s->ctest2 = val & LSI_CTEST2_PCICIE; + break; case 0x1b: /* CTEST3 */ s->ctest3 = val & 0x0f; break; diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 97cd167114..c480553083 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -1554,7 +1554,7 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) BusChild *kid; SCSIDevice *target_dev = NULL; - QTAILQ_FOREACH_REVERSE(kid, &bus->qbus.children, ChildrenHead, sibling) { + QTAILQ_FOREACH_REVERSE(kid, &bus->qbus.children, sibling) { DeviceState *qdev = kid->child; SCSIDevice *dev = SCSI_DEVICE(qdev); diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events index 0fb6a99616..2fe8a7c062 100644 --- a/hw/scsi/trace-events +++ b/hw/scsi/trace-events @@ -167,6 +167,7 @@ esp_handle_satn_stop(uint32_t cmdlen) "cmdlen %d" esp_write_response(uint32_t status) "Transfer status (status=%d)" esp_do_dma(uint32_t cmdlen, uint32_t len) "command len %d + %d" esp_command_complete(void) "SCSI Command complete" +esp_command_complete_deferred(void) "SCSI Command complete deferred" esp_command_complete_unexpected(void) "SCSI command completed unexpectedly" esp_command_complete_fail(void) "Command failed" esp_transfer_data(uint32_t dma_left, int32_t ti_size) "transfer %d/%d" |