| From foo@baz Thu Jan 21 02:24:10 PM CET 2021 |
| From: "Nuno Sá" <nuno.sa@analog.com> |
| Date: Thu, 12 Nov 2020 15:43:22 +0100 |
| Subject: iio: buffer: Fix demux update |
| |
| From: "Nuno Sá" <nuno.sa@analog.com> |
| |
| commit 19ef7b70ca9487773c29b449adf0c70f540a0aab upstream |
| |
| When updating the buffer demux, we will skip a scan element from the |
| device in the case `in_ind != out_ind` and we enter the while loop. |
| in_ind should only be refreshed with `find_next_bit()` in the end of the |
| loop. |
| |
| Note, to cause problems we need a situation where we are skippig over |
| an element (channel not enabled) that happens to not have the same size |
| as the next element. Whilst this is a possible situation we haven't |
| actually identified any cases in mainline where it happens as most drivers |
| have consistent channel storage sizes with the exception of the timestamp |
| which is the last element and hence never skipped over. |
| |
| Fixes: 5ada4ea9be16 ("staging:iio: add demux optionally to path from device to buffer") |
| Signed-off-by: Nuno Sá <nuno.sa@analog.com> |
| Link: https://lore.kernel.org/r/20201112144323.28887-1-nuno.sa@analog.com |
| Cc: <Stable@vger.kernel.org> |
| Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> |
| [sudip: adjust context] |
| Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/iio/industrialio-buffer.c | 6 +++--- |
| 1 file changed, 3 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/iio/industrialio-buffer.c |
| +++ b/drivers/iio/industrialio-buffer.c |
| @@ -1281,9 +1281,6 @@ static int iio_buffer_update_demux(struc |
| indio_dev->masklength, |
| in_ind + 1); |
| while (in_ind != out_ind) { |
| - in_ind = find_next_bit(indio_dev->active_scan_mask, |
| - indio_dev->masklength, |
| - in_ind + 1); |
| ch = iio_find_channel_from_si(indio_dev, in_ind); |
| if (ch->scan_type.repeat > 1) |
| length = ch->scan_type.storagebits / 8 * |
| @@ -1292,6 +1289,9 @@ static int iio_buffer_update_demux(struc |
| length = ch->scan_type.storagebits / 8; |
| /* Make sure we are aligned */ |
| in_loc = roundup(in_loc, length) + length; |
| + in_ind = find_next_bit(indio_dev->active_scan_mask, |
| + indio_dev->masklength, |
| + in_ind + 1); |
| } |
| ch = iio_find_channel_from_si(indio_dev, in_ind); |
| if (ch->scan_type.repeat > 1) |