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