aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ppdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/ppdev.c')
-rw-r--r--drivers/char/ppdev.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 02abfddce45a..3fcf80ff12f2 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -67,7 +67,7 @@
67#include <linux/slab.h> 67#include <linux/slab.h>
68#include <linux/major.h> 68#include <linux/major.h>
69#include <linux/ppdev.h> 69#include <linux/ppdev.h>
70#include <linux/smp_lock.h> 70#include <linux/mutex.h>
71#include <linux/uaccess.h> 71#include <linux/uaccess.h>
72 72
73#define PP_VERSION "ppdev: user-space parallel port driver" 73#define PP_VERSION "ppdev: user-space parallel port driver"
@@ -97,6 +97,7 @@ struct pp_struct {
97/* ROUND_UP macro from fs/select.c */ 97/* ROUND_UP macro from fs/select.c */
98#define ROUND_UP(x,y) (((x)+(y)-1)/(y)) 98#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
99 99
100static DEFINE_MUTEX(pp_do_mutex);
100static inline void pp_enable_irq (struct pp_struct *pp) 101static inline void pp_enable_irq (struct pp_struct *pp)
101{ 102{
102 struct parport *port = pp->pdev->port; 103 struct parport *port = pp->pdev->port;
@@ -456,6 +457,7 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
456 return -ENODEV; 457 return -ENODEV;
457 458
458 modes = port->modes; 459 modes = port->modes;
460 parport_put_port(port);
459 if (copy_to_user (argp, &modes, sizeof (modes))) { 461 if (copy_to_user (argp, &modes, sizeof (modes))) {
460 return -EFAULT; 462 return -EFAULT;
461 } 463 }
@@ -612,6 +614,7 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
612 614
613 case PPGETTIME: 615 case PPGETTIME:
614 to_jiffies = pp->pdev->timeout; 616 to_jiffies = pp->pdev->timeout;
617 memset(&par_timeout, 0, sizeof(par_timeout));
615 par_timeout.tv_sec = to_jiffies / HZ; 618 par_timeout.tv_sec = to_jiffies / HZ;
616 par_timeout.tv_usec = (to_jiffies % (long)HZ) * (1000000/HZ); 619 par_timeout.tv_usec = (to_jiffies % (long)HZ) * (1000000/HZ);
617 if (copy_to_user (argp, &par_timeout, sizeof(struct timeval))) 620 if (copy_to_user (argp, &par_timeout, sizeof(struct timeval)))
@@ -630,9 +633,9 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
630static long pp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 633static long pp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
631{ 634{
632 long ret; 635 long ret;
633 lock_kernel(); 636 mutex_lock(&pp_do_mutex);
634 ret = pp_do_ioctl(file, cmd, arg); 637 ret = pp_do_ioctl(file, cmd, arg);
635 unlock_kernel(); 638 mutex_unlock(&pp_do_mutex);
636 return ret; 639 return ret;
637} 640}
638 641
@@ -641,7 +644,6 @@ static int pp_open (struct inode * inode, struct file * file)
641 unsigned int minor = iminor(inode); 644 unsigned int minor = iminor(inode);
642 struct pp_struct *pp; 645 struct pp_struct *pp;
643 646
644 cycle_kernel_lock();
645 if (minor >= PARPORT_MAX) 647 if (minor >= PARPORT_MAX)
646 return -ENXIO; 648 return -ENXIO;
647 649