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