[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250912101322.1282507-2-ovidiu.panait.oss@gmail.com>
Date: Fri, 12 Sep 2025 13:13:22 +0300
From: Ovidiu Panait <ovidiu.panait.oss@...il.com>
To: gregkh@...uxfoundation.org,
linux-kernel@...r.kernel.org,
linux-staging@...ts.linux.dev
Cc: gshahrouzi@...il.com,
Ovidiu Panait <ovidiu.panait.oss@...il.com>,
stable@...r.kernel.org
Subject: [PATCH 2/2] staging: axis-fifo: flush RX FIFO on read errors
Flush stale data from the RX FIFO in case of errors, to avoid reading
old data when new packets arrive.
Commit c6e8d85fafa7 ("staging: axis-fifo: Remove hardware resets for
user errors") removed full FIFO resets from the read error paths, which
fixed potential TX data losses, but introduced this RX issue.
Fixes: c6e8d85fafa7 ("staging: axis-fifo: Remove hardware resets for user errors")
Cc: stable@...r.kernel.org
Signed-off-by: Ovidiu Panait <ovidiu.panait.oss@...il.com>
---
drivers/staging/axis-fifo/axis-fifo.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c
index c47c6a022402..2c8e25a8c657 100644
--- a/drivers/staging/axis-fifo/axis-fifo.c
+++ b/drivers/staging/axis-fifo/axis-fifo.c
@@ -230,6 +230,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
}
bytes_available = ioread32(fifo->base_addr + XLLF_RLR_OFFSET);
+ words_available = bytes_available / sizeof(u32);
if (!bytes_available) {
dev_err(fifo->dt_device, "received a packet of length 0\n");
ret = -EIO;
@@ -240,7 +241,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu)\n",
bytes_available, len);
ret = -EINVAL;
- goto end_unlock;
+ goto err_flush_rx;
}
if (bytes_available % sizeof(u32)) {
@@ -249,11 +250,9 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
*/
dev_err(fifo->dt_device, "received a packet that isn't word-aligned\n");
ret = -EIO;
- goto end_unlock;
+ goto err_flush_rx;
}
- words_available = bytes_available / sizeof(u32);
-
/* read data into an intermediate buffer, copying the contents
* to userspace when the buffer is full
*/
@@ -265,18 +264,23 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
tmp_buf[i] = ioread32(fifo->base_addr +
XLLF_RDFD_OFFSET);
}
+ words_available -= copy;
if (copy_to_user(buf + copied * sizeof(u32), tmp_buf,
copy * sizeof(u32))) {
ret = -EFAULT;
- goto end_unlock;
+ goto err_flush_rx;
}
copied += copy;
- words_available -= copy;
}
+ mutex_unlock(&fifo->read_lock);
+
+ return bytes_available;
- ret = bytes_available;
+err_flush_rx:
+ while (words_available--)
+ ioread32(fifo->base_addr + XLLF_RDFD_OFFSET);
end_unlock:
mutex_unlock(&fifo->read_lock);
--
2.50.0
Powered by blists - more mailing lists