vserver 1.9.3
[linux-2.6.git] / drivers / char / epca.c
index 8b838c1..0f13bef 100644 (file)
@@ -48,8 +48,8 @@
 #define ENABLE_PCI
 #endif /* CONFIG_PCI */
 
-#define putUser(arg1, arg2) put_user(arg1, (unsigned long *)arg2)
-#define getUser(arg1, arg2) get_user(arg1, (unsigned int *)arg2)
+#define putUser(arg1, arg2) put_user(arg1, (unsigned long __user *)arg2)
+#define getUser(arg1, arg2) get_user(arg1, (unsigned __user *)arg2)
 
 #ifdef ENABLE_PCI
 #include <linux/pci.h>
@@ -74,7 +74,6 @@
 #define DIGIINFOMAJOR       35  /* For Digi specific ioctl */ 
 
 
-#define MIN(a,b)       ((a) < (b) ? (a) : (b))
 #define MAXCARDS 7
 #define epcaassert(x, msg)  if (!(x)) epca_error(__LINE__, msg)
 
@@ -218,7 +217,7 @@ static void setup_empty_event(struct tty_struct *tty, struct channel *ch);
 void epca_setup(char *, int *);
 void console_print(const char *);
 
-static int get_termio(struct tty_struct *, struct termio *);
+static int get_termio(struct tty_struct *, struct termio __user *);
 static int pc_write(struct tty_struct *, int, const unsigned char *, int);
 int pc_init(void);
 
@@ -551,9 +550,7 @@ static void pc_close(struct tty_struct * tty, struct file * filp)
                if (tty->driver->flush_buffer)
                        tty->driver->flush_buffer(tty);
 
-               if (tty->ldisc.flush_buffer)
-                       tty->ldisc.flush_buffer(tty);
-
+               tty_ldisc_flush(tty);
                shutdown(ch);
                tty->closing = 0;
                ch->event = 0;
@@ -657,10 +654,7 @@ static void pc_hangup(struct tty_struct *tty)
                cli();
                if (tty->driver->flush_buffer)
                        tty->driver->flush_buffer(tty);
-
-               if (tty->ldisc.flush_buffer)
-                       tty->ldisc.flush_buffer(tty);
-
+               tty_ldisc_flush(tty);
                shutdown(ch);
 
                ch->tty   = NULL;
