Skip to content

Commit 226082e

Browse files
ovpanaitgregkh
authored andcommitted
staging: axis-fifo: flush RX FIFO on read errors
commit 82a051e2553b9e297cba82a975d9c538b882c79e 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: [email protected] Signed-off-by: Ovidiu Panait <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 8247c59 commit 226082e

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)