iio: ensure scan index is unique at device register
authorVlad Dogaru <vlad.dogaru@intel.com>
Mon, 29 Dec 2014 09:37:48 +0000 (11:37 +0200)
committerJonathan Cameron <jic23@kernel.org>
Mon, 5 Jan 2015 18:59:57 +0000 (18:59 +0000)
Having two or more channels with the same positive scan_index field
makes no sense if the device supports buffering.  Prevent this situation
by failing to register such a device.

Signed-off-by: Vlad Dogaru <vlad.dogaru@intel.com>
Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/iio/industrialio-core.c

index b7a39771705fc9f4728a089bb7151ba45c9383b7..69feb912515a44e30d17bda54f939a5d318378dd 100644 (file)
@@ -1134,6 +1134,29 @@ static const struct file_operations iio_buffer_fileops = {
        .compat_ioctl = iio_ioctl,
 };
 
+static int iio_check_unique_scan_index(struct iio_dev *indio_dev)
+{
+       int i, j;
+       const struct iio_chan_spec *channels = indio_dev->channels;
+
+       if (!(indio_dev->modes & INDIO_ALL_BUFFER_MODES))
+               return 0;
+
+       for (i = 0; i < indio_dev->num_channels - 1; i++) {
+               if (channels[i].scan_index < 0)
+                       continue;
+               for (j = i + 1; j < indio_dev->num_channels; j++)
+                       if (channels[i].scan_index == channels[j].scan_index) {
+                               dev_err(&indio_dev->dev,
+                                       "Duplicate scan index %d\n",
+                                       channels[i].scan_index);
+                               return -EINVAL;
+                       }
+       }
+
+       return 0;
+}
+
 static const struct iio_buffer_setup_ops noop_ring_setup_ops;
 
 /**
@@ -1148,6 +1171,10 @@ int iio_device_register(struct iio_dev *indio_dev)
        if (!indio_dev->dev.of_node && indio_dev->dev.parent)
                indio_dev->dev.of_node = indio_dev->dev.parent->of_node;
 
+       ret = iio_check_unique_scan_index(indio_dev);
+       if (ret < 0)
+               return ret;
+
        /* configure elements for the chrdev */
        indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id);