ultrix_ioctl.c revision 1.22 1 1.22 simonb /* $NetBSD: ultrix_ioctl.c,v 1.22 2003/06/29 09:42:10 simonb Exp $ */
2 1.1 jonathan /* from : NetBSD: sunos_ioctl.c,v 1.21 1995/10/07 06:27:31 mycroft Exp */
3 1.1 jonathan
4 1.1 jonathan /*
5 1.1 jonathan * Copyright (c) 1993 Markus Wild.
6 1.1 jonathan * All rights reserved.
7 1.1 jonathan *
8 1.1 jonathan * Redistribution and use in source and binary forms, with or without
9 1.1 jonathan * modification, are permitted provided that the following conditions
10 1.1 jonathan * are met:
11 1.1 jonathan * 1. Redistributions of source code must retain the above copyright
12 1.1 jonathan * notice, this list of conditions and the following disclaimer.
13 1.1 jonathan * 2. The name of the author may not be used to endorse or promote products
14 1.1 jonathan * derived from this software without specific prior written permission
15 1.1 jonathan *
16 1.1 jonathan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 1.1 jonathan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 1.1 jonathan * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 1.1 jonathan * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 1.1 jonathan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 1.1 jonathan * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 1.1 jonathan * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 1.1 jonathan * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 1.1 jonathan * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 1.1 jonathan * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 1.1 jonathan *
27 1.1 jonathan * loosely from: Header: sunos_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp
28 1.1 jonathan */
29 1.18 lukem
30 1.18 lukem #include <sys/cdefs.h>
31 1.22 simonb __KERNEL_RCSID(0, "$NetBSD: ultrix_ioctl.c,v 1.22 2003/06/29 09:42:10 simonb Exp $");
32 1.11 thorpej
33 1.16 mrg #if defined(_KERNEL_OPT)
34 1.11 thorpej #include "opt_compat_ultrix.h"
35 1.12 thorpej #include "opt_compat_sunos.h"
36 1.15 jdolecek #endif
37 1.1 jonathan
38 1.1 jonathan #include <sys/param.h>
39 1.1 jonathan #include <sys/proc.h>
40 1.1 jonathan #include <sys/systm.h>
41 1.1 jonathan #include <sys/file.h>
42 1.1 jonathan #include <sys/filedesc.h>
43 1.1 jonathan #include <sys/ioctl.h>
44 1.1 jonathan #include <sys/termios.h>
45 1.1 jonathan #include <sys/tty.h>
46 1.1 jonathan #include <sys/socket.h>
47 1.1 jonathan #include <sys/audioio.h>
48 1.1 jonathan #include <net/if.h>
49 1.1 jonathan
50 1.1 jonathan #include <sys/mount.h>
51 1.1 jonathan
52 1.1 jonathan #include <compat/ultrix/ultrix_syscallargs.h>
53 1.19 thorpej #include <sys/sa.h>
54 1.1 jonathan #include <sys/syscallargs.h>
55 1.1 jonathan
56 1.1 jonathan #include <compat/sunos/sunos.h>
57 1.1 jonathan
58 1.15 jdolecek #include <compat/ultrix/ultrix_tty.h>
59 1.1 jonathan
60 1.2 jonathan #define emul_termio ultrix_termio
61 1.2 jonathan #define emul_termios ultrix_termios
62 1.1 jonathan
63 1.1 jonathan /*
64 1.1 jonathan * SunOS ioctl calls.
65 1.1 jonathan * This file is something of a hodge-podge.
66 1.1 jonathan * Support gets added as things turn up....
67 1.1 jonathan */
68 1.1 jonathan
69 1.1 jonathan static struct speedtab sptab[] = {
70 1.1 jonathan { 0, 0 },
71 1.1 jonathan { 50, 1 },
72 1.1 jonathan { 75, 2 },
73 1.1 jonathan { 110, 3 },
74 1.1 jonathan { 134, 4 },
75 1.1 jonathan { 135, 4 },
76 1.1 jonathan { 150, 5 },
77 1.1 jonathan { 200, 6 },
78 1.1 jonathan { 300, 7 },
79 1.1 jonathan { 600, 8 },
80 1.1 jonathan { 1200, 9 },
81 1.1 jonathan { 1800, 10 },
82 1.1 jonathan { 2400, 11 },
83 1.1 jonathan { 4800, 12 },
84 1.1 jonathan { 9600, 13 },
85 1.1 jonathan { 19200, 14 },
86 1.1 jonathan { 38400, 15 },
87 1.1 jonathan { -1, -1 }
88 1.1 jonathan };
89 1.1 jonathan
90 1.1 jonathan static u_long s2btab[] = {
91 1.1 jonathan 0,
92 1.1 jonathan 50,
93 1.1 jonathan 75,
94 1.1 jonathan 110,
95 1.1 jonathan 134,
96 1.1 jonathan 150,
97 1.1 jonathan 200,
98 1.1 jonathan 300,
99 1.1 jonathan 600,
100 1.1 jonathan 1200,
101 1.1 jonathan 1800,
102 1.1 jonathan 2400,
103 1.1 jonathan 4800,
104 1.1 jonathan 9600,
105 1.1 jonathan 19200,
106 1.1 jonathan 38400,
107 1.1 jonathan };
108 1.1 jonathan
109 1.2 jonathan
110 1.2 jonathan /*
111 1.2 jonathan * Translate a single tty control char from the emulation value
112 1.2 jonathan * to native termios, and vice-versa. Special-case
113 1.2 jonathan * the value of POSIX_VDISABLE, mapping it to and from 0.
114 1.2 jonathan */
115 1.2 jonathan #define NATIVE_TO_EMUL_CC(bsd_cc) \
116 1.2 jonathan (((bsd_cc) != _POSIX_VDISABLE) ? (bsd_cc) : 0)
117 1.2 jonathan
118 1.2 jonathan #define EMUL_TO_NATIVE_CC(emul_cc) \
119 1.2 jonathan (emul_cc) ? (emul_cc) : _POSIX_VDISABLE;
120 1.2 jonathan
121 1.2 jonathan
122 1.10 jonathan static void stios2btios __P((struct emul_termios *, struct termios *));
123 1.10 jonathan static void btios2stios __P((struct termios *, struct emul_termios *));
124 1.10 jonathan static void stios2stio __P((struct emul_termios *, struct emul_termio *));
125 1.10 jonathan static void stio2stios __P((struct emul_termio *, struct emul_termios *));
126 1.2 jonathan
127 1.1 jonathan /*
128 1.1 jonathan * these two conversion functions have mostly been done
129 1.1 jonathan * with some perl cut&paste, then handedited to comment
130 1.1 jonathan * out what doesn't exist under NetBSD.
131 1.1 jonathan * A note from Markus's code:
132 1.1 jonathan * (l & BITMASK1) / BITMASK1 * BITMASK2 is translated
133 1.1 jonathan * optimally by gcc m68k, much better than any ?: stuff.
134 1.1 jonathan * Code may vary with different architectures of course.
135 1.1 jonathan *
136 1.1 jonathan * I don't know what optimizer you used, but seeing divu's and
137 1.1 jonathan * bfextu's in the m68k assembly output did not encourage me...
138 1.1 jonathan * as well, gcc on the sparc definately generates much better
139 1.1 jonathan * code with ?:.
140 1.1 jonathan */
141 1.1 jonathan
142 1.2 jonathan
143 1.1 jonathan static void
144 1.1 jonathan stios2btios(st, bt)
145 1.2 jonathan struct emul_termios *st;
146 1.1 jonathan struct termios *bt;
147 1.1 jonathan {
148 1.14 augustss u_long l, r;
149 1.1 jonathan
150 1.1 jonathan l = st->c_iflag;
151 1.1 jonathan r = ((l & 0x00000001) ? IGNBRK : 0);
152 1.1 jonathan r |= ((l & 0x00000002) ? BRKINT : 0);
153 1.1 jonathan r |= ((l & 0x00000004) ? IGNPAR : 0);
154 1.1 jonathan r |= ((l & 0x00000008) ? PARMRK : 0);
155 1.1 jonathan r |= ((l & 0x00000010) ? INPCK : 0);
156 1.1 jonathan r |= ((l & 0x00000020) ? ISTRIP : 0);
157 1.1 jonathan r |= ((l & 0x00000040) ? INLCR : 0);
158 1.1 jonathan r |= ((l & 0x00000080) ? IGNCR : 0);
159 1.1 jonathan r |= ((l & 0x00000100) ? ICRNL : 0);
160 1.1 jonathan /* ((l & 0x00000200) ? IUCLC : 0) */
161 1.1 jonathan r |= ((l & 0x00000400) ? IXON : 0);
162 1.1 jonathan r |= ((l & 0x00000800) ? IXANY : 0);
163 1.1 jonathan r |= ((l & 0x00001000) ? IXOFF : 0);
164 1.1 jonathan r |= ((l & 0x00002000) ? IMAXBEL : 0);
165 1.1 jonathan bt->c_iflag = r;
166 1.1 jonathan
167 1.1 jonathan l = st->c_oflag;
168 1.1 jonathan r = ((l & 0x00000001) ? OPOST : 0);
169 1.1 jonathan /* ((l & 0x00000002) ? OLCUC : 0) */
170 1.1 jonathan r |= ((l & 0x00000004) ? ONLCR : 0);
171 1.1 jonathan /* ((l & 0x00000008) ? OCRNL : 0) */
172 1.1 jonathan /* ((l & 0x00000010) ? ONOCR : 0) */
173 1.1 jonathan /* ((l & 0x00000020) ? ONLRET : 0) */
174 1.1 jonathan /* ((l & 0x00000040) ? OFILL : 0) */
175 1.1 jonathan /* ((l & 0x00000080) ? OFDEL : 0) */
176 1.1 jonathan /* ((l & 0x00000100) ? NLDLY : 0) */
177 1.1 jonathan /* ((l & 0x00000100) ? NL1 : 0) */
178 1.1 jonathan /* ((l & 0x00000600) ? CRDLY : 0) */
179 1.1 jonathan /* ((l & 0x00000200) ? CR1 : 0) */
180 1.1 jonathan /* ((l & 0x00000400) ? CR2 : 0) */
181 1.1 jonathan /* ((l & 0x00000600) ? CR3 : 0) */
182 1.1 jonathan /* ((l & 0x00001800) ? TABDLY : 0) */
183 1.1 jonathan /* ((l & 0x00000800) ? TAB1 : 0) */
184 1.1 jonathan /* ((l & 0x00001000) ? TAB2 : 0) */
185 1.1 jonathan r |= ((l & 0x00001800) ? OXTABS : 0);
186 1.1 jonathan /* ((l & 0x00002000) ? BSDLY : 0) */
187 1.1 jonathan /* ((l & 0x00002000) ? BS1 : 0) */
188 1.1 jonathan /* ((l & 0x00004000) ? VTDLY : 0) */
189 1.1 jonathan /* ((l & 0x00004000) ? VT1 : 0) */
190 1.1 jonathan /* ((l & 0x00008000) ? FFDLY : 0) */
191 1.1 jonathan /* ((l & 0x00008000) ? FF1 : 0) */
192 1.1 jonathan /* ((l & 0x00010000) ? PAGEOUT : 0) */
193 1.1 jonathan /* ((l & 0x00020000) ? WRAP : 0) */
194 1.1 jonathan bt->c_oflag = r;
195 1.1 jonathan
196 1.1 jonathan l = st->c_cflag;
197 1.1 jonathan switch (l & 0x00000030) {
198 1.1 jonathan case 0:
199 1.1 jonathan r = CS5;
200 1.1 jonathan break;
201 1.1 jonathan case 0x00000010:
202 1.1 jonathan r = CS6;
203 1.1 jonathan break;
204 1.1 jonathan case 0x00000020:
205 1.1 jonathan r = CS7;
206 1.1 jonathan break;
207 1.1 jonathan case 0x00000030:
208 1.1 jonathan r = CS8;
209 1.1 jonathan break;
210 1.1 jonathan }
211 1.1 jonathan r |= ((l & 0x00000040) ? CSTOPB : 0);
212 1.1 jonathan r |= ((l & 0x00000080) ? CREAD : 0);
213 1.1 jonathan r |= ((l & 0x00000100) ? PARENB : 0);
214 1.1 jonathan r |= ((l & 0x00000200) ? PARODD : 0);
215 1.1 jonathan r |= ((l & 0x00000400) ? HUPCL : 0);
216 1.1 jonathan r |= ((l & 0x00000800) ? CLOCAL : 0);
217 1.1 jonathan /* ((l & 0x00001000) ? LOBLK : 0) */
218 1.1 jonathan r |= ((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0);
219 1.1 jonathan bt->c_cflag = r;
220 1.1 jonathan
221 1.1 jonathan bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
222 1.1 jonathan
223 1.1 jonathan l = st->c_lflag;
224 1.1 jonathan r = ((l & 0x00000001) ? ISIG : 0);
225 1.1 jonathan r |= ((l & 0x00000002) ? ICANON : 0);
226 1.1 jonathan /* ((l & 0x00000004) ? XCASE : 0) */
227 1.1 jonathan r |= ((l & 0x00000008) ? ECHO : 0);
228 1.1 jonathan r |= ((l & 0x00000010) ? ECHOE : 0);
229 1.1 jonathan r |= ((l & 0x00000020) ? ECHOK : 0);
230 1.1 jonathan r |= ((l & 0x00000040) ? ECHONL : 0);
231 1.1 jonathan r |= ((l & 0x00000080) ? NOFLSH : 0);
232 1.1 jonathan r |= ((l & 0x00000100) ? TOSTOP : 0);
233 1.1 jonathan r |= ((l & 0x00000200) ? ECHOCTL : 0);
234 1.1 jonathan r |= ((l & 0x00000400) ? ECHOPRT : 0);
235 1.1 jonathan r |= ((l & 0x00000800) ? ECHOKE : 0);
236 1.1 jonathan /* ((l & 0x00001000) ? DEFECHO : 0) */
237 1.1 jonathan r |= ((l & 0x00002000) ? FLUSHO : 0);
238 1.1 jonathan r |= ((l & 0x00004000) ? PENDIN : 0);
239 1.1 jonathan bt->c_lflag = r;
240 1.1 jonathan
241 1.2 jonathan bt->c_cc[VINTR] = EMUL_TO_NATIVE_CC(st->c_cc[0]);
242 1.2 jonathan bt->c_cc[VQUIT] = EMUL_TO_NATIVE_CC(st->c_cc[1]);
243 1.2 jonathan bt->c_cc[VERASE] = EMUL_TO_NATIVE_CC(st->c_cc[2]);
244 1.2 jonathan bt->c_cc[VKILL] = EMUL_TO_NATIVE_CC(st->c_cc[3]);
245 1.2 jonathan bt->c_cc[VEOF] = EMUL_TO_NATIVE_CC(st->c_cc[4]);
246 1.2 jonathan bt->c_cc[VEOL] = EMUL_TO_NATIVE_CC(st->c_cc[5]);
247 1.2 jonathan bt->c_cc[VEOL2] = EMUL_TO_NATIVE_CC(st->c_cc[6]);
248 1.2 jonathan /* not present on NetBSD */
249 1.2 jonathan /* bt->c_cc[VSWTCH] = EMUL_TO_NATIVE_CC(st->c_cc[7]); */
250 1.2 jonathan bt->c_cc[VSTART] = EMUL_TO_NATIVE_CC(st->c_cc[10]);
251 1.2 jonathan bt->c_cc[VSTOP] = EMUL_TO_NATIVE_CC(st->c_cc[11]);
252 1.4 jonathan bt->c_cc[VSUSP] = EMUL_TO_NATIVE_CC(st->c_cc[12]);
253 1.4 jonathan bt->c_cc[VDSUSP] = EMUL_TO_NATIVE_CC(st->c_cc[13]);
254 1.2 jonathan bt->c_cc[VREPRINT] = EMUL_TO_NATIVE_CC(st->c_cc[14]);
255 1.2 jonathan bt->c_cc[VDISCARD] = EMUL_TO_NATIVE_CC(st->c_cc[15]);
256 1.2 jonathan bt->c_cc[VWERASE] = EMUL_TO_NATIVE_CC(st->c_cc[16]);
257 1.2 jonathan bt->c_cc[VLNEXT] = EMUL_TO_NATIVE_CC(st->c_cc[17]);
258 1.2 jonathan bt->c_cc[VSTATUS] = EMUL_TO_NATIVE_CC(st->c_cc[18]);
259 1.2 jonathan
260 1.2 jonathan #ifdef COMPAT_ULTRIX
261 1.2 jonathan /* Ultrix termio/termios has real vmin/vtime */
262 1.2 jonathan bt->c_cc[VMIN] = EMUL_TO_NATIVE_CC(st->c_cc[8]);
263 1.2 jonathan bt->c_cc[VTIME] = EMUL_TO_NATIVE_CC(st->c_cc[9]);
264 1.2 jonathan #else
265 1.1 jonathan /* if `raw mode', create native VMIN/VTIME from SunOS VEOF/VEOL */
266 1.1 jonathan bt->c_cc[VMIN] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOF];
267 1.1 jonathan bt->c_cc[VTIME] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOL];
268 1.2 jonathan #endif
269 1.2 jonathan
270 1.1 jonathan }
271 1.1 jonathan
272 1.2 jonathan /*
273 1.2 jonathan * Convert bsd termios to "sunos" emulated termios
274 1.2 jonathan */
275 1.1 jonathan static void
276 1.1 jonathan btios2stios(bt, st)
277 1.1 jonathan struct termios *bt;
278 1.2 jonathan struct emul_termios *st;
279 1.1 jonathan {
280 1.14 augustss u_long l, r;
281 1.1 jonathan
282 1.1 jonathan l = bt->c_iflag;
283 1.1 jonathan r = ((l & IGNBRK) ? 0x00000001 : 0);
284 1.1 jonathan r |= ((l & BRKINT) ? 0x00000002 : 0);
285 1.1 jonathan r |= ((l & IGNPAR) ? 0x00000004 : 0);
286 1.1 jonathan r |= ((l & PARMRK) ? 0x00000008 : 0);
287 1.1 jonathan r |= ((l & INPCK) ? 0x00000010 : 0);
288 1.1 jonathan r |= ((l & ISTRIP) ? 0x00000020 : 0);
289 1.1 jonathan r |= ((l & INLCR) ? 0x00000040 : 0);
290 1.1 jonathan r |= ((l & IGNCR) ? 0x00000080 : 0);
291 1.1 jonathan r |= ((l & ICRNL) ? 0x00000100 : 0);
292 1.1 jonathan /* ((l & IUCLC) ? 0x00000200 : 0) */
293 1.1 jonathan r |= ((l & IXON) ? 0x00000400 : 0);
294 1.1 jonathan r |= ((l & IXANY) ? 0x00000800 : 0);
295 1.1 jonathan r |= ((l & IXOFF) ? 0x00001000 : 0);
296 1.1 jonathan r |= ((l & IMAXBEL) ? 0x00002000 : 0);
297 1.1 jonathan st->c_iflag = r;
298 1.1 jonathan
299 1.1 jonathan l = bt->c_oflag;
300 1.1 jonathan r = ((l & OPOST) ? 0x00000001 : 0);
301 1.1 jonathan /* ((l & OLCUC) ? 0x00000002 : 0) */
302 1.1 jonathan r |= ((l & ONLCR) ? 0x00000004 : 0);
303 1.1 jonathan /* ((l & OCRNL) ? 0x00000008 : 0) */
304 1.1 jonathan /* ((l & ONOCR) ? 0x00000010 : 0) */
305 1.1 jonathan /* ((l & ONLRET) ? 0x00000020 : 0) */
306 1.1 jonathan /* ((l & OFILL) ? 0x00000040 : 0) */
307 1.1 jonathan /* ((l & OFDEL) ? 0x00000080 : 0) */
308 1.1 jonathan /* ((l & NLDLY) ? 0x00000100 : 0) */
309 1.1 jonathan /* ((l & NL1) ? 0x00000100 : 0) */
310 1.1 jonathan /* ((l & CRDLY) ? 0x00000600 : 0) */
311 1.1 jonathan /* ((l & CR1) ? 0x00000200 : 0) */
312 1.1 jonathan /* ((l & CR2) ? 0x00000400 : 0) */
313 1.1 jonathan /* ((l & CR3) ? 0x00000600 : 0) */
314 1.1 jonathan /* ((l & TABDLY) ? 0x00001800 : 0) */
315 1.1 jonathan /* ((l & TAB1) ? 0x00000800 : 0) */
316 1.1 jonathan /* ((l & TAB2) ? 0x00001000 : 0) */
317 1.1 jonathan r |= ((l & OXTABS) ? 0x00001800 : 0);
318 1.1 jonathan /* ((l & BSDLY) ? 0x00002000 : 0) */
319 1.1 jonathan /* ((l & BS1) ? 0x00002000 : 0) */
320 1.1 jonathan /* ((l & VTDLY) ? 0x00004000 : 0) */
321 1.1 jonathan /* ((l & VT1) ? 0x00004000 : 0) */
322 1.1 jonathan /* ((l & FFDLY) ? 0x00008000 : 0) */
323 1.1 jonathan /* ((l & FF1) ? 0x00008000 : 0) */
324 1.1 jonathan /* ((l & PAGEOUT) ? 0x00010000 : 0) */
325 1.1 jonathan /* ((l & WRAP) ? 0x00020000 : 0) */
326 1.1 jonathan st->c_oflag = r;
327 1.1 jonathan
328 1.1 jonathan l = bt->c_cflag;
329 1.1 jonathan switch (l & CSIZE) {
330 1.1 jonathan case CS5:
331 1.1 jonathan r = 0;
332 1.1 jonathan break;
333 1.1 jonathan case CS6:
334 1.1 jonathan r = 0x00000010;
335 1.1 jonathan break;
336 1.1 jonathan case CS7:
337 1.1 jonathan r = 0x00000020;
338 1.1 jonathan break;
339 1.1 jonathan case CS8:
340 1.1 jonathan r = 0x00000030;
341 1.1 jonathan break;
342 1.1 jonathan }
343 1.1 jonathan r |= ((l & CSTOPB) ? 0x00000040 : 0);
344 1.1 jonathan r |= ((l & CREAD) ? 0x00000080 : 0);
345 1.1 jonathan r |= ((l & PARENB) ? 0x00000100 : 0);
346 1.1 jonathan r |= ((l & PARODD) ? 0x00000200 : 0);
347 1.1 jonathan r |= ((l & HUPCL) ? 0x00000400 : 0);
348 1.1 jonathan r |= ((l & CLOCAL) ? 0x00000800 : 0);
349 1.1 jonathan /* ((l & LOBLK) ? 0x00001000 : 0) */
350 1.1 jonathan r |= ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0);
351 1.1 jonathan st->c_cflag = r;
352 1.1 jonathan
353 1.1 jonathan l = bt->c_lflag;
354 1.1 jonathan r = ((l & ISIG) ? 0x00000001 : 0);
355 1.1 jonathan r |= ((l & ICANON) ? 0x00000002 : 0);
356 1.1 jonathan /* ((l & XCASE) ? 0x00000004 : 0) */
357 1.1 jonathan r |= ((l & ECHO) ? 0x00000008 : 0);
358 1.1 jonathan r |= ((l & ECHOE) ? 0x00000010 : 0);
359 1.1 jonathan r |= ((l & ECHOK) ? 0x00000020 : 0);
360 1.1 jonathan r |= ((l & ECHONL) ? 0x00000040 : 0);
361 1.1 jonathan r |= ((l & NOFLSH) ? 0x00000080 : 0);
362 1.1 jonathan r |= ((l & TOSTOP) ? 0x00000100 : 0);
363 1.1 jonathan r |= ((l & ECHOCTL) ? 0x00000200 : 0);
364 1.1 jonathan r |= ((l & ECHOPRT) ? 0x00000400 : 0);
365 1.1 jonathan r |= ((l & ECHOKE) ? 0x00000800 : 0);
366 1.1 jonathan /* ((l & DEFECHO) ? 0x00001000 : 0) */
367 1.1 jonathan r |= ((l & FLUSHO) ? 0x00002000 : 0);
368 1.1 jonathan r |= ((l & PENDIN) ? 0x00004000 : 0);
369 1.1 jonathan st->c_lflag = r;
370 1.1 jonathan
371 1.1 jonathan l = ttspeedtab(bt->c_ospeed, sptab);
372 1.1 jonathan if (l >= 0)
373 1.1 jonathan st->c_cflag |= l;
374 1.1 jonathan
375 1.2 jonathan st->c_cc[0] = NATIVE_TO_EMUL_CC(bt->c_cc[VINTR]);
376 1.2 jonathan st->c_cc[1] = NATIVE_TO_EMUL_CC(bt->c_cc[VQUIT]);
377 1.2 jonathan st->c_cc[2] = NATIVE_TO_EMUL_CC(bt->c_cc[VERASE]);
378 1.2 jonathan st->c_cc[3] = NATIVE_TO_EMUL_CC(bt->c_cc[VKILL]);
379 1.2 jonathan st->c_cc[4] = NATIVE_TO_EMUL_CC(bt->c_cc[VEOF]);
380 1.2 jonathan st->c_cc[5] = NATIVE_TO_EMUL_CC(bt->c_cc[VEOL]);
381 1.2 jonathan st->c_cc[6] = NATIVE_TO_EMUL_CC(bt->c_cc[VEOL2]);
382 1.9 jonathan
383 1.9 jonathan /* XXX ultrix has a VSWTCH. NetBSD does not. */
384 1.9 jonathan #ifdef notdef
385 1.2 jonathan st->c_cc[7] = NATIVE_TO_EMUL_CC(bt->c_cc[VSWTCH]);
386 1.2 jonathan #else
387 1.1 jonathan st->c_cc[7] = 0;
388 1.2 jonathan #endif
389 1.2 jonathan st->c_cc[10] = NATIVE_TO_EMUL_CC(bt->c_cc[VSTART]);
390 1.2 jonathan st->c_cc[11] = NATIVE_TO_EMUL_CC(bt->c_cc[VSTOP]);
391 1.2 jonathan st->c_cc[12]= NATIVE_TO_EMUL_CC(bt->c_cc[VSUSP]);
392 1.2 jonathan st->c_cc[13]= NATIVE_TO_EMUL_CC(bt->c_cc[VDSUSP]);
393 1.2 jonathan st->c_cc[14]= NATIVE_TO_EMUL_CC(bt->c_cc[VREPRINT]);
394 1.2 jonathan st->c_cc[15]= NATIVE_TO_EMUL_CC(bt->c_cc[VDISCARD]);
395 1.2 jonathan st->c_cc[16]= NATIVE_TO_EMUL_CC(bt->c_cc[VWERASE]);
396 1.2 jonathan st->c_cc[17]= NATIVE_TO_EMUL_CC(bt->c_cc[VLNEXT]);
397 1.2 jonathan st->c_cc[18]= NATIVE_TO_EMUL_CC(bt->c_cc[VSTATUS]);
398 1.2 jonathan
399 1.2 jonathan #ifdef COMPAT_ULTRIX
400 1.2 jonathan st->c_cc[8]= NATIVE_TO_EMUL_CC(bt->c_cc[VMIN]);
401 1.2 jonathan st->c_cc[9]= NATIVE_TO_EMUL_CC(bt->c_cc[VTIME]);
402 1.2 jonathan #else
403 1.1 jonathan if (!(bt->c_lflag & ICANON)) {
404 1.1 jonathan /* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */
405 1.1 jonathan st->c_cc[4] = bt->c_cc[VMIN];
406 1.1 jonathan st->c_cc[5] = bt->c_cc[VTIME];
407 1.1 jonathan }
408 1.2 jonathan #endif
409 1.1 jonathan
410 1.2 jonathan #ifdef COMPAT_SUNOS
411 1.2 jonathan st->c_line = 0; /* 4.3bsd "old" line discipline */
412 1.2 jonathan #else
413 1.9 jonathan st->c_line = 2; /* 4.3bsd "new" line discipline, Ultrix default. */
414 1.2 jonathan #endif
415 1.1 jonathan }
416 1.1 jonathan
417 1.2 jonathan #define TERMIO_NCC 10 /* ultrix termio NCC is 10 */
418 1.2 jonathan
419 1.2 jonathan /*
420 1.2 jonathan * Convert emulated struct termios to termio(?)
421 1.2 jonathan */
422 1.1 jonathan static void
423 1.1 jonathan stios2stio(ts, t)
424 1.2 jonathan struct emul_termios *ts;
425 1.2 jonathan struct emul_termio *t;
426 1.1 jonathan {
427 1.1 jonathan t->c_iflag = ts->c_iflag;
428 1.1 jonathan t->c_oflag = ts->c_oflag;
429 1.1 jonathan t->c_cflag = ts->c_cflag;
430 1.1 jonathan t->c_lflag = ts->c_lflag;
431 1.1 jonathan t->c_line = ts->c_line;
432 1.13 perry memcpy(t->c_cc, ts->c_cc, TERMIO_NCC);
433 1.1 jonathan }
434 1.1 jonathan
435 1.2 jonathan /*
436 1.2 jonathan * Convert the other way
437 1.2 jonathan */
438 1.1 jonathan static void
439 1.1 jonathan stio2stios(t, ts)
440 1.2 jonathan struct emul_termio *t;
441 1.2 jonathan struct emul_termios *ts;
442 1.1 jonathan {
443 1.1 jonathan ts->c_iflag = t->c_iflag;
444 1.1 jonathan ts->c_oflag = t->c_oflag;
445 1.1 jonathan ts->c_cflag = t->c_cflag;
446 1.1 jonathan ts->c_lflag = t->c_lflag;
447 1.1 jonathan ts->c_line = t->c_line;
448 1.13 perry memcpy(ts->c_cc, t->c_cc, TERMIO_NCC); /* don't touch the upper fields! */
449 1.1 jonathan }
450 1.1 jonathan
451 1.1 jonathan int
452 1.19 thorpej ultrix_sys_ioctl(l, v, retval)
453 1.19 thorpej struct lwp *l;
454 1.1 jonathan void *v;
455 1.1 jonathan register_t *retval;
456 1.1 jonathan {
457 1.1 jonathan struct ultrix_sys_ioctl_args *uap = v;
458 1.22 simonb struct filedesc *fdp = l->l_proc->p_fd;
459 1.14 augustss struct file *fp;
460 1.22 simonb int (*ctl)(struct file *, u_long, void *, struct lwp *);
461 1.1 jonathan int error;
462 1.1 jonathan
463 1.17 thorpej if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
464 1.1 jonathan return EBADF;
465 1.1 jonathan
466 1.1 jonathan if ((fp->f_flag & (FREAD|FWRITE)) == 0)
467 1.1 jonathan return EBADF;
468 1.1 jonathan
469 1.1 jonathan ctl = fp->f_ops->fo_ioctl;
470 1.1 jonathan
471 1.1 jonathan switch (SCARG(uap, com)) {
472 1.1 jonathan case _IOR('t', 0, int):
473 1.1 jonathan SCARG(uap, com) = TIOCGETD;
474 1.1 jonathan break;
475 1.1 jonathan case _IOW('t', 1, int):
476 1.1 jonathan {
477 1.1 jonathan int disc;
478 1.1 jonathan
479 1.20 dsl if ((error = copyin(SCARG(uap, data), &disc, sizeof disc)) != 0)
480 1.1 jonathan return error;
481 1.1 jonathan
482 1.1 jonathan /* map SunOS NTTYDISC into our termios discipline */
483 1.1 jonathan if (disc == 2)
484 1.1 jonathan disc = 0;
485 1.1 jonathan /* all other disciplines are not supported by NetBSD */
486 1.1 jonathan if (disc)
487 1.1 jonathan return ENXIO;
488 1.1 jonathan
489 1.22 simonb return (*ctl)(fp, TIOCSETD, &disc, l);
490 1.1 jonathan }
491 1.1 jonathan case _IOW('t', 101, int): /* sun SUNOS_TIOCSSOFTCAR */
492 1.1 jonathan {
493 1.1 jonathan int x; /* unused */
494 1.1 jonathan
495 1.20 dsl return copyin(&x, SCARG(uap, data), sizeof x);
496 1.1 jonathan }
497 1.1 jonathan case _IOR('t', 100, int): /* sun SUNOS_TIOCSSOFTCAR */
498 1.1 jonathan {
499 1.1 jonathan int x = 0;
500 1.1 jonathan
501 1.20 dsl return copyout(&x, SCARG(uap, data), sizeof x);
502 1.1 jonathan }
503 1.1 jonathan case _IO('t', 36): /* sun TIOCCONS, no parameters */
504 1.1 jonathan {
505 1.1 jonathan int on = 1;
506 1.22 simonb return (*ctl)(fp, TIOCCONS, &on, l);
507 1.1 jonathan }
508 1.1 jonathan case _IOW('t', 37, struct sunos_ttysize):
509 1.1 jonathan {
510 1.1 jonathan struct winsize ws;
511 1.1 jonathan struct sunos_ttysize ss;
512 1.1 jonathan
513 1.22 simonb if ((error = (*ctl)(fp, TIOCGWINSZ, &ws, l)) != 0)
514 1.1 jonathan return (error);
515 1.1 jonathan
516 1.20 dsl if ((error = copyin(SCARG(uap, data), &ss, sizeof (ss))) != 0)
517 1.1 jonathan return error;
518 1.1 jonathan
519 1.1 jonathan ws.ws_row = ss.ts_row;
520 1.1 jonathan ws.ws_col = ss.ts_col;
521 1.1 jonathan
522 1.22 simonb return (*ctl)(fp, TIOCSWINSZ, &ws, l);
523 1.1 jonathan }
524 1.1 jonathan case _IOW('t', 38, struct sunos_ttysize):
525 1.1 jonathan {
526 1.1 jonathan struct winsize ws;
527 1.1 jonathan struct sunos_ttysize ss;
528 1.1 jonathan
529 1.22 simonb if ((error = (*ctl)(fp, TIOCGWINSZ, &ws, l)) != 0)
530 1.1 jonathan return (error);
531 1.1 jonathan
532 1.1 jonathan ss.ts_row = ws.ws_row;
533 1.1 jonathan ss.ts_col = ws.ws_col;
534 1.1 jonathan
535 1.20 dsl return copyout (&ss, SCARG(uap, data), sizeof (ss));
536 1.1 jonathan }
537 1.8 jonathan case _IOW('t', 118, int):
538 1.1 jonathan SCARG(uap, com) = TIOCSPGRP;
539 1.1 jonathan break;
540 1.8 jonathan case _IOR('t', 119, int):
541 1.1 jonathan SCARG(uap, com) = TIOCGPGRP;
542 1.1 jonathan break;
543 1.8 jonathan
544 1.2 jonathan /* Emulate termio or termios tcget() */
545 1.1 jonathan case ULTRIX_TCGETA:
546 1.1 jonathan case ULTRIX_TCGETS:
547 1.1 jonathan {
548 1.1 jonathan struct termios bts;
549 1.1 jonathan struct ultrix_termios sts;
550 1.1 jonathan struct ultrix_termio st;
551 1.1 jonathan
552 1.22 simonb if ((error = (*ctl)(fp, TIOCGETA, &bts, l)) != 0)
553 1.1 jonathan return error;
554 1.1 jonathan
555 1.1 jonathan btios2stios (&bts, &sts);
556 1.1 jonathan if (SCARG(uap, com) == ULTRIX_TCGETA) {
557 1.1 jonathan stios2stio (&sts, &st);
558 1.20 dsl return copyout(&st, SCARG(uap, data), sizeof (st));
559 1.1 jonathan } else
560 1.20 dsl return copyout(&sts, SCARG(uap, data), sizeof (sts));
561 1.1 jonathan /*NOTREACHED*/
562 1.1 jonathan }
563 1.2 jonathan /* Emulate termio tcset() */
564 1.1 jonathan case ULTRIX_TCSETA:
565 1.1 jonathan case ULTRIX_TCSETAW:
566 1.1 jonathan case ULTRIX_TCSETAF:
567 1.1 jonathan {
568 1.1 jonathan struct termios bts;
569 1.1 jonathan struct ultrix_termios sts;
570 1.1 jonathan struct ultrix_termio st;
571 1.1 jonathan int result;
572 1.1 jonathan
573 1.20 dsl if ((error = copyin(SCARG(uap, data), &st, sizeof (st))) != 0)
574 1.1 jonathan return error;
575 1.1 jonathan
576 1.1 jonathan /* get full BSD termios so we don't lose information */
577 1.22 simonb if ((error = (*ctl)(fp, TIOCGETA, &bts, l)) != 0)
578 1.1 jonathan return error;
579 1.1 jonathan
580 1.1 jonathan /*
581 1.1 jonathan * convert to sun termios, copy in information from
582 1.1 jonathan * termio, and convert back, then set new values.
583 1.1 jonathan */
584 1.1 jonathan btios2stios(&bts, &sts);
585 1.1 jonathan stio2stios(&st, &sts);
586 1.1 jonathan stios2btios(&sts, &bts);
587 1.1 jonathan
588 1.1 jonathan /*
589 1.1 jonathan * map ioctl code: ultrix tcsets are numbered in reverse order
590 1.1 jonathan */
591 1.1 jonathan #ifdef notyet
592 1.1 jonathan return (*ctl)(fp, ULTRIX_TCSETA - SCARG(uap, com) + TIOCSETA,
593 1.22 simonb &bts, l);
594 1.1 jonathan #else
595 1.1 jonathan result= (*ctl)(fp, ULTRIX_TCSETA - SCARG(uap, com) + TIOCSETA,
596 1.22 simonb &bts, l);
597 1.7 christos printf("ultrix TCSETA %lx returns %d\n",
598 1.6 christos ULTRIX_TCSETA - SCARG(uap, com), result);
599 1.1 jonathan return result;
600 1.1 jonathan #endif
601 1.1 jonathan
602 1.1 jonathan }
603 1.2 jonathan /* Emulate termios tcset() */
604 1.1 jonathan case ULTRIX_TCSETS:
605 1.1 jonathan case ULTRIX_TCSETSW:
606 1.1 jonathan case ULTRIX_TCSETSF:
607 1.1 jonathan {
608 1.1 jonathan struct termios bts;
609 1.1 jonathan struct ultrix_termios sts;
610 1.1 jonathan
611 1.20 dsl if ((error = copyin(SCARG(uap, data), &sts, sizeof (sts))) != 0)
612 1.1 jonathan return error;
613 1.1 jonathan stios2btios (&sts, &bts);
614 1.1 jonathan return (*ctl)(fp, ULTRIX_TCSETS - SCARG(uap, com) + TIOCSETA,
615 1.22 simonb &bts, l);
616 1.1 jonathan }
617 1.1 jonathan /*
618 1.1 jonathan * Pseudo-tty ioctl translations.
619 1.1 jonathan */
620 1.1 jonathan case _IOW('t', 32, int): { /* TIOCTCNTL */
621 1.1 jonathan int error, on;
622 1.1 jonathan
623 1.20 dsl error = copyin(SCARG(uap, data), &on, sizeof (on));
624 1.3 jonathan if (error != 0)
625 1.1 jonathan return error;
626 1.22 simonb return (*ctl)(fp, TIOCUCNTL, &on, l);
627 1.1 jonathan }
628 1.1 jonathan case _IOW('t', 33, int): { /* TIOCSIGNAL */
629 1.1 jonathan int error, sig;
630 1.1 jonathan
631 1.20 dsl error = copyin(SCARG(uap, data), &sig, sizeof (sig));
632 1.3 jonathan if (error != 0)
633 1.1 jonathan return error;
634 1.22 simonb return (*ctl)(fp, TIOCSIG, &sig, l);
635 1.1 jonathan }
636 1.8 jonathan
637 1.1 jonathan /*
638 1.1 jonathan * Socket ioctl translations.
639 1.1 jonathan */
640 1.3 jonathan #define IN_TYPE(a, type_t) { \
641 1.3 jonathan type_t localbuf; \
642 1.20 dsl if ((error = copyin(SCARG(uap, data), \
643 1.20 dsl &localbuf, sizeof (type_t))) != 0) \
644 1.3 jonathan return error; \
645 1.22 simonb return (*ctl)(fp, a, &localbuf, l); \
646 1.3 jonathan }
647 1.3 jonathan
648 1.3 jonathan #define INOUT_TYPE(a, type_t) { \
649 1.3 jonathan type_t localbuf; \
650 1.20 dsl if ((error = copyin(SCARG(uap, data), &localbuf, \
651 1.3 jonathan sizeof (type_t))) != 0) \
652 1.3 jonathan return error; \
653 1.22 simonb if ((error = (*ctl)(fp, a, &localbuf, l)) != 0) \
654 1.3 jonathan return error; \
655 1.20 dsl return copyout(&localbuf, SCARG(uap, data), sizeof (type_t)); \
656 1.3 jonathan }
657 1.3 jonathan
658 1.3 jonathan
659 1.1 jonathan #define IFREQ_IN(a) { \
660 1.1 jonathan struct ifreq ifreq; \
661 1.20 dsl if ((error = copyin(SCARG(uap, data), &ifreq, sizeof (ifreq))) != 0) \
662 1.1 jonathan return error; \
663 1.22 simonb return (*ctl)(fp, a, &ifreq, l); \
664 1.1 jonathan }
665 1.3 jonathan
666 1.1 jonathan #define IFREQ_INOUT(a) { \
667 1.1 jonathan struct ifreq ifreq; \
668 1.20 dsl if ((error = copyin(SCARG(uap, data), &ifreq, sizeof (ifreq))) != 0) \
669 1.1 jonathan return error; \
670 1.22 simonb if ((error = (*ctl)(fp, a, &ifreq, l)) != 0) \
671 1.1 jonathan return error; \
672 1.20 dsl return copyout(&ifreq, SCARG(uap, data), sizeof (ifreq)); \
673 1.1 jonathan }
674 1.1 jonathan
675 1.1 jonathan case _IOW('i', 12, struct ifreq):
676 1.1 jonathan /* SIOCSIFADDR */
677 1.1 jonathan break;
678 1.1 jonathan
679 1.1 jonathan case _IOWR('i', 13, struct ifreq):
680 1.1 jonathan IFREQ_INOUT(OSIOCGIFADDR);
681 1.1 jonathan
682 1.1 jonathan case _IOW('i', 14, struct ifreq):
683 1.1 jonathan /* SIOCSIFDSTADDR */
684 1.1 jonathan break;
685 1.1 jonathan
686 1.1 jonathan case _IOWR('i', 15, struct ifreq):
687 1.1 jonathan IFREQ_INOUT(OSIOCGIFDSTADDR);
688 1.1 jonathan
689 1.1 jonathan case _IOW('i', 16, struct ifreq):
690 1.1 jonathan /* SIOCSIFFLAGS */
691 1.1 jonathan break;
692 1.1 jonathan
693 1.1 jonathan case _IOWR('i', 17, struct ifreq):
694 1.1 jonathan /* SIOCGIFFLAGS */
695 1.1 jonathan break;
696 1.1 jonathan
697 1.8 jonathan case _IOWR('i', 18, struct ifreq):
698 1.1 jonathan IFREQ_INOUT(SIOCGIFBRDADDR);
699 1.1 jonathan
700 1.8 jonathan case _IOWR('i', 19, struct ifreq):
701 1.8 jonathan IFREQ_INOUT(SIOCSIFBRDADDR);
702 1.1 jonathan
703 1.21 christos case _IOWR('i', 20, struct ifconf): /* SIOCGIFCONF */
704 1.21 christos {
705 1.21 christos struct ifconf ifconf;
706 1.21 christos
707 1.21 christos /*
708 1.21 christos * XXX: two more problems
709 1.21 christos * 1. our sockaddr's are variable length, not always sizeof(sockaddr)
710 1.21 christos * 2. this returns a name per protocol, ie. it returns two "lo0"'s
711 1.21 christos */
712 1.21 christos error = copyin(SCARG(uap, data), &ifconf, sizeof (ifconf));
713 1.21 christos if (error)
714 1.21 christos return error;
715 1.22 simonb error = (*ctl)(fp, OSIOCGIFCONF, &ifconf, l);
716 1.21 christos if (error)
717 1.21 christos return error;
718 1.21 christos return copyout(&ifconf, SCARG(uap, data), sizeof (ifconf));
719 1.21 christos }
720 1.21 christos
721 1.21 christos
722 1.8 jonathan case _IOWR('i', 21, struct ifreq):
723 1.1 jonathan IFREQ_INOUT(OSIOCGIFNETMASK);
724 1.1 jonathan
725 1.8 jonathan case _IOW('i', 22, struct ifreq):
726 1.1 jonathan IFREQ_IN(SIOCSIFNETMASK);
727 1.1 jonathan
728 1.8 jonathan /* 23: _IOWR('i', 23, struct ifreq): Ultrix SIOCSPHYADDR */
729 1.8 jonathan /* 24: _IOWR('i', 24, struct ifreq): Ultrix SIOCSADDMULTI */
730 1.8 jonathan /* 25: _IOWR('i', 25, struct ifreq): Ultrix SIOCSDELMULTI */
731 1.8 jonathan
732 1.21 christos case _IOW('i', 26, struct ifreq): /* SIOCSIFRDCTRS? */
733 1.21 christos case _IOWR('i', 27, struct ifreq): /* SIOCGIFZCTRS? */
734 1.21 christos case _IOWR('i', 28, struct ifreq): /* read physaddr ? */
735 1.21 christos return EOPNOTSUPP;
736 1.1 jonathan
737 1.1 jonathan
738 1.1 jonathan case _IOW('i', 30, struct arpreq):
739 1.1 jonathan /* SIOCSARP */
740 1.1 jonathan break;
741 1.1 jonathan
742 1.1 jonathan case _IOWR('i', 31, struct arpreq):
743 1.1 jonathan /* SIOCGARP */
744 1.1 jonathan break;
745 1.1 jonathan
746 1.1 jonathan case _IOW('i', 32, struct arpreq):
747 1.1 jonathan /* SIOCDARP */
748 1.1 jonathan break;
749 1.1 jonathan
750 1.21 christos case _IOW('i', 40, struct ifreq): /* SIOCARPREQ */
751 1.21 christos return EOPNOTSUPP;
752 1.21 christos
753 1.21 christos case _IOWR('i', 41, struct ifreq):
754 1.21 christos IFREQ_INOUT(SIOCGIFMETRIC);
755 1.21 christos
756 1.21 christos case _IOWR('i', 42, struct ifreq):
757 1.21 christos IFREQ_IN(SIOCSIFMETRIC);
758 1.8 jonathan
759 1.1 jonathan case _IOW('i', 44, struct ifreq): /* SIOCSETSYNC */
760 1.1 jonathan case _IOWR('i', 45, struct ifreq): /* SIOCGETSYNC */
761 1.1 jonathan case _IOWR('i', 46, struct ifreq): /* SIOCSDSTATS */
762 1.1 jonathan case _IOWR('i', 47, struct ifreq): /* SIOCSESTATS */
763 1.1 jonathan case _IOW('i', 48, int): /* SIOCSPROMISC */
764 1.8 jonathan return EOPNOTSUPP;
765 1.8 jonathan
766 1.8 jonathan /* emulate for vat, vic tools */
767 1.1 jonathan case _IOW('i', 49, struct ifreq): /* SIOCADDMULTI */
768 1.1 jonathan case _IOW('i', 50, struct ifreq): /* SIOCDELMULTI */
769 1.1 jonathan return EOPNOTSUPP;
770 1.1 jonathan
771 1.1 jonathan }
772 1.19 thorpej return (sys_ioctl(l, uap, retval));
773 1.1 jonathan }
774