@@ -826,7 +820,7 @@ static int pc_write(struct tty_struct * tty, int from_user,
                        bytesAvailable will then take on this newly calculated value.
                ---------------------------------------------------------------------- */
 
-               bytesAvailable = MIN(dataLen, bytesAvailable);
+               bytesAvailable = min(dataLen, bytesAvailable);
 
                /* First we read the data in from the file system into a temp buffer */
 
@@ -835,38 +829,29 @@ static int pc_write(struct tty_struct * tty, int from_user,
 
                if (bytesAvailable) 
                { /* Begin bytesAvailable */
+                       /* ---------------------------------------------------------------
+                               The below function reads data from user memory.  This routine
+                               can not be used in an interrupt routine. (Because it may 
+                               generate a page fault)  It can only be called while we can the
+                               user context is accessible. 
+
+                               The prototype is :
+                               inline void copy_from_user(void * to, const void * from,
+                                                         unsigned long count);
+
+                               I also think (Check hackers guide) that optimization must
+                               be turned ON.  (Which sounds strange to me...)
+
+                               Remember copy_from_user WILL generate a page fault if the
+                               user memory being accessed has been swapped out.  This can
+                               cause this routine to temporarily sleep while this page
+                               fault is occurring.
+                       
+                       ----------------------------------------------------------------- */
 
-                       /* Can the user buffer be accessed at the moment ? */
-                       if (verify_area(VERIFY_READ, (char*)buf, bytesAvailable))
-                               bytesAvailable = 0; /* Can't do; try again later */
-                       else  /* Evidently it can, began transmission */
-                       { /* Begin if area verified */
-                               /* ---------------------------------------------------------------
-                                       The below function reads data from user memory.  This routine
-                                       can not be used in an interrupt routine. (Because it may 
-                                       generate a page fault)  It can only be called while we can the
-                                       user context is accessible. 
-
-                                       The prototype is :
-                                       inline void copy_from_user(void * to, const void * from,
-                                                                 unsigned long count);
-
-                                       I also think (Check hackers guide) that optimization must
-                                       be turned ON.  (Which sounds strange to me...)
-       
-                                       Remember copy_from_user WILL generate a page fault if the
-                                       user memory being accessed has been swapped out.  This can
-                                       cause this routine to temporarily sleep while this page
-                                       fault is occurring.
-                               
-                               ----------------------------------------------------------------- */
-
-                               if (copy_from_user(ch->tmp_buf, buf,
-                                                  bytesAvailable))
-                                       return -EFAULT;
-
-                       } /* End if area verified */
-
+                       if (copy_from_user(ch->tmp_buf, buf,
+                                          bytesAvailable))
+                               return -EFAULT;
                } /* End bytesAvailable */
 
                /* ------------------------------------------------------------------ 
@@ -921,7 +906,7 @@ static int pc_write(struct tty_struct * tty, int from_user,
                        space; reduce the amount of data to fit the space.
        ---------------------------------------------------------------------- */
 
-       bytesAvailable = MIN(remain, bytesAvailable);
+       bytesAvailable = min(remain, bytesAvailable);
 
        txwinon(ch);
        while (bytesAvailable > 0) 
@@ -932,7 +917,7 @@ static int pc_write(struct tty_struct * tty, int from_user,
                        data copy fills to the end of card buffer.
                ------------------------------------------------------------------- */
 
-               dataLen = MIN(bytesAvailable, dataLen);
+               dataLen = min(bytesAvailable, dataLen);
                memcpy(ch->txptr + head, buf, dataLen);
                buf += dataLen;
                head += dataLen;
@@ -1129,8 +1114,7 @@ static void pc_flush_buffer(struct tty_struct *tty)
        restore_flags(flags);
 
        wake_up_interruptible(&tty->write_wait);
-       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
-               (tty->ldisc.write_wakeup)(tty);
+       tty_wakeup(tty);
 
 } /* End pc_flush_buffer */
 
@@ -1984,7 +1968,7 @@ static void post_fep_init(unsigned int crd)
                ch->boardnum   = crd;
                ch->channelnum = i;
                ch->magic      = EPCA_MAGIC;
-               ch->tty        = 0;
+               ch->tty        = NULL;
 
                if (shrinkmem) 
                {
@@ -2271,9 +2255,7 @@ static void doevent(int crd)
                                { /* Begin if LOWWAIT */
 
                                        ch->statusflags &= ~LOWWAIT;
-                                       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                                                 tty->ldisc.write_wakeup)
-                                               (tty->ldisc.write_wakeup)(tty);
+                                       tty_wakeup(tty);
                                        wake_up_interruptible(&tty->write_wait);
 
                                } /* End if LOWWAIT */
@@ -2290,9 +2272,7 @@ static void doevent(int crd)
                                { /* Begin if EMPTYWAIT */
 
                                        ch->statusflags &= ~EMPTYWAIT;
-                                       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                                                 tty->ldisc.write_wakeup)
-                                               (tty->ldisc.write_wakeup)(tty);
+                                       tty_wakeup(tty);
 
                                        wake_up_interruptible(&tty->write_wait);
 
@@ -2728,7 +2708,7 @@ static void receive_data(struct channel *ch)
 { /* Begin receive_data */
 
        unchar *rptr;
-       struct termios *ts = 0;
+       struct termios *ts = NULL;
        struct tty_struct *tty;
        volatile struct board_chan *bc;
        register int dataToRead, wrapgap, bytesAvailable;
@@ -2851,8 +2831,6 @@ static void receive_data(struct channel *ch)
 static int info_ioctl(struct tty_struct *tty, struct file * file,
                    unsigned int cmd, unsigned long arg)
 {
-       int error;
-       
        switch (cmd) 
        { /* Begin switch cmd */
 
@@ -2862,13 +2840,7 @@ static int info_ioctl(struct tty_struct *tty, struct file * file,
                        struct digi_info di ;
                        int brd;
 
-                       getUser(brd, (unsigned int *)arg);
-
-                       if ((error = verify_area(VERIFY_WRITE, (char*)arg, sizeof(di))))
-                       {
-                               printk(KERN_ERR "DIGI_GETINFO : verify area size 0x%x failed\n",sizeof(di));
-                               return(error);
-                       }
+                       getUser(brd, (unsigned int __user *)arg);
 
                        if ((brd < 0) || (brd >= num_cards) || (num_cards == 0))
                                return (-ENODEV);
@@ -2882,7 +2854,7 @@ static int info_ioctl(struct tty_struct *tty, struct file * file,
                        di.port = boards[brd].port ;
                        di.membase = boards[brd].membase ;
 
-                       if (copy_to_user((char *)arg, &di, sizeof (di)))
+                       if (copy_to_user((void __user *)arg, &di, sizeof (di)))
                                return -EFAULT;
                        break;
 
@@ -3020,6 +2992,7 @@ static int pc_tiocmset(struct tty_struct *tty, struct file *file,
        epcaparam(tty,ch);
        memoff(ch);
        restore_flags(flags);
+       return 0;
 }
 
 static int pc_ioctl(struct tty_struct *tty, struct file * file,
@@ -3027,12 +3000,13 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
 { /* Begin pc_ioctl */
 
        digiflow_t dflow;
-       int retval, error;
+       int retval;
        unsigned long flags;
        unsigned int mflag, mstat;
        unsigned char startc, stopc;
        volatile struct board_chan *bc;
        struct channel *ch = (struct channel *) tty->driver_data;
+       void __user *argp = (void __user *)arg;
        
        if (ch)
                bc = ch->brdchan;
@@ -3054,13 +3028,13 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
        { /* Begin switch cmd */
 
                case TCGETS:
-                       if (copy_to_user((struct termios *)arg
+                       if (copy_to_user(argp
                                         tty->termios, sizeof(struct termios)))
                                return -EFAULT;
                        return(0);
 
                case TCGETA:
-                       return get_termio(tty, (struct termio *)arg);
+                       return get_termio(tty, argp);
 
                case TCSBRK:    /* SVID version: non-zero arg --> no break */
 
@@ -3090,21 +3064,16 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
                        return 0;
 
                case TIOCGSOFTCAR:
-
-                       error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
-                       if (error)
-                               return error;
-
-                       putUser(C_CLOCAL(tty) ? 1 : 0,
-                                   (unsigned long *) arg);
+                       if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)arg))
+                               return -EFAULT;
                        return 0;
 
                case TIOCSSOFTCAR:
-                       /*RONNIE PUT VERIFY_READ (See above) check here */
                {
                        unsigned int value;
 
-                       getUser(value, (unsigned int *)arg);
+                       if (get_user(value, (unsigned __user *)argp))
+                               return -EFAULT;
                        tty->termios->c_cflag =
                                ((tty->termios->c_cflag & ~CLOCAL) |
                                 (value ? CLOCAL : 0));
@@ -3113,12 +3082,12 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
 
                case TIOCMODG:
                        mflag = pc_tiocmget(tty, file);
-                       if (putUser(mflag, (unsigned int *) arg))
+                       if (put_user(mflag, (unsigned long __user *)argp))
                                return -EFAULT;
                        break;
 
                case TIOCMODS:
-                       if (getUser(mstat, (unsigned int *)arg))
+                       if (get_user(mstat, (unsigned __user *)argp))
                                return -EFAULT;
                        return pc_tiocmset(tty, file, mstat, ~mstat);
 
@@ -3141,8 +3110,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
                        break;
 
                case DIGI_GETA:
-                       if (copy_to_user((char*)arg, &ch->digiext,
-                                        sizeof(digi_t)))
+                       if (copy_to_user(argp, &ch->digiext, sizeof(digi_t)))
                                return -EFAULT;
                        break;
 
@@ -3157,6 +3125,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
                        }
                        else 
                        {
+                               /* ldisc lock already held in ioctl */
                                if (tty->ldisc.flush_buffer)
                                        tty->ldisc.flush_buffer(tty);
                        }
@@ -3164,8 +3133,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
                        /* Fall Thru */
 
                case DIGI_SETA:
-                       if (copy_from_user(&ch->digiext, (char*)arg,
-                                          sizeof(digi_t)))
+                       if (copy_from_user(&ch->digiext, argp, sizeof(digi_t)))
                                return -EFAULT;
                        
                        if (ch->digiext.digi_flags & DIGI_ALTPIN) 
@@ -3209,7 +3177,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
                        memoff(ch);
                        restore_flags(flags);
 
-                       if (copy_to_user((char*)arg, &dflow, sizeof(dflow)))
+                       if (copy_to_user(argp, &dflow, sizeof(dflow)))
                                return -EFAULT;
                        break;
 
@@ -3226,7 +3194,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
                                stopc = ch->stopca;
                        }
 
-                       if (copy_from_user(&dflow, (char*)arg, sizeof(dflow)))
+                       if (copy_from_user(&dflow, argp, sizeof(dflow)))
                                return -EFAULT;
 
                        if (dflow.startc != startc || dflow.stopc != stopc) 
@@ -3329,7 +3297,6 @@ static void do_softint(void *private_)
                }
 
        } /* End EPCA_MAGIC */
-       MOD_DEC_USE_COUNT;
 } /* End do_softint */
 
 /* ------------------------------------------------------------
@@ -3555,17 +3522,9 @@ static void setup_empty_event(struct tty_struct *tty, struct channel *ch)
 
 /* --------------------- Begin get_termio ----------------------- */
 
-static int get_termio(struct tty_struct * tty, struct termio * termio)
+static int get_termio(struct tty_struct * tty, struct termio __user * termio)
 { /* Begin get_termio */
-       int error;
-
-       error = verify_area(VERIFY_WRITE, termio, sizeof (struct termio));
-       if (error)
-               return error;
-
-       kernel_termios_to_user_termio(termio, tty->termios);
-
-       return 0;
+       return kernel_termios_to_user_termio(termio, tty->termios);
 } /* End get_termio */
 /* ---------------------- Begin epca_setup  -------------------------- */
 void epca_setup(char *str, int *ints)