drivers/iio/adc/ade9000.c | 2 ++ 1 file changed, 2 insertions(+)
ade9000_configure_scan() always sets the SPI transfer length to half
the waveform buffer:
st->xfer[1].len = (st->wfb_nr_samples / 2) * 4;
However, ade9000_iio_push_buffer() iterates over the full
wfb_nr_samples, pushing twice as many samples as were actually read
via SPI. The second half contains stale or uninitialized data from
the rx buffer.
Fix by setting the SPI transfer length to the full waveform buffer
size in ade9000_iio_push_buffer(), since the trigger mode fills the
entire buffer before firing the interrupt.
Fixes: 81de7b4619fc ("iio: adc: add ade9000 support")
Signed-off-by: Giorgi Tchankvetadze <giorgitchankvetadze1997@gmail.com>
---
drivers/iio/adc/ade9000.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/iio/adc/ade9000.c b/drivers/iio/adc/ade9000.c
index db085dc5e526..c6eb06ef8d37 100644
--- a/drivers/iio/adc/ade9000.c
+++ b/drivers/iio/adc/ade9000.c
@@ -804,6 +804,8 @@ static int ade9000_iio_push_buffer(struct iio_dev *indio_dev)
guard(mutex)(&st->lock);
+ st->xfer[1].len = st->wfb_nr_samples * 4;
+
ret = spi_sync(st->spi, &st->spi_msg);
if (ret) {
dev_err_ratelimited(&st->spi->dev,
--
2.52.0
On 3/2/26 1:20 AM, Giorgi Tchankvetadze wrote:
> ade9000_configure_scan() always sets the SPI transfer length to half
> the waveform buffer:
>
> st->xfer[1].len = (st->wfb_nr_samples / 2) * 4;
>
> However, ade9000_iio_push_buffer() iterates over the full
> wfb_nr_samples, pushing twice as many samples as were actually read
> via SPI. The second half contains stale or uninitialized data from
> the rx buffer.
>
> Fix by setting the SPI transfer length to the full waveform buffer
> size in ade9000_iio_push_buffer(), since the trigger mode fills the
> entire buffer before firing the interrupt.
>
> Fixes: 81de7b4619fc ("iio: adc: add ade9000 support")
> Signed-off-by: Giorgi Tchankvetadze <giorgitchankvetadze1997@gmail.com>
> ---
> drivers/iio/adc/ade9000.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/iio/adc/ade9000.c b/drivers/iio/adc/ade9000.c
> index db085dc5e526..c6eb06ef8d37 100644
> --- a/drivers/iio/adc/ade9000.c
> +++ b/drivers/iio/adc/ade9000.c
> @@ -804,6 +804,8 @@ static int ade9000_iio_push_buffer(struct iio_dev *indio_dev)
>
> guard(mutex)(&st->lock);
>
> + st->xfer[1].len = st->wfb_nr_samples * 4;
> +
> ret = spi_sync(st->spi, &st->spi_msg);
> if (ret) {
> dev_err_ratelimited(&st->spi->dev,
This could use some more comments in the code to explain the different
code paths. I have a feeling this isn't the ideal solution. Writing
over .len in a separate function from when the xfer is set up is
a recipe for more bugs.
The xfer is set up in ade9000_configure_scan() and that function
has an argument of either ADE9000_REG_WF_HALF_BUFF or ADE9000_REG_WF_BUFF.
Could we use that to determine the correct .len and set it in one
place in ade9000_configure_scan()?
© 2016 - 2026 Red Hat, Inc.