1 /* $NetBSD: linux_termios.c,v 1.35 2008/04/28 20:23:44 martin Exp $ */
4 * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Frank van der Linden and Eric Haszlakiewicz.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: linux_termios.c,v 1.35 2008/04/28 20:23:44 martin Exp $");
35 #if defined(_KERNEL_OPT)
39 #include <sys/param.h>
41 #include <sys/systm.h>
43 #include <sys/filedesc.h>
44 #include <sys/ioctl.h>
45 #include <sys/mount.h>
46 #include <sys/termios.h>
47 #include <sys/kernel.h>
49 #include <sys/syscallargs.h>
51 #include <compat/linux/common/linux_types.h>
52 #include <compat/linux/common/linux_ioctl.h>
53 #include <compat/linux/common/linux_signal.h>
54 #include <compat/linux/common/linux_util.h>
55 #include <compat/linux/common/linux_termios.h>
56 #include <compat/linux/common/linux_ipc.h>
57 #include <compat/linux/common/linux_sem.h>
59 #include <compat/linux/linux_syscallargs.h>
62 #define DPRINTF(a) uprintf a
68 linux_ioctl_termios(struct lwp
*l
, const struct linux_sys_ioctl_args
*uap
, register_t
*retval
)
72 syscallarg(u_long) com;
73 syscallarg(void *) data;
77 struct linux_termio tmplt
;
78 struct linux_termios tmplts
;
79 struct termios tmpbts
;
81 struct sys_ioctl_args ia
;
84 int (*bsdioctl
)(file_t
*, u_long
, void *);
86 if ((fp
= fd_getfile(SCARG(uap
, fd
))) == NULL
)
89 if ((fp
->f_flag
& (FREAD
| FWRITE
)) == 0) {
94 bsdioctl
= fp
->f_ops
->fo_ioctl
;
95 com
= SCARG(uap
, com
);
100 error
= (*bsdioctl
)(fp
, TIOCGETA
, &tmpbts
);
103 bsd_termios_to_linux_termios(&tmpbts
, &tmplts
);
104 error
= copyout(&tmplts
, SCARG(uap
, data
), sizeof tmplts
);
110 * First fill in all fields, so that we keep the current
111 * values for fields that Linux doesn't know about.
113 error
= (*bsdioctl
)(fp
, TIOCGETA
, &tmpbts
);
116 error
= copyin(SCARG(uap
, data
), &tmplts
, sizeof tmplts
);
119 linux_termios_to_bsd_termios(&tmplts
, &tmpbts
);
131 error
= (*bsdioctl
)(fp
, com
, &tmpbts
);
134 error
= (*bsdioctl
)(fp
, TIOCGETA
, &tmpbts
);
137 bsd_termios_to_linux_termio(&tmpbts
, &tmplt
);
138 error
= copyout(&tmplt
, SCARG(uap
, data
), sizeof tmplt
);
144 * First fill in all fields, so that we keep the current
145 * values for fields that Linux doesn't know about.
147 error
= (*bsdioctl
)(fp
, TIOCGETA
, &tmpbts
);
150 error
= copyin(SCARG(uap
, data
), &tmplt
, sizeof tmplt
);
153 linux_termio_to_bsd_termios(&tmplt
, &tmpbts
);
165 error
= (*bsdioctl
)(fp
, com
, &tmpbts
);
168 switch((u_long
)SCARG(uap
, data
)) {
182 error
= (*bsdioctl
)(fp
, TIOCFLUSH
, &idat
);
185 error
= (*bsdioctl
)(fp
, TIOCGETD
, &idat
);
199 idat
= LINUX_N_STRIP
;
202 * Linux does not have the tablet line discipline.
206 idat
= -1; /* XXX What should this be? */
209 error
= copyout(&idat
, SCARG(uap
, data
), sizeof idat
);
212 error
= copyin(SCARG(uap
, data
), &idat
, sizeof idat
);
229 * We can't handle the mouse line discipline Linux has.
239 error
= (*bsdioctl
)(fp
, TIOCSETD
, &idat
);
241 case LINUX_TIOCLINUX
:
242 error
= copyin(SCARG(uap
, data
), &tioclinux
, sizeof tioclinux
);
246 case LINUX_TIOCLINUX_KERNMSG
:
248 * XXX needed to not fail for some things. Could
249 * try to use TIOCCONS, but the char argument
250 * specifies the VT #, not an fd.
254 case LINUX_TIOCLINUX_COPY
:
255 case LINUX_TIOCLINUX_PASTE
:
256 case LINUX_TIOCLINUX_UNBLANK
:
257 case LINUX_TIOCLINUX_LOADLUT
:
258 case LINUX_TIOCLINUX_READSHIFT
:
259 case LINUX_TIOCLINUX_READMOUSE
:
260 case LINUX_TIOCLINUX_VESABLANK
:
261 case LINUX_TIOCLINUX_CURCONS
: /* could use VT_GETACTIVE */
266 case LINUX_TIOCGWINSZ
:
267 SCARG(&ia
, com
) = TIOCGWINSZ
;
269 case LINUX_TIOCSWINSZ
:
270 SCARG(&ia
, com
) = TIOCSWINSZ
;
272 case LINUX_TIOCGPGRP
:
273 SCARG(&ia
, com
) = TIOCGPGRP
;
275 case LINUX_TIOCSPGRP
:
276 SCARG(&ia
, com
) = TIOCSPGRP
;
279 SCARG(&ia
, com
) = FIONREAD
;
282 SCARG(&ia
, com
) = FIONBIO
;
285 SCARG(&ia
, com
) = FIOASYNC
;
288 SCARG(&ia
, com
) = TIOCEXCL
;
291 SCARG(&ia
, com
) = TIOCNXCL
;
294 SCARG(&ia
, com
) = TIOCCONS
;
296 case LINUX_TIOCNOTTY
:
297 SCARG(&ia
, com
) = TIOCNOTTY
;
300 idat
= (u_long
)SCARG(uap
, data
);
302 SCARG(&ia
, com
) = TIOCDRAIN
;
304 if ((error
= (*bsdioctl
)(fp
, TIOCSBRK
, NULL
)) != 0)
306 error
= tsleep(&idat
, PZERO
| PCATCH
, "linux_tcsbrk", hz
/ 4);
307 if (error
== EINTR
|| error
== ERESTART
) {
308 (void)(*bsdioctl
)(fp
, TIOCCBRK
, NULL
);
311 error
= (*bsdioctl
)(fp
, TIOCCBRK
, NULL
);
316 SCARG(&ia
, com
) = TIOCMGET
;
319 SCARG(&ia
, com
) = TIOCMSET
;
322 SCARG(&ia
, com
) = TIOCMBIC
;
325 SCARG(&ia
, com
) = TIOCMBIS
;
327 #ifdef LINUX_TIOCGPTN
333 error
= (*bsdioctl
)(fp
, TIOCPTSNAME
, &ptm
);
336 error
= copyout(&ptm
.sfd
, SCARG(uap
, data
),
340 #endif /* NO_DEV_PTM */
341 #endif /* LINUX_TIOCGPTN */
342 #ifdef LINUX_TIOCSPTLCK
343 case LINUX_TIOCSPTLCK
:
344 fd_putfile(SCARG(uap
, fd
));
345 error
= copyin(SCARG(uap
, data
), &idat
, sizeof(idat
));
348 DPRINTF(("TIOCSPTLCK %d\n", idat
));
356 SCARG(&ia
, fd
) = SCARG(uap
, fd
);
357 SCARG(&ia
, data
) = SCARG(uap
, data
);
358 error
= sys_ioctl(curlwp
, &ia
, retval
);
360 fd_putfile(SCARG(uap
, fd
));