[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 10/25] esp: remove dma_left from ESPState
From: |
Mark Cave-Ayland |
Subject: |
[PATCH 10/25] esp: remove dma_left from ESPState |
Date: |
Wed, 30 Dec 2020 15:37:30 +0000 |
The ESP device already keeps track of the remaining bytes left to transfer via
its TC (transfer counter) register which is decremented for each byte that
is transferred across the SCSI bus.
Switch the transfer logic to use the value of TC instead of dma_left and then
remove dma_left completely.
In order to preserve migration bump the version of vmstate_sysbus_esp_scsi to
2 and add a post_load function to transfer the old dma_left value to the TC
register.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
hw/scsi/esp.c | 47 +++++++++++++++++++++++++++----------------
include/hw/scsi/esp.h | 5 +++--
2 files changed, 33 insertions(+), 19 deletions(-)
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 5b47d035ab..69fed3cb22 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -228,7 +228,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t
busid)
s->ti_size = datalen;
if (datalen != 0) {
s->rregs[ESP_RSTAT] = STAT_TC;
- s->dma_left = 0;
+ esp_set_tc(s, 0);
if (datalen > 0) {
s->rregs[ESP_RSTAT] |= STAT_DI;
} else {
@@ -384,6 +384,7 @@ static void do_dma_pdma_cb(ESPState *s)
{
int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
int len = s->pdma_cur - s->pdma_start;
+
if (s->do_cmd) {
s->ti_size = 0;
s->cmdlen = 0;
@@ -391,7 +392,6 @@ static void do_dma_pdma_cb(ESPState *s)
do_cmd(s, s->cmdbuf);
return;
}
- s->dma_left -= len;
s->async_buf += len;
s->async_len -= len;
if (to_device) {
@@ -406,7 +406,7 @@ static void do_dma_pdma_cb(ESPState *s)
* complete the DMA operation immediately. Otherwise defer
* until the scsi layer has completed.
*/
- if (to_device || s->dma_left != 0 || s->ti_size == 0) {
+ if (to_device || esp_get_tc(s) != 0 || s->ti_size == 0) {
return;
}
}
@@ -420,7 +420,7 @@ static void esp_do_dma(ESPState *s)
uint32_t len;
int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
- len = s->dma_left;
+ len = esp_get_tc(s);
if (s->do_cmd) {
/*
* handle_ti_cmd() case: esp_do_dma() is called only from
@@ -470,7 +470,7 @@ static void esp_do_dma(ESPState *s)
return;
}
}
- s->dma_left -= len;
+ esp_set_tc(s, esp_get_tc(s) - len);
s->async_buf += len;
s->async_len -= len;
if (to_device) {
@@ -485,7 +485,7 @@ static void esp_do_dma(ESPState *s)
* complete the DMA operation immediately. Otherwise defer
* until the scsi layer has completed.
*/
- if (to_device || s->dma_left != 0 || s->ti_size == 0) {
+ if (to_device || esp_get_tc(s) != 0 || s->ti_size == 0) {
return;
}
}
@@ -501,7 +501,6 @@ static void esp_report_command_complete(ESPState *s,
uint32_t status)
trace_esp_command_complete_unexpected();
}
s->ti_size = 0;
- s->dma_left = 0;
s->async_len = 0;
if (status) {
trace_esp_command_complete_fail();
@@ -538,12 +537,13 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len)
{
ESPState *s = req->hba_private;
int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
+ uint32_t dmalen = esp_get_tc(s);
assert(!s->do_cmd);
- trace_esp_transfer_data(s->dma_left, s->ti_size);
+ trace_esp_transfer_data(dmalen, s->ti_size);
s->async_len = len;
s->async_buf = scsi_req_get_buf(req);
- if (s->dma_left) {
+ if (dmalen) {
esp_do_dma(s);
} else if (to_device) {
/*
@@ -574,7 +574,6 @@ static void handle_ti(ESPState *s)
}
trace_esp_handle_ti(minlen);
if (s->dma) {
- s->dma_left = minlen;
s->rregs[ESP_RSTAT] &= ~STAT_TC;
esp_do_dma(s);
} else if (s->do_cmd) {
@@ -846,7 +845,7 @@ const VMStateDescription vmstate_esp = {
VMSTATE_BUFFER_START_MIDDLE_V(cmdbuf, ESPState, 16, 4),
VMSTATE_UINT32(cmdlen, ESPState),
VMSTATE_UINT32(do_cmd, ESPState),
- VMSTATE_UINT32(dma_left, ESPState),
+ VMSTATE_UINT32(mig_dma_left, ESPState),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription * []) {
@@ -887,12 +886,11 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr
addr,
{
SysBusESPState *sysbus = opaque;
ESPState *s = &sysbus->esp;
- uint32_t dmalen;
+ uint32_t dmalen = esp_get_tc(s);
uint8_t *buf = get_pdma_buf(s);
trace_esp_pdma_write(size);
- dmalen = esp_get_tc(s);
if (dmalen == 0 || s->pdma_len == 0) {
return;
}
@@ -922,27 +920,30 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr
addr,
{
SysBusESPState *sysbus = opaque;
ESPState *s = &sysbus->esp;
+ uint32_t dmalen = esp_get_tc(s);
uint8_t *buf = get_pdma_buf(s);
uint64_t val = 0;
trace_esp_pdma_read(size);
- if (s->pdma_len == 0) {
+ if (dmalen == 0 || s->pdma_len == 0) {
return 0;
}
switch (size) {
case 1:
val = buf[s->pdma_cur++];
s->pdma_len--;
+ dmalen--;
break;
case 2:
val = buf[s->pdma_cur++];
val = (val << 8) | buf[s->pdma_cur++];
s->pdma_len -= 2;
+ dmalen -= 2;
break;
}
-
- if (s->pdma_len == 0 && s->pdma_cb) {
+ esp_set_tc(s, dmalen);
+ if (dmalen == 0 || (s->pdma_len == 0 && s->pdma_cb)) {
esp_lower_drq(s);
s->pdma_cb(s);
s->pdma_cb = NULL;
@@ -1012,10 +1013,22 @@ static void sysbus_esp_hard_reset(DeviceState *dev)
esp_hard_reset(&sysbus->esp);
}
+static int sysbus_esp_scsi_post_load(void *opaque, int version_id)
+{
+ ESPState *s = opaque;
+
+ if (version_id < 2) {
+ esp_set_tc(s, s->mig_dma_left);
+ }
+
+ return 1;
+}
+
static const VMStateDescription vmstate_sysbus_esp_scsi = {
.name = "sysbusespscsi",
- .version_id = 1,
+ .version_id = 2,
.minimum_version_id = 1,
+ .post_load = sysbus_esp_scsi_post_load,
.fields = (VMStateField[]) {
VMSTATE_STRUCT(esp, SysBusESPState, 0, vmstate_esp, ESPState),
VMSTATE_END_OF_LIST()
diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index b307f5d261..f45bbde23c 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -43,8 +43,6 @@ struct ESPState {
uint32_t cmdlen;
uint32_t do_cmd;
- /* The amount of data left in the current DMA transfer. */
- uint32_t dma_left;
int dma_enabled;
uint32_t async_len;
@@ -60,6 +58,9 @@ struct ESPState {
uint32_t pdma_start;
uint32_t pdma_cur;
void (*pdma_cb)(ESPState *s);
+
+ /* Legacy field for vmstate_sysbus_esp_scsi version < 2 */
+ uint32_t mig_dma_left;
};
#define TYPE_ESP "esp"
--
2.20.1
- [PATCH 00/25] esp: consolidate PDMA transfer buffers, Mark Cave-Ayland, 2020/12/30
- [PATCH 02/25] esp: add trace event when receiving a TI command, Mark Cave-Ayland, 2020/12/30
- [PATCH 01/25] esp: checkpatch fixes, Mark Cave-Ayland, 2020/12/30
- [PATCH 03/25] esp: fix esp_reg_read() trace event, Mark Cave-Ayland, 2020/12/30
- [PATCH 04/25] esp: add PDMA trace events, Mark Cave-Ayland, 2020/12/30
- [PATCH 07/25] esp: introduce esp_get_stc(), Mark Cave-Ayland, 2020/12/30
- [PATCH 05/25] esp: determine transfer direction directly from SCSI phase, Mark Cave-Ayland, 2020/12/30
- [PATCH 06/25] esp: introduce esp_get_tc() and esp_set_tc(), Mark Cave-Ayland, 2020/12/30
- [PATCH 08/25] esp: apply transfer length adjustment when STC is zero at TC load time, Mark Cave-Ayland, 2020/12/30
- [PATCH 09/25] esp: remove dma_counter from ESPState, Mark Cave-Ayland, 2020/12/30
- [PATCH 10/25] esp: remove dma_left from ESPState,
Mark Cave-Ayland <=
- [PATCH 11/25] esp: remove minlen restriction in handle_ti, Mark Cave-Ayland, 2020/12/30
- [PATCH 12/25] esp: introduce esp_pdma_read() and esp_pdma_write() functions, Mark Cave-Ayland, 2020/12/30
- [PATCH 14/25] esp: move pdma_len and TC logic into esp_pdma_read()/esp_pdma_write(), Mark Cave-Ayland, 2020/12/30
- [PATCH 13/25] esp: use pdma_origin directly in esp_pdma_read()/esp_pdma_write(), Mark Cave-Ayland, 2020/12/30
- [PATCH 16/25] esp: remove redundant pdma_start from ESPState, Mark Cave-Ayland, 2020/12/30
- [PATCH 15/25] esp: accumulate SCSI commands for PDMA transfers in cmdbuf instead of pdma_buf, Mark Cave-Ayland, 2020/12/30
- [PATCH 17/25] esp: move PDMA length adjustments into esp_pdma_read()/esp_pdma_write(), Mark Cave-Ayland, 2020/12/30
- [PATCH 18/25] esp: use ti_wptr/ti_rptr to manage the current FIFO position for PDMA, Mark Cave-Ayland, 2020/12/30
- [PATCH 19/25] esp: use in-built TC to determine PDMA transfer length, Mark Cave-Ayland, 2020/12/30
- [PATCH 20/25] esp: remove CMD pdma_origin, Mark Cave-Ayland, 2020/12/30