LP is quite complex and has a lot of ioctl logic. Just push the BKL down
into a driver wrapper for the moment.
Signed-off-by: Alan Cox <alan@redhat.com>
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 60ac642..3a42f87 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -126,7 +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
#include <linux/lp.h>
@@ -557,10 +557,9 @@ static int lp_release(struct inode * inode, struct file * file)
return 0;
}
-static int lp_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long lp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
- unsigned int minor = iminor(inode);
+ unsigned int minor = iminor(file->f_path.dentry->d_inode);
int status;
int retval = 0;
void __user *argp = (void __user *)arg;
@@ -570,9 +569,13 @@ static int lp_ioctl(struct inode *inode, struct file *file,
#endif
if (minor >= LP_NO)
return -ENODEV;
- if ((LP_F(minor) & LP_EXIST) == 0)
+
+ lock_kernel();
+ if ((LP_F(minor) & LP_EXIST) == 0) {
+ unlock_kernel();
return -ENODEV;
- switch ( cmd ) {
+ }
+ switch (cmd ) {
struct timeval par_timeout;
long to_jiffies;
@@ -604,12 +607,12 @@ static int lp_ioctl(struct inode *inode, struct file *file,
LP_WAIT(minor) = arg;
break;
case LPSETIRQ:
- return -EINVAL;
+ retval = -EINVAL;
break;
case LPGETIRQ:
if (copy_to_user(argp, &LP_IRQ(minor),
sizeof(int)))
- return -EFAULT;
+ retval = -EFAULT;
break;
case LPGETSTATUS:
lp_claim_parport_or_block (&lp_table[minor]);
@@ -617,7 +620,7 @@ static int lp_ioctl(struct inode *inode, struct file *file,
lp_release_parport (&lp_table[minor]);
if (copy_to_user(argp, &status, sizeof(int)))
- return -EFAULT;
+ retval = -EFAULT;
break;
case LPRESET:
lp_reset(minor);
@@ -626,8 +629,8 @@ static int lp_ioctl(struct inode *inode, struct file *file,
case LPGETSTATS:
if (copy_to_user(argp, &LP_STAT(minor),
sizeof(struct lp_stats)))
- return -EFAULT;
- if (capable(CAP_SYS_ADMIN))
+ retval = -EFAULT;
+ else if (capable(CAP_SYS_ADMIN))
memset(&LP_STAT(minor), 0,
sizeof(struct lp_stats));
break;
@@ -635,37 +638,40 @@ static int lp_ioctl(struct inode *inode, struct file *file,
case LPGETFLAGS:
status = LP_F(minor);
if (copy_to_user(argp, &status, sizeof(int)))
- return -EFAULT;
+ retval = -EFAULT;
break;
case LPSETTIMEOUT:
if (copy_from_user (&par_timeout, argp,
sizeof (struct timeval))) {
- return -EFAULT;
+ retval = -EFAULT;
+ break;
}
/* Convert to jiffies, place in lp_table */
if ((par_timeout.tv_sec < 0) ||
(par_timeout.tv_usec < 0)) {
- return -EINVAL;
+ retval = -EINVAL;
+ break;
}
to_jiffies = DIV_ROUND_UP(par_timeout.tv_usec, 1000000/HZ);
to_jiffies += par_timeout.tv_sec * (long) HZ;
- if (to_jiffies <= 0) {
- return -EINVAL;
- }
- lp_table[minor].timeout = to_jiffies;
+ if (to_jiffies <= 0)
+ retval = -EINVAL;
+ else
+ lp_table[minor].timeout = to_jiffies;
break;
default:
- retval = -EINVAL;
+ retval = -ENOTTY;
}
+ unlock_kernel();
return retval;
}
static const struct file_operations lp_fops = {
.owner = THIS_MODULE,
.write = lp_write,
- .ioctl = lp_ioctl,
+ .unlocked_ioctl = lp_ioctl,
.open = lp_open,
.release = lp_release,
#ifdef CONFIG_PARPORT_1284
--
| Bart Van Assche | Integration of SCST in the mainstream Linux kernel |
| Greg KH | [GIT PATCH] driver core patches against 2.6.24 |
| Linus Torvalds | Linux 2.6.27 |
| Andrew Morton | Re: PROBLEM: high load average when idle |
git: | |
| Nguyen Thai Ngoc Duy | Re: VCS comparison table |
| Michael Hendricks | removing content from git history |
| walt | git versus CVS (versus bk) |
| Francis Moreau | emacs and git... |
| Marcos Laufer | dmesg IBM x3650 OpenBSD 4.3 |
| Richard Stallman | Real men don't attack straw men |
| Karel Kulhavy | lookup option in /etc/resolv.conf ignored |
| Alexey Suslikov | OT: OpenBSD on Asus eeePC |
| Paul Moore | [PATCH v7 00/17] Labeled networking patches for 2.6.28 |
| Dale Farnsworth | Re: [PATCH 01/39] mv643xx_eth: reverse topological sort of functions |
| David Miller | Re: xfrm_state locking regression... |
| Michael Chan | [PATCH net-next 4/6] bnx2: Eliminate TSO header modifications. |
| How to make my PCIE ATA storage device running in Linux | 9 hours ago | Linux general |
| sata/ide timeout errors on asus server-mb | 12 hours ago | Linux kernel |
| Shared swap partition | 13 hours ago | Linux general |
| usb mic not detected | 17 hours ago | Applications and Utilities |
| Problem in Inserting a module | 18 hours ago | Linux kernel |
| Treason Uncloaked | 23 hours ago | Linux kernel |
| high memory | 3 days ago | Linux kernel |
| semaphore access speed | 3 days ago | Applications and Utilities |
| the kernel how to power off the machine | 3 days ago | Linux kernel |
| Easter Eggs in windows XP | 3 days ago | Windows |
