sunos32_ioctl.c revision 1.15.2.5 1 1.15.2.5 yamt /* $NetBSD: sunos32_ioctl.c,v 1.15.2.5 2008/01/21 09:42:04 yamt Exp $ */
2 1.2 mrg /* from: NetBSD: sunos_ioctl.c,v 1.35 2001/02/03 22:20:02 mrg Exp */
3 1.1 mrg
4 1.1 mrg /*
5 1.1 mrg * Copyright (c) 2001 Matthew R. Green
6 1.1 mrg * All rights reserved.
7 1.1 mrg *
8 1.1 mrg * Redistribution and use in source and binary forms, with or without
9 1.1 mrg * modification, are permitted provided that the following conditions
10 1.1 mrg * are met:
11 1.1 mrg * 1. Redistributions of source code must retain the above copyright
12 1.1 mrg * notice, this list of conditions and the following disclaimer.
13 1.1 mrg * 2. Redistributions in binary form must reproduce the above copyright
14 1.1 mrg * notice, this list of conditions and the following disclaimer in the
15 1.1 mrg * documentation and/or other materials provided with the distribution.
16 1.1 mrg * 3. The name of the author may not be used to endorse or promote products
17 1.1 mrg * derived from this software without specific prior written permission.
18 1.1 mrg *
19 1.1 mrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 1.1 mrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 1.1 mrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 1.1 mrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 1.1 mrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 1.1 mrg * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 1.1 mrg * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 1.1 mrg * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 1.1 mrg * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 1.1 mrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 1.1 mrg * SUCH DAMAGE.
30 1.1 mrg */
31 1.1 mrg
32 1.2 mrg /*
33 1.2 mrg * Copyright (c) 1993 Markus Wild.
34 1.2 mrg * All rights reserved.
35 1.2 mrg *
36 1.2 mrg * Redistribution and use in source and binary forms, with or without
37 1.2 mrg * modification, are permitted provided that the following conditions
38 1.2 mrg * are met:
39 1.2 mrg * 1. Redistributions of source code must retain the above copyright
40 1.2 mrg * notice, this list of conditions and the following disclaimer.
41 1.2 mrg * 2. The name of the author may not be used to endorse or promote products
42 1.2 mrg * derived from this software without specific prior written permission
43 1.2 mrg *
44 1.2 mrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
45 1.2 mrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
46 1.2 mrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
47 1.2 mrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
48 1.2 mrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
49 1.2 mrg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 1.2 mrg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 1.2 mrg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 1.2 mrg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
53 1.2 mrg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 1.2 mrg *
55 1.2 mrg * loosely from: Header: sunos_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp
56 1.2 mrg */
57 1.7 lukem
58 1.7 lukem #include <sys/cdefs.h>
59 1.15.2.5 yamt __KERNEL_RCSID(0, "$NetBSD: sunos32_ioctl.c,v 1.15.2.5 2008/01/21 09:42:04 yamt Exp $");
60 1.2 mrg
61 1.4 mrg #if defined(_KERNEL_OPT)
62 1.2 mrg #include "opt_compat_netbsd32.h"
63 1.2 mrg #include "opt_execfmt.h"
64 1.2 mrg #endif
65 1.2 mrg
66 1.2 mrg #include <sys/param.h>
67 1.2 mrg #include <sys/proc.h>
68 1.2 mrg #include <sys/systm.h>
69 1.2 mrg #include <sys/file.h>
70 1.2 mrg #include <sys/filedesc.h>
71 1.2 mrg #include <sys/ioctl.h>
72 1.2 mrg #include <sys/termios.h>
73 1.2 mrg #include <sys/tty.h>
74 1.2 mrg #include <sys/socket.h>
75 1.2 mrg #include <sys/audioio.h>
76 1.2 mrg #include <sys/vnode.h>
77 1.2 mrg #include <sys/mount.h>
78 1.2 mrg #include <sys/disklabel.h>
79 1.2 mrg #include <sys/syscallargs.h>
80 1.2 mrg
81 1.2 mrg #include <miscfs/specfs/specdev.h>
82 1.2 mrg
83 1.2 mrg #include <net/if.h>
84 1.2 mrg
85 1.2 mrg #include <dev/sun/disklabel.h>
86 1.2 mrg
87 1.15.2.3 yamt #include <compat/sys/sockio.h>
88 1.15.2.3 yamt
89 1.2 mrg #include <compat/sunos/sunos.h>
90 1.2 mrg #include <compat/sunos/sunos_syscallargs.h>
91 1.2 mrg #include <compat/netbsd32/netbsd32.h>
92 1.2 mrg #include <compat/netbsd32/netbsd32_syscallargs.h>
93 1.2 mrg #include <compat/sunos32/sunos32.h>
94 1.2 mrg #include <compat/sunos32/sunos32_syscallargs.h>
95 1.2 mrg #include <compat/common/compat_util.h>
96 1.2 mrg
97 1.2 mrg /*
98 1.2 mrg * SunOS ioctl calls.
99 1.2 mrg * This file is something of a hodge-podge.
100 1.2 mrg * Support gets added as things turn up....
101 1.2 mrg */
102 1.2 mrg
103 1.14 matt static const struct speedtab sptab[] = {
104 1.2 mrg { 0, 0 },
105 1.2 mrg { 50, 1 },
106 1.2 mrg { 75, 2 },
107 1.2 mrg { 110, 3 },
108 1.2 mrg { 134, 4 },
109 1.2 mrg { 135, 4 },
110 1.2 mrg { 150, 5 },
111 1.2 mrg { 200, 6 },
112 1.2 mrg { 300, 7 },
113 1.2 mrg { 600, 8 },
114 1.2 mrg { 1200, 9 },
115 1.2 mrg { 1800, 10 },
116 1.2 mrg { 2400, 11 },
117 1.2 mrg { 4800, 12 },
118 1.2 mrg { 9600, 13 },
119 1.2 mrg { 19200, 14 },
120 1.2 mrg { 38400, 15 },
121 1.2 mrg { -1, -1 }
122 1.2 mrg };
123 1.2 mrg
124 1.14 matt static const netbsd32_u_long s2btab[] = {
125 1.2 mrg 0,
126 1.2 mrg 50,
127 1.2 mrg 75,
128 1.2 mrg 110,
129 1.2 mrg 134,
130 1.2 mrg 150,
131 1.2 mrg 200,
132 1.2 mrg 300,
133 1.2 mrg 600,
134 1.2 mrg 1200,
135 1.2 mrg 1800,
136 1.2 mrg 2400,
137 1.2 mrg 4800,
138 1.2 mrg 9600,
139 1.2 mrg 19200,
140 1.2 mrg 38400,
141 1.2 mrg };
142 1.2 mrg
143 1.15.2.4 yamt static void stios2btios(struct sunos_termios *, struct termios *);
144 1.15.2.4 yamt static void btios2stios(struct termios *, struct sunos_termios *);
145 1.15.2.4 yamt static void stios2stio(struct sunos_termios *, struct sunos_termio *);
146 1.15.2.4 yamt static void stio2stios(struct sunos_termio *, struct sunos_termios *);
147 1.2 mrg
148 1.2 mrg /*
149 1.2 mrg * These two conversion functions have mostly been done
150 1.2 mrg * with some perl cut&paste, then hand-edited to comment
151 1.2 mrg * out what doesn't exist under NetBSD.
152 1.2 mrg * A note from Markus's code:
153 1.2 mrg * (l & BITMASK1) / BITMASK1 * BITMASK2 is translated
154 1.2 mrg * optimally by gcc m68k, much better than any ?: stuff.
155 1.2 mrg * Code may vary with different architectures of course.
156 1.2 mrg *
157 1.2 mrg * I don't know what optimizer you used, but seeing divu's and
158 1.2 mrg * bfextu's in the m68k assembly output did not encourage me...
159 1.2 mrg * as well, gcc on the sparc definitely generates much better
160 1.2 mrg * code with `?:'.
161 1.2 mrg */
162 1.2 mrg
163 1.2 mrg static void
164 1.15.2.5 yamt stios2btios(struct sunos_termios *st, struct termios *bt)
165 1.2 mrg {
166 1.3 mrg netbsd32_u_long l, r;
167 1.2 mrg
168 1.2 mrg l = st->c_iflag;
169 1.2 mrg r = ((l & 0x00000001) ? IGNBRK : 0);
170 1.2 mrg r |= ((l & 0x00000002) ? BRKINT : 0);
171 1.2 mrg r |= ((l & 0x00000004) ? IGNPAR : 0);
172 1.2 mrg r |= ((l & 0x00000008) ? PARMRK : 0);
173 1.2 mrg r |= ((l & 0x00000010) ? INPCK : 0);
174 1.2 mrg r |= ((l & 0x00000020) ? ISTRIP : 0);
175 1.2 mrg r |= ((l & 0x00000040) ? INLCR : 0);
176 1.2 mrg r |= ((l & 0x00000080) ? IGNCR : 0);
177 1.2 mrg r |= ((l & 0x00000100) ? ICRNL : 0);
178 1.2 mrg /* ((l & 0x00000200) ? IUCLC : 0) */
179 1.2 mrg r |= ((l & 0x00000400) ? IXON : 0);
180 1.2 mrg r |= ((l & 0x00000800) ? IXANY : 0);
181 1.2 mrg r |= ((l & 0x00001000) ? IXOFF : 0);
182 1.2 mrg r |= ((l & 0x00002000) ? IMAXBEL : 0);
183 1.2 mrg bt->c_iflag = r;
184 1.2 mrg
185 1.2 mrg l = st->c_oflag;
186 1.2 mrg r = ((l & 0x00000001) ? OPOST : 0);
187 1.2 mrg /* ((l & 0x00000002) ? OLCUC : 0) */
188 1.2 mrg r |= ((l & 0x00000004) ? ONLCR : 0);
189 1.2 mrg /* ((l & 0x00000008) ? OCRNL : 0) */
190 1.2 mrg /* ((l & 0x00000010) ? ONOCR : 0) */
191 1.2 mrg /* ((l & 0x00000020) ? ONLRET : 0) */
192 1.2 mrg /* ((l & 0x00000040) ? OFILL : 0) */
193 1.2 mrg /* ((l & 0x00000080) ? OFDEL : 0) */
194 1.2 mrg /* ((l & 0x00000100) ? NLDLY : 0) */
195 1.2 mrg /* ((l & 0x00000100) ? NL1 : 0) */
196 1.2 mrg /* ((l & 0x00000600) ? CRDLY : 0) */
197 1.2 mrg /* ((l & 0x00000200) ? CR1 : 0) */
198 1.2 mrg /* ((l & 0x00000400) ? CR2 : 0) */
199 1.2 mrg /* ((l & 0x00000600) ? CR3 : 0) */
200 1.2 mrg /* ((l & 0x00001800) ? TABDLY : 0) */
201 1.2 mrg /* ((l & 0x00000800) ? TAB1 : 0) */
202 1.2 mrg /* ((l & 0x00001000) ? TAB2 : 0) */
203 1.2 mrg r |= ((l & 0x00001800) ? OXTABS : 0);
204 1.2 mrg /* ((l & 0x00002000) ? BSDLY : 0) */
205 1.2 mrg /* ((l & 0x00002000) ? BS1 : 0) */
206 1.2 mrg /* ((l & 0x00004000) ? VTDLY : 0) */
207 1.2 mrg /* ((l & 0x00004000) ? VT1 : 0) */
208 1.2 mrg /* ((l & 0x00008000) ? FFDLY : 0) */
209 1.2 mrg /* ((l & 0x00008000) ? FF1 : 0) */
210 1.2 mrg /* ((l & 0x00010000) ? PAGEOUT : 0) */
211 1.2 mrg /* ((l & 0x00020000) ? WRAP : 0) */
212 1.2 mrg bt->c_oflag = r;
213 1.2 mrg
214 1.2 mrg l = st->c_cflag;
215 1.2 mrg switch (l & 0x00000030) {
216 1.2 mrg case 0:
217 1.2 mrg r = CS5;
218 1.2 mrg break;
219 1.2 mrg case 0x00000010:
220 1.2 mrg r = CS6;
221 1.2 mrg break;
222 1.2 mrg case 0x00000020:
223 1.2 mrg r = CS7;
224 1.2 mrg break;
225 1.2 mrg case 0x00000030:
226 1.2 mrg r = CS8;
227 1.2 mrg break;
228 1.2 mrg }
229 1.2 mrg r |= ((l & 0x00000040) ? CSTOPB : 0);
230 1.2 mrg r |= ((l & 0x00000080) ? CREAD : 0);
231 1.2 mrg r |= ((l & 0x00000100) ? PARENB : 0);
232 1.2 mrg r |= ((l & 0x00000200) ? PARODD : 0);
233 1.2 mrg r |= ((l & 0x00000400) ? HUPCL : 0);
234 1.2 mrg r |= ((l & 0x00000800) ? CLOCAL : 0);
235 1.2 mrg /* ((l & 0x00001000) ? LOBLK : 0) */
236 1.2 mrg r |= ((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0);
237 1.2 mrg bt->c_cflag = r;
238 1.2 mrg
239 1.2 mrg bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
240 1.2 mrg
241 1.2 mrg l = st->c_lflag;
242 1.2 mrg r = ((l & 0x00000001) ? ISIG : 0);
243 1.2 mrg r |= ((l & 0x00000002) ? ICANON : 0);
244 1.2 mrg /* ((l & 0x00000004) ? XCASE : 0) */
245 1.2 mrg r |= ((l & 0x00000008) ? ECHO : 0);
246 1.2 mrg r |= ((l & 0x00000010) ? ECHOE : 0);
247 1.2 mrg r |= ((l & 0x00000020) ? ECHOK : 0);
248 1.2 mrg r |= ((l & 0x00000040) ? ECHONL : 0);
249 1.2 mrg r |= ((l & 0x00000080) ? NOFLSH : 0);
250 1.2 mrg r |= ((l & 0x00000100) ? TOSTOP : 0);
251 1.2 mrg r |= ((l & 0x00000200) ? ECHOCTL : 0);
252 1.2 mrg r |= ((l & 0x00000400) ? ECHOPRT : 0);
253 1.2 mrg r |= ((l & 0x00000800) ? ECHOKE : 0);
254 1.2 mrg /* ((l & 0x00001000) ? DEFECHO : 0) */
255 1.2 mrg r |= ((l & 0x00002000) ? FLUSHO : 0);
256 1.2 mrg r |= ((l & 0x00004000) ? PENDIN : 0);
257 1.2 mrg bt->c_lflag = r;
258 1.2 mrg
259 1.2 mrg bt->c_cc[VINTR] = st->c_cc[0] ? st->c_cc[0] : _POSIX_VDISABLE;
260 1.2 mrg bt->c_cc[VQUIT] = st->c_cc[1] ? st->c_cc[1] : _POSIX_VDISABLE;
261 1.2 mrg bt->c_cc[VERASE] = st->c_cc[2] ? st->c_cc[2] : _POSIX_VDISABLE;
262 1.2 mrg bt->c_cc[VKILL] = st->c_cc[3] ? st->c_cc[3] : _POSIX_VDISABLE;
263 1.2 mrg bt->c_cc[VEOF] = st->c_cc[4] ? st->c_cc[4] : _POSIX_VDISABLE;
264 1.2 mrg bt->c_cc[VEOL] = st->c_cc[5] ? st->c_cc[5] : _POSIX_VDISABLE;
265 1.2 mrg bt->c_cc[VEOL2] = st->c_cc[6] ? st->c_cc[6] : _POSIX_VDISABLE;
266 1.2 mrg /* bt->c_cc[VSWTCH] = st->c_cc[7] ? st->c_cc[7] : _POSIX_VDISABLE; */
267 1.2 mrg bt->c_cc[VSTART] = st->c_cc[8] ? st->c_cc[8] : _POSIX_VDISABLE;
268 1.2 mrg bt->c_cc[VSTOP] = st->c_cc[9] ? st->c_cc[9] : _POSIX_VDISABLE;
269 1.2 mrg bt->c_cc[VSUSP] = st->c_cc[10] ? st->c_cc[10] : _POSIX_VDISABLE;
270 1.2 mrg bt->c_cc[VDSUSP] = st->c_cc[11] ? st->c_cc[11] : _POSIX_VDISABLE;
271 1.2 mrg bt->c_cc[VREPRINT] = st->c_cc[12] ? st->c_cc[12] : _POSIX_VDISABLE;
272 1.2 mrg bt->c_cc[VDISCARD] = st->c_cc[13] ? st->c_cc[13] : _POSIX_VDISABLE;
273 1.2 mrg bt->c_cc[VWERASE] = st->c_cc[14] ? st->c_cc[14] : _POSIX_VDISABLE;
274 1.2 mrg bt->c_cc[VLNEXT] = st->c_cc[15] ? st->c_cc[15] : _POSIX_VDISABLE;
275 1.2 mrg bt->c_cc[VSTATUS] = st->c_cc[16] ? st->c_cc[16] : _POSIX_VDISABLE;
276 1.2 mrg
277 1.2 mrg /* if `raw mode', create native VMIN/VTIME from SunOS VEOF/VEOL */
278 1.2 mrg bt->c_cc[VMIN] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOF];
279 1.2 mrg bt->c_cc[VTIME] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOL];
280 1.2 mrg }
281 1.2 mrg
282 1.2 mrg
283 1.2 mrg static void
284 1.15.2.5 yamt btios2stios(struct termios *bt, struct sunos_termios *st)
285 1.2 mrg {
286 1.3 mrg netbsd32_u_long l, r;
287 1.2 mrg int s;
288 1.2 mrg
289 1.2 mrg l = bt->c_iflag;
290 1.2 mrg r = ((l & IGNBRK) ? 0x00000001 : 0);
291 1.2 mrg r |= ((l & BRKINT) ? 0x00000002 : 0);
292 1.2 mrg r |= ((l & IGNPAR) ? 0x00000004 : 0);
293 1.2 mrg r |= ((l & PARMRK) ? 0x00000008 : 0);
294 1.2 mrg r |= ((l & INPCK) ? 0x00000010 : 0);
295 1.2 mrg r |= ((l & ISTRIP) ? 0x00000020 : 0);
296 1.2 mrg r |= ((l & INLCR) ? 0x00000040 : 0);
297 1.2 mrg r |= ((l & IGNCR) ? 0x00000080 : 0);
298 1.2 mrg r |= ((l & ICRNL) ? 0x00000100 : 0);
299 1.2 mrg /* ((l & IUCLC) ? 0x00000200 : 0) */
300 1.2 mrg r |= ((l & IXON) ? 0x00000400 : 0);
301 1.2 mrg r |= ((l & IXANY) ? 0x00000800 : 0);
302 1.2 mrg r |= ((l & IXOFF) ? 0x00001000 : 0);
303 1.2 mrg r |= ((l & IMAXBEL) ? 0x00002000 : 0);
304 1.2 mrg st->c_iflag = r;
305 1.2 mrg
306 1.2 mrg l = bt->c_oflag;
307 1.2 mrg r = ((l & OPOST) ? 0x00000001 : 0);
308 1.2 mrg /* ((l & OLCUC) ? 0x00000002 : 0) */
309 1.2 mrg r |= ((l & ONLCR) ? 0x00000004 : 0);
310 1.2 mrg /* ((l & OCRNL) ? 0x00000008 : 0) */
311 1.2 mrg /* ((l & ONOCR) ? 0x00000010 : 0) */
312 1.2 mrg /* ((l & ONLRET) ? 0x00000020 : 0) */
313 1.2 mrg /* ((l & OFILL) ? 0x00000040 : 0) */
314 1.2 mrg /* ((l & OFDEL) ? 0x00000080 : 0) */
315 1.2 mrg /* ((l & NLDLY) ? 0x00000100 : 0) */
316 1.2 mrg /* ((l & NL1) ? 0x00000100 : 0) */
317 1.2 mrg /* ((l & CRDLY) ? 0x00000600 : 0) */
318 1.2 mrg /* ((l & CR1) ? 0x00000200 : 0) */
319 1.2 mrg /* ((l & CR2) ? 0x00000400 : 0) */
320 1.2 mrg /* ((l & CR3) ? 0x00000600 : 0) */
321 1.2 mrg /* ((l & TABDLY) ? 0x00001800 : 0) */
322 1.2 mrg /* ((l & TAB1) ? 0x00000800 : 0) */
323 1.2 mrg /* ((l & TAB2) ? 0x00001000 : 0) */
324 1.2 mrg r |= ((l & OXTABS) ? 0x00001800 : 0);
325 1.2 mrg /* ((l & BSDLY) ? 0x00002000 : 0) */
326 1.2 mrg /* ((l & BS1) ? 0x00002000 : 0) */
327 1.2 mrg /* ((l & VTDLY) ? 0x00004000 : 0) */
328 1.2 mrg /* ((l & VT1) ? 0x00004000 : 0) */
329 1.2 mrg /* ((l & FFDLY) ? 0x00008000 : 0) */
330 1.2 mrg /* ((l & FF1) ? 0x00008000 : 0) */
331 1.2 mrg /* ((l & PAGEOUT) ? 0x00010000 : 0) */
332 1.2 mrg /* ((l & WRAP) ? 0x00020000 : 0) */
333 1.2 mrg st->c_oflag = r;
334 1.2 mrg
335 1.2 mrg l = bt->c_cflag;
336 1.2 mrg switch (l & CSIZE) {
337 1.2 mrg case CS5:
338 1.2 mrg r = 0;
339 1.2 mrg break;
340 1.2 mrg case CS6:
341 1.2 mrg r = 0x00000010;
342 1.2 mrg break;
343 1.2 mrg case CS7:
344 1.2 mrg r = 0x00000020;
345 1.2 mrg break;
346 1.2 mrg case CS8:
347 1.2 mrg r = 0x00000030;
348 1.2 mrg break;
349 1.2 mrg }
350 1.2 mrg r |= ((l & CSTOPB) ? 0x00000040 : 0);
351 1.2 mrg r |= ((l & CREAD) ? 0x00000080 : 0);
352 1.2 mrg r |= ((l & PARENB) ? 0x00000100 : 0);
353 1.2 mrg r |= ((l & PARODD) ? 0x00000200 : 0);
354 1.2 mrg r |= ((l & HUPCL) ? 0x00000400 : 0);
355 1.2 mrg r |= ((l & CLOCAL) ? 0x00000800 : 0);
356 1.2 mrg /* ((l & LOBLK) ? 0x00001000 : 0) */
357 1.2 mrg r |= ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0);
358 1.2 mrg st->c_cflag = r;
359 1.2 mrg
360 1.2 mrg l = bt->c_lflag;
361 1.2 mrg r = ((l & ISIG) ? 0x00000001 : 0);
362 1.2 mrg r |= ((l & ICANON) ? 0x00000002 : 0);
363 1.2 mrg /* ((l & XCASE) ? 0x00000004 : 0) */
364 1.2 mrg r |= ((l & ECHO) ? 0x00000008 : 0);
365 1.2 mrg r |= ((l & ECHOE) ? 0x00000010 : 0);
366 1.2 mrg r |= ((l & ECHOK) ? 0x00000020 : 0);
367 1.2 mrg r |= ((l & ECHONL) ? 0x00000040 : 0);
368 1.2 mrg r |= ((l & NOFLSH) ? 0x00000080 : 0);
369 1.2 mrg r |= ((l & TOSTOP) ? 0x00000100 : 0);
370 1.2 mrg r |= ((l & ECHOCTL) ? 0x00000200 : 0);
371 1.2 mrg r |= ((l & ECHOPRT) ? 0x00000400 : 0);
372 1.2 mrg r |= ((l & ECHOKE) ? 0x00000800 : 0);
373 1.2 mrg /* ((l & DEFECHO) ? 0x00001000 : 0) */
374 1.2 mrg r |= ((l & FLUSHO) ? 0x00002000 : 0);
375 1.2 mrg r |= ((l & PENDIN) ? 0x00004000 : 0);
376 1.2 mrg st->c_lflag = r;
377 1.2 mrg
378 1.2 mrg s = ttspeedtab(bt->c_ospeed, sptab);
379 1.2 mrg if (s >= 0)
380 1.2 mrg st->c_cflag |= s;
381 1.2 mrg
382 1.2 mrg st->c_cc[0] = bt->c_cc[VINTR] != _POSIX_VDISABLE? bt->c_cc[VINTR]:0;
383 1.2 mrg st->c_cc[1] = bt->c_cc[VQUIT] != _POSIX_VDISABLE? bt->c_cc[VQUIT]:0;
384 1.2 mrg st->c_cc[2] = bt->c_cc[VERASE] != _POSIX_VDISABLE? bt->c_cc[VERASE]:0;
385 1.2 mrg st->c_cc[3] = bt->c_cc[VKILL] != _POSIX_VDISABLE? bt->c_cc[VKILL]:0;
386 1.2 mrg st->c_cc[4] = bt->c_cc[VEOF] != _POSIX_VDISABLE? bt->c_cc[VEOF]:0;
387 1.2 mrg st->c_cc[5] = bt->c_cc[VEOL] != _POSIX_VDISABLE? bt->c_cc[VEOL]:0;
388 1.2 mrg st->c_cc[6] = bt->c_cc[VEOL2] != _POSIX_VDISABLE? bt->c_cc[VEOL2]:0;
389 1.2 mrg st->c_cc[7] = 0;
390 1.2 mrg /* bt->c_cc[VSWTCH] != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */
391 1.2 mrg st->c_cc[8] = bt->c_cc[VSTART] != _POSIX_VDISABLE? bt->c_cc[VSTART]:0;
392 1.2 mrg st->c_cc[9] = bt->c_cc[VSTOP] != _POSIX_VDISABLE? bt->c_cc[VSTOP]:0;
393 1.2 mrg st->c_cc[10]= bt->c_cc[VSUSP] != _POSIX_VDISABLE? bt->c_cc[VSUSP]:0;
394 1.2 mrg st->c_cc[11]= bt->c_cc[VDSUSP] != _POSIX_VDISABLE? bt->c_cc[VDSUSP]:0;
395 1.2 mrg st->c_cc[12]= bt->c_cc[VREPRINT]!= _POSIX_VDISABLE? bt->c_cc[VREPRINT]:0;
396 1.2 mrg st->c_cc[13]= bt->c_cc[VDISCARD]!= _POSIX_VDISABLE? bt->c_cc[VDISCARD]:0;
397 1.2 mrg st->c_cc[14]= bt->c_cc[VWERASE] != _POSIX_VDISABLE? bt->c_cc[VWERASE]:0;
398 1.2 mrg st->c_cc[15]= bt->c_cc[VLNEXT] != _POSIX_VDISABLE? bt->c_cc[VLNEXT]:0;
399 1.2 mrg st->c_cc[16]= bt->c_cc[VSTATUS] != _POSIX_VDISABLE? bt->c_cc[VSTATUS]:0;
400 1.2 mrg
401 1.2 mrg if (!(bt->c_lflag & ICANON)) {
402 1.2 mrg /* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */
403 1.2 mrg st->c_cc[4] = bt->c_cc[VMIN];
404 1.2 mrg st->c_cc[5] = bt->c_cc[VTIME];
405 1.2 mrg }
406 1.2 mrg
407 1.2 mrg st->c_line = 0;
408 1.2 mrg }
409 1.2 mrg
410 1.2 mrg static void
411 1.15.2.5 yamt stios2stio(struct sunos_termios *ts, struct sunos_termio *t)
412 1.2 mrg {
413 1.2 mrg t->c_iflag = ts->c_iflag;
414 1.2 mrg t->c_oflag = ts->c_oflag;
415 1.2 mrg t->c_cflag = ts->c_cflag;
416 1.2 mrg t->c_lflag = ts->c_lflag;
417 1.2 mrg t->c_line = ts->c_line;
418 1.2 mrg memcpy(t->c_cc, ts->c_cc, 8);
419 1.2 mrg }
420 1.2 mrg
421 1.2 mrg static void
422 1.15.2.5 yamt stio2stios(struct sunos_termio *t, struct sunos_termios *ts)
423 1.2 mrg {
424 1.2 mrg ts->c_iflag = t->c_iflag;
425 1.2 mrg ts->c_oflag = t->c_oflag;
426 1.2 mrg ts->c_cflag = t->c_cflag;
427 1.2 mrg ts->c_lflag = t->c_lflag;
428 1.2 mrg ts->c_line = t->c_line;
429 1.2 mrg memcpy(ts->c_cc, t->c_cc, 8); /* don't touch the upper fields! */
430 1.2 mrg }
431 1.2 mrg
432 1.15.2.5 yamt
433 1.15.2.5 yamt static int
434 1.15.2.5 yamt sunos32_do_ioctl(int fd, int cmd, void *arg, struct lwp *l)
435 1.2 mrg {
436 1.2 mrg struct file *fp;
437 1.15.2.5 yamt struct vnode *vp;
438 1.2 mrg int error;
439 1.2 mrg
440 1.15.2.5 yamt if ((fp = fd_getfile(l->l_proc->p_fd, fd)) == NULL)
441 1.2 mrg return EBADF;
442 1.2 mrg
443 1.15.2.5 yamt if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
444 1.15.2.5 yamt FILE_UNLOCK(fp);
445 1.2 mrg return EBADF;
446 1.15.2.5 yamt }
447 1.2 mrg
448 1.15.2.5 yamt FILE_USE(fp);
449 1.15.2.5 yamt error = fp->f_ops->fo_ioctl(fp, cmd, arg, l);
450 1.15.2.5 yamt if (error == EIO && cmd == TIOCGPGRP) {
451 1.15.2.5 yamt vp = (struct vnode *)fp->f_data;
452 1.15.2.5 yamt if (vp != NULL && vp->v_type == VCHR && major(vp->v_rdev) == 21)
453 1.15.2.5 yamt error = ENOTTY;
454 1.15.2.5 yamt }
455 1.15.2.5 yamt FILE_UNUSE(fp, l);
456 1.15.2.5 yamt return error;
457 1.15.2.5 yamt }
458 1.15.2.5 yamt
459 1.15.2.5 yamt int
460 1.15.2.5 yamt sunos32_sys_ioctl(struct lwp *l, const struct sunos32_sys_ioctl_args *uap, register_t *retval)
461 1.15.2.5 yamt {
462 1.15.2.5 yamt /* {
463 1.15.2.5 yamt int fd;
464 1.15.2.5 yamt netbsd32_u_long com;
465 1.15.2.5 yamt netbsd32_caddr_t data;
466 1.15.2.5 yamt } */
467 1.15.2.5 yamt struct netbsd32_ioctl_args bsd_ua;
468 1.15.2.5 yamt int error;
469 1.15.2.5 yamt
470 1.15.2.5 yamt SCARG(&bsd_ua, fd) = SCARG(uap, fd);
471 1.15.2.5 yamt SCARG(&bsd_ua, com) = SCARG(uap, com);
472 1.15.2.5 yamt SCARG(&bsd_ua, data) = SCARG(uap, data);
473 1.2 mrg
474 1.2 mrg switch (SCARG(uap, com)) {
475 1.2 mrg case _IOR('t', 0, int):
476 1.15.2.5 yamt SCARG(&bsd_ua, com) = TIOCGETD;
477 1.2 mrg break;
478 1.2 mrg case _IOW('t', 1, int):
479 1.2 mrg {
480 1.2 mrg int disc;
481 1.2 mrg
482 1.15.2.3 yamt if ((error = copyin(SCARG_P32(uap, data), &disc,
483 1.2 mrg sizeof disc)) != 0)
484 1.2 mrg return error;
485 1.2 mrg
486 1.2 mrg /* map SunOS NTTYDISC into our termios discipline */
487 1.2 mrg if (disc == 2)
488 1.2 mrg disc = 0;
489 1.2 mrg /* all other disciplines are not supported by NetBSD */
490 1.2 mrg if (disc)
491 1.2 mrg return ENXIO;
492 1.2 mrg
493 1.15.2.5 yamt return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCSETD, &disc, l);
494 1.2 mrg }
495 1.2 mrg case _IOW('t', 101, int): /* sun SUNOS_TIOCSSOFTCAR */
496 1.2 mrg {
497 1.2 mrg int x; /* unused */
498 1.2 mrg
499 1.15.2.3 yamt return copyin(SCARG_P32(uap, data), &x, sizeof x);
500 1.2 mrg }
501 1.2 mrg case _IOR('t', 100, int): /* sun SUNOS_TIOCSSOFTCAR */
502 1.2 mrg {
503 1.2 mrg int x = 0;
504 1.2 mrg
505 1.15.2.3 yamt return copyout(&x, SCARG_P32(uap, data), sizeof x);
506 1.2 mrg }
507 1.2 mrg case _IO('t', 36): /* sun TIOCCONS, no parameters */
508 1.2 mrg {
509 1.2 mrg int on = 1;
510 1.15.2.5 yamt return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCCONS, &on, l);
511 1.2 mrg }
512 1.2 mrg case _IOW('t', 37, struct sunos_ttysize):
513 1.2 mrg {
514 1.2 mrg struct winsize ws;
515 1.2 mrg struct sunos_ttysize ss;
516 1.2 mrg
517 1.15.2.5 yamt if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGWINSZ, &ws, l)) != 0)
518 1.2 mrg return (error);
519 1.2 mrg
520 1.15.2.3 yamt if ((error = copyin(SCARG_P32(uap, data), &ss, sizeof (ss))) != 0)
521 1.2 mrg return error;
522 1.2 mrg
523 1.2 mrg ws.ws_row = ss.ts_row;
524 1.2 mrg ws.ws_col = ss.ts_col;
525 1.2 mrg
526 1.15.2.5 yamt return (sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCSWINSZ, &ws, l));
527 1.2 mrg }
528 1.2 mrg case _IOW('t', 38, struct sunos_ttysize):
529 1.2 mrg {
530 1.2 mrg struct winsize ws;
531 1.2 mrg struct sunos_ttysize ss;
532 1.2 mrg
533 1.15.2.5 yamt if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGWINSZ, &ws, l)) != 0)
534 1.2 mrg return (error);
535 1.2 mrg
536 1.2 mrg ss.ts_row = ws.ws_row;
537 1.2 mrg ss.ts_col = ws.ws_col;
538 1.2 mrg
539 1.15.2.3 yamt return copyout(&ss, SCARG_P32(uap, data), sizeof (ss));
540 1.2 mrg }
541 1.2 mrg case _IOW('t', 130, int): /* TIOCSETPGRP: posix variant */
542 1.15.2.5 yamt SCARG(&bsd_ua, com) = TIOCSPGRP;
543 1.2 mrg break;
544 1.2 mrg case _IOR('t', 131, int): /* TIOCGETPGRP: posix variant */
545 1.2 mrg {
546 1.2 mrg /*
547 1.2 mrg * sigh, must do error translation on pty devices
548 1.2 mrg * (see also kern/tty_pty.c)
549 1.2 mrg */
550 1.2 mrg int pgrp;
551 1.15.2.5 yamt error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGPGRP, &pgrp, l);
552 1.15.2.5 yamt if (error)
553 1.2 mrg return (error);
554 1.15.2.3 yamt return copyout(&pgrp, SCARG_P32(uap, data), sizeof(pgrp));
555 1.2 mrg }
556 1.2 mrg case _IO('t', 132):
557 1.15.2.5 yamt SCARG(&bsd_ua, com) = TIOCSCTTY;
558 1.2 mrg break;
559 1.2 mrg case SUNOS_TCGETA:
560 1.2 mrg case SUNOS_TCGETS:
561 1.2 mrg {
562 1.2 mrg struct termios bts;
563 1.2 mrg struct sunos_termios sts;
564 1.2 mrg struct sunos_termio st;
565 1.2 mrg
566 1.15.2.5 yamt if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGETA, &bts, l)) != 0)
567 1.2 mrg return error;
568 1.2 mrg
569 1.2 mrg btios2stios (&bts, &sts);
570 1.2 mrg if (SCARG(uap, com) == SUNOS_TCGETA) {
571 1.2 mrg stios2stio (&sts, &st);
572 1.15.2.3 yamt return copyout(&st, SCARG_P32(uap, data),
573 1.2 mrg sizeof (st));
574 1.2 mrg } else
575 1.15.2.3 yamt return copyout(&sts, SCARG_P32(uap, data),
576 1.2 mrg sizeof (sts));
577 1.2 mrg /*NOTREACHED*/
578 1.2 mrg }
579 1.2 mrg case SUNOS_TCSETA:
580 1.2 mrg case SUNOS_TCSETAW:
581 1.2 mrg case SUNOS_TCSETAF:
582 1.2 mrg {
583 1.2 mrg struct termios bts;
584 1.2 mrg struct sunos_termios sts;
585 1.2 mrg struct sunos_termio st;
586 1.2 mrg
587 1.15.2.3 yamt if ((error = copyin(SCARG_P32(uap, data), &st,
588 1.2 mrg sizeof (st))) != 0)
589 1.2 mrg return error;
590 1.2 mrg
591 1.2 mrg /* get full BSD termios so we don't lose information */
592 1.15.2.5 yamt if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGETA, &bts, l)) != 0)
593 1.2 mrg return error;
594 1.2 mrg
595 1.2 mrg /*
596 1.2 mrg * convert to sun termios, copy in information from
597 1.2 mrg * termio, and convert back, then set new values.
598 1.2 mrg */
599 1.2 mrg btios2stios(&bts, &sts);
600 1.2 mrg stio2stios(&st, &sts);
601 1.2 mrg stios2btios(&sts, &bts);
602 1.2 mrg
603 1.15.2.5 yamt return sunos32_do_ioctl(SCARG(&bsd_ua, fd), SCARG(uap, com) - SUNOS_TCSETA + TIOCSETA,
604 1.15.2.1 yamt &bts, l);
605 1.2 mrg }
606 1.2 mrg case SUNOS_TCSETS:
607 1.2 mrg case SUNOS_TCSETSW:
608 1.2 mrg case SUNOS_TCSETSF:
609 1.2 mrg {
610 1.2 mrg struct termios bts;
611 1.2 mrg struct sunos_termios sts;
612 1.2 mrg
613 1.15.2.3 yamt if ((error = copyin(SCARG_P32(uap, data), &sts,
614 1.2 mrg sizeof (sts))) != 0)
615 1.2 mrg return error;
616 1.2 mrg stios2btios (&sts, &bts);
617 1.15.2.5 yamt return sunos32_do_ioctl(SCARG(&bsd_ua, fd), SCARG(uap, com) - SUNOS_TCSETS + TIOCSETA,
618 1.15.2.1 yamt &bts, l);
619 1.2 mrg }
620 1.2 mrg /*
621 1.2 mrg * Pseudo-tty ioctl translations.
622 1.2 mrg */
623 1.2 mrg case _IOW('t', 32, int): { /* TIOCTCNTL */
624 1.15 christos int error1, on;
625 1.2 mrg
626 1.15.2.3 yamt error1 = copyin(SCARG_P32(uap, data), &on, sizeof (on));
627 1.15 christos if (error1)
628 1.15 christos return error1;
629 1.15.2.5 yamt return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCUCNTL, &on, l);
630 1.2 mrg }
631 1.2 mrg case _IOW('t', 33, int): { /* TIOCSIGNAL */
632 1.15 christos int error1, sig;
633 1.2 mrg
634 1.15.2.3 yamt error1 = copyin(SCARG_P32(uap, data), &sig, sizeof (sig));
635 1.15 christos if (error1)
636 1.15 christos return error1;
637 1.15.2.5 yamt return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCSIG, &sig, l);
638 1.2 mrg }
639 1.2 mrg
640 1.2 mrg /*
641 1.2 mrg * Socket ioctl translations.
642 1.2 mrg */
643 1.2 mrg #define IFREQ_IN(a) { \
644 1.15.2.3 yamt struct oifreq ifreq; \
645 1.15.2.3 yamt error = copyin(SCARG_P32(uap, data), &ifreq, sizeof (ifreq)); \
646 1.2 mrg if (error) \
647 1.2 mrg return error; \
648 1.15.2.5 yamt return sunos32_do_ioctl(SCARG(&bsd_ua, fd), a, &ifreq, l); \
649 1.2 mrg }
650 1.2 mrg #define IFREQ_INOUT(a) { \
651 1.15.2.3 yamt struct oifreq ifreq; \
652 1.15.2.3 yamt error = copyin(SCARG_P32(uap, data), &ifreq, sizeof (ifreq)); \
653 1.2 mrg if (error) \
654 1.2 mrg return error; \
655 1.15.2.5 yamt if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), a, &ifreq, l)) != 0) \
656 1.2 mrg return error; \
657 1.15.2.3 yamt return copyout(&ifreq, SCARG_P32(uap, data), sizeof (ifreq)); \
658 1.2 mrg }
659 1.2 mrg
660 1.15.2.3 yamt case _IOW('i', 12, struct oifreq):
661 1.2 mrg /* SIOCSIFADDR */
662 1.2 mrg break;
663 1.2 mrg
664 1.15.2.3 yamt case _IOWR('i', 13, struct oifreq):
665 1.15.2.3 yamt IFREQ_INOUT(OOSIOCGIFADDR);
666 1.2 mrg
667 1.15.2.3 yamt case _IOW('i', 14, struct oifreq):
668 1.2 mrg /* SIOCSIFDSTADDR */
669 1.2 mrg break;
670 1.2 mrg
671 1.15.2.3 yamt case _IOWR('i', 15, struct oifreq):
672 1.15.2.3 yamt IFREQ_INOUT(OOSIOCGIFDSTADDR);
673 1.2 mrg
674 1.15.2.3 yamt case _IOW('i', 16, struct oifreq):
675 1.2 mrg /* SIOCSIFFLAGS */
676 1.2 mrg break;
677 1.2 mrg
678 1.15.2.3 yamt case _IOWR('i', 17, struct oifreq):
679 1.2 mrg /* SIOCGIFFLAGS */
680 1.2 mrg break;
681 1.2 mrg
682 1.15.2.3 yamt case _IOW('i', 21, struct oifreq):
683 1.2 mrg IFREQ_IN(SIOCSIFMTU);
684 1.2 mrg
685 1.15.2.3 yamt case _IOWR('i', 22, struct oifreq):
686 1.2 mrg IFREQ_INOUT(SIOCGIFMTU);
687 1.2 mrg
688 1.15.2.3 yamt case _IOWR('i', 23, struct oifreq):
689 1.2 mrg IFREQ_INOUT(SIOCGIFBRDADDR);
690 1.2 mrg
691 1.15.2.3 yamt case _IOW('i', 24, struct oifreq):
692 1.2 mrg IFREQ_IN(SIOCSIFBRDADDR);
693 1.2 mrg
694 1.15.2.3 yamt case _IOWR('i', 25, struct oifreq):
695 1.15.2.3 yamt IFREQ_INOUT(OOSIOCGIFNETMASK);
696 1.2 mrg
697 1.15.2.3 yamt case _IOW('i', 26, struct oifreq):
698 1.2 mrg IFREQ_IN(SIOCSIFNETMASK);
699 1.2 mrg
700 1.15.2.3 yamt case _IOWR('i', 27, struct oifreq):
701 1.2 mrg IFREQ_INOUT(SIOCGIFMETRIC);
702 1.2 mrg
703 1.15.2.3 yamt case _IOWR('i', 28, struct oifreq):
704 1.2 mrg IFREQ_IN(SIOCSIFMETRIC);
705 1.2 mrg
706 1.2 mrg case _IOW('i', 30, struct arpreq):
707 1.2 mrg /* SIOCSARP */
708 1.2 mrg break;
709 1.2 mrg
710 1.2 mrg case _IOWR('i', 31, struct arpreq):
711 1.2 mrg /* SIOCGARP */
712 1.2 mrg break;
713 1.2 mrg
714 1.2 mrg case _IOW('i', 32, struct arpreq):
715 1.2 mrg /* SIOCDARP */
716 1.2 mrg break;
717 1.2 mrg
718 1.15.2.3 yamt case _IOW('i', 18, struct oifreq): /* SIOCSIFMEM */
719 1.15.2.3 yamt case _IOWR('i', 19, struct oifreq): /* SIOCGIFMEM */
720 1.15.2.3 yamt case _IOW('i', 40, struct oifreq): /* SIOCUPPER */
721 1.15.2.3 yamt case _IOW('i', 41, struct oifreq): /* SIOCLOWER */
722 1.15.2.3 yamt case _IOW('i', 44, struct oifreq): /* SIOCSETSYNC */
723 1.15.2.3 yamt case _IOWR('i', 45, struct oifreq): /* SIOCGETSYNC */
724 1.15.2.3 yamt case _IOWR('i', 46, struct oifreq): /* SIOCSDSTATS */
725 1.15.2.3 yamt case _IOWR('i', 47, struct oifreq): /* SIOCSESTATS */
726 1.2 mrg case _IOW('i', 48, int): /* SIOCSPROMISC */
727 1.15.2.3 yamt case _IOW('i', 49, struct oifreq): /* SIOCADDMULTI */
728 1.15.2.3 yamt case _IOW('i', 50, struct oifreq): /* SIOCDELMULTI */
729 1.2 mrg return EOPNOTSUPP;
730 1.2 mrg
731 1.15.2.3 yamt case _IOWR('i', 20, struct oifconf): /* SIOCGIFCONF */
732 1.2 mrg {
733 1.15.2.3 yamt struct oifconf ifcf;
734 1.2 mrg
735 1.2 mrg /*
736 1.2 mrg * XXX: two more problems
737 1.2 mrg * 1. our sockaddr's are variable length, not always sizeof(sockaddr)
738 1.2 mrg * 2. this returns a name per protocol, ie. it returns two "lo0"'s
739 1.2 mrg */
740 1.15.2.3 yamt error = copyin(SCARG_P32(uap, data), &ifcf,
741 1.15 christos sizeof (ifcf));
742 1.2 mrg if (error)
743 1.2 mrg return error;
744 1.15.2.5 yamt error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), OOSIOCGIFCONF, &ifcf, l);
745 1.2 mrg if (error)
746 1.2 mrg return error;
747 1.15.2.3 yamt return copyout(&ifcf, SCARG_P32(uap, data),
748 1.15 christos sizeof (ifcf));
749 1.2 mrg }
750 1.2 mrg
751 1.2 mrg /*
752 1.2 mrg * Audio ioctl translations.
753 1.2 mrg */
754 1.2 mrg case _IOR('A', 1, struct sunos_audio_info): /* AUDIO_GETINFO */
755 1.2 mrg sunos_au_getinfo:
756 1.2 mrg {
757 1.2 mrg struct audio_info aui;
758 1.2 mrg struct sunos_audio_info sunos_aui;
759 1.2 mrg
760 1.15.2.5 yamt error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), AUDIO_GETINFO, &aui, l);
761 1.2 mrg if (error)
762 1.2 mrg return error;
763 1.2 mrg
764 1.2 mrg sunos_aui.play = *(struct sunos_audio_prinfo *)&aui.play;
765 1.2 mrg sunos_aui.record = *(struct sunos_audio_prinfo *)&aui.record;
766 1.2 mrg
767 1.2 mrg /* `avail_ports' is `seek' in BSD */
768 1.2 mrg sunos_aui.play.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE;
769 1.2 mrg sunos_aui.record.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE;
770 1.2 mrg
771 1.2 mrg sunos_aui.play.waiting = 0;
772 1.2 mrg sunos_aui.record.waiting = 0;
773 1.2 mrg sunos_aui.play.eof = 0;
774 1.2 mrg sunos_aui.record.eof = 0;
775 1.2 mrg sunos_aui.monitor_gain = 0; /* aui.__spare; XXX */
776 1.2 mrg /*XXXsunos_aui.output_muted = 0;*/
777 1.2 mrg /*XXX*/sunos_aui.reserved[0] = 0;
778 1.2 mrg /*XXX*/sunos_aui.reserved[1] = 0;
779 1.2 mrg /*XXX*/sunos_aui.reserved[2] = 0;
780 1.2 mrg /*XXX*/sunos_aui.reserved[3] = 0;
781 1.2 mrg
782 1.15.2.3 yamt return copyout(&sunos_aui, SCARG_P32(uap, data),
783 1.2 mrg sizeof (sunos_aui));
784 1.2 mrg }
785 1.2 mrg
786 1.2 mrg case _IOWR('A', 2, struct sunos_audio_info): /* AUDIO_SETINFO */
787 1.2 mrg {
788 1.2 mrg struct audio_info aui;
789 1.2 mrg struct sunos_audio_info sunos_aui;
790 1.2 mrg
791 1.15.2.3 yamt error = copyin(SCARG_P32(uap, data), &sunos_aui,
792 1.2 mrg sizeof (sunos_aui));
793 1.2 mrg if (error)
794 1.2 mrg return error;
795 1.2 mrg
796 1.2 mrg aui.play = *(struct audio_prinfo *)&sunos_aui.play;
797 1.2 mrg aui.record = *(struct audio_prinfo *)&sunos_aui.record;
798 1.2 mrg /* aui.__spare = sunos_aui.monitor_gain; */
799 1.2 mrg aui.blocksize = ~0;
800 1.2 mrg aui.hiwat = ~0;
801 1.2 mrg aui.lowat = ~0;
802 1.2 mrg /* XXX somebody check this please. - is: aui.backlog = ~0; */
803 1.2 mrg aui.mode = ~0;
804 1.2 mrg /*
805 1.2 mrg * The bsd driver does not distinguish between paused and
806 1.2 mrg * active. (In the sun driver, not active means samples are
807 1.9 wiz * not output at all, but paused means the last streams buffer
808 1.2 mrg * is drained and then output stops.) If either are 0, then
809 1.2 mrg * when stop output. Otherwise, if either are non-zero,
810 1.2 mrg * we resume.
811 1.2 mrg */
812 1.2 mrg if (sunos_aui.play.pause == 0 || sunos_aui.play.active == 0)
813 1.2 mrg aui.play.pause = 0;
814 1.2 mrg else if (sunos_aui.play.pause != (u_char)~0 ||
815 1.2 mrg sunos_aui.play.active != (u_char)~0)
816 1.2 mrg aui.play.pause = 1;
817 1.2 mrg if (sunos_aui.record.pause == 0 || sunos_aui.record.active == 0)
818 1.2 mrg aui.record.pause = 0;
819 1.2 mrg else if (sunos_aui.record.pause != (u_char)~0 ||
820 1.2 mrg sunos_aui.record.active != (u_char)~0)
821 1.2 mrg aui.record.pause = 1;
822 1.2 mrg
823 1.15.2.5 yamt error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), AUDIO_SETINFO, &aui, l);
824 1.2 mrg if (error)
825 1.2 mrg return error;
826 1.2 mrg /* Return new state */
827 1.2 mrg goto sunos_au_getinfo;
828 1.2 mrg }
829 1.2 mrg case _IO('A', 3): /* AUDIO_DRAIN */
830 1.15.2.5 yamt return sunos32_do_ioctl(SCARG(&bsd_ua, fd), AUDIO_DRAIN, NULL, l);
831 1.2 mrg case _IOR('A', 4, int): /* AUDIO_GETDEV */
832 1.2 mrg {
833 1.2 mrg int devtype = SUNOS_AUDIO_DEV_AMD;
834 1.15.2.3 yamt return copyout(&devtype, SCARG_P32(uap, data),
835 1.2 mrg sizeof (devtype));
836 1.2 mrg }
837 1.2 mrg
838 1.2 mrg /*
839 1.2 mrg * Selected streams ioctls.
840 1.2 mrg */
841 1.2 mrg #define SUNOS_S_FLUSHR 1
842 1.2 mrg #define SUNOS_S_FLUSHW 2
843 1.2 mrg #define SUNOS_S_FLUSHRW 3
844 1.2 mrg
845 1.2 mrg #define SUNOS_S_INPUT 1
846 1.2 mrg #define SUNOS_S_HIPRI 2
847 1.2 mrg #define SUNOS_S_OUTPUT 4
848 1.2 mrg #define SUNOS_S_MSG 8
849 1.2 mrg
850 1.2 mrg case _IO('S', 5): /* I_FLUSH */
851 1.2 mrg {
852 1.2 mrg int tmp = 0;
853 1.15.2.3 yamt switch ((intptr_t)SCARG_P32(uap, data)) {
854 1.2 mrg case SUNOS_S_FLUSHR: tmp = FREAD;
855 1.2 mrg case SUNOS_S_FLUSHW: tmp = FWRITE;
856 1.2 mrg case SUNOS_S_FLUSHRW: tmp = FREAD|FWRITE;
857 1.2 mrg }
858 1.15.2.5 yamt return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCFLUSH, &tmp, l);
859 1.2 mrg }
860 1.2 mrg case _IO('S', 9): /* I_SETSIG */
861 1.2 mrg {
862 1.2 mrg int on = 1;
863 1.15.2.3 yamt if (((intptr_t)SCARG_P32(uap, data) &
864 1.2 mrg (SUNOS_S_HIPRI|SUNOS_S_INPUT)) ==
865 1.2 mrg SUNOS_S_HIPRI)
866 1.2 mrg return EOPNOTSUPP;
867 1.15.2.5 yamt return sunos32_do_ioctl(SCARG(&bsd_ua, fd), FIOASYNC, &on, l);
868 1.2 mrg }
869 1.2 mrg /*
870 1.2 mrg * SunOS disk ioctls, taken from arch/sparc/sparc/disksubr.c
871 1.2 mrg * (which was from the old sparc/scsi/sun_disklabel.c), and
872 1.2 mrg * modified to suite.
873 1.2 mrg */
874 1.2 mrg case DKIOCGGEOM:
875 1.2 mrg {
876 1.2 mrg struct disklabel dl;
877 1.2 mrg
878 1.15.2.5 yamt error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), DIOCGDINFO, &dl, l);
879 1.2 mrg if (error)
880 1.2 mrg return (error);
881 1.2 mrg
882 1.15.2.3 yamt #define datageom ((struct sun_dkgeom *)SCARG_P32(uap, data))
883 1.11 dsl /* XXX can't do memset() on a user address (dsl) */
884 1.15.2.3 yamt memset(SCARG_P32(uap, data), 0, sizeof(*datageom));
885 1.2 mrg
886 1.2 mrg datageom->sdkc_ncylinders = dl.d_ncylinders;
887 1.2 mrg datageom->sdkc_acylinders = dl.d_acylinders;
888 1.2 mrg datageom->sdkc_ntracks = dl.d_ntracks;
889 1.2 mrg datageom->sdkc_nsectors = dl.d_nsectors;
890 1.2 mrg datageom->sdkc_interleave = dl.d_interleave;
891 1.2 mrg datageom->sdkc_sparespercyl = dl.d_sparespercyl;
892 1.2 mrg datageom->sdkc_rpm = dl.d_rpm;
893 1.2 mrg datageom->sdkc_pcylinders = dl.d_ncylinders + dl.d_acylinders;
894 1.2 mrg #undef datageom
895 1.2 mrg break;
896 1.2 mrg }
897 1.2 mrg
898 1.2 mrg case DKIOCINFO:
899 1.2 mrg /* Homey don't do DKIOCINFO */
900 1.11 dsl /* XXX can't do memset() on a user address (dsl) */
901 1.15.2.3 yamt memset(SCARG_P32(uap, data), 0, sizeof(struct sun_dkctlr));
902 1.2 mrg break;
903 1.2 mrg
904 1.2 mrg case DKIOCGPART:
905 1.2 mrg {
906 1.2 mrg struct partinfo pi;
907 1.2 mrg
908 1.15.2.5 yamt error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), DIOCGPART, &pi, l);
909 1.2 mrg if (error)
910 1.2 mrg return (error);
911 1.2 mrg
912 1.2 mrg if (pi.disklab->d_secpercyl == 0)
913 1.2 mrg return (ERANGE); /* XXX */
914 1.2 mrg if (pi.part->p_offset % pi.disklab->d_secpercyl != 0)
915 1.2 mrg return (ERANGE); /* XXX */
916 1.15.2.3 yamt /* XXX can't do direct writes to a user address (dsl) */
917 1.15.2.3 yamt #define datapart ((struct sun_dkpart *)SCARG_P32(uap, data))
918 1.2 mrg datapart->sdkp_cyloffset = pi.part->p_offset / pi.disklab->d_secpercyl;
919 1.2 mrg datapart->sdkp_nsectors = pi.part->p_size;
920 1.2 mrg #undef datapart
921 1.2 mrg }
922 1.2 mrg
923 1.2 mrg }
924 1.15.2.5 yamt return (netbsd32_ioctl(l, &bsd_ua, retval));
925 1.2 mrg }
926 1.2 mrg
927 1.2 mrg /* SunOS fcntl(2) cmds not implemented */
928 1.2 mrg #define SUN_F_RGETLK 10
929 1.2 mrg #define SUN_F_RSETLK 11
930 1.2 mrg #define SUN_F_CNVT 12
931 1.2 mrg #define SUN_F_RSETLKW 13
932 1.2 mrg
933 1.2 mrg /* SunOS flock translation */
934 1.2 mrg struct sunos_flock {
935 1.2 mrg short l_type;
936 1.2 mrg short l_whence;
937 1.3 mrg netbsd32_long l_start;
938 1.3 mrg netbsd32_long l_len;
939 1.2 mrg short l_pid;
940 1.2 mrg short l_xxx;
941 1.2 mrg };
942 1.2 mrg
943 1.15.2.4 yamt static void bsd_to_sunos_flock(struct flock *, struct sunos_flock *);
944 1.15.2.4 yamt static void sunos_to_bsd_flock(struct sunos_flock *, struct flock *);
945 1.2 mrg
946 1.2 mrg #define SUNOS_F_RDLCK 1
947 1.2 mrg #define SUNOS_F_WRLCK 2
948 1.2 mrg #define SUNOS_F_UNLCK 3
949 1.2 mrg
950 1.2 mrg static void
951 1.15.2.5 yamt bsd_to_sunos_flock(struct flock *iflp, struct sunos_flock *oflp)
952 1.2 mrg {
953 1.2 mrg switch (iflp->l_type) {
954 1.2 mrg case F_RDLCK:
955 1.2 mrg oflp->l_type = SUNOS_F_RDLCK;
956 1.2 mrg break;
957 1.2 mrg case F_WRLCK:
958 1.2 mrg oflp->l_type = SUNOS_F_WRLCK;
959 1.2 mrg break;
960 1.2 mrg case F_UNLCK:
961 1.2 mrg oflp->l_type = SUNOS_F_UNLCK;
962 1.2 mrg break;
963 1.2 mrg default:
964 1.2 mrg oflp->l_type = -1;
965 1.2 mrg break;
966 1.2 mrg }
967 1.2 mrg
968 1.2 mrg oflp->l_whence = (short) iflp->l_whence;
969 1.3 mrg oflp->l_start = (netbsd32_long) iflp->l_start;
970 1.3 mrg oflp->l_len = (netbsd32_long) iflp->l_len;
971 1.2 mrg oflp->l_pid = (short) iflp->l_pid;
972 1.2 mrg oflp->l_xxx = 0;
973 1.2 mrg }
974 1.2 mrg
975 1.2 mrg
976 1.2 mrg static void
977 1.15.2.5 yamt sunos_to_bsd_flock(struct sunos_flock *iflp, struct flock *oflp)
978 1.2 mrg {
979 1.2 mrg switch (iflp->l_type) {
980 1.2 mrg case SUNOS_F_RDLCK:
981 1.2 mrg oflp->l_type = F_RDLCK;
982 1.2 mrg break;
983 1.2 mrg case SUNOS_F_WRLCK:
984 1.2 mrg oflp->l_type = F_WRLCK;
985 1.2 mrg break;
986 1.2 mrg case SUNOS_F_UNLCK:
987 1.2 mrg oflp->l_type = F_UNLCK;
988 1.2 mrg break;
989 1.2 mrg default:
990 1.2 mrg oflp->l_type = -1;
991 1.2 mrg break;
992 1.2 mrg }
993 1.2 mrg
994 1.2 mrg oflp->l_whence = iflp->l_whence;
995 1.2 mrg oflp->l_start = (off_t) iflp->l_start;
996 1.2 mrg oflp->l_len = (off_t) iflp->l_len;
997 1.2 mrg oflp->l_pid = (pid_t) iflp->l_pid;
998 1.2 mrg
999 1.2 mrg }
1000 1.2 mrg static struct {
1001 1.3 mrg netbsd32_long sun_flg;
1002 1.3 mrg netbsd32_long bsd_flg;
1003 1.2 mrg } sunfcntl_flgtab[] = {
1004 1.2 mrg /* F_[GS]ETFLags that differ: */
1005 1.2 mrg #define SUN_FSETBLK 0x0010
1006 1.2 mrg #define SUN_SHLOCK 0x0080
1007 1.2 mrg #define SUN_EXLOCK 0x0100
1008 1.2 mrg #define SUN_FNBIO 0x1000
1009 1.2 mrg #define SUN_FSYNC 0x2000
1010 1.2 mrg #define SUN_NONBLOCK 0x4000
1011 1.2 mrg #define SUN_FNOCTTY 0x8000
1012 1.2 mrg { SUN_NONBLOCK, O_NONBLOCK },
1013 1.2 mrg { SUN_FNBIO, O_NONBLOCK },
1014 1.2 mrg { SUN_SHLOCK, O_SHLOCK },
1015 1.2 mrg { SUN_EXLOCK, O_EXLOCK },
1016 1.2 mrg { SUN_FSYNC, O_FSYNC },
1017 1.2 mrg { SUN_FSETBLK, 0 },
1018 1.2 mrg { SUN_FNOCTTY, 0 }
1019 1.2 mrg };
1020 1.2 mrg
1021 1.2 mrg int
1022 1.15.2.5 yamt sunos32_sys_fcntl(struct lwp *l, const struct sunos32_sys_fcntl_args *uap, register_t *retval)
1023 1.2 mrg {
1024 1.15.2.5 yamt /* {
1025 1.3 mrg syscallarg(int) fd;
1026 1.3 mrg syscallarg(int) cmd;
1027 1.3 mrg syscallarg(netbsd32_voidp) arg;
1028 1.15.2.5 yamt } */
1029 1.15.2.5 yamt struct sys_fcntl_args bsd_ua;
1030 1.15.2.3 yamt uintptr_t flg;
1031 1.2 mrg int n, ret;
1032 1.2 mrg
1033 1.15.2.5 yamt SCARG(&bsd_ua, fd) = SCARG(uap, fd);
1034 1.15.2.5 yamt SCARG(&bsd_ua, cmd) = SCARG(uap, cmd);
1035 1.15.2.5 yamt SCARG(&bsd_ua, arg) = SCARG_P32(uap, arg);
1036 1.15.2.5 yamt
1037 1.2 mrg switch (SCARG(uap, cmd)) {
1038 1.2 mrg case F_SETFL:
1039 1.15.2.3 yamt flg = (intptr_t)SCARG_P32(uap, arg);
1040 1.2 mrg n = sizeof(sunfcntl_flgtab) / sizeof(sunfcntl_flgtab[0]);
1041 1.2 mrg while (--n >= 0) {
1042 1.2 mrg if (flg & sunfcntl_flgtab[n].sun_flg) {
1043 1.2 mrg flg &= ~sunfcntl_flgtab[n].sun_flg;
1044 1.2 mrg flg |= sunfcntl_flgtab[n].bsd_flg;
1045 1.2 mrg }
1046 1.2 mrg }
1047 1.15.2.5 yamt SCARG(&bsd_ua, arg) = (void *)flg;
1048 1.2 mrg break;
1049 1.2 mrg
1050 1.2 mrg case F_GETLK:
1051 1.2 mrg case F_SETLK:
1052 1.2 mrg case F_SETLKW:
1053 1.2 mrg {
1054 1.2 mrg int error;
1055 1.15.2.3 yamt struct sunos_flock ifl;
1056 1.15.2.3 yamt struct flock fl;
1057 1.2 mrg
1058 1.15.2.3 yamt error = copyin(SCARG_P32(uap, arg), &ifl, sizeof ifl);
1059 1.2 mrg if (error)
1060 1.2 mrg return error;
1061 1.2 mrg sunos_to_bsd_flock(&ifl, &fl);
1062 1.2 mrg
1063 1.15.2.3 yamt error = do_fcntl_lock(l, SCARG(uap, fd), SCARG(uap, cmd), &fl);
1064 1.15.2.3 yamt if (error || SCARG(uap, cmd) != F_GETLK)
1065 1.2 mrg return error;
1066 1.2 mrg
1067 1.2 mrg bsd_to_sunos_flock(&fl, &ifl);
1068 1.15.2.3 yamt return copyout(&ifl, SCARG_P32(uap, arg), sizeof ifl);
1069 1.2 mrg }
1070 1.2 mrg break;
1071 1.2 mrg case SUN_F_RGETLK:
1072 1.2 mrg case SUN_F_RSETLK:
1073 1.2 mrg case SUN_F_CNVT:
1074 1.2 mrg case SUN_F_RSETLKW:
1075 1.2 mrg return (EOPNOTSUPP);
1076 1.2 mrg }
1077 1.2 mrg
1078 1.15.2.5 yamt ret = sys_fcntl(l, &bsd_ua, retval);
1079 1.15.2.5 yamt if (ret != 0)
1080 1.15.2.5 yamt return ret;
1081 1.2 mrg
1082 1.2 mrg switch (SCARG(uap, cmd)) {
1083 1.2 mrg case F_GETFL:
1084 1.2 mrg n = sizeof(sunfcntl_flgtab) / sizeof(sunfcntl_flgtab[0]);
1085 1.15.2.5 yamt ret = *retval;
1086 1.2 mrg while (--n >= 0) {
1087 1.2 mrg if (ret & sunfcntl_flgtab[n].bsd_flg) {
1088 1.2 mrg ret &= ~sunfcntl_flgtab[n].bsd_flg;
1089 1.2 mrg ret |= sunfcntl_flgtab[n].sun_flg;
1090 1.2 mrg }
1091 1.2 mrg }
1092 1.15.2.5 yamt *retval = ret;
1093 1.2 mrg break;
1094 1.2 mrg }
1095 1.1 mrg
1096 1.15.2.5 yamt return 0;
1097 1.2 mrg }
1098