[PATCH] ocfs2: fix oops in mmap_truncate testing
[pandora-kernel.git] / arch / mips / kernel / irixioctl.c
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
25 struct irix_termios {
26         tcflag_t c_iflag, c_oflag, c_cflag, c_lflag;
27         cc_t c_cc[NCCS];
28 };
29
30 asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
31 {
32         struct tty_struct *tp, *rtp;
33         mm_segment_t old_fs;
34         int i, error = 0;
35
36 #ifdef DEBUG_IOCTLS
37         printk("[%s:%d] irix_ioctl(%d, ", current->comm, current->pid, fd);
38 #endif
39         switch(cmd) {
40         case 0x00005401:
41 #ifdef DEBUG_IOCTLS
42                 printk("TCGETA, %08lx) ", arg);
43 #endif
44                 error = sys_ioctl(fd, TCGETA, arg);
45                 break;
46
47         case 0x0000540d: {
48                 struct termios kt;
49                 struct irix_termios __user *it =
50                         (struct irix_termios __user *) arg;
51
52 #ifdef DEBUG_IOCTLS
53                 printk("TCGETS, %08lx) ", arg);
54 #endif
55                 if (!access_ok(VERIFY_WRITE, it, sizeof(*it))) {
56                         error = -EFAULT;
57                         break;
58                 }
59                 old_fs = get_fs(); set_fs(get_ds());
60                 error = sys_ioctl(fd, TCGETS, (unsigned long) &kt);
61                 set_fs(old_fs);
62                 if (error)
63                         break;
64
65                 error = __put_user(kt.c_iflag, &it->c_iflag);
66                 error |= __put_user(kt.c_oflag, &it->c_oflag);
67                 error |= __put_user(kt.c_cflag, &it->c_cflag);
68                 error |= __put_user(kt.c_lflag, &it->c_lflag);
69
70                 for (i = 0; i < NCCS; i++)
71                         error |= __put_user(kt.c_cc[i], &it->c_cc[i]);
72                 break;
73         }
74
75         case 0x0000540e: {
76                 struct termios kt;
77                 struct irix_termios *it = (struct irix_termios *) arg;
78
79 #ifdef DEBUG_IOCTLS
80                 printk("TCSETS, %08lx) ", arg);
81 #endif
82                 if (!access_ok(VERIFY_READ, 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 = __get_user(kt.c_iflag, &it->c_iflag);
93                 error |= __get_user(kt.c_oflag, &it->c_oflag);
94                 error |= __get_user(kt.c_cflag, &it->c_cflag);
95                 error |= __get_user(kt.c_lflag, &it->c_lflag);
96
97                 for (i = 0; i < NCCS; i++)
98                         error |= __get_user(kt.c_cc[i], &it->c_cc[i]);
99
100                 if (error)
101                         break;
102                 old_fs = get_fs(); set_fs(get_ds());
103                 error = sys_ioctl(fd, TCSETS, (unsigned long) &kt);
104                 set_fs(old_fs);
105                 break;
106         }
107
108         case 0x0000540f:
109 #ifdef DEBUG_IOCTLS
110                 printk("TCSETSW, %08lx) ", arg);
111 #endif
112                 error = sys_ioctl(fd, TCSETSW, arg);
113                 break;
114
115         case 0x00005471:
116 #ifdef DEBUG_IOCTLS
117                 printk("TIOCNOTTY, %08lx) ", arg);
118 #endif
119                 error = sys_ioctl(fd, TIOCNOTTY, arg);
120                 break;
121
122         case 0x00007416: {
123                 pid_t pid;
124 #ifdef DEBUG_IOCTLS
125                 printk("TIOCGSID, %08lx) ", arg);
126 #endif
127                 old_fs = get_fs(); set_fs(get_ds());
128                 error = sys_ioctl(fd, TIOCGSID, (unsigned long)&pid);
129                 set_fs(old_fs);
130                 if (!error)
131                         error = put_user(pid, (unsigned long __user *) arg);
132                 break;
133         }
134         case 0x746e:
135                 /* TIOCSTART, same effect as hitting ^Q */
136 #ifdef DEBUG_IOCTLS
137                 printk("TIOCSTART, %08lx) ", arg);
138 #endif
139                 error = sys_ioctl(fd, TCXONC, TCOON);
140                 break;
141
142         case 0x20006968:
143 #ifdef DEBUG_IOCTLS
144                 printk("SIOCGETLABEL, %08lx) ", arg);
145 #endif
146                 error = -ENOPKG;
147                 break;
148
149         case 0x40047477:
150 #ifdef DEBUG_IOCTLS
151                 printk("TIOCGPGRP, %08lx) ", arg);
152 #endif
153                 error = sys_ioctl(fd, TIOCGPGRP, arg);
154 #ifdef DEBUG_IOCTLS
155                 printk("arg=%d ", *(int *)arg);
156 #endif
157                 break;
158
159         case 0x40087468:
160 #ifdef DEBUG_IOCTLS
161                 printk("TIOCGWINSZ, %08lx) ", arg);
162 #endif
163                 error = sys_ioctl(fd, TIOCGWINSZ, arg);
164                 break;
165
166         case 0x8004667e:
167                 error = sys_ioctl(fd, FIONBIO, arg);
168                 break;
169
170         case 0x80047476:
171                 error = sys_ioctl(fd, TIOCSPGRP, arg);
172                 break;
173
174         case 0x8020690c:
175                 error = sys_ioctl(fd, SIOCSIFADDR, arg);
176                 break;
177
178         case 0x80206910:
179                 error = sys_ioctl(fd, SIOCSIFFLAGS, arg);
180                 break;
181
182         case 0xc0206911:
183                 error = sys_ioctl(fd, SIOCGIFFLAGS, arg);
184                 break;
185
186         case 0xc020691b:
187                 error = sys_ioctl(fd, SIOCGIFMETRIC, arg);
188                 break;
189
190         default: {
191 #ifdef DEBUG_MISSING_IOCTL
192                 char *msg = "Unimplemented IOCTL cmd tell linux-mips@linux-mips.org\n";
193
194 #ifdef DEBUG_IOCTLS
195                 printk("UNIMP_IOCTL, %08lx)\n", arg);
196 #endif
197                 old_fs = get_fs(); set_fs(get_ds());
198                 sys_write(2, msg, strlen(msg));
199                 set_fs(old_fs);
200                 printk("[%s:%d] Does unimplemented IRIX ioctl cmd %08lx\n",
201                        current->comm, current->pid, cmd);
202                 do_exit(255);
203 #else
204                 error = sys_ioctl(fd, cmd, arg);
205 #endif
206         }
207
208         };
209 #ifdef DEBUG_IOCTLS
210         printk("error=%d\n", error);
211 #endif
212         return error;
213 }