Skip to content

Commit 99d67ef

Browse files
ovpanaitgregkh
authored andcommitted
staging: axis-fifo: flush RX FIFO on read errors
commit 82a051e upstream. Flush stale data from the RX FIFO in case of errors, to avoid reading old data when new packets arrive. Commit c6e8d85 ("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: c6e8d85 ("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>
1 parent 7441d70 commit 99d67ef

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

drivers/staging/axis-fifo/axis-fifo.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
391391
}
392392

393393
bytes_available = ioread32(fifo->base_addr + XLLF_RLR_OFFSET);
394+
words_available = bytes_available / sizeof(u32);
394395
if (!bytes_available) {
395396
dev_err(fifo->dt_device, "received a packet of length 0\n");
396397
ret = -EIO;
@@ -401,7 +402,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
401402
dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu)\n",
402403
bytes_available, len);
403404
ret = -EINVAL;
404-
goto end_unlock;
405+
goto err_flush_rx;
405406
}
406407

407408
if (bytes_available % sizeof(u32)) {
@@ -410,11 +411,9 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
410411
*/
411412
dev_err(fifo->dt_device, "received a packet that isn't word-aligned\n");
412413
ret = -EIO;
413-
goto end_unlock;
414+
goto err_flush_rx;
414415
}
415416

416-
words_available = bytes_available / sizeof(u32);
417-
418417
/* read data into an intermediate buffer, copying the contents
419418
* to userspace when the buffer is full
420419
*/
@@ -426,18 +425,23 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
426425
tmp_buf[i] = ioread32(fifo->base_addr +
427426
XLLF_RDFD_OFFSET);
428427
}
428+
words_available -= copy;
429429

430430
if (copy_to_user(buf + copied * sizeof(u32), tmp_buf,
431431
copy * sizeof(u32))) {
432432
ret = -EFAULT;
433-
goto end_unlock;
433+
goto err_flush_rx;
434434
}
435435

436436
copied += copy;
437-
words_available -= copy;
438437
}
438+
mutex_unlock(&fifo->read_lock);
439+
440+
return bytes_available;
439441

440-
ret = bytes_available;
442+
err_flush_rx:
443+
while (words_available--)
444+
ioread32(fifo->base_addr + XLLF_RDFD_OFFSET);
441445

442446
end_unlock:
443447
mutex_unlock(&fifo->read_lock);

0 commit comments

Comments
 (0)