Some iio drivers currently share an available info buffer that might be changed while iio core prints it to sysfs. To avoid the buffer corruption, add a release callback to let iio drivers allocate a copy of the available info buffer and later free it in the release callback. Such control is kept in the driver logic so that some driver that needs a big available info buffer might also perform some check to keep the copied buffer around in case no race has occurred. Signed-off-by: Matteo Martelli <matteomartelli3@xxxxxxxxx> --- drivers/iio/industrialio-core.c | 14 +++++++++++--- include/linux/iio/iio.h | 4 ++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 6a6568d4a2cb3a3f63381d5a6f25a2881b3ba2ed..4aea9de9f15a4d70f9d02fb3d47df49eef8c8423 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -859,12 +859,20 @@ static ssize_t iio_read_channel_info_avail(struct device *dev, return ret; switch (ret) { case IIO_AVAIL_LIST: - return iio_format_avail_list(buf, vals, type, length); + ret = iio_format_avail_list(buf, vals, type, length); + break; case IIO_AVAIL_RANGE: - return iio_format_avail_range(buf, vals, type); + ret = iio_format_avail_range(buf, vals, type); + break; default: - return -EINVAL; + ret = -EINVAL; } + + if (indio_dev->info->read_avail_release_resource) + indio_dev->info->read_avail_release_resource( + indio_dev, this_attr->c, vals, this_attr->address); + + return ret; } /** diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 18779b631e9071801958fc9d50b941b548fab940..55326f0310b2e9b3fa561c4728e7eabe1d7a5e78 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -491,6 +491,10 @@ struct iio_info { int *length, long mask); + void (*read_avail_release_resource)(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int *vals, long mask); + int (*write_raw)(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, -- 2.46.2