From bb01443e2cdad4ff5b98e00252e93110d00f4392 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 19 Dec 2011 15:23:45 +0100 Subject: staging:iio: Make sure a device is only opened once at a time Our buffer implementation does not support multiple concurrent readers. So we have to ensure that a device is only opened once at a time. So do the same thing we do for the event fd and introduce a per device busy flag. The flag gets set when opening the device and gets cleared when closing the device. If a open is attempted while the busy flag is set we return -EBUSY. Acked-by: Jonathan Cameron Signed-off-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/iio.h | 3 +++ drivers/staging/iio/industrialio-core.c | 17 ++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index 45b6d759c2e7..be6ced31f65e 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -313,6 +313,7 @@ struct iio_buffer_setup_ops { * @chrdev: [INTERN] associated character device * @groups: [INTERN] attribute groups * @groupcounter: [INTERN] index of next attribute group + * @flags: [INTERN] file ops related flags including busy flag. **/ struct iio_dev { int id; @@ -344,6 +345,8 @@ struct iio_dev { #define IIO_MAX_GROUPS 6 const struct attribute_group *groups[IIO_MAX_GROUPS + 1]; int groupcounter; + + unsigned long flags; }; /** diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 2eef85fa38c7..12d1576a0766 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -1083,9 +1083,18 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp) { struct iio_dev *indio_dev = container_of(inode->i_cdev, struct iio_dev, chrdev); + unsigned int ret; + + if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags)) + return -EBUSY; + filp->private_data = indio_dev; - return iio_chrdev_buffer_open(indio_dev); + ret = iio_chrdev_buffer_open(indio_dev); + if (ret < 0) + clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); + + return ret; } /** @@ -1093,8 +1102,10 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp) **/ static int iio_chrdev_release(struct inode *inode, struct file *filp) { - iio_chrdev_buffer_release(container_of(inode->i_cdev, - struct iio_dev, chrdev)); + struct iio_dev *indio_dev = container_of(inode->i_cdev, + struct iio_dev, chrdev); + iio_chrdev_buffer_release(indio_dev); + clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); return 0; } -- cgit v1.2.3