linux/arch/mips/kernel/irixioctl.c
<<
>>
Prefs
   1/*
   2 * irixioctl.c: A fucking mess...
   3 *
   4 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
   5 */
   6
   7#include <linux/kernel.h>
   8#include <linux/sched.h>
   9#include <linux/fs.h>
  10#include <linux/mm.h>
  11#include <linux/smp.h>
  12#include <linux/sockios.h>
  13#include <linux/syscalls.h>
  14#include <linux/tty.h>
  15#include <linux/file.h>
  16#include <linux/rcupdate.h>
  17
  18#include <asm/uaccess.h>
  19#include <asm/ioctl.h>
  20#include <asm/ioctls.h>
  21
  22#undef DEBUG_IOCTLS
  23#undef DEBUG_MISSING_IOCTL
  24
  25struct irix_termios {
  26        tcflag_t c_iflag, c_oflag, c_cflag, c_lflag;
  27        cc_t c_cc[NCCS];
  28};
  29
  30extern void start_tty(struct tty_struct *tty);
  31static struct tty_struct *get_tty(int fd)
  32{
  33        struct file *filp;
  34        struct tty_struct *ttyp = NULL;
  35
  36        rcu_read_lock();
  37        filp = fcheck(fd);
  38        if(filp && filp->private_data) {
  39                ttyp = (struct tty_struct *) filp->private_data;
  40
  41                if(ttyp->magic != TTY_MAGIC)
  42                        ttyp =NULL;
  43        }
  44        rcu_read_unlock();
  45        return ttyp;
  46}
  47
  48static struct tty_struct *get_real_tty(struct tty_struct *tp)
  49{
  50        if (tp->driver->type == TTY_DRIVER_TYPE_PTY &&
  51           tp->driver->subtype == PTY_TYPE_MASTER)
  52                return tp->link;
  53        else
  54                return tp;
  55}
  56
  57asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
  58{
  59        struct tty_struct *tp, *rtp;
  60        mm_segment_t old_fs;
  61        int i, error = 0;
  62
  63#ifdef DEBUG_IOCTLS
  64        printk("[%s:%d] irix_ioctl(%d, ", current->comm, current->pid, fd);
  65#endif
  66        switch(cmd) {
  67        case 0x00005401:
  68#ifdef DEBUG_IOCTLS
  69                printk("TCGETA, %08lx) ", arg);
  70#endif
  71                error = sys_ioctl(fd, TCGETA, arg);
  72                break;
  73
  74        case 0x0000540d: {
  75                struct termios kt;
  76                struct irix_termios __user *it =
  77                        (struct irix_termios __user *) arg;
  78
  79#ifdef DEBUG_IOCTLS
  80                printk("TCGETS, %08lx) ", arg);
  81#endif
  82                if (!access_ok(VERIFY_WRITE, it, sizeof(*it))) {
  83                        error = -EFAULT;
  84                        break;
  85                }
  86                old_fs = get_fs(); set_fs(get_ds());
  87                error = sys_ioctl(fd, TCGETS, (unsigned long) &kt);
  88                set_fs(old_fs);
  89                if (error)
  90                        break;
  91
  92                error = __put_user(kt.c_iflag, &it->c_iflag);
  93                error |= __put_user(kt.c_oflag, &it->c_oflag);
  94                error |= __put_user(kt.c_cflag, &it->c_cflag);
  95                error |= __put_user(kt.c_lflag, &it->c_lflag);
  96
  97                for (i = 0; i < NCCS; i++)
  98                        error |= __put_user(kt.c_cc[i], &it->c_cc[i]);
  99                break;
 100        }
 101
 102        case 0x0000540e: {
 103                struct termios kt;
 104                struct irix_termios *it = (struct irix_termios *) arg;
 105
 106#ifdef DEBUG_IOCTLS
 107                printk("TCSETS, %08lx) ", arg);
 108#endif
 109                if (!access_ok(VERIFY_READ, it, sizeof(*it))) {
 110                        error = -EFAULT;
 111                        break;
 112                }
 113                old_fs = get_fs(); set_fs(get_ds());
 114                error = sys_ioctl(fd, TCGETS, (unsigned long) &kt);
 115                set_fs(old_fs);
 116                if (error)
 117                        break;
 118
 119                error = __get_user(kt.c_iflag, &it->c_iflag);
 120                error |= __get_user(kt.c_oflag, &it->c_oflag);
 121                error |= __get_user(kt.c_cflag, &it->c_cflag);
 122                error |= __get_user(kt.c_lflag, &it->c_lflag);
 123
 124                for (i = 0; i < NCCS; i++)
 125                        error |= __get_user(kt.c_cc[i], &it->c_cc[i]);
 126
 127                if (error)
 128                        break;
 129                old_fs = get_fs(); set_fs(get_ds());
 130                error = sys_ioctl(fd, TCSETS, (unsigned long) &kt);
 131                set_fs(old_fs);
 132                break;
 133        }
 134
 135        case 0x0000540f:
 136#ifdef DEBUG_IOCTLS
 137                printk("TCSETSW, %08lx) ", arg);
 138#endif
 139                error = sys_ioctl(fd, TCSETSW, arg);
 140                break;
 141
 142        case 0x00005471:
 143#ifdef DEBUG_IOCTLS
 144                printk("TIOCNOTTY, %08lx) ", arg);
 145#endif
 146                error = sys_ioctl(fd, TIOCNOTTY, arg);
 147                break;
 148
 149        case 0x00007416:
 150#ifdef DEBUG_IOCTLS
 151                printk("TIOCGSID, %08lx) ", arg);
 152#endif
 153                tp = get_tty(fd);
 154                if(!tp) {
 155                        error = -EINVAL;
 156                        break;
 157                }
 158                rtp = get_real_tty(tp);
 159#ifdef DEBUG_IOCTLS
 160                printk("rtp->session=%d ", rtp->session);
 161#endif
 162                error = put_user(rtp->session, (unsigned long __user *) arg);
 163                break;
 164
 165        case 0x746e:
 166                /* TIOCSTART, same effect as hitting ^Q */
 167#ifdef DEBUG_IOCTLS
 168                printk("TIOCSTART, %08lx) ", arg);
 169#endif
 170                tp = get_tty(fd);
 171                if(!tp) {
 172                        error = -EINVAL;
 173                        break;
 174                }
 175                rtp = get_real_tty(tp);
 176                start_tty(rtp);
 177                break;
 178
 179        case 0x20006968:
 180#ifdef DEBUG_IOCTLS
 181                printk("SIOCGETLABEL, %08lx) ", arg);
 182#endif
 183                error = -ENOPKG;
 184                break;
 185
 186        case 0x40047477:
 187#ifdef DEBUG_IOCTLS
 188                printk("TIOCGPGRP, %08lx) ", arg);
 189#endif
 190                error = sys_ioctl(fd, TIOCGPGRP, arg);
 191#ifdef DEBUG_IOCTLS
 192                printk("arg=%d ", *(int *)arg);
 193#endif
 194                break;
 195
 196        case 0x40087468:
 197#ifdef DEBUG_IOCTLS
 198                printk("TIOCGWINSZ, %08lx) ", arg);
 199#endif
 200                error = sys_ioctl(fd, TIOCGWINSZ, arg);
 201                break;
 202
 203        case 0x8004667e:
 204                error = sys_ioctl(fd, FIONBIO, arg);
 205                break;
 206
 207        case 0x80047476:
 208                error = sys_ioctl(fd, TIOCSPGRP, arg);
 209                break;
 210
 211        case 0x8020690c:
 212                error = sys_ioctl(fd, SIOCSIFADDR, arg);
 213                break;
 214
 215        case 0x80206910:
 216                error = sys_ioctl(fd, SIOCSIFFLAGS, arg);
 217                break;
 218
 219        case 0xc0206911:
 220                error = sys_ioctl(fd, SIOCGIFFLAGS, arg);
 221                break;
 222
 223        case 0xc020691b:
 224                error = sys_ioctl(fd, SIOCGIFMETRIC, arg);
 225                break;
 226
 227        default: {
 228#ifdef DEBUG_MISSING_IOCTL
 229                char *msg = "Unimplemented IOCTL cmd tell linux-mips@linux-mips.org\n";
 230
 231#ifdef DEBUG_IOCTLS
 232                printk("UNIMP_IOCTL, %08lx)\n", arg);
 233#endif
 234                old_fs = get_fs(); set_fs(get_ds());
 235                sys_write(2, msg, strlen(msg));
 236                set_fs(old_fs);
 237                printk("[%s:%d] Does unimplemented IRIX ioctl cmd %08lx\n",
 238                       current->comm, current->pid, cmd);
 239                do_exit(255);
 240#else
 241                error = sys_ioctl(fd, cmd, arg);
 242#endif
 243        }
 244
 245        };
 246#ifdef DEBUG_IOCTLS
 247        printk("error=%d\n", error);
 248#endif
 249        return error;
 250}
 251
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.