Previous versions of `iio_compute_scan_bytes` only aligned the current element to its own length (i.e. its own natural alignment). This worked in case the length of each channel's scan elements had been smaller then the length of the successive channel's scan elements. E.g. u16 u32 <- aligned to its natural alignment But if the length of a channel's scan elements is greater then the length of scan elements of the consecutive channel no alignment had been taken into account. This is however needed to preserve the alignment for multiple consecutive sets of scan elements. u32 <- alignment is off by two byte for the second set of scan elements u16 <- no alignment takes place This commit fixes this by aligning the scan bytes to the size of the largest scan element. Signed-off-by: Lars Möllendorf <lars.moellendorf@xxxxxxxxxx> --- drivers/iio/industrialio-buffer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 5d05c38c4ba9..2f037cd59d53 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -546,7 +546,7 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const unsigned long *mask, bool timestamp) { unsigned bytes = 0; - int length, i; + int length, i, largest = 0; /* How much space will the demuxed element take? */ for_each_set_bit(i, mask, @@ -554,13 +554,17 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev, length = iio_storage_bytes_for_si(indio_dev, i); bytes = ALIGN(bytes, length); bytes += length; + largest = max(largest, length); } if (timestamp) { length = iio_storage_bytes_for_timestamp(indio_dev); bytes = ALIGN(bytes, length); bytes += length; + largest = max(largest, length); } + + bytes = ALIGN(bytes, largest); return bytes; } -- 2.23.0