aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2024-01-12 12:52:55 +0000
committerMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2024-02-13 19:37:04 +0000
commit49c60d1617d4870a5e7c4f9c2dc24fb3759b9679 (patch)
treeb050407bdc561f6850e2aeb33a0d872187d150cc /hw
parentcf40a5e42084e157e1cd7bed2619f3b44fbb3fe8 (diff)
downloadqemu-49c60d1617d4870a5e7c4f9c2dc24fb3759b9679.zip
qemu-49c60d1617d4870a5e7c4f9c2dc24fb3759b9679.tar.gz
qemu-49c60d1617d4870a5e7c4f9c2dc24fb3759b9679.tar.bz2
esp.c: add FIFO wraparound support to esp_fifo_pop_buf()
The fifo8_pop_buf() function returns a pointer to the FIFO buffer up to the specified length. Since the FIFO buffer is modelled as an array then once the FIFO wraps around, only the continuous portion of the buffer can be returned. In future the use of continuous and unaligned accesses will advance the internal FIFO head pointer, so modify esp_fifo_pop_buf() to ensure that any wraparound content is also returned up to the requested length. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Tested-by: Helge Deller <deller@gmx.de> Tested-by: Thomas Huth <thuth@redhat.com> Message-Id: <20240112125420.514425-4-mark.cave-ayland@ilande.co.uk> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Diffstat (limited to 'hw')
-rw-r--r--hw/scsi/esp.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index b382865..8d8f6a8 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -121,17 +121,30 @@ static uint8_t esp_fifo_pop(Fifo8 *fifo)
static uint32_t esp_fifo_pop_buf(Fifo8 *fifo, uint8_t *dest, int maxlen)
{
const uint8_t *buf;
- uint32_t n;
+ uint32_t n, n2;
+ int len;
if (maxlen == 0) {
return 0;
}
- buf = fifo8_pop_buf(fifo, maxlen, &n);
+ len = maxlen;
+ buf = fifo8_pop_buf(fifo, len, &n);
if (dest) {
memcpy(dest, buf, n);
}
+ /* Add FIFO wraparound if needed */
+ len -= n;
+ len = MIN(len, fifo8_num_used(fifo));
+ if (len) {
+ buf = fifo8_pop_buf(fifo, len, &n2);
+ if (dest) {
+ memcpy(&dest[n], buf, n2);
+ }
+ n += n2;
+ }
+
return n;
}