aboutsummaryrefslogtreecommitdiff
path: root/drivers/char/ppdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/ppdev.c')
-rw-r--r--drivers/char/ppdev.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 432655bcb04..ae0b42b66e5 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -64,9 +64,10 @@
#include <linux/parport.h>
#include <linux/ctype.h>
#include <linux/poll.h>
+#include <linux/slab.h>
#include <linux/major.h>
#include <linux/ppdev.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/uaccess.h>
#define PP_VERSION "ppdev: user-space parallel port driver"
@@ -96,6 +97,7 @@ struct pp_struct {
/* ROUND_UP macro from fs/select.c */
#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
+static DEFINE_MUTEX(pp_do_mutex);
static inline void pp_enable_irq (struct pp_struct *pp)
{
struct parport *port = pp->pdev->port;
@@ -105,7 +107,7 @@ static inline void pp_enable_irq (struct pp_struct *pp)
static ssize_t pp_read (struct file * file, char __user * buf, size_t count,
loff_t * ppos)
{
- unsigned int minor = iminor(file->f_path.dentry->d_inode);
+ unsigned int minor = iminor(file_inode(file));
struct pp_struct *pp = file->private_data;
char * kbuffer;
ssize_t bytes_read = 0;
@@ -187,7 +189,7 @@ static ssize_t pp_read (struct file * file, char __user * buf, size_t count,
static ssize_t pp_write (struct file * file, const char __user * buf,
size_t count, loff_t * ppos)
{
- unsigned int minor = iminor(file->f_path.dentry->d_inode);
+ unsigned int minor = iminor(file_inode(file));
struct pp_struct *pp = file->private_data;
char * kbuffer;
ssize_t bytes_written = 0;
@@ -249,12 +251,8 @@ static ssize_t pp_write (struct file * file, const char __user * buf,
break;
}
- if (signal_pending (current)) {
- if (!bytes_written) {
- bytes_written = -EINTR;
- }
+ if (signal_pending (current))
break;
- }
cond_resched();
}
@@ -286,12 +284,10 @@ static int register_device (int minor, struct pp_struct *pp)
char *name;
int fl;
- name = kmalloc (strlen (CHRDEV) + 3, GFP_KERNEL);
+ name = kasprintf(GFP_KERNEL, CHRDEV "%x", minor);
if (name == NULL)
return -ENOMEM;
- sprintf (name, CHRDEV "%x", minor);
-
port = parport_find_number (minor);
if (!port) {
printk (KERN_WARNING "%s: no associated port!\n", name);
@@ -328,7 +324,7 @@ static enum ieee1284_phase init_phase (int mode)
static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
- unsigned int minor = iminor(file->f_path.dentry->d_inode);
+ unsigned int minor = iminor(file_inode(file));
struct pp_struct *pp = file->private_data;
struct parport * port;
void __user *argp = (void __user *)arg;
@@ -457,6 +453,7 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return -ENODEV;
modes = port->modes;
+ parport_put_port(port);
if (copy_to_user (argp, &modes, sizeof (modes))) {
return -EFAULT;
}
@@ -613,6 +610,7 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case PPGETTIME:
to_jiffies = pp->pdev->timeout;
+ memset(&par_timeout, 0, sizeof(par_timeout));
par_timeout.tv_sec = to_jiffies / HZ;
par_timeout.tv_usec = (to_jiffies % (long)HZ) * (1000000/HZ);
if (copy_to_user (argp, &par_timeout, sizeof(struct timeval)))
@@ -631,9 +629,9 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
static long pp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long ret;
- lock_kernel();
+ mutex_lock(&pp_do_mutex);
ret = pp_do_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&pp_do_mutex);
return ret;
}
@@ -642,7 +640,6 @@ 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;
@@ -782,7 +779,8 @@ static int __init ppdev_init (void)
err = PTR_ERR(ppdev_class);
goto out_chrdev;
}
- if (parport_register_driver(&pp_driver)) {
+ err = parport_register_driver(&pp_driver);
+ if (err < 0) {
printk (KERN_WARNING CHRDEV ": unable to register with parport\n");
goto out_class;
}