diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 0a14bd825fe0..6eee1b044c60 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -239,13 +239,19 @@ static ssize_t iio_scan_el_show(struct device *dev, /* Note NULL used as error indicator as it doesn't make sense. */ static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks, unsigned int masklength, - const unsigned long *mask) + const unsigned long *mask, + bool strict) { if (bitmap_empty(mask, masklength)) return NULL; while (*av_masks) { - if (bitmap_subset(mask, av_masks, masklength)) - return av_masks; + if (strict) { + if (bitmap_equal(mask, av_masks, masklength)) + return av_masks; + } else { + if (bitmap_subset(mask, av_masks, masklength)) + return av_masks; + } av_masks += BITS_TO_LONGS(masklength); } return NULL; @@ -295,7 +301,7 @@ static int iio_scan_mask_set(struct iio_dev *indio_dev, if (indio_dev->available_scan_masks) { mask = iio_scan_mask_match(indio_dev->available_scan_masks, indio_dev->masklength, - trialmask); + trialmask, false); if (!mask) goto err_invalid_mask; } @@ -602,6 +608,7 @@ static int iio_verify_update(struct iio_dev *indio_dev, { unsigned long *compound_mask; const unsigned long *scan_mask; + bool strict_scanmask = false; struct iio_buffer *buffer; bool scan_timestamp; unsigned int modes; @@ -631,7 +638,14 @@ static int iio_verify_update(struct iio_dev *indio_dev, if ((modes & INDIO_BUFFER_TRIGGERED) && indio_dev->trig) { config->mode = INDIO_BUFFER_TRIGGERED; } else if (modes & INDIO_BUFFER_HARDWARE) { + /* + * Keep things simple for now and only allow a single buffer to + * be connected in hardware mode. + */ + if (insert_buffer && !list_empty(&indio_dev->buffer_list)) + return -EINVAL; config->mode = INDIO_BUFFER_HARDWARE; + strict_scanmask = true; } else if (modes & INDIO_BUFFER_SOFTWARE) { config->mode = INDIO_BUFFER_SOFTWARE; } else { @@ -666,7 +680,8 @@ static int iio_verify_update(struct iio_dev *indio_dev, if (indio_dev->available_scan_masks) { scan_mask = iio_scan_mask_match(indio_dev->available_scan_masks, indio_dev->masklength, - compound_mask); + compound_mask, + strict_scanmask); kfree(compound_mask); if (scan_mask == NULL) return -EINVAL;