1 /* $NetBSD: sunos32_ioctl.c,v 1.28 2008/03/21 21:54:59 ad Exp $ */
2 /* from: NetBSD: sunos_ioctl.c,v 1.35 2001/02/03 22:20:02 mrg Exp */
5 * Copyright (c) 2001 Matthew R. Green
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * Copyright (c) 1993 Markus Wild.
32 * All rights reserved.
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions
37 * 1. Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 * 2. The name of the author may not be used to endorse or promote products
40 * derived from this software without specific prior written permission
42 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 * loosely from: Header: sunos_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp
56 #include <sys/cdefs.h>
57 __KERNEL_RCSID(0, "$NetBSD: sunos32_ioctl.c,v 1.28 2008/03/21 21:54:59 ad Exp $");
59 #if defined(_KERNEL_OPT)
60 #include "opt_compat_netbsd32.h"
61 #include "opt_execfmt.h"
64 #include <sys/param.h>
66 #include <sys/systm.h>
68 #include <sys/filedesc.h>
69 #include <sys/ioctl.h>
70 #include <sys/termios.h>
72 #include <sys/socket.h>
73 #include <sys/audioio.h>
74 #include <sys/vnode.h>
75 #include <sys/mount.h>
76 #include <sys/disklabel.h>
77 #include <sys/syscallargs.h>
79 #include <miscfs/specfs/specdev.h>
83 #include <dev/sun/disklabel.h>
85 #include <compat/sys/sockio.h>
87 #include <compat/sunos/sunos.h>
88 #include <compat/sunos/sunos_syscallargs.h>
89 #include <compat/netbsd32/netbsd32.h>
90 #include <compat/netbsd32/netbsd32_syscallargs.h>
91 #include <compat/sunos32/sunos32.h>
92 #include <compat/sunos32/sunos32_syscallargs.h>
93 #include <compat/common/compat_util.h>
97 * This file is something of a hodge-podge.
98 * Support gets added as things turn up....
101 static const struct speedtab sptab
[] = {
122 static const netbsd32_u_long s2btab
[] = {
141 static void stios2btios(struct sunos_termios
*, struct termios
*);
142 static void btios2stios(struct termios
*, struct sunos_termios
*);
143 static void stios2stio(struct sunos_termios
*, struct sunos_termio
*);
144 static void stio2stios(struct sunos_termio
*, struct sunos_termios
*);
147 * These two conversion functions have mostly been done
148 * with some perl cut&paste, then hand-edited to comment
149 * out what doesn't exist under NetBSD.
150 * A note from Markus's code:
151 * (l & BITMASK1) / BITMASK1 * BITMASK2 is translated
152 * optimally by gcc m68k, much better than any ?: stuff.
153 * Code may vary with different architectures of course.
155 * I don't know what optimizer you used, but seeing divu's and
156 * bfextu's in the m68k assembly output did not encourage me...
157 * as well, gcc on the sparc definitely generates much better
162 stios2btios(struct sunos_termios
*st
, struct termios
*bt
)
164 netbsd32_u_long l
, r
;
167 r
= ((l
& 0x00000001) ? IGNBRK
: 0);
168 r
|= ((l
& 0x00000002) ? BRKINT
: 0);
169 r
|= ((l
& 0x00000004) ? IGNPAR
: 0);
170 r
|= ((l
& 0x00000008) ? PARMRK
: 0);
171 r
|= ((l
& 0x00000010) ? INPCK
: 0);
172 r
|= ((l
& 0x00000020) ? ISTRIP
: 0);
173 r
|= ((l
& 0x00000040) ? INLCR
: 0);
174 r
|= ((l
& 0x00000080) ? IGNCR
: 0);
175 r
|= ((l
& 0x00000100) ? ICRNL
: 0);
176 /* ((l & 0x00000200) ? IUCLC : 0) */
177 r
|= ((l
& 0x00000400) ? IXON
: 0);
178 r
|= ((l
& 0x00000800) ? IXANY
: 0);
179 r
|= ((l
& 0x00001000) ? IXOFF
: 0);
180 r
|= ((l
& 0x00002000) ? IMAXBEL
: 0);
184 r
= ((l
& 0x00000001) ? OPOST
: 0);
185 /* ((l & 0x00000002) ? OLCUC : 0) */
186 r
|= ((l
& 0x00000004) ? ONLCR
: 0);
187 /* ((l & 0x00000008) ? OCRNL : 0) */
188 /* ((l & 0x00000010) ? ONOCR : 0) */
189 /* ((l & 0x00000020) ? ONLRET : 0) */
190 /* ((l & 0x00000040) ? OFILL : 0) */
191 /* ((l & 0x00000080) ? OFDEL : 0) */
192 /* ((l & 0x00000100) ? NLDLY : 0) */
193 /* ((l & 0x00000100) ? NL1 : 0) */
194 /* ((l & 0x00000600) ? CRDLY : 0) */
195 /* ((l & 0x00000200) ? CR1 : 0) */
196 /* ((l & 0x00000400) ? CR2 : 0) */
197 /* ((l & 0x00000600) ? CR3 : 0) */
198 /* ((l & 0x00001800) ? TABDLY : 0) */
199 /* ((l & 0x00000800) ? TAB1 : 0) */
200 /* ((l & 0x00001000) ? TAB2 : 0) */
201 r
|= ((l
& 0x00001800) ? OXTABS
: 0);
202 /* ((l & 0x00002000) ? BSDLY : 0) */
203 /* ((l & 0x00002000) ? BS1 : 0) */
204 /* ((l & 0x00004000) ? VTDLY : 0) */
205 /* ((l & 0x00004000) ? VT1 : 0) */
206 /* ((l & 0x00008000) ? FFDLY : 0) */
207 /* ((l & 0x00008000) ? FF1 : 0) */
208 /* ((l & 0x00010000) ? PAGEOUT : 0) */
209 /* ((l & 0x00020000) ? WRAP : 0) */
213 switch (l
& 0x00000030) {
227 r
|= ((l
& 0x00000040) ? CSTOPB
: 0);
228 r
|= ((l
& 0x00000080) ? CREAD
: 0);
229 r
|= ((l
& 0x00000100) ? PARENB
: 0);
230 r
|= ((l
& 0x00000200) ? PARODD
: 0);
231 r
|= ((l
& 0x00000400) ? HUPCL
: 0);
232 r
|= ((l
& 0x00000800) ? CLOCAL
: 0);
233 /* ((l & 0x00001000) ? LOBLK : 0) */
234 r
|= ((l
& 0x80000000) ? (CRTS_IFLOW
|CCTS_OFLOW
) : 0);
237 bt
->c_ispeed
= bt
->c_ospeed
= s2btab
[l
& 0x0000000f];
240 r
= ((l
& 0x00000001) ? ISIG
: 0);
241 r
|= ((l
& 0x00000002) ? ICANON
: 0);
242 /* ((l & 0x00000004) ? XCASE : 0) */
243 r
|= ((l
& 0x00000008) ? ECHO
: 0);
244 r
|= ((l
& 0x00000010) ? ECHOE
: 0);
245 r
|= ((l
& 0x00000020) ? ECHOK
: 0);
246 r
|= ((l
& 0x00000040) ? ECHONL
: 0);
247 r
|= ((l
& 0x00000080) ? NOFLSH
: 0);
248 r
|= ((l
& 0x00000100) ? TOSTOP
: 0);
249 r
|= ((l
& 0x00000200) ? ECHOCTL
: 0);
250 r
|= ((l
& 0x00000400) ? ECHOPRT
: 0);
251 r
|= ((l
& 0x00000800) ? ECHOKE
: 0);
252 /* ((l & 0x00001000) ? DEFECHO : 0) */
253 r
|= ((l
& 0x00002000) ? FLUSHO
: 0);
254 r
|= ((l
& 0x00004000) ? PENDIN
: 0);
257 bt
->c_cc
[VINTR
] = st
->c_cc
[0] ? st
->c_cc
[0] : _POSIX_VDISABLE
;
258 bt
->c_cc
[VQUIT
] = st
->c_cc
[1] ? st
->c_cc
[1] : _POSIX_VDISABLE
;
259 bt
->c_cc
[VERASE
] = st
->c_cc
[2] ? st
->c_cc
[2] : _POSIX_VDISABLE
;
260 bt
->c_cc
[VKILL
] = st
->c_cc
[3] ? st
->c_cc
[3] : _POSIX_VDISABLE
;
261 bt
->c_cc
[VEOF
] = st
->c_cc
[4] ? st
->c_cc
[4] : _POSIX_VDISABLE
;
262 bt
->c_cc
[VEOL
] = st
->c_cc
[5] ? st
->c_cc
[5] : _POSIX_VDISABLE
;
263 bt
->c_cc
[VEOL2
] = st
->c_cc
[6] ? st
->c_cc
[6] : _POSIX_VDISABLE
;
264 /* bt->c_cc[VSWTCH] = st->c_cc[7] ? st->c_cc[7] : _POSIX_VDISABLE; */
265 bt
->c_cc
[VSTART
] = st
->c_cc
[8] ? st
->c_cc
[8] : _POSIX_VDISABLE
;
266 bt
->c_cc
[VSTOP
] = st
->c_cc
[9] ? st
->c_cc
[9] : _POSIX_VDISABLE
;
267 bt
->c_cc
[VSUSP
] = st
->c_cc
[10] ? st
->c_cc
[10] : _POSIX_VDISABLE
;
268 bt
->c_cc
[VDSUSP
] = st
->c_cc
[11] ? st
->c_cc
[11] : _POSIX_VDISABLE
;
269 bt
->c_cc
[VREPRINT
] = st
->c_cc
[12] ? st
->c_cc
[12] : _POSIX_VDISABLE
;
270 bt
->c_cc
[VDISCARD
] = st
->c_cc
[13] ? st
->c_cc
[13] : _POSIX_VDISABLE
;
271 bt
->c_cc
[VWERASE
] = st
->c_cc
[14] ? st
->c_cc
[14] : _POSIX_VDISABLE
;
272 bt
->c_cc
[VLNEXT
] = st
->c_cc
[15] ? st
->c_cc
[15] : _POSIX_VDISABLE
;
273 bt
->c_cc
[VSTATUS
] = st
->c_cc
[16] ? st
->c_cc
[16] : _POSIX_VDISABLE
;
275 /* if `raw mode', create native VMIN/VTIME from SunOS VEOF/VEOL */
276 bt
->c_cc
[VMIN
] = (bt
->c_lflag
& ICANON
) ? 1 : bt
->c_cc
[VEOF
];
277 bt
->c_cc
[VTIME
] = (bt
->c_lflag
& ICANON
) ? 1 : bt
->c_cc
[VEOL
];
282 btios2stios(struct termios
*bt
, struct sunos_termios
*st
)
284 netbsd32_u_long l
, r
;
288 r
= ((l
& IGNBRK
) ? 0x00000001 : 0);
289 r
|= ((l
& BRKINT
) ? 0x00000002 : 0);
290 r
|= ((l
& IGNPAR
) ? 0x00000004 : 0);
291 r
|= ((l
& PARMRK
) ? 0x00000008 : 0);
292 r
|= ((l
& INPCK
) ? 0x00000010 : 0);
293 r
|= ((l
& ISTRIP
) ? 0x00000020 : 0);
294 r
|= ((l
& INLCR
) ? 0x00000040 : 0);
295 r
|= ((l
& IGNCR
) ? 0x00000080 : 0);
296 r
|= ((l
& ICRNL
) ? 0x00000100 : 0);
297 /* ((l & IUCLC) ? 0x00000200 : 0) */
298 r
|= ((l
& IXON
) ? 0x00000400 : 0);
299 r
|= ((l
& IXANY
) ? 0x00000800 : 0);
300 r
|= ((l
& IXOFF
) ? 0x00001000 : 0);
301 r
|= ((l
& IMAXBEL
) ? 0x00002000 : 0);
305 r
= ((l
& OPOST
) ? 0x00000001 : 0);
306 /* ((l & OLCUC) ? 0x00000002 : 0) */
307 r
|= ((l
& ONLCR
) ? 0x00000004 : 0);
308 /* ((l & OCRNL) ? 0x00000008 : 0) */
309 /* ((l & ONOCR) ? 0x00000010 : 0) */
310 /* ((l & ONLRET) ? 0x00000020 : 0) */
311 /* ((l & OFILL) ? 0x00000040 : 0) */
312 /* ((l & OFDEL) ? 0x00000080 : 0) */
313 /* ((l & NLDLY) ? 0x00000100 : 0) */
314 /* ((l & NL1) ? 0x00000100 : 0) */
315 /* ((l & CRDLY) ? 0x00000600 : 0) */
316 /* ((l & CR1) ? 0x00000200 : 0) */
317 /* ((l & CR2) ? 0x00000400 : 0) */
318 /* ((l & CR3) ? 0x00000600 : 0) */
319 /* ((l & TABDLY) ? 0x00001800 : 0) */
320 /* ((l & TAB1) ? 0x00000800 : 0) */
321 /* ((l & TAB2) ? 0x00001000 : 0) */
322 r
|= ((l
& OXTABS
) ? 0x00001800 : 0);
323 /* ((l & BSDLY) ? 0x00002000 : 0) */
324 /* ((l & BS1) ? 0x00002000 : 0) */
325 /* ((l & VTDLY) ? 0x00004000 : 0) */
326 /* ((l & VT1) ? 0x00004000 : 0) */
327 /* ((l & FFDLY) ? 0x00008000 : 0) */
328 /* ((l & FF1) ? 0x00008000 : 0) */
329 /* ((l & PAGEOUT) ? 0x00010000 : 0) */
330 /* ((l & WRAP) ? 0x00020000 : 0) */
348 r
|= ((l
& CSTOPB
) ? 0x00000040 : 0);
349 r
|= ((l
& CREAD
) ? 0x00000080 : 0);
350 r
|= ((l
& PARENB
) ? 0x00000100 : 0);
351 r
|= ((l
& PARODD
) ? 0x00000200 : 0);
352 r
|= ((l
& HUPCL
) ? 0x00000400 : 0);
353 r
|= ((l
& CLOCAL
) ? 0x00000800 : 0);
354 /* ((l & LOBLK) ? 0x00001000 : 0) */
355 r
|= ((l
& (CRTS_IFLOW
|CCTS_OFLOW
)) ? 0x80000000 : 0);
359 r
= ((l
& ISIG
) ? 0x00000001 : 0);
360 r
|= ((l
& ICANON
) ? 0x00000002 : 0);
361 /* ((l & XCASE) ? 0x00000004 : 0) */
362 r
|= ((l
& ECHO
) ? 0x00000008 : 0);
363 r
|= ((l
& ECHOE
) ? 0x00000010 : 0);
364 r
|= ((l
& ECHOK
) ? 0x00000020 : 0);
365 r
|= ((l
& ECHONL
) ? 0x00000040 : 0);
366 r
|= ((l
& NOFLSH
) ? 0x00000080 : 0);
367 r
|= ((l
& TOSTOP
) ? 0x00000100 : 0);
368 r
|= ((l
& ECHOCTL
) ? 0x00000200 : 0);
369 r
|= ((l
& ECHOPRT
) ? 0x00000400 : 0);
370 r
|= ((l
& ECHOKE
) ? 0x00000800 : 0);
371 /* ((l & DEFECHO) ? 0x00001000 : 0) */
372 r
|= ((l
& FLUSHO
) ? 0x00002000 : 0);
373 r
|= ((l
& PENDIN
) ? 0x00004000 : 0);
376 s
= ttspeedtab(bt
->c_ospeed
, sptab
);
380 st
->c_cc
[0] = bt
->c_cc
[VINTR
] != _POSIX_VDISABLE
? bt
->c_cc
[VINTR
]:0;
381 st
->c_cc
[1] = bt
->c_cc
[VQUIT
] != _POSIX_VDISABLE
? bt
->c_cc
[VQUIT
]:0;
382 st
->c_cc
[2] = bt
->c_cc
[VERASE
] != _POSIX_VDISABLE
? bt
->c_cc
[VERASE
]:0;
383 st
->c_cc
[3] = bt
->c_cc
[VKILL
] != _POSIX_VDISABLE
? bt
->c_cc
[VKILL
]:0;
384 st
->c_cc
[4] = bt
->c_cc
[VEOF
] != _POSIX_VDISABLE
? bt
->c_cc
[VEOF
]:0;
385 st
->c_cc
[5] = bt
->c_cc
[VEOL
] != _POSIX_VDISABLE
? bt
->c_cc
[VEOL
]:0;
386 st
->c_cc
[6] = bt
->c_cc
[VEOL2
] != _POSIX_VDISABLE
? bt
->c_cc
[VEOL2
]:0;
388 /* bt->c_cc[VSWTCH] != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */
389 st
->c_cc
[8] = bt
->c_cc
[VSTART
] != _POSIX_VDISABLE
? bt
->c_cc
[VSTART
]:0;
390 st
->c_cc
[9] = bt
->c_cc
[VSTOP
] != _POSIX_VDISABLE
? bt
->c_cc
[VSTOP
]:0;
391 st
->c_cc
[10]= bt
->c_cc
[VSUSP
] != _POSIX_VDISABLE
? bt
->c_cc
[VSUSP
]:0;
392 st
->c_cc
[11]= bt
->c_cc
[VDSUSP
] != _POSIX_VDISABLE
? bt
->c_cc
[VDSUSP
]:0;
393 st
->c_cc
[12]= bt
->c_cc
[VREPRINT
]!= _POSIX_VDISABLE
? bt
->c_cc
[VREPRINT
]:0;
394 st
->c_cc
[13]= bt
->c_cc
[VDISCARD
]!= _POSIX_VDISABLE
? bt
->c_cc
[VDISCARD
]:0;
395 st
->c_cc
[14]= bt
->c_cc
[VWERASE
] != _POSIX_VDISABLE
? bt
->c_cc
[VWERASE
]:0;
396 st
->c_cc
[15]= bt
->c_cc
[VLNEXT
] != _POSIX_VDISABLE
? bt
->c_cc
[VLNEXT
]:0;
397 st
->c_cc
[16]= bt
->c_cc
[VSTATUS
] != _POSIX_VDISABLE
? bt
->c_cc
[VSTATUS
]:0;
399 if (!(bt
->c_lflag
& ICANON
)) {
400 /* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */
401 st
->c_cc
[4] = bt
->c_cc
[VMIN
];
402 st
->c_cc
[5] = bt
->c_cc
[VTIME
];
409 stios2stio(struct sunos_termios
*ts
, struct sunos_termio
*t
)
411 t
->c_iflag
= ts
->c_iflag
;
412 t
->c_oflag
= ts
->c_oflag
;
413 t
->c_cflag
= ts
->c_cflag
;
414 t
->c_lflag
= ts
->c_lflag
;
415 t
->c_line
= ts
->c_line
;
416 memcpy(t
->c_cc
, ts
->c_cc
, 8);
420 stio2stios(struct sunos_termio
*t
, struct sunos_termios
*ts
)
422 ts
->c_iflag
= t
->c_iflag
;
423 ts
->c_oflag
= t
->c_oflag
;
424 ts
->c_cflag
= t
->c_cflag
;
425 ts
->c_lflag
= t
->c_lflag
;
426 ts
->c_line
= t
->c_line
;
427 memcpy(ts
->c_cc
, t
->c_cc
, 8); /* don't touch the upper fields! */
432 sunos32_do_ioctl(int fd
, int cmd
, void *arg
, struct lwp
*l
)
438 if ((fp
= fd_getfile(fd
)) == NULL
)
440 if ((fp
->f_flag
& (FREAD
|FWRITE
)) == 0) {
444 error
= fp
->f_ops
->fo_ioctl(fp
, cmd
, arg
);
445 if (error
== EIO
&& cmd
== TIOCGPGRP
) {
446 vp
= (struct vnode
*)fp
->f_data
;
447 if (vp
!= NULL
&& vp
->v_type
== VCHR
&& major(vp
->v_rdev
) == 21)
455 sunos32_sys_ioctl(struct lwp
*l
, const struct sunos32_sys_ioctl_args
*uap
, register_t
*retval
)
460 netbsd32_caddr_t data;
462 struct netbsd32_ioctl_args bsd_ua
;
465 SCARG(&bsd_ua
, fd
) = SCARG(uap
, fd
);
466 SCARG(&bsd_ua
, com
) = SCARG(uap
, com
);
467 SCARG(&bsd_ua
, data
) = SCARG(uap
, data
);
469 switch (SCARG(uap
, com
)) {
470 case _IOR('t', 0, int):
471 SCARG(&bsd_ua
, com
) = TIOCGETD
;
473 case _IOW('t', 1, int):
477 if ((error
= copyin(SCARG_P32(uap
, data
), &disc
,
481 /* map SunOS NTTYDISC into our termios discipline */
484 /* all other disciplines are not supported by NetBSD */
488 return sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), TIOCSETD
, &disc
, l
);
490 case _IOW('t', 101, int): /* sun SUNOS_TIOCSSOFTCAR */
494 return copyin(SCARG_P32(uap
, data
), &x
, sizeof x
);
496 case _IOR('t', 100, int): /* sun SUNOS_TIOCSSOFTCAR */
500 return copyout(&x
, SCARG_P32(uap
, data
), sizeof x
);
502 case _IO('t', 36): /* sun TIOCCONS, no parameters */
505 return sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), TIOCCONS
, &on
, l
);
507 case _IOW('t', 37, struct sunos_ttysize
):
510 struct sunos_ttysize ss
;
512 if ((error
= sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), TIOCGWINSZ
, &ws
, l
)) != 0)
515 if ((error
= copyin(SCARG_P32(uap
, data
), &ss
, sizeof (ss
))) != 0)
518 ws
.ws_row
= ss
.ts_row
;
519 ws
.ws_col
= ss
.ts_col
;
521 return (sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), TIOCSWINSZ
, &ws
, l
));
523 case _IOW('t', 38, struct sunos_ttysize
):
526 struct sunos_ttysize ss
;
528 if ((error
= sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), TIOCGWINSZ
, &ws
, l
)) != 0)
531 ss
.ts_row
= ws
.ws_row
;
532 ss
.ts_col
= ws
.ws_col
;
534 return copyout(&ss
, SCARG_P32(uap
, data
), sizeof (ss
));
536 case _IOW('t', 130, int): /* TIOCSETPGRP: posix variant */
537 SCARG(&bsd_ua
, com
) = TIOCSPGRP
;
539 case _IOR('t', 131, int): /* TIOCGETPGRP: posix variant */
542 * sigh, must do error translation on pty devices
543 * (see also kern/tty_pty.c)
546 error
= sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), TIOCGPGRP
, &pgrp
, l
);
549 return copyout(&pgrp
, SCARG_P32(uap
, data
), sizeof(pgrp
));
552 SCARG(&bsd_ua
, com
) = TIOCSCTTY
;
558 struct sunos_termios sts
;
559 struct sunos_termio st
;
561 if ((error
= sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), TIOCGETA
, &bts
, l
)) != 0)
564 btios2stios (&bts
, &sts
);
565 if (SCARG(uap
, com
) == SUNOS_TCGETA
) {
566 stios2stio (&sts
, &st
);
567 return copyout(&st
, SCARG_P32(uap
, data
),
570 return copyout(&sts
, SCARG_P32(uap
, data
),
579 struct sunos_termios sts
;
580 struct sunos_termio st
;
582 if ((error
= copyin(SCARG_P32(uap
, data
), &st
,
586 /* get full BSD termios so we don't lose information */
587 if ((error
= sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), TIOCGETA
, &bts
, l
)) != 0)
591 * convert to sun termios, copy in information from
592 * termio, and convert back, then set new values.
594 btios2stios(&bts
, &sts
);
595 stio2stios(&st
, &sts
);
596 stios2btios(&sts
, &bts
);
598 return sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), SCARG(uap
, com
) - SUNOS_TCSETA
+ TIOCSETA
,
606 struct sunos_termios sts
;
608 if ((error
= copyin(SCARG_P32(uap
, data
), &sts
,
611 stios2btios (&sts
, &bts
);
612 return sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), SCARG(uap
, com
) - SUNOS_TCSETS
+ TIOCSETA
,
616 * Pseudo-tty ioctl translations.
618 case _IOW('t', 32, int): { /* TIOCTCNTL */
621 error1
= copyin(SCARG_P32(uap
, data
), &on
, sizeof (on
));
624 return sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), TIOCUCNTL
, &on
, l
);
626 case _IOW('t', 33, int): { /* TIOCSIGNAL */
629 error1
= copyin(SCARG_P32(uap
, data
), &sig
, sizeof (sig
));
632 return sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), TIOCSIG
, &sig
, l
);
636 * Socket ioctl translations.
638 #define IFREQ_IN(a) { \
639 struct oifreq ifreq; \
640 error = copyin(SCARG_P32(uap, data), &ifreq, sizeof (ifreq)); \
643 return sunos32_do_ioctl(SCARG(&bsd_ua, fd), a, &ifreq, l); \
645 #define IFREQ_INOUT(a) { \
646 struct oifreq ifreq; \
647 error = copyin(SCARG_P32(uap, data), &ifreq, sizeof (ifreq)); \
650 if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), a, &ifreq, l)) != 0) \
652 return copyout(&ifreq, SCARG_P32(uap, data), sizeof (ifreq)); \
655 case _IOW('i', 12, struct oifreq
):
659 case _IOWR('i', 13, struct oifreq
):
660 IFREQ_INOUT(OOSIOCGIFADDR
);
662 case _IOW('i', 14, struct oifreq
):
666 case _IOWR('i', 15, struct oifreq
):
667 IFREQ_INOUT(OOSIOCGIFDSTADDR
);
669 case _IOW('i', 16, struct oifreq
):
673 case _IOWR('i', 17, struct oifreq
):
677 case _IOW('i', 21, struct oifreq
):
678 IFREQ_IN(SIOCSIFMTU
);
680 case _IOWR('i', 22, struct oifreq
):
681 IFREQ_INOUT(SIOCGIFMTU
);
683 case _IOWR('i', 23, struct oifreq
):
684 IFREQ_INOUT(SIOCGIFBRDADDR
);
686 case _IOW('i', 24, struct oifreq
):
687 IFREQ_IN(SIOCSIFBRDADDR
);
689 case _IOWR('i', 25, struct oifreq
):
690 IFREQ_INOUT(OOSIOCGIFNETMASK
);
692 case _IOW('i', 26, struct oifreq
):
693 IFREQ_IN(SIOCSIFNETMASK
);
695 case _IOWR('i', 27, struct oifreq
):
696 IFREQ_INOUT(SIOCGIFMETRIC
);
698 case _IOWR('i', 28, struct oifreq
):
699 IFREQ_IN(SIOCSIFMETRIC
);
701 case _IOW('i', 30, struct arpreq
):
705 case _IOWR('i', 31, struct arpreq
):
709 case _IOW('i', 32, struct arpreq
):
713 case _IOW('i', 18, struct oifreq
): /* SIOCSIFMEM */
714 case _IOWR('i', 19, struct oifreq
): /* SIOCGIFMEM */
715 case _IOW('i', 40, struct oifreq
): /* SIOCUPPER */
716 case _IOW('i', 41, struct oifreq
): /* SIOCLOWER */
717 case _IOW('i', 44, struct oifreq
): /* SIOCSETSYNC */
718 case _IOWR('i', 45, struct oifreq
): /* SIOCGETSYNC */
719 case _IOWR('i', 46, struct oifreq
): /* SIOCSDSTATS */
720 case _IOWR('i', 47, struct oifreq
): /* SIOCSESTATS */
721 case _IOW('i', 48, int): /* SIOCSPROMISC */
722 case _IOW('i', 49, struct oifreq
): /* SIOCADDMULTI */
723 case _IOW('i', 50, struct oifreq
): /* SIOCDELMULTI */
726 case _IOWR('i', 20, struct oifconf
): /* SIOCGIFCONF */
731 * XXX: two more problems
732 * 1. our sockaddr's are variable length, not always sizeof(sockaddr)
733 * 2. this returns a name per protocol, ie. it returns two "lo0"'s
735 error
= copyin(SCARG_P32(uap
, data
), &ifcf
,
739 error
= sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), OOSIOCGIFCONF
, &ifcf
, l
);
742 return copyout(&ifcf
, SCARG_P32(uap
, data
),
747 * Audio ioctl translations.
749 case _IOR('A', 1, struct sunos_audio_info
): /* AUDIO_GETINFO */
752 struct audio_info aui
;
753 struct sunos_audio_info sunos_aui
;
755 error
= sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), AUDIO_GETINFO
, &aui
, l
);
759 sunos_aui
.play
= *(struct sunos_audio_prinfo
*)&aui
.play
;
760 sunos_aui
.record
= *(struct sunos_audio_prinfo
*)&aui
.record
;
762 /* `avail_ports' is `seek' in BSD */
763 sunos_aui
.play
.avail_ports
= AUDIO_SPEAKER
| AUDIO_HEADPHONE
;
764 sunos_aui
.record
.avail_ports
= AUDIO_SPEAKER
| AUDIO_HEADPHONE
;
766 sunos_aui
.play
.waiting
= 0;
767 sunos_aui
.record
.waiting
= 0;
768 sunos_aui
.play
.eof
= 0;
769 sunos_aui
.record
.eof
= 0;
770 sunos_aui
.monitor_gain
= 0; /* aui.__spare; XXX */
771 /*XXXsunos_aui.output_muted = 0;*/
772 /*XXX*/sunos_aui
.reserved
[0] = 0;
773 /*XXX*/sunos_aui
.reserved
[1] = 0;
774 /*XXX*/sunos_aui
.reserved
[2] = 0;
775 /*XXX*/sunos_aui
.reserved
[3] = 0;
777 return copyout(&sunos_aui
, SCARG_P32(uap
, data
),
781 case _IOWR('A', 2, struct sunos_audio_info
): /* AUDIO_SETINFO */
783 struct audio_info aui
;
784 struct sunos_audio_info sunos_aui
;
786 error
= copyin(SCARG_P32(uap
, data
), &sunos_aui
,
791 aui
.play
= *(struct audio_prinfo
*)&sunos_aui
.play
;
792 aui
.record
= *(struct audio_prinfo
*)&sunos_aui
.record
;
793 /* aui.__spare = sunos_aui.monitor_gain; */
797 /* XXX somebody check this please. - is: aui.backlog = ~0; */
800 * The bsd driver does not distinguish between paused and
801 * active. (In the sun driver, not active means samples are
802 * not output at all, but paused means the last streams buffer
803 * is drained and then output stops.) If either are 0, then
804 * when stop output. Otherwise, if either are non-zero,
807 if (sunos_aui
.play
.pause
== 0 || sunos_aui
.play
.active
== 0)
809 else if (sunos_aui
.play
.pause
!= (u_char
)~0 ||
810 sunos_aui
.play
.active
!= (u_char
)~0)
812 if (sunos_aui
.record
.pause
== 0 || sunos_aui
.record
.active
== 0)
813 aui
.record
.pause
= 0;
814 else if (sunos_aui
.record
.pause
!= (u_char
)~0 ||
815 sunos_aui
.record
.active
!= (u_char
)~0)
816 aui
.record
.pause
= 1;
818 error
= sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), AUDIO_SETINFO
, &aui
, l
);
821 /* Return new state */
822 goto sunos_au_getinfo
;
824 case _IO('A', 3): /* AUDIO_DRAIN */
825 return sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), AUDIO_DRAIN
, NULL
, l
);
826 case _IOR('A', 4, int): /* AUDIO_GETDEV */
828 int devtype
= SUNOS_AUDIO_DEV_AMD
;
829 return copyout(&devtype
, SCARG_P32(uap
, data
),
834 * Selected streams ioctls.
836 #define SUNOS_S_FLUSHR 1
837 #define SUNOS_S_FLUSHW 2
838 #define SUNOS_S_FLUSHRW 3
840 #define SUNOS_S_INPUT 1
841 #define SUNOS_S_HIPRI 2
842 #define SUNOS_S_OUTPUT 4
843 #define SUNOS_S_MSG 8
845 case _IO('S', 5): /* I_FLUSH */
848 switch ((intptr_t)SCARG_P32(uap
, data
)) {
849 case SUNOS_S_FLUSHR
: tmp
= FREAD
;
850 case SUNOS_S_FLUSHW
: tmp
= FWRITE
;
851 case SUNOS_S_FLUSHRW
: tmp
= FREAD
|FWRITE
;
853 return sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), TIOCFLUSH
, &tmp
, l
);
855 case _IO('S', 9): /* I_SETSIG */
858 if (((intptr_t)SCARG_P32(uap
, data
) &
859 (SUNOS_S_HIPRI
|SUNOS_S_INPUT
)) ==
862 return sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), FIOASYNC
, &on
, l
);
865 * SunOS disk ioctls, taken from arch/sparc/sparc/disksubr.c
866 * (which was from the old sparc/scsi/sun_disklabel.c), and
873 error
= sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), DIOCGDINFO
, &dl
, l
);
877 #define datageom ((struct sun_dkgeom *)SCARG_P32(uap, data))
878 /* XXX can't do memset() on a user address (dsl) */
879 memset(SCARG_P32(uap
, data
), 0, sizeof(*datageom
));
881 datageom
->sdkc_ncylinders
= dl
.d_ncylinders
;
882 datageom
->sdkc_acylinders
= dl
.d_acylinders
;
883 datageom
->sdkc_ntracks
= dl
.d_ntracks
;
884 datageom
->sdkc_nsectors
= dl
.d_nsectors
;
885 datageom
->sdkc_interleave
= dl
.d_interleave
;
886 datageom
->sdkc_sparespercyl
= dl
.d_sparespercyl
;
887 datageom
->sdkc_rpm
= dl
.d_rpm
;
888 datageom
->sdkc_pcylinders
= dl
.d_ncylinders
+ dl
.d_acylinders
;
894 /* Homey don't do DKIOCINFO */
895 /* XXX can't do memset() on a user address (dsl) */
896 memset(SCARG_P32(uap
, data
), 0, sizeof(struct sun_dkctlr
));
903 error
= sunos32_do_ioctl(SCARG(&bsd_ua
, fd
), DIOCGPART
, &pi
, l
);
907 if (pi
.disklab
->d_secpercyl
== 0)
908 return (ERANGE
); /* XXX */
909 if (pi
.part
->p_offset
% pi
.disklab
->d_secpercyl
!= 0)
910 return (ERANGE
); /* XXX */
911 /* XXX can't do direct writes to a user address (dsl) */
912 #define datapart ((struct sun_dkpart *)SCARG_P32(uap, data))
913 datapart
->sdkp_cyloffset
= pi
.part
->p_offset
/ pi
.disklab
->d_secpercyl
;
914 datapart
->sdkp_nsectors
= pi
.part
->p_size
;
919 return (netbsd32_ioctl(l
, &bsd_ua
, retval
));
922 /* SunOS fcntl(2) cmds not implemented */
923 #define SUN_F_RGETLK 10
924 #define SUN_F_RSETLK 11
925 #define SUN_F_CNVT 12
926 #define SUN_F_RSETLKW 13
928 /* SunOS flock translation */
932 netbsd32_long l_start
;
938 static void bsd_to_sunos_flock(struct flock
*, struct sunos_flock
*);
939 static void sunos_to_bsd_flock(struct sunos_flock
*, struct flock
*);
941 #define SUNOS_F_RDLCK 1
942 #define SUNOS_F_WRLCK 2
943 #define SUNOS_F_UNLCK 3
946 bsd_to_sunos_flock(struct flock
*iflp
, struct sunos_flock
*oflp
)
948 switch (iflp
->l_type
) {
950 oflp
->l_type
= SUNOS_F_RDLCK
;
953 oflp
->l_type
= SUNOS_F_WRLCK
;
956 oflp
->l_type
= SUNOS_F_UNLCK
;
963 oflp
->l_whence
= (short) iflp
->l_whence
;
964 oflp
->l_start
= (netbsd32_long
) iflp
->l_start
;
965 oflp
->l_len
= (netbsd32_long
) iflp
->l_len
;
966 oflp
->l_pid
= (short) iflp
->l_pid
;
972 sunos_to_bsd_flock(struct sunos_flock
*iflp
, struct flock
*oflp
)
974 switch (iflp
->l_type
) {
976 oflp
->l_type
= F_RDLCK
;
979 oflp
->l_type
= F_WRLCK
;
982 oflp
->l_type
= F_UNLCK
;
989 oflp
->l_whence
= iflp
->l_whence
;
990 oflp
->l_start
= (off_t
) iflp
->l_start
;
991 oflp
->l_len
= (off_t
) iflp
->l_len
;
992 oflp
->l_pid
= (pid_t
) iflp
->l_pid
;
996 netbsd32_long sun_flg
;
997 netbsd32_long bsd_flg
;
998 } sunfcntl_flgtab
[] = {
999 /* F_[GS]ETFLags that differ: */
1000 #define SUN_FSETBLK 0x0010
1001 #define SUN_SHLOCK 0x0080
1002 #define SUN_EXLOCK 0x0100
1003 #define SUN_FNBIO 0x1000
1004 #define SUN_FSYNC 0x2000
1005 #define SUN_NONBLOCK 0x4000
1006 #define SUN_FNOCTTY 0x8000
1007 { SUN_NONBLOCK
, O_NONBLOCK
},
1008 { SUN_FNBIO
, O_NONBLOCK
},
1009 { SUN_SHLOCK
, O_SHLOCK
},
1010 { SUN_EXLOCK
, O_EXLOCK
},
1011 { SUN_FSYNC
, O_FSYNC
},
1017 sunos32_sys_fcntl(struct lwp
*l
, const struct sunos32_sys_fcntl_args
*uap
, register_t
*retval
)
1021 syscallarg(int) cmd;
1022 syscallarg(netbsd32_voidp) arg;
1024 struct sys_fcntl_args bsd_ua
;
1028 SCARG(&bsd_ua
, fd
) = SCARG(uap
, fd
);
1029 SCARG(&bsd_ua
, cmd
) = SCARG(uap
, cmd
);
1030 SCARG(&bsd_ua
, arg
) = SCARG_P32(uap
, arg
);
1032 switch (SCARG(uap
, cmd
)) {
1034 flg
= (intptr_t)SCARG_P32(uap
, arg
);
1035 n
= sizeof(sunfcntl_flgtab
) / sizeof(sunfcntl_flgtab
[0]);
1037 if (flg
& sunfcntl_flgtab
[n
].sun_flg
) {
1038 flg
&= ~sunfcntl_flgtab
[n
].sun_flg
;
1039 flg
|= sunfcntl_flgtab
[n
].bsd_flg
;
1042 SCARG(&bsd_ua
, arg
) = (void *)flg
;
1050 struct sunos_flock ifl
;
1053 error
= copyin(SCARG_P32(uap
, arg
), &ifl
, sizeof ifl
);
1056 sunos_to_bsd_flock(&ifl
, &fl
);
1058 error
= do_fcntl_lock(SCARG(uap
, fd
), SCARG(uap
, cmd
), &fl
);
1059 if (error
|| SCARG(uap
, cmd
) != F_GETLK
)
1062 bsd_to_sunos_flock(&fl
, &ifl
);
1063 return copyout(&ifl
, SCARG_P32(uap
, arg
), sizeof ifl
);
1070 return (EOPNOTSUPP
);
1073 ret
= sys_fcntl(l
, &bsd_ua
, retval
);
1077 switch (SCARG(uap
, cmd
)) {
1079 n
= sizeof(sunfcntl_flgtab
) / sizeof(sunfcntl_flgtab
[0]);
1082 if (ret
& sunfcntl_flgtab
[n
].bsd_flg
) {
1083 ret
&= ~sunfcntl_flgtab
[n
].bsd_flg
;
1084 ret
|= sunfcntl_flgtab
[n
].sun_flg
;