Skip to content

Commit 82a051e

Browse files
ovpanaitgregkh
authored andcommitted
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 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 6d07bee commit 82a051e

1 file changed

Lines changed: 11 additions & 7 deletions

File tree

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

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

229229
bytes_available = ioread32(fifo->base_addr + XLLF_RLR_OFFSET);
230+
words_available = bytes_available / sizeof(u32);
230231
if (!bytes_available) {
231232
dev_err(fifo->dt_device, "received a packet of length 0\n");
232233
ret = -EIO;
@@ -237,7 +238,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
237238
dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu)\n",
238239
bytes_available, len);
239240
ret = -EINVAL;
240-
goto end_unlock;
241+
goto err_flush_rx;
241242
}
242243

243244
if (bytes_available % sizeof(u32)) {
@@ -246,11 +247,9 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
246247
*/
247248
dev_err(fifo->dt_device, "received a packet that isn't word-aligned\n");
248249
ret = -EIO;
249-
goto end_unlock;
250+
goto err_flush_rx;
250251
}
251252

252-
words_available = bytes_available / sizeof(u32);
253-
254253
/* read data into an intermediate buffer, copying the contents
255254
* to userspace when the buffer is full
256255
*/
@@ -262,18 +261,23 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
262261
tmp_buf[i] = ioread32(fifo->base_addr +
263262
XLLF_RDFD_OFFSET);
264263
}
264+
words_available -= copy;
265265

266266
if (copy_to_user(buf + copied * sizeof(u32), tmp_buf,
267267
copy * sizeof(u32))) {
268268
ret = -EFAULT;
269-
goto end_unlock;
269+
goto err_flush_rx;
270270
}
271271

272272
copied += copy;
273-
words_available -= copy;
274273
}
274+
mutex_unlock(&fifo->read_lock);
275+
276+
return bytes_available;
275277

276-
ret = bytes_available;
278+
err_flush_rx:
279+
while (words_available--)
280+
ioread32(fifo->base_addr + XLLF_RDFD_OFFSET);
277281

278282
end_unlock:
279283
mutex_unlock(&fifo->read_lock);

0 commit comments

Comments
 (0)