mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
thunderbolt: stream: Make read return framing error to the userspace
If any of the frames are corrupted during the receive we currently log a warning and pass them to the userspace without it knowing they were corrupted. Make the driver behave better and return an error (-EIO) to the userspace in that case. For the CLOSE packet, payload does not matter so we handle it the usual way. Reviewed-by: Ivy Lopez <skunkolee@gmail.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
This commit is contained in:
parent
5ef3b5a4ea
commit
a93a8e3200
|
|
@ -375,6 +375,7 @@ tbstream_dev_rx_callback(struct tb_ring *ring, struct ring_frame *frame,
|
|||
{
|
||||
struct tbstream_frame *sf = container_of(frame, typeof(*sf), frame);
|
||||
struct tbstream_dev *sdev = sf->sdev;
|
||||
__poll_t mask;
|
||||
|
||||
if (canceled)
|
||||
return;
|
||||
|
|
@ -382,19 +383,17 @@ tbstream_dev_rx_callback(struct tb_ring *ring, struct ring_frame *frame,
|
|||
sf->completed = true;
|
||||
sdev->rx_ring.prod++;
|
||||
|
||||
if (sf->frame.flags & RING_DESC_CRC_ERROR) {
|
||||
pr_warn("RX CRC error\n");
|
||||
} else if (sf->frame.flags & RING_DESC_BUFFER_OVERRUN) {
|
||||
pr_warn("RX buffer overrun\n");
|
||||
} else {
|
||||
__poll_t mask = EPOLLIN | EPOLLRDNORM;
|
||||
|
||||
if (sf->frame.eof == TBSTREAM_CLOSE) {
|
||||
WRITE_ONCE(sdev->close_received, true);
|
||||
mask |= EPOLLHUP;
|
||||
}
|
||||
wake_up_interruptible_poll(&sdev->wait, mask);
|
||||
mask = EPOLLIN | EPOLLRDNORM;
|
||||
/*
|
||||
* The CLOSE packet does not have a payload so the flags do not
|
||||
* matter. The read_iter() deals with the flags.
|
||||
*/
|
||||
if (sf->frame.eof == TBSTREAM_CLOSE) {
|
||||
WRITE_ONCE(sdev->close_received, true);
|
||||
mask |= EPOLLHUP;
|
||||
}
|
||||
|
||||
wake_up_interruptible_poll(&sdev->wait, mask);
|
||||
}
|
||||
|
||||
static struct tbstream_frame *
|
||||
|
|
@ -877,6 +876,19 @@ tbstream_dev_fops_read_iter(struct kiocb *kiocb, struct iov_iter *to)
|
|||
WRITE_ONCE(sdev->closed, true);
|
||||
}
|
||||
break;
|
||||
} else if (sf->frame.flags &
|
||||
(RING_DESC_CRC_ERROR | RING_DESC_BUFFER_OVERRUN)) {
|
||||
/*
|
||||
* If something was already read return that now
|
||||
* and next read will report the error.
|
||||
*/
|
||||
if (!nbytes) {
|
||||
pr_warn("corrupted frame received, flags %#x\n",
|
||||
sf->frame.flags);
|
||||
tbstream_dev_consume_rx(sdev);
|
||||
ret = -EIO;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
sf_size = tb_ring_frame_size(&sf->frame);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user