Merge branch 'upstream'
[linux-2.6] / arch / sparc / kernel / sunos_ioctl.c
1 /* $Id: sunos_ioctl.c,v 1.34 2000/09/03 14:10:56 anton Exp $
2  * sunos_ioctl.c: The Linux Operating system: SunOS ioctl compatibility.
3  * 
4  * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
5  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6  */
7
8 #include <asm/uaccess.h>
9
10 #include <linux/sched.h>
11 #include <linux/errno.h>
12 #include <linux/string.h>
13 #include <linux/termios.h>
14 #include <linux/ioctl.h>
15 #include <linux/route.h>
16 #include <linux/sockios.h>
17 #include <linux/if.h>
18 #include <linux/netdevice.h>
19 #include <linux/if_arp.h>
20 #include <linux/fs.h>
21 #include <linux/mm.h>
22 #include <linux/smp.h>
23 #include <linux/smp_lock.h>
24 #include <linux/syscalls.h>
25 #include <linux/file.h>
26
27 #if 0
28 extern char sunkbd_type;
29 extern char sunkbd_layout;
30 #endif
31
32 /* NR_OPEN is now larger and dynamic in recent kernels. */
33 #define SUNOS_NR_OPEN   256
34
35 asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
36 {
37         int ret = -EBADF;
38
39         if (fd >= SUNOS_NR_OPEN || !fcheck(fd))
40                 goto out;
41
42         /* First handle an easy compat. case for tty ldisc. */
43         if (cmd == TIOCSETD) {
44                 int __user *p;
45                 int ntty = N_TTY, tmp;
46                 mm_segment_t oldfs;
47
48                 p = (int __user *) arg;
49                 ret = -EFAULT;
50                 if (get_user(tmp, p))
51                         goto out;
52                 if (tmp == 2) {
53                         oldfs = get_fs();
54                         set_fs(KERNEL_DS);
55                         ret = sys_ioctl(fd, cmd, (unsigned long) &ntty);
56                         set_fs(oldfs);
57                         ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
58                         goto out;
59                 }
60         }
61
62         /* Binary compatibility is good American knowhow fuckin' up. */
63         if (cmd == TIOCNOTTY) {
64                 ret = sys_setsid();
65                 goto out;
66         }
67
68         /* SunOS networking ioctls. */
69         switch (cmd) {
70         case _IOW('r', 10, struct rtentry):
71                 ret = sys_ioctl(fd, SIOCADDRT, arg);
72                 goto out;
73         case _IOW('r', 11, struct rtentry):
74                 ret = sys_ioctl(fd, SIOCDELRT, arg);
75                 goto out;
76         case _IOW('i', 12, struct ifreq):
77                 ret = sys_ioctl(fd, SIOCSIFADDR, arg);
78                 goto out;
79         case _IOWR('i', 13, struct ifreq):
80                 ret = sys_ioctl(fd, SIOCGIFADDR, arg);
81                 goto out;
82         case _IOW('i', 14, struct ifreq):
83                 ret = sys_ioctl(fd, SIOCSIFDSTADDR, arg);
84                 goto out;
85         case _IOWR('i', 15, struct ifreq):
86                 ret = sys_ioctl(fd, SIOCGIFDSTADDR, arg);
87                 goto out;
88         case _IOW('i', 16, struct ifreq):
89                 ret = sys_ioctl(fd, SIOCSIFFLAGS, arg);
90                 goto out;
91         case _IOWR('i', 17, struct ifreq):
92                 ret = sys_ioctl(fd, SIOCGIFFLAGS, arg);
93                 goto out;
94         case _IOW('i', 18, struct ifreq):
95                 ret = sys_ioctl(fd, SIOCSIFMEM, arg);
96                 goto out;
97         case _IOWR('i', 19, struct ifreq):
98                 ret = sys_ioctl(fd, SIOCGIFMEM, arg);
99                 goto out;
100         case _IOWR('i', 20, struct ifconf):
101                 ret = sys_ioctl(fd, SIOCGIFCONF, arg);
102                 goto out;
103         case _IOW('i', 21, struct ifreq): /* SIOCSIFMTU */
104                 ret = sys_ioctl(fd, SIOCSIFMTU, arg);
105                 goto out;
106         case _IOWR('i', 22, struct ifreq): /* SIOCGIFMTU */
107                 ret = sys_ioctl(fd, SIOCGIFMTU, arg);
108                 goto out;
109
110         case _IOWR('i', 23, struct ifreq):
111                 ret = sys_ioctl(fd, SIOCGIFBRDADDR, arg);
112                 goto out;
113         case _IOW('i', 24, struct ifreq):
114                 ret = sys_ioctl(fd, SIOCSIFBRDADDR, arg);
115                 goto out;
116         case _IOWR('i', 25, struct ifreq):
117                 ret = sys_ioctl(fd, SIOCGIFNETMASK, arg);
118                 goto out;
119         case _IOW('i', 26, struct ifreq):
120                 ret = sys_ioctl(fd, SIOCSIFNETMASK, arg);
121                 goto out;
122         case _IOWR('i', 27, struct ifreq):
123                 ret = sys_ioctl(fd, SIOCGIFMETRIC, arg);
124                 goto out;
125         case _IOW('i', 28, struct ifreq):
126                 ret = sys_ioctl(fd, SIOCSIFMETRIC, arg);
127                 goto out;
128
129         case _IOW('i', 30, struct arpreq):
130                 ret = sys_ioctl(fd, SIOCSARP, arg);
131                 goto out;
132         case _IOWR('i', 31, struct arpreq):
133                 ret = sys_ioctl(fd, SIOCGARP, arg);
134                 goto out;
135         case _IOW('i', 32, struct arpreq):
136                 ret = sys_ioctl(fd, SIOCDARP, arg);
137                 goto out;
138
139         case _IOW('i', 40, struct ifreq): /* SIOCUPPER */
140         case _IOW('i', 41, struct ifreq): /* SIOCLOWER */
141         case _IOW('i', 44, struct ifreq): /* SIOCSETSYNC */
142         case _IOW('i', 45, struct ifreq): /* SIOCGETSYNC */
143         case _IOW('i', 46, struct ifreq): /* SIOCSSDSTATS */
144         case _IOW('i', 47, struct ifreq): /* SIOCSSESTATS */
145         case _IOW('i', 48, struct ifreq): /* SIOCSPROMISC */
146                 ret = -EOPNOTSUPP;
147                 goto out;
148
149         case _IOW('i', 49, struct ifreq):
150                 ret = sys_ioctl(fd, SIOCADDMULTI, arg);
151                 goto out;
152         case _IOW('i', 50, struct ifreq):
153                 ret = sys_ioctl(fd, SIOCDELMULTI, arg);
154                 goto out;
155
156         /* FDDI interface ioctls, unsupported. */
157                 
158         case _IOW('i', 51, struct ifreq): /* SIOCFDRESET */
159         case _IOW('i', 52, struct ifreq): /* SIOCFDSLEEP */
160         case _IOW('i', 53, struct ifreq): /* SIOCSTRTFMWAR */
161         case _IOW('i', 54, struct ifreq): /* SIOCLDNSTRTFW */
162         case _IOW('i', 55, struct ifreq): /* SIOCGETFDSTAT */
163         case _IOW('i', 56, struct ifreq): /* SIOCFDNMIINT */
164         case _IOW('i', 57, struct ifreq): /* SIOCFDEXUSER */
165         case _IOW('i', 58, struct ifreq): /* SIOCFDGNETMAP */
166         case _IOW('i', 59, struct ifreq): /* SIOCFDGIOCTL */
167                 printk("FDDI ioctl, returning EOPNOTSUPP\n");
168                 ret = -EOPNOTSUPP;
169                 goto out;
170
171         case _IOW('t', 125, int):
172                 /* More stupid tty sunos ioctls, just
173                  * say it worked.
174                  */
175                 ret = 0;
176                 goto out;
177         /* Non posix grp */
178         case _IOW('t', 118, int): {
179                 int oldval, newval, __user *ptr;
180
181                 cmd = TIOCSPGRP;
182                 ptr = (int __user *) arg;
183                 ret = -EFAULT;
184                 if (get_user(oldval, ptr))
185                         goto out;
186                 ret = sys_ioctl(fd, cmd, arg);
187                 __get_user(newval, ptr);
188                 if (newval == -1) {
189                         __put_user(oldval, ptr);
190                         ret = -EIO;
191                 }
192                 if (ret == -ENOTTY)
193                         ret = -EIO;
194                 goto out;
195         }
196
197         case _IOR('t', 119, int): {
198                 int oldval, newval, __user *ptr;
199
200                 cmd = TIOCGPGRP;
201                 ptr = (int __user *) arg;
202                 ret = -EFAULT;
203                 if (get_user(oldval, ptr))
204                         goto out;
205                 ret = sys_ioctl(fd, cmd, arg);
206                 __get_user(newval, ptr);
207                 if (newval == -1) {
208                         __put_user(oldval, ptr);
209                         ret = -EIO;
210                 }
211                 if (ret == -ENOTTY)
212                         ret = -EIO;
213                 goto out;
214         }
215         }
216
217 #if 0
218         if ((cmd & 0xff00) == ('k' << 8)) {
219                 printk ("[[KBIO: %8.8x\n", (unsigned int) cmd);
220         }
221 #endif
222
223         ret = sys_ioctl(fd, cmd, arg);
224         /* so stupid... */
225         ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
226 out:
227         return ret;
228 }
229
230