staging: axis-fifo: flush RX FIFO on read errors
commit82a051e255upstream. Flush stale data from the RX FIFO in case of errors, to avoid reading old data when new packets arrive. Commitc6e8d85faf("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:c6e8d85faf("staging: axis-fifo: Remove hardware resets for user errors") Cc: stable@vger.kernel.org Signed-off-by: Ovidiu Panait <ovidiu.panait.oss@gmail.com> Link: https://lore.kernel.org/r/20250912101322.1282507-2-ovidiu.panait.oss@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
5873888534
commit
86bdd3deca
@@ -400,6 +400,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;
|
||||
@@ -410,7 +411,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)) {
|
||||
@@ -419,11 +420,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
|
||||
*/
|
||||
@@ -435,18 +434,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);
|
||||
|
||||
ret = bytes_available;
|
||||
return bytes_available;
|
||||
|
||||
err_flush_rx:
|
||||
while (words_available--)
|
||||
ioread32(fifo->base_addr + XLLF_RDFD_OFFSET);
|
||||
|
||||
end_unlock:
|
||||
mutex_unlock(&fifo->read_lock);
|
||||
|
||||
Reference in New Issue
Block a user