Skip to content

Commit

Permalink
staging:iio: Make sure a device is only opened once at a time
Browse files Browse the repository at this point in the history
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 <jic23@kernel.org>
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Lars-Peter Clausen authored and Greg Kroah-Hartman committed Dec 22, 2011
1 parent e38c79e commit bb01443
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 3 deletions.
3 changes: 3 additions & 0 deletions drivers/staging/iio/iio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
};

/**
Expand Down
17 changes: 14 additions & 3 deletions drivers/staging/iio/industrialio-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1083,18 +1083,29 @@ 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;
}

/**
* iio_chrdev_release() - chrdev file close buffer access and ioctls
**/
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;
}

Expand Down

0 comments on commit bb01443

Please sign in to comment.