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