Commit abedd296 authored by Jonathan Corbet's avatar Jonathan Corbet

lp: cdev lock_kernel() pushdown

Signed-off-by: default avatarJonathan Corbet <corbet@lwn.net>
parent 12ead6b0
...@@ -126,6 +126,7 @@ ...@@ -126,6 +126,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/smp_lock.h>
#include <linux/parport.h> #include <linux/parport.h>
#undef LP_STATS #undef LP_STATS
...@@ -489,14 +490,21 @@ static ssize_t lp_read(struct file * file, char __user * buf, ...@@ -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) static int lp_open(struct inode * inode, struct file * file)
{ {
unsigned int minor = iminor(inode); unsigned int minor = iminor(inode);
int ret = 0;
if (minor >= LP_NO) lock_kernel();
return -ENXIO; if (minor >= LP_NO) {
if ((LP_F(minor) & LP_EXIST) == 0) ret = -ENXIO;
return -ENXIO; goto out;
if (test_and_set_bit(LP_BUSY_BIT_POS, &LP_F(minor))) }
return -EBUSY; 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, /* 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 we may still want to open it to perform ioctl()s. Therefore we
have commandeered O_NONBLOCK, even though it is being used in 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) ...@@ -510,21 +518,25 @@ static int lp_open(struct inode * inode, struct file * file)
if (status & LP_POUTPA) { if (status & LP_POUTPA) {
printk(KERN_INFO "lp%d out of paper\n", minor); printk(KERN_INFO "lp%d out of paper\n", minor);
LP_F(minor) &= ~LP_BUSY; LP_F(minor) &= ~LP_BUSY;
return -ENOSPC; ret = -ENOSPC;
goto out;
} else if (!(status & LP_PSELECD)) { } else if (!(status & LP_PSELECD)) {
printk(KERN_INFO "lp%d off-line\n", minor); printk(KERN_INFO "lp%d off-line\n", minor);
LP_F(minor) &= ~LP_BUSY; LP_F(minor) &= ~LP_BUSY;
return -EIO; ret = -EIO;
goto out;
} else if (!(status & LP_PERRORP)) { } else if (!(status & LP_PERRORP)) {
printk(KERN_ERR "lp%d printer error\n", minor); printk(KERN_ERR "lp%d printer error\n", minor);
LP_F(minor) &= ~LP_BUSY; LP_F(minor) &= ~LP_BUSY;
return -EIO; ret = -EIO;
goto out;
} }
} }
lp_table[minor].lp_buffer = kmalloc(LP_BUFFER_SIZE, GFP_KERNEL); lp_table[minor].lp_buffer = kmalloc(LP_BUFFER_SIZE, GFP_KERNEL);
if (!lp_table[minor].lp_buffer) { if (!lp_table[minor].lp_buffer) {
LP_F(minor) &= ~LP_BUSY; LP_F(minor) &= ~LP_BUSY;
return -ENOMEM; ret = -ENOMEM;
goto out;
} }
/* Determine if the peripheral supports ECP mode */ /* Determine if the peripheral supports ECP mode */
lp_claim_parport_or_block (&lp_table[minor]); lp_claim_parport_or_block (&lp_table[minor]);
...@@ -540,7 +552,9 @@ static int lp_open(struct inode * inode, struct file * file) ...@@ -540,7 +552,9 @@ static int lp_open(struct inode * inode, struct file * file)
parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT); parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT);
lp_release_parport (&lp_table[minor]); lp_release_parport (&lp_table[minor]);
lp_table[minor].current_mode = IEEE1284_MODE_COMPAT; 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) static int lp_release(struct inode * inode, struct file * file)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment