vserver 2.0 rc7
[linux-2.6.git] / drivers / char / lp.c
index 92a54cb..4dee945 100644 (file)
@@ -12,7 +12,7 @@
  * "lp=" command line parameters added by Grant Guenther, grant@torque.net
  * lp_read (Status readback) support added by Carsten Gross,
  *                                             carsten@sol.wohnheim.uni-ulm.de
- * Support for parport by Philip Blundell <Philip.Blundell@pobox.com>
+ * Support for parport by Philip Blundell <philb@gnu.org>
  * Parport sharing hacking by Andrea Arcangeli
  * Fixed kernel_(to/from)_user memory copy to check for errors
  *                             by Riccardo Facchetti <fizban@tin.it>
 #include <linux/poll.h>
 #include <linux/console.h>
 #include <linux/device.h>
+#include <linux/wait.h>
 
 #include <linux/parport.h>
 #undef LP_STATS
@@ -218,6 +219,7 @@ static int lp_reset(int minor)
 
 static void lp_error (int minor)
 {
+       DEFINE_WAIT(wait);
        int polling;
 
        if (LP_F(minor) & LP_ABORT)
@@ -225,8 +227,9 @@ static void lp_error (int minor)
 
        polling = lp_table[minor].dev->port->irq == PARPORT_IRQ_NONE;
        if (polling) lp_release_parport (&lp_table[minor]);
-       interruptible_sleep_on_timeout (&lp_table[minor].waitq,
-                                       LP_TIMEOUT_POLLED);
+       prepare_to_wait(&lp_table[minor].waitq, &wait, TASK_INTERRUPTIBLE);
+       schedule_timeout(LP_TIMEOUT_POLLED);
+       finish_wait(&lp_table[minor].waitq, &wait);
        if (polling) lp_claim_parport_or_block (&lp_table[minor]);
        else parport_yield_blocking (lp_table[minor].dev);
 }
@@ -314,12 +317,14 @@ static ssize_t lp_write(struct file * file, const char __user * buf,
        if (copy_size > LP_BUFFER_SIZE)
                copy_size = LP_BUFFER_SIZE;
 
-       if (copy_from_user (kbuf, buf, copy_size))
-               return -EFAULT;
-
        if (down_interruptible (&lp_table[minor].port_mutex))
                return -EINTR;
 
+       if (copy_from_user (kbuf, buf, copy_size)) {
+               retv = -EFAULT;
+               goto out_unlock;
+       }
+
        /* Claim Parport or sleep until it becomes available
         */
        lp_claim_parport_or_block (&lp_table[minor]);
@@ -398,7 +403,7 @@ static ssize_t lp_write(struct file * file, const char __user * buf,
                lp_table[minor].current_mode = IEEE1284_MODE_COMPAT;
                lp_release_parport (&lp_table[minor]);
        }
-
+out_unlock:
        up (&lp_table[minor].port_mutex);
 
        return retv;
@@ -410,6 +415,7 @@ static ssize_t lp_write(struct file * file, const char __user * buf,
 static ssize_t lp_read(struct file * file, char __user * buf,
                       size_t count, loff_t *ppos)
 {
+       DEFINE_WAIT(wait);
        unsigned int minor=iminor(file->f_dentry->d_inode);
        struct parport *port = lp_table[minor].dev->port;
        ssize_t retval = 0;
@@ -458,9 +464,11 @@ static ssize_t lp_read(struct file * file, char __user * buf,
                                retval = -EIO;
                                goto out;
                        }
-               } else
-                       interruptible_sleep_on_timeout (&lp_table[minor].waitq,
-                                                       LP_TIMEOUT_POLLED);
+               } else {
+                       prepare_to_wait(&lp_table[minor].waitq, &wait, TASK_INTERRUPTIBLE);
+                       schedule_timeout(LP_TIMEOUT_POLLED);
+                       finish_wait(&lp_table[minor].waitq, &wait);
+               }
 
                if (signal_pending (current)) {
                        retval = -ERESTARTSYS;