1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-12-25 14:56:47 +02:00

GPIODEV: Fix open-count race condition.

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@10625 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
mb 2008-03-19 11:32:08 +00:00
parent 89564986c3
commit bad75cb0eb

View File

@ -25,6 +25,7 @@
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/atomic.h>
#include <linux/init.h>
#include <linux/genhd.h>
#include <linux/device.h>
@ -35,10 +36,12 @@
#define DEVNAME "gpio"
static int dev_major;
static int gpio_is_open = 0;
unsigned int gpio_access_mask = 0;
static unsigned int gpio_access_mask;
static struct class *gpio_class;
/* Counter is 1, if the device is not opened and zero (or less) if opened. */
static atomic_t gpio_open_cnt = ATOMIC_INIT(1);
static int
gpio_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
{
@ -94,15 +97,18 @@ gpio_open(struct inode *inode, struct file *file)
goto out;
}
if (gpio_is_open)
{
/* FIXME: We should really allow multiple applications to open the device
* at the same time, as long as the apps access different IO pins.
* The generic gpio-registration functions can be used for that.
* Two new IOCTLs have to be introduced for that. Need to check userspace
* compatibility first. --mb */
if (!atomic_dec_and_test(&gpio_open_cnt)) {
atomic_inc(&gpio_open_cnt);
printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor);
result = -EBUSY;
goto out;
}
gpio_is_open = 1;
out:
return result;
}
@ -110,7 +116,8 @@ out:
static int
gpio_close(struct inode * inode, struct file * file)
{
gpio_is_open = 0;
smp_mb__before_atomic_inc();
atomic_inc(&gpio_open_cnt);
return 0;
}