[PATCH] remove horrors with irix tty ioctls handling
[pandora-kernel.git] / arch / mips / kernel / irixioctl.c
index 3cdc223..b39bdba 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/sockios.h>
 #include <linux/syscalls.h>
 #include <linux/tty.h>
@@ -28,38 +27,11 @@ struct irix_termios {
        cc_t c_cc[NCCS];
 };
 
-extern void start_tty(struct tty_struct *tty);
-static struct tty_struct *get_tty(int fd)
-{
-       struct file *filp;
-       struct tty_struct *ttyp = NULL;
-
-       rcu_read_lock();
-       filp = fcheck(fd);
-       if(filp && filp->private_data) {
-               ttyp = (struct tty_struct *) filp->private_data;
-
-               if(ttyp->magic != TTY_MAGIC)
-                       ttyp =NULL;
-       }
-       rcu_read_unlock();
-       return ttyp;
-}
-
-static struct tty_struct *get_real_tty(struct tty_struct *tp)
-{
-       if (tp->driver->type == TTY_DRIVER_TYPE_PTY &&
-          tp->driver->subtype == PTY_TYPE_MASTER)
-               return tp->link;
-       else
-               return tp;
-}
-
 asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
 {
        struct tty_struct *tp, *rtp;
        mm_segment_t old_fs;
-       int error = 0;
+       int i, error = 0;
 
 #ifdef DEBUG_IOCTLS
        printk("[%s:%d] irix_ioctl(%d, ", current->comm, current->pid, fd);
@@ -74,12 +46,13 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
 
        case 0x0000540d: {
                struct termios kt;
-               struct irix_termios *it = (struct irix_termios *) arg;
+               struct irix_termios __user *it =
+                       (struct irix_termios __user *) arg;
 
 #ifdef DEBUG_IOCTLS
                printk("TCGETS, %08lx) ", arg);
 #endif
-               if(!access_ok(VERIFY_WRITE, it, sizeof(*it))) {
+               if (!access_ok(VERIFY_WRITE, it, sizeof(*it))) {
                        error = -EFAULT;
                        break;
                }
@@ -88,13 +61,14 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
                set_fs(old_fs);
                if (error)
                        break;
-               __put_user(kt.c_iflag, &it->c_iflag);
-               __put_user(kt.c_oflag, &it->c_oflag);
-               __put_user(kt.c_cflag, &it->c_cflag);
-               __put_user(kt.c_lflag, &it->c_lflag);
-               for(error = 0; error < NCCS; error++)
-                       __put_user(kt.c_cc[error], &it->c_cc[error]);
-               error = 0;
+
+               error = __put_user(kt.c_iflag, &it->c_iflag);
+               error |= __put_user(kt.c_oflag, &it->c_oflag);
+               error |= __put_user(kt.c_cflag, &it->c_cflag);
+               error |= __put_user(kt.c_lflag, &it->c_lflag);
+
+               for (i = 0; i < NCCS; i++)
+                       error |= __put_user(kt.c_cc[i], &it->c_cc[i]);
                break;
        }
 
@@ -112,14 +86,19 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
                old_fs = get_fs(); set_fs(get_ds());
                error = sys_ioctl(fd, TCGETS, (unsigned long) &kt);
                set_fs(old_fs);
-               if(error)
+               if (error)
+                       break;
+
+               error = __get_user(kt.c_iflag, &it->c_iflag);
+               error |= __get_user(kt.c_oflag, &it->c_oflag);
+               error |= __get_user(kt.c_cflag, &it->c_cflag);
+               error |= __get_user(kt.c_lflag, &it->c_lflag);
+
+               for (i = 0; i < NCCS; i++)
+                       error |= __get_user(kt.c_cc[i], &it->c_cc[i]);
+
+               if (error)
                        break;
-               __get_user(kt.c_iflag, &it->c_iflag);
-               __get_user(kt.c_oflag, &it->c_oflag);
-               __get_user(kt.c_cflag, &it->c_cflag);
-               __get_user(kt.c_lflag, &it->c_lflag);
-               for(error = 0; error < NCCS; error++)
-                       __get_user(kt.c_cc[error], &it->c_cc[error]);
                old_fs = get_fs(); set_fs(get_ds());
                error = sys_ioctl(fd, TCSETS, (unsigned long) &kt);
                set_fs(old_fs);
@@ -140,34 +119,24 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
                error = sys_ioctl(fd, TIOCNOTTY, arg);
                break;
 
-       case 0x00007416:
+       case 0x00007416: {
+               pid_t pid;
 #ifdef DEBUG_IOCTLS
                printk("TIOCGSID, %08lx) ", arg);
 #endif
-               tp = get_tty(fd);
-               if(!tp) {
-                       error = -EINVAL;
-                       break;
-               }
-               rtp = get_real_tty(tp);
-#ifdef DEBUG_IOCTLS
-               printk("rtp->session=%d ", rtp->session);
-#endif
-               error = put_user(rtp->session, (unsigned long *) arg);
+               old_fs = get_fs(); set_fs(get_ds());
+               error = sys_ioctl(fd, TIOCGSID, (unsigned long)&pid);
+               set_fs(old_fs);
+               if (!error)
+                       error = put_user(pid, (unsigned long __user *) arg);
                break;
-
+       }
        case 0x746e:
                /* TIOCSTART, same effect as hitting ^Q */
 #ifdef DEBUG_IOCTLS
                printk("TIOCSTART, %08lx) ", arg);
 #endif
-               tp = get_tty(fd);
-               if(!tp) {
-                       error = -EINVAL;
-                       break;
-               }
-               rtp = get_real_tty(tp);
-               start_tty(rtp);
+               error = sys_ioctl(fd, TCXONC, TCOON);
                break;
 
        case 0x20006968:
@@ -195,50 +164,32 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
                break;
 
        case 0x8004667e:
-#ifdef DEBUG_IOCTLS
-               printk("FIONBIO, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
                error = sys_ioctl(fd, FIONBIO, arg);
                break;
 
        case 0x80047476:
-#ifdef DEBUG_IOCTLS
-               printk("TIOCSPGRP, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
                error = sys_ioctl(fd, TIOCSPGRP, arg);
                break;
 
        case 0x8020690c:
-#ifdef DEBUG_IOCTLS
-               printk("SIOCSIFADDR, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
                error = sys_ioctl(fd, SIOCSIFADDR, arg);
                break;
 
        case 0x80206910:
-#ifdef DEBUG_IOCTLS
-               printk("SIOCSIFFLAGS, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
                error = sys_ioctl(fd, SIOCSIFFLAGS, arg);
                break;
 
        case 0xc0206911:
-#ifdef DEBUG_IOCTLS
-               printk("SIOCGIFFLAGS, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
                error = sys_ioctl(fd, SIOCGIFFLAGS, arg);
                break;
 
        case 0xc020691b:
-#ifdef DEBUG_IOCTLS
-               printk("SIOCGIFMETRIC, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
                error = sys_ioctl(fd, SIOCGIFMETRIC, arg);
                break;
 
        default: {
 #ifdef DEBUG_MISSING_IOCTL
-               char *msg = "Unimplemented IOCTL cmd tell linux@engr.sgi.com\n";
+               char *msg = "Unimplemented IOCTL cmd tell linux-mips@linux-mips.org\n";
 
 #ifdef DEBUG_IOCTLS
                printk("UNIMP_IOCTL, %08lx)\n", arg);
@@ -250,7 +201,7 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
                       current->comm, current->pid, cmd);
                do_exit(255);
 #else
-               error = sys_ioctl (fd, cmd, arg);
+               error = sys_ioctl(fd, cmd, arg);
 #endif
        }