aboutsummaryrefslogtreecommitdiff
path: root/drivers/char
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-14 14:48:31 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-14 14:48:31 -0700
commitd1794f2c5b5817eb79ccc5e00701ca748d1b073a (patch)
tree5a4c98e694e88a8c82f342d0cc9edb2a4cbbef36 /drivers/char
parenta41eebab7537890409ea9dfe0fcda9b5fbdb090d (diff)
parent2fceef397f9880b212a74c418290ce69e7ac00eb (diff)
Merge branch 'bkl-removal' of git://git.lwn.net/linux-2.6
* 'bkl-removal' of git://git.lwn.net/linux-2.6: (146 commits) IB/umad: BKL is not needed for ib_umad_open() IB/uverbs: BKL is not needed for ib_uverbs_open() bf561-coreb: BKL unneeded for open() Call fasync() functions without the BKL snd/PCM: fasync BKL pushdown ipmi: fasync BKL pushdown ecryptfs: fasync BKL pushdown Bluetooth VHCI: fasync BKL pushdown tty_io: fasync BKL pushdown tun: fasync BKL pushdown i2o: fasync BKL pushdown mpt: fasync BKL pushdown Remove BKL from remote_llseek v2 Make FAT users happier by not deadlocking x86-mce: BKL pushdown vmwatchdog: BKL pushdown vmcp: BKL pushdown via-pmu: BKL pushdown uml-random: BKL pushdown uml-mmapper: BKL pushdown ...
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/frontend.c4
-rw-r--r--drivers/char/apm-emulation.c3
-rw-r--r--drivers/char/briq_panel.c9
-rw-r--r--drivers/char/cs5535_gpio.c2
-rw-r--r--drivers/char/ds1286.c4
-rw-r--r--drivers/char/ds1620.c9
-rw-r--r--drivers/char/dsp56k.c16
-rw-r--r--drivers/char/dtlk.c3
-rw-r--r--drivers/char/efirtc.c2
-rw-r--r--drivers/char/genrtc.c7
-rw-r--r--drivers/char/hpet.c4
-rw-r--r--drivers/char/hw_random/core.c2
-rw-r--r--drivers/char/ip2/ip2main.c34
-rw-r--r--drivers/char/ip27-rtc.c4
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c10
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c3
-rw-r--r--drivers/char/lcd.c3
-rw-r--r--drivers/char/lp.c38
-rw-r--r--drivers/char/mbcs.c5
-rw-r--r--drivers/char/mem.c10
-rw-r--r--drivers/char/misc.c3
-rw-r--r--drivers/char/mwave/mwavedd.c2
-rw-r--r--drivers/char/nvram.c4
-rw-r--r--drivers/char/pc8736x_gpio.c2
-rw-r--r--drivers/char/ppdev.c2
-rw-r--r--drivers/char/raw.c3
-rw-r--r--drivers/char/rtc.c4
-rw-r--r--drivers/char/scx200_gpio.c2
-rw-r--r--drivers/char/snsc.c5
-rw-r--r--drivers/char/sonypi.c3
-rw-r--r--drivers/char/tb0219.c2
-rw-r--r--drivers/char/tlclk.c19
-rw-r--r--drivers/char/tpm/tpm.c5
-rw-r--r--drivers/char/tty_io.c41
-rw-r--r--drivers/char/vc_screen.c9
-rw-r--r--drivers/char/viotape.c3
-rw-r--r--drivers/char/vr41xx_giu.c2
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c6
38 files changed, 214 insertions, 75 deletions
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index e6cb1ab03e0..a96f3197e60 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -39,6 +39,7 @@
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include "agp.h"
@@ -677,6 +678,7 @@ static int agp_open(struct inode *inode, struct file *file)
struct agp_client *client;
int rc = -ENXIO;
+ lock_kernel();
mutex_lock(&(agp_fe.agp_mutex));
if (minor != AGPGART_MINOR)
@@ -703,12 +705,14 @@ static int agp_open(struct inode *inode, struct file *file)
agp_insert_file_private(priv);
DBG("private=%p, client=%p", priv, client);
mutex_unlock(&(agp_fe.agp_mutex));
+ unlock_kernel();
return 0;
err_out_nomem:
rc = -ENOMEM;
err_out:
mutex_unlock(&(agp_fe.agp_mutex));
+ unlock_kernel();
return rc;
}
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c
index cdd876dbb2b..da8a1658a27 100644
--- a/drivers/char/apm-emulation.c
+++ b/drivers/char/apm-emulation.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/miscdevice.h>
@@ -416,6 +417,7 @@ static int apm_open(struct inode * inode, struct file * filp)
{
struct apm_user *as;
+ lock_kernel();
as = kzalloc(sizeof(*as), GFP_KERNEL);
if (as) {
/*
@@ -435,6 +437,7 @@ static int apm_open(struct inode * inode, struct file * filp)
filp->private_data = as;
}
+ unlock_kernel();
return as ? 0 : -ENOMEM;
}
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c
index b6f2639f903..d8cff909001 100644
--- a/drivers/char/briq_panel.c
+++ b/drivers/char/briq_panel.c
@@ -6,6 +6,7 @@
#include <linux/module.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/tty.h>
@@ -67,11 +68,15 @@ static void set_led(char state)
static int briq_panel_open(struct inode *ino, struct file *filep)
{
- /* enforce single access */
- if (vfd_is_open)
+ lock_kernel();
+ /* enforce single access, vfd_is_open is protected by BKL */
+ if (vfd_is_open) {
+ unlock_kernel();
return -EBUSY;
+ }
vfd_is_open = 1;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c
index c0a4a0bb509..04ba906b488 100644
--- a/drivers/char/cs5535_gpio.c
+++ b/drivers/char/cs5535_gpio.c
@@ -17,6 +17,7 @@
#include <linux/cdev.h>
#include <linux/ioport.h>
#include <linux/pci.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -157,6 +158,7 @@ static int cs5535_gpio_open(struct inode *inode, struct file *file)
{
u32 m = iminor(inode);
+ cycle_kernel_lock();
/* the mask says which pins are usable by this driver */
if ((mask & (1 << m)) == 0)
return -EINVAL;
diff --git a/drivers/char/ds1286.c b/drivers/char/ds1286.c
index ea35ab2c990..fb584938c9c 100644
--- a/drivers/char/ds1286.c
+++ b/drivers/char/ds1286.c
@@ -27,6 +27,7 @@
* option) any later version.
*/
#include <linux/ds1286.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
@@ -252,6 +253,7 @@ static int ds1286_ioctl(struct inode *inode, struct file *file,
static int ds1286_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
spin_lock_irq(&ds1286_lock);
if (ds1286_status & RTC_IS_OPEN)
@@ -260,10 +262,12 @@ static int ds1286_open(struct inode *inode, struct file *file)
ds1286_status |= RTC_IS_OPEN;
spin_unlock_irq(&ds1286_lock);
+ unlock_kernel();
return 0;
out_busy:
spin_lock_irq(&ds1286_lock);
+ unlock_kernel();
return -EBUSY;
}
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index 334ad5bbe6b..34275c6f1da 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -8,6 +8,7 @@
#include <linux/proc_fs.h>
#include <linux/capability.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
@@ -208,6 +209,12 @@ static void ds1620_read_state(struct therm *therm)
therm->hi = cvt_9_to_int(ds1620_in(THERM_READ_TH, 9));
}
+static int ds1620_open(struct inode *inode, struct file *file)
+{
+ cycle_kernel_lock();
+ return nonseekable_open(inode, file);
+}
+
static ssize_t
ds1620_read(struct file *file, char __user *buf, size_t count, loff_t *ptr)
{
@@ -336,7 +343,7 @@ static struct proc_dir_entry *proc_therm_ds1620;
static const struct file_operations ds1620_fops = {
.owner = THIS_MODULE,
- .open = nonseekable_open,
+ .open = ds1620_open,
.read = ds1620_read,
.ioctl = ds1620_ioctl,
};
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index a69c6528326..7bf7485377e 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -33,6 +33,7 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/smp_lock.h>
#include <asm/atarihw.h>
#include <asm/traps.h>
@@ -436,13 +437,17 @@ static unsigned int dsp56k_poll(struct file *file, poll_table *wait)
static int dsp56k_open(struct inode *inode, struct file *file)
{
int dev = iminor(inode) & 0x0f;
+ int ret = 0;
+ lock_kernel();
switch(dev)
{
case DSP56K_DEV_56001:
- if (test_and_set_bit(0, &dsp56k.in_use))
- return -EBUSY;
+ if (test_and_set_bit(0, &dsp56k.in_use)) {
+ ret = -EBUSY;
+ goto out;
+ }
dsp56k.timeout = TIMEOUT;
dsp56k.maxio = MAXIO;
@@ -458,10 +463,11 @@ static int dsp56k_open(struct inode *inode, struct file *file)
break;
default:
- return -ENODEV;
+ ret = -ENODEV;
}
-
- return 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int dsp56k_release(struct inode *inode, struct file *file)
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index abde6ddefe6..6b900b297cc 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -56,6 +56,7 @@
#include <linux/errno.h> /* for -EBUSY */
#include <linux/ioport.h> /* for request_region */
#include <linux/delay.h> /* for loops_per_jiffy */
+#include <linux/smp_lock.h> /* cycle_kernel_lock() */
#include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */
#include <asm/uaccess.h> /* for get_user, etc. */
#include <linux/wait.h> /* for wait_queue */
@@ -288,10 +289,12 @@ static int dtlk_ioctl(struct inode *inode,
}
}
+/* Note that nobody ever sets dtlk_busy... */
static int dtlk_open(struct inode *inode, struct file *file)
{
TRACE_TEXT("(dtlk_open");
+ cycle_kernel_lock();
nonseekable_open(inode, file);
switch (iminor(inode)) {
case DTLK_MINOR:
diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c
index 49233f58987..d57ca3e4e53 100644
--- a/drivers/char/efirtc.c
+++ b/drivers/char/efirtc.c
@@ -28,6 +28,7 @@
*/
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
@@ -272,6 +273,7 @@ efi_rtc_open(struct inode *inode, struct file *file)
* We do accept multiple open files at the same time as we
* synchronize on the per call operation.
*/
+ cycle_kernel_lock();
return 0;
}
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c
index 69f0a2993af..aac0985a572 100644
--- a/drivers/char/genrtc.c
+++ b/drivers/char/genrtc.c
@@ -51,6 +51,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
+#include <linux/smp_lock.h>
#include <linux/workqueue.h>
#include <asm/uaccess.h>
@@ -338,12 +339,16 @@ static int gen_rtc_ioctl(struct inode *inode, struct file *file,
static int gen_rtc_open(struct inode *inode, struct file *file)
{
- if (gen_rtc_status & RTC_IS_OPEN)
+ lock_kernel();
+ if (gen_rtc_status & RTC_IS_OPEN) {
+ unlock_kernel();
return -EBUSY;
+ }
gen_rtc_status |= RTC_IS_OPEN;
gen_rtc_irq_data = 0;
irq_active = 0;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index e7fb0bca366..fb0a85a1eb3 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -14,6 +14,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/major.h>
@@ -193,6 +194,7 @@ static int hpet_open(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE)
return -EINVAL;
+ lock_kernel();
spin_lock_irq(&hpet_lock);
for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next)
@@ -207,6 +209,7 @@ static int hpet_open(struct inode *inode, struct file *file)
if (!devp) {
spin_unlock_irq(&hpet_lock);
+ unlock_kernel();
return -EBUSY;
}
@@ -214,6 +217,7 @@ static int hpet_open(struct inode *inode, struct file *file)
devp->hd_irqdata = 0;
devp->hd_flags |= HPET_OPEN;
spin_unlock_irq(&hpet_lock);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 662d60e44e9..e5d583c84e4 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -37,6 +37,7 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
@@ -86,6 +87,7 @@ static int rng_dev_open(struct inode *inode, struct file *filp)
return -EINVAL;
if (filp->f_mode & FMODE_WRITE)
return -EINVAL;
+ cycle_kernel_lock();
return 0;
}
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index c12cf8fc4be..61b6fe4156b 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -98,6 +98,7 @@
#include <linux/major.h>
#include <linux/wait.h>
#include <linux/device.h>
+#include <linux/smp_lock.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
@@ -2908,42 +2909,11 @@ ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg )
static int
ip2_ipl_open( struct inode *pInode, struct file *pFile )
{
- unsigned int iplminor = iminor(pInode);
- i2eBordStrPtr pB;
- i2ChanStrPtr pCh;
#ifdef IP2DEBUG_IPL
printk (KERN_DEBUG "IP2IPL: open\n" );
#endif
-
- switch(iplminor) {
- // These are the IPL devices
- case 0:
- case 4:
- case 8:
- case 12:
- break;
-
- // These are the status devices
- case 1:
- case 5:
- case 9:
- case 13:
- break;
-
- // These are the debug devices
- case 2:
- case 6:
- case 10:
- case 14:
- pB = i2BoardPtrTable[iplminor / 4];
- pCh = (i2ChanStrPtr) pB->i2eChannelPtr;
- break;
-
- // This is the trace device
- case 3:
- break;
- }
+ cycle_kernel_lock();
return 0;
}
diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c
index 86e6538a77b..ec9d0443d92 100644
--- a/drivers/char/ip27-rtc.c
+++ b/drivers/char/ip27-rtc.c
@@ -27,6 +27,7 @@
#include <linux/bcd.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/ioport.h>
@@ -163,15 +164,18 @@ static long rtc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
static int rtc_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
spin_lock_irq(&rtc_lock);
if (rtc_status & RTC_IS_OPEN) {
spin_unlock_irq(&rtc_lock);
+ unlock_kernel();
return -EBUSY;
}
rtc_status |= RTC_IS_OPEN;
spin_unlock_irq(&rtc_lock);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 0246a2b8ce4..c11a4048345 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -43,6 +43,7 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/compat.h>
+#include <linux/smp_lock.h>
struct ipmi_file_private
{
@@ -100,7 +101,9 @@ static int ipmi_fasync(int fd, struct file *file, int on)
struct ipmi_file_private *priv = file->private_data;
int result;
+ lock_kernel(); /* could race against open() otherwise */
result = fasync_helper(fd, file, on, &priv->fasync_queue);
+ unlock_kernel();
return (result);
}
@@ -121,6 +124,7 @@ static int ipmi_open(struct inode *inode, struct file *file)
if (!priv)
return -ENOMEM;
+ lock_kernel();
priv->file = file;
rv = ipmi_create_user(if_num,
@@ -129,7 +133,7 @@ static int ipmi_open(struct inode *inode, struct file *file)
&(priv->user));
if (rv) {
kfree(priv);
- return rv;
+ goto out;
}
file->private_data = priv;
@@ -144,7 +148,9 @@ static int ipmi_open(struct inode *inode, struct file *file)
priv->default_retries = -1;
priv->default_retry_time_ms = 0;
- return 0;
+out:
+ unlock_kernel();
+ return rv;
}
static int ipmi_release(struct inode *inode, struct file *file)
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 0e6df289cb4..235fab0bdf7 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -35,6 +35,7 @@
#include <linux/moduleparam.h>
#include <linux/ipmi.h>
#include <linux/ipmi_smi.h>
+#include <linux/smp_lock.h>
#include <linux/watchdog.h>
#include <linux/miscdevice.h>
#include <linux/init.h>
@@ -818,6 +819,8 @@ static int ipmi_open(struct inode *ino, struct file *filep)
if (test_and_set_bit(0, &ipmi_wdog_open))
return -EBUSY;
+ cycle_kernel_lock();
+
/*
* Don't start the timer now, let it start on the
* first heartbeat.
diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c
index 4fe9206f84d..1c29b20e4f4 100644
--- a/drivers/char/lcd.c
+++ b/drivers/char/lcd.c
@@ -20,6 +20,7 @@
#include <linux/mc146818rtc.h>
#include <linux/netdevice.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <asm/io.h>
@@ -414,6 +415,8 @@ static int lcd_ioctl(struct inode *inode, struct file *file,
static int lcd_open(struct inode *inode, struct file *file)
{
+ cycle_kernel_lock();
+
if (!lcd_present)
return -ENXIO;
else
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 60ac642752b..71abb4c33aa 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -126,6 +126,7 @@
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/jiffies.h>
+#include <linux/smp_lock.h>
#include <linux/parport.h>
#undef LP_STATS
@@ -489,14 +490,21 @@ static ssize_t lp_read(struct file * file, char __user * buf,
static int lp_open(struct inode * inode, struct file * file)
{
unsigned int minor = iminor(inode);
+ int ret = 0;
- if (minor >= LP_NO)
- return -ENXIO;
- if ((LP_F(minor) & LP_EXIST) == 0)
- return -ENXIO;
- if (test_and_set_bit(LP_BUSY_BIT_POS, &LP_F(minor)))
- return -EBUSY;
-
+ lock_kernel();
+ if (minor >= LP_NO) {
+ ret = -ENXIO;
+ goto out;
+ }
+ if ((LP_F(minor) & LP_EXIST) == 0) {
+ ret = -ENXIO;
+ goto out;
+ }
+ if (test_and_set_bit(LP_BUSY_BIT_POS, &LP_F(minor))) {
+ ret = -EBUSY;
+ goto out;
+ }
/* If ABORTOPEN is set and the printer is offline or out of paper,
we may still want to open it to perform ioctl()s. Therefore we
have commandeered O_NONBLOCK, even though it is being used in
@@ -510,21 +518,25 @@ static int lp_open(struct inode * inode, struct file * file)
if (status & LP_POUTPA) {
printk(KERN_INFO "lp%d out of paper\n", minor);
LP_F(minor) &= ~LP_BUSY;
- return -ENOSPC;
+ ret = -ENOSPC;
+ goto out;
} else if (!(status & LP_PSELECD)) {
printk(KERN_INFO "lp%d off-line\n", minor);
LP_F(minor) &= ~LP_BUSY;
- return -EIO;
+ ret = -EIO;
+ goto out;
} else if (!(status & LP_PERRORP)) {
printk(KERN_ERR "lp%d printer error\n", minor);
LP_F(minor) &= ~LP_BUSY;
- return -EIO;
+ ret = -EIO;
+ goto out;
}
}
lp_table[minor].lp_buffer = kmalloc(LP_BUFFER_SIZE, GFP_KERNEL);
if (!lp_table[minor].lp_buffer) {
LP_F(minor) &= ~LP_BUSY;
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out;
}
/* Determine if the peripheral supports ECP mode */
lp_claim_parport_or_block (&lp_table[minor]);
@@ -540,7 +552,9 @@ static int lp_open(struct inode * inode, struct file * file)
parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT);
lp_release_parport (&lp_table[minor]);
lp_table[minor].current_mode = IEEE1284_MODE_COMPAT;
- return 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int lp_release(struct inode * inode, struct file * file)
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index f4716ad7348..acd8e9ed474 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -24,6 +24,7 @@
#include <linux/mm.h>
#include <linux/uio.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -382,15 +383,19 @@ static int mbcs_open(struct inode *ip, struct file *fp)
struct mbcs_soft *soft;
int minor;
+ lock_kernel();
minor = iminor(ip);
+ /* Nothing protects access to this list... */
list_for_each_entry(soft, &soft_list, list) {
if (soft->nasid == minor) {
fp->private_data = soft->cxdev;
+ unlock_kernel();
return 0;
}
}
+ unlock_kernel();
return -ENODEV;
}
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 934ffafedae..070e22e8ea9 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -26,6 +26,7 @@
#include <linux/bootmem.h>
#include <linux/splice.h>
#include <linux/pfn.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -889,6 +890,9 @@ static const struct file_operations kmsg_fops = {
static int memory_open(struct inode * inode, struct file * filp)
{
+ int ret = 0;
+
+ lock_kernel();
switch (iminor(inode)) {
case 1:
filp->f_op = &mem_fops;
@@ -932,11 +936,13 @@ static int memory_open(struct inode * inode, struct file * filp)
break;
#endif
default:
+ unlock_kernel();
return -ENXIO;
}
if (filp->f_op && filp->f_op->open)
- return filp->f_op->open(inode,filp);
- return 0;
+ ret = filp->f_op->open(inode,filp);
+ unlock_kernel();
+ return ret;
}
static const struct file_operations memory_fops = {
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index eaace0db0ff..6e1563c3d30 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -49,6 +49,7 @@
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
+#include <linux/smp_lock.h>
/*
* Head entry for the doubly linked miscdevice list
@@ -118,6 +119,7 @@ static int misc_open(struct inode * inode, struct file * file)
int err = -ENODEV;
const struct file_operations *old_fops, *new_fops = NULL;
+ lock_kernel();
mutex_lock(&misc_mtx);
list_for_each_entry(c, &misc_list, list) {
@@ -155,6 +157,7 @@ static int misc_open(struct inode * inode, struct file * file)
fops_put(old_fops);
fail:
mutex_unlock(&misc_mtx);
+ unlock_kernel();
return err;
}
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
index 8d14823b051..50243fcd87e 100644
--- a/drivers/char/mwave/mwavedd.c
+++ b/drivers/char/mwave/mwavedd.c
@@ -56,6 +56,7 @@
#include <linux/serial.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/serial_8250.h>
#include "smapi.h"
@@ -100,6 +101,7 @@ static int mwave_open(struct inode *inode, struct file *file)
PRINTK_2(TRACE_MWAVE,
"mwavedd::mwave_open, exit return retval %x\n", retval);
+ cycle_kernel_lock();
return retval;
}
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index 98dec380af4..197cd7a0c33 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -107,6 +107,7 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -333,12 +334,14 @@ nvram_ioctl(struct inode *inode, struct file *file,
static int
nvram_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
spin_lock(&nvram_state_lock);
if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
(nvram_open_mode & NVRAM_EXCL) ||
((file->f_mode & 2) && (nvram_open_mode & NVRAM_WRITE))) {
spin_unlock(&nvram_state_lock);
+ unlock_kernel();
return -EBUSY;
}
@@ -349,6 +352,7 @@ nvram_open(struct inode *inode, struct file *file)
nvram_open_cnt++;
spin_unlock(&nvram_state_lock);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c
index ecfaf180e5b..b930de50407 100644
--- a/drivers/char/pc8736x_gpio.c
+++ b/drivers/char/pc8736x_gpio.c
@@ -20,6 +20,7 @@
#include <linux/mutex.h>
#include <linux/nsc_gpio.h>
#include <linux/platform_device.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#define DEVNAME "pc8736x_gpio"
@@ -217,6 +218,7 @@ static int pc8736x_gpio_open(struct inode *inode, struct file *file)
unsigned m = iminor(inode);
file->private_data = &pc8736x_gpio_ops;
+ cycle_kernel_lock();
dev_dbg(&pdev->dev, "open %d\n", m);
if (m >= PC8736X_GPIO_CT)
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 3aab837d948..f6e6acadd9a 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -66,6 +66,7 @@
#include <linux/poll.h>
#include <linux/major.h>
#include <linux/ppdev.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#define PP_VERSION "ppdev: user-space parallel port driver"
@@ -638,6 +639,7 @@ static int pp_open (struct inode * inode, struct file * file)
unsigned int minor = iminor(inode);
struct pp_struct *pp;
+ cycle_kernel_lock();
if (minor >= PARPORT_MAX)
return -ENXIO;
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index bbfa0e241cb..505fcbe884a 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -19,6 +19,7 @@
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -53,6 +54,7 @@ static int raw_open(struct inode *inode, struct file *filp)
return 0;
}
+ lock_kernel();
mutex_lock(&raw_mutex);
/*
@@ -79,6 +81,7 @@ static int raw_open(struct inode *inode, struct file *filp)
bdev->bd_inode->i_mapping;
filp->private_data = bdev;
mutex_unlock(&raw_mutex);
+ unlock_kernel();
return 0;
out2:
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 909cac93fa2..fa92a8af5a5 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -73,6 +73,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <linux/sysctl.h>
#include <linux/wait.h>
#include <linux/bcd.h>
@@ -734,6 +735,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
* needed here. Or anywhere else in this driver. */
static int rtc_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
spin_lock_irq(&rtc_lock);
if (rtc_status & RTC_IS_OPEN)
@@ -743,10 +745,12 @@ static int rtc_open(struct inode *inode, struct file *file)
rtc_irq_data = 0;
spin_unlock_irq(&rtc_lock);
+ unlock_kernel();
return 0;
out_busy:
spin_unlock_irq(&rtc_lock);
+ unlock_kernel();
return -EBUSY;
}
diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c
index 99e5272e3c5..1d9100561c8 100644
--- a/drivers/char/scx200_gpio.c
+++ b/drivers/char/scx200_gpio.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -51,6 +52,7 @@ static int scx200_gpio_open(struct inode *inode, struct file *file)
unsigned m = iminor(inode);
file->private_data = &scx200_gpio_ops;
+ cycle_kernel_lock();
if (m >= MAX_PINS)
return -EINVAL;
return nonseekable_open(inode, file);
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index 8fe099a4106..0b799ac1b04 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -21,6 +21,7 @@
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/module.h>
@@ -104,6 +105,7 @@ scdrv_open(struct inode *inode, struct file *file)
file->private_data = sd;
/* hook this subchannel up to the system controller interrupt */
+ lock_kernel();
rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt,
IRQF_SHARED | IRQF_DISABLED,
SYSCTL_BASENAME, sd);
@@ -111,9 +113,10 @@ scdrv_open(struct inode *inode, struct file *file)
ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch);
kfree(sd);
printk("%s: irq request failed (%d)\n", __func__, rv);
+ unlock_kernel();
return -EBUSY;
}
-
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 58533de5902..85e0eb76eea 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -49,6 +49,7 @@
#include <linux/err.h>
#include <linux/kfifo.h>
#include <linux/platform_device.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -906,12 +907,14 @@ static int sonypi_misc_release(struct inode *inode, struct file *file)
static int sonypi_misc_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
mutex_lock(&sonypi_device.lock);
/* Flush input queue on first open */
if (!sonypi_device.open_count)
kfifo_reset(sonypi_device.fifo);
sonypi_device.open_count++;
mutex_unlock(&sonypi_device.lock);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
index 4c431cb7cf1..6062b62800f 100644
--- a/drivers/char/tb0219.c
+++ b/drivers/char/tb0219.c
@@ -21,6 +21,7 @@
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/reboot.h>
@@ -236,6 +237,7 @@ static int tanbac_tb0219_open(struct inode *inode, struct file *file)
{
unsigned int minor;
+ cycle_kernel_lock();
minor = iminor(inode);
switch (minor) {
case 0:
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 35e58030d29..8f2284be68e 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -36,6 +36,7 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/sysfs.h>
#include <linux/device.h>
@@ -204,11 +205,14 @@ static int tlclk_open(struct inode *inode, struct file *filp)
{
int result;
- if (test_and_set_bit(0, &useflags))
- return -EBUSY;
+ lock_kernel();
+ if (test_and_set_bit(0, &useflags)) {
+ result = -EBUSY;
/* this legacy device is always one per system and it doesn't
* know how to handle multiple concurrent clients.
*/
+ goto out;
+ }
/* Make sure there is no interrupt pending while
* initialising interrupt handler */
@@ -218,13 +222,14 @@ static int tlclk_open(struct inode *inode, struct file *filp)
* we can't share this IRQ */
result = request_irq(telclk_interrupt, &tlclk_interrupt,
IRQF_DISABLED, "telco_clock", tlclk_interrupt);
- if (result == -EBUSY) {
+ if (result == -EBUSY)
printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n");
- return -EBUSY;
- }
- inb(TLCLK_REG6); /* Clear interrupt events */
+ else
+ inb(TLCLK_REG6); /* Clear interrupt events */
- return 0;
+out:
+ unlock_kernel();
+ return result;
}
static int tlclk_release(struct inode *inode, struct file *filp)
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index a5d8bcb4000..e1fc193d939 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -26,6 +26,7 @@
#include <linux/poll.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include "tpm.h"
@@ -897,6 +898,7 @@ int tpm_open(struct inode *inode, struct file *file)
int rc = 0, minor = iminor(inode);
struct tpm_chip *chip = NULL, *pos;
+ lock_kernel();
spin_lock(&driver_lock);
list_for_each_entry(pos, &tpm_chip_list, list) {
@@ -926,16 +928,19 @@ int tpm_open(struct inode *inode, struct file *file)
if (chip->data_buffer == NULL) {
chip->num_opens--;
put_device(chip->dev);
+ unlock_kernel();
return -ENOMEM;
}
atomic_set(&chip->data_pending, 0);
file->private_data = chip;
+ unlock_kernel();
return 0;
err_out:
spin_unlock(&driver_lock);
+ unlock_kernel();
return rc;
}
EXPORT_SYMBOL_GPL(tpm_open);
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 750131010af..047a17339f8 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -2665,7 +2665,7 @@ static void release_dev(struct file *filp)
* ->siglock protects ->signal/->sighand
*/
-static int tty_open(struct inode *inode, struct file *filp)
+static int __tty_open(struct inode *inode, struct file *filp)
{
struct tty_struct *tty;
int noctty, retval;
@@ -2779,6 +2779,19 @@ got_driver:
return 0;
}
+/* BKL pushdown: scary code avoidance wrapper */
+static int tty_open(struct inode *inode, struct file *filp)
+{
+ int ret;
+
+ lock_kernel();
+ ret = __tty_open(inode, filp);
+ unlock_kernel();
+ return ret;
+}
+
+
+
#ifdef CONFIG_UNIX98_PTYS
/**
* ptmx_open - open a unix 98 pty master
@@ -2792,7 +2805,7 @@ got_driver:
* allocated_ptys_lock handles the list of free pty numbers
*/
-static int ptmx_open(struct inode *inode, struct file *filp)
+static int __ptmx_open(struct inode *inode, struct file *filp)
{
struct tty_struct *tty;
int retval;
@@ -2831,6 +2844,16 @@ out:
devpts_kill_index(index);
return retval;
}
+
+static int ptmx_open(struct inode *inode, struct file *filp)
+{
+ int ret;
+
+ lock_kernel();
+ ret = __ptmx_open(inode, filp);
+ unlock_kernel();
+ return ret;
+}
#endif
/**
@@ -2886,15 +2909,16 @@ static int tty_fasync(int fd, struct file *filp, int on)
{
struct tty_struct *tty;
unsigned long flags;
- int retval;
+ int retval = 0;
+ lock_kernel();
tty = (struct tty_struct *)filp->private_data;
if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))
- return 0;
+ goto out;
retval = fasync_helper(fd, filp, on, &tty->fasync);
if (retval <= 0)
- return retval;
+ goto out;
if (on) {
enum pid_type type;
@@ -2912,12 +2936,15 @@ static int tty_fasync(int fd, struct file *filp, int on)
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
retval = __f_setown(filp, pid, type, 0);
if (retval)
- return retval;
+ goto out;
} else {
if (!tty->fasync && !waitqueue_active(&tty->read_wait))
tty->minimum_to_wake = N_TTY_BUF_SIZE;
}
- return 0;
+ retval = 0;
+out:
+ unlock_kernel();
+ return retval;
}
/**
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 83aeedda200..eebfad2777d 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -34,6 +34,7 @@
#include <linux/kbd_kern.h>
#include <linux/console.h>
#include <linux/device.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
@@ -460,9 +461,13 @@ static int
vcs_open(struct inode *inode, struct file *filp)
{
unsigned int currcons = iminor(inode) & 127;
+ int ret = 0;
+
+ lock_kernel();
if(currcons && !vc_cons_allocated(currcons-1))
- return -ENXIO;
- return 0;
+ ret = -ENXIO;
+ unlock_kernel();
+ return ret;
}
static const struct file_operations vcs_fops = {
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index c39ddaff5e8..977f7d35e76 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -46,6 +46,7 @@
#include <linux/completion.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/ioctls.h>
@@ -687,6 +688,7 @@ static int viotap_open(struct inode *inode, struct file *file)
if (op == NULL)
return -ENOMEM;
+ lock_kernel();
get_dev_info(file->f_path.dentry->d_inode, &devi);
/* Note: We currently only support one mode! */
@@ -717,6 +719,7 @@ static int viotap_open(struct inode *inode, struct file *file)
free_op:
free_op_struct(op);
+ unlock_kernel();
return ret;
}
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
index e5ed09192be..ffe9b4e3072 100644
--- a/drivers/char/vr41xx_giu.c
+++ b/drivers/char/vr41xx_giu.c
@@ -27,6 +27,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/types.h>
@@ -547,6 +548,7 @@ static int gpio_open(struct inode *inode, struct file *file)
{
unsigned int pin;
+ cycle_kernel_lock();
pin = iminor(inode);
if (pin >= giu_nr_pins)
return -EBADF;
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 3edf1fc1296..1e1b81e57cd 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -85,6 +85,7 @@
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <linux/sysctl.h>
#include <linux/version.h>
#include <linux/fs.h>
@@ -504,11 +505,12 @@ static int hwicap_open(struct inode *inode, struct file *file)
struct hwicap_drvdata *drvdata;
int status;
+ lock_kernel();
drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev);
status = mutex_lock_interruptible(&drvdata->sem);
if (status)
- return status;
+ goto out;
if (drvdata->is_open) {
status = -EBUSY;
@@ -528,6 +530,8 @@ static int hwicap_open(struct inode *inode, struct file *file)
error:
mutex_unlock(&drvdata->sem);
+ out:
+ unlock_kernel();
return status;
}