xref: /netbsd-src/sys/compat/linux/common/linux_termios.h (revision d48f14661dda8638fee055ba15d35bdfb29b9fa8)
1 /*	$NetBSD: linux_termios.h,v 1.15 2006/02/15 09:31:17 manu Exp $	*/
2 
3 /*-
4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Eric Haszlakiewicz.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
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.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the NetBSD
21  *	Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #ifndef _LINUX_TERMIOS_H
40 #define _LINUX_TERMIOS_H
41 
42 #if defined(__i386__)
43 #include <compat/linux/arch/i386/linux_termios.h>
44 #elif defined(__m68k__)
45 #include <compat/linux/arch/m68k/linux_termios.h>
46 #elif defined(__alpha__)
47 #include <compat/linux/arch/alpha/linux_termios.h>
48 #elif defined(__powerpc__)
49 #include <compat/linux/arch/powerpc/linux_termios.h>
50 #elif defined(__mips__)
51 #include <compat/linux/arch/mips/linux_termios.h>
52 #elif defined(__arm__)
53 #include <compat/linux/arch/arm/linux_termios.h>
54 #elif defined(__amd64__)
55 #include <compat/linux/arch/amd64/linux_termios.h>
56 #else
57 #error Undefined linux_termios.h machine type.
58 #endif
59 
60 struct linux_winsize {
61 	unsigned short ws_row;
62 	unsigned short ws_col;
63 	unsigned short ws_xpixel;
64 	unsigned short ws_ypixel;
65 };
66 
67 /*
68  * LINUX_NCC is architecture dependent. It is now
69  * defined in sys/compat/linux/<arch>/linux_termios.h
70  */
71 struct linux_termio {
72 	unsigned short c_iflag;
73 	unsigned short c_oflag;
74 	unsigned short c_cflag;
75 	unsigned short c_lflag;
76 	unsigned char c_line;
77 	unsigned char c_cc[LINUX_NCC];
78 };
79 
80 struct linux_termios {
81 	linux_tcflag_t	c_iflag;
82 	linux_tcflag_t	c_oflag;
83 	linux_tcflag_t	c_cflag;
84 	linux_tcflag_t	c_lflag;
85 	linux_cc_t	c_line;
86 	linux_cc_t	c_cc[LINUX_NCCS];
87 #ifdef LINUX_LARGE_STRUCT_TERMIOS
88 	/*
89     * Present on some linux ports but unused:
90 	 * However we must enable it, else it breaks ioctl
91 	 * definitions (the size does not match anymore)
92     */
93 	linux_speed_t	c_ispeed;
94 	linux_speed_t	c_ospeed;
95 #endif
96 };
97 
98 /* Linux modem line defines.. not sure if they'll be used */
99 #define LINUX_TIOCM_LE		0x0001
100 #define LINUX_TIOCM_DTR		0x0002
101 #define LINUX_TIOCM_RTS		0x0004
102 #define LINUX_TIOCM_ST		0x0008
103 #define LINUX_TIOCM_SR		0x0010
104 #define LINUX_TIOCM_CTS		0x0020
105 #define LINUX_TIOCM_CAR		0x0040
106 #define LINUX_TIOCM_RNG		0x0080
107 #define LINUX_TIOCM_DSR		0x0100
108 #define LINUX_TIOCM_CD		LINUX_TIOCM_CAR
109 #define LINUX_TIOCM_RI 		LINUX_TIOCM_RNG
110 
111 #define	LINUX_TCIFLUSH		0
112 #define	LINUX_TCOFLUSH		1
113 #define	LINUX_TCIOFLUSH		2
114 
115 #define	LINUX_TCOOFF		0
116 #define	LINUX_TCOON		1
117 #define	LINUX_TCIOFF		2
118 #define	LINUX_TCION		3
119 
120 #define	LINUX_TCSANOW		0
121 #define	LINUX_TCSADRAIN		1
122 #define	LINUX_TCSAFLUSH		2
123 
124 /* Linux line disciplines */
125 #define LINUX_N_TTY		0
126 #define LINUX_N_SLIP		1
127 #define LINUX_N_MOUSE		2
128 #define LINUX_N_PPP		3
129 #define	LINUX_N_STRIP		4
130 
131 /* currently unused: */
132 #define	LINUX_N_AX25		5
133 #define	LINUX_N_X25		6
134 #define	LINUX_N_6PACK		7
135 
136 /* values passed to TIOCLINUX ioctl */
137 #define LINUX_TIOCLINUX_COPY		 2
138 #define LINUX_TIOCLINUX_PASTE		 3
139 #define LINUX_TIOCLINUX_UNBLANK		 4
140 #define LINUX_TIOCLINUX_LOADLUT		 5
141 #define LINUX_TIOCLINUX_READSHIFT	 6
142 #define LINUX_TIOCLINUX_READMOUSE	 7
143 #define LINUX_TIOCLINUX_VESABLANK	10
144 #define LINUX_TIOCLINUX_KERNMSG		11
145 #define LINUX_TIOCLINUX_CURCONS		12
146 
147 static speed_t linux_speeds[] = {
148 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
149 	9600, 19200, 38400, 57600, 115200, 230400
150 };
151 
152 static const int linux_spmasks[] = {
153 	LINUX_B0, LINUX_B50, LINUX_B75, LINUX_B110, LINUX_B134, LINUX_B150,
154 	LINUX_B200, LINUX_B300, LINUX_B600, LINUX_B1200, LINUX_B1800,
155 	LINUX_B2400, LINUX_B4800, LINUX_B9600, LINUX_B19200, LINUX_B38400,
156 	LINUX_B57600, LINUX_B115200, LINUX_B230400
157 };
158 
159 #ifdef COMPAT_LINUX32
160 struct linux32_termio;
161 struct linux32_termios;
162 static void linux32_termio_to_bsd_termios __P((struct linux32_termio *,
163 					     struct termios *));
164 static void bsd_termios_to_linux32_termio __P((struct termios *,
165 					     struct linux32_termio *));
166 static void linux32_termios_to_bsd_termios __P((struct linux32_termios *,
167 					      struct termios *));
168 static void bsd_termios_to_linux32_termios __P((struct termios *,
169 					      struct linux32_termios *));
170 #else
171 struct linux_termio;
172 struct linux_termios;
173 static void linux_termio_to_bsd_termios __P((struct linux_termio *,
174 					     struct termios *));
175 static void bsd_termios_to_linux_termio __P((struct termios *,
176 					     struct linux_termio *));
177 static void linux_termios_to_bsd_termios __P((struct linux_termios *,
178 					      struct termios *));
179 static void bsd_termios_to_linux_termios __P((struct termios *,
180 					      struct linux_termios *));
181 #endif
182 
183 /*
184  * Deal with termio ioctl cruft. This doesn't look very good..
185  * XXX too much code duplication, obviously..
186  *
187  * The conversion routines between Linux and BSD structures assume
188  * that the fields are already filled with the current values,
189  * so that fields present in BSD but not in Linux keep their current
190  * values.
191  */
192 
193 static void
194 #ifdef COMPAT_LINUX32
195 linux32_termio_to_bsd_termios(lt, bts)
196 	struct linux32_termio *lt;
197 	struct termios *bts;
198 #else
199 linux_termio_to_bsd_termios(lt, bts)
200 	struct linux_termio *lt;
201 	struct termios *bts;
202 #endif
203 {
204 	int index;
205 
206 	bts->c_iflag = 0;
207 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNBRK, IGNBRK);
208 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_BRKINT, BRKINT);
209 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNPAR, IGNPAR);
210 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_INPCK, INPCK);
211 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_ISTRIP, ISTRIP);
212 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_INLCR, INLCR);
213 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNCR, IGNCR);
214 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_ICRNL, ICRNL);
215 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXON, IXON);
216 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXANY, IXANY);
217 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXOFF, IXOFF);
218 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IMAXBEL, IMAXBEL);
219 
220 	bts->c_oflag = 0;
221 	bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_OPOST, OPOST);
222 	bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_ONLCR, ONLCR);
223 	bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_XTABS, OXTABS);
224 
225 	/*
226 	 * This could have been:
227 	 * bts->c_cflag = (lt->c_flag & LINUX_CSIZE) << 4
228 	 * But who knows, those values might perhaps change one day.
229 	 */
230 	switch (lt->c_cflag & LINUX_CSIZE) {
231 	case LINUX_CS5:
232 		bts->c_cflag = CS5;
233 		break;
234 	case LINUX_CS6:
235 		bts->c_cflag = CS6;
236 		break;
237 	case LINUX_CS7:
238 		bts->c_cflag = CS7;
239 		break;
240 	case LINUX_CS8:
241 		bts->c_cflag = CS8;
242 		break;
243 	}
244 	bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CSTOPB, CSTOPB);
245 	bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CREAD, CREAD);
246 	bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_PARENB, PARENB);
247 	bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_PARODD, PARODD);
248 	bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_HUPCL, HUPCL);
249 	bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CLOCAL, CLOCAL);
250 	bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CRTSCTS, CRTSCTS);
251 
252 	bts->c_lflag = 0;
253 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ISIG, ISIG);
254 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ICANON, ICANON);
255 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHO, ECHO);
256 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOE, ECHOE);
257 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOK, ECHOK);
258 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHONL, ECHONL);
259 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_NOFLSH, NOFLSH);
260 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_TOSTOP, TOSTOP);
261 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOCTL, ECHOCTL);
262 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOPRT, ECHOPRT);
263 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOKE, ECHOKE);
264 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_FLUSHO, FLUSHO);
265 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_PENDIN, PENDIN);
266 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_IEXTEN, IEXTEN);
267 
268 	index = lt->c_cflag & LINUX_CBAUD;
269 	if (index & LINUX_CBAUDEX)
270 		index = (index & ~LINUX_CBAUDEX) + LINUX_NSPEEDS - 1;
271 	bts->c_ispeed = bts->c_ospeed = linux_speeds[index];
272 
273 	bts->c_cc[VINTR] = lt->c_cc[LINUX_OLD_VINTR];
274 	bts->c_cc[VQUIT] = lt->c_cc[LINUX_OLD_VQUIT];
275 	bts->c_cc[VERASE] = lt->c_cc[LINUX_OLD_VERASE];
276 	bts->c_cc[VKILL] = lt->c_cc[LINUX_OLD_VKILL];
277 	bts->c_cc[VEOF] = lt->c_cc[LINUX_OLD_VEOF];
278 	bts->c_cc[VTIME] = lt->c_cc[LINUX_OLD_VTIME];
279 	bts->c_cc[VMIN] = lt->c_cc[LINUX_OLD_VMIN];
280 }
281 
282 static void
283 #ifdef COMPAT_LINUX32
284 bsd_termios_to_linux32_termio(bts, lt)
285 	struct termios *bts;
286 	struct linux32_termio *lt;
287 #else
288 bsd_termios_to_linux_termio(bts, lt)
289 	struct termios *bts;
290 	struct linux_termio *lt;
291 #endif
292 {
293 	int i, mask;
294 
295 	lt->c_iflag = 0;
296 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNBRK, LINUX_IGNBRK);
297 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, BRKINT, LINUX_BRKINT);
298 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNPAR, LINUX_IGNPAR);
299 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, INPCK, LINUX_INPCK);
300 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, ISTRIP, LINUX_ISTRIP);
301 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, INLCR, LINUX_INLCR);
302 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNCR, LINUX_IGNCR);
303 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, ICRNL, LINUX_ICRNL);
304 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXON, LINUX_IXON);
305 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXANY, LINUX_IXANY);
306 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXOFF, LINUX_IXOFF);
307 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IMAXBEL, LINUX_IMAXBEL);
308 
309 	lt->c_oflag = 0;
310 	lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, OPOST, LINUX_OPOST);
311 	lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, ONLCR, LINUX_ONLCR);
312 	lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, OXTABS, LINUX_XTABS);
313 
314 	switch (bts->c_cflag & CSIZE) {
315 	case CS5:
316 		lt->c_cflag = LINUX_CS5;
317 		break;
318 	case CS6:
319 		lt->c_cflag = LINUX_CS6;
320 		break;
321 	case CS7:
322 		lt->c_cflag = LINUX_CS7;
323 		break;
324 	case CS8:
325 		lt->c_cflag = LINUX_CS8;
326 		break;
327 	}
328 	lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CSTOPB, LINUX_CSTOPB);
329 	lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CREAD, LINUX_CREAD);
330 	lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARENB, LINUX_PARENB);
331 	lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARODD, LINUX_PARODD);
332 	lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, HUPCL, LINUX_HUPCL);
333 	lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CLOCAL, LINUX_CLOCAL);
334 	lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CRTSCTS, LINUX_CRTSCTS);
335 
336 	lt->c_lflag = 0;
337 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ISIG, LINUX_ISIG);
338 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ICANON, LINUX_ICANON);
339 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHO, LINUX_ECHO);
340 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOE, LINUX_ECHOE);
341 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOK, LINUX_ECHOK);
342 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHONL, LINUX_ECHONL);
343 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, NOFLSH, LINUX_NOFLSH);
344 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, TOSTOP, LINUX_TOSTOP);
345 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOCTL, LINUX_ECHOCTL);
346 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOPRT, LINUX_ECHOPRT);
347 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOKE, LINUX_ECHOKE);
348 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, FLUSHO, LINUX_FLUSHO);
349 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, PENDIN, LINUX_PENDIN);
350 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, IEXTEN, LINUX_IEXTEN);
351 
352 	mask = LINUX_B9600;	/* XXX default value should this be 0? */
353 	for (i = 0; i < sizeof (linux_speeds) / sizeof (speed_t); i++) {
354 		if (bts->c_ospeed == linux_speeds[i]) {
355 			mask = linux_spmasks[i];
356 			break;
357 		}
358 	}
359 	lt->c_cflag |= mask;
360 
361 	lt->c_cc[LINUX_VINTR] = bts->c_cc[VINTR];
362 	lt->c_cc[LINUX_VQUIT] = bts->c_cc[VQUIT];
363 	lt->c_cc[LINUX_VERASE] = bts->c_cc[VERASE];
364 	lt->c_cc[LINUX_VKILL] = bts->c_cc[VKILL];
365 	lt->c_cc[LINUX_VEOF] = bts->c_cc[VEOF];
366 	lt->c_cc[LINUX_VTIME] = bts->c_cc[VTIME];
367 	lt->c_cc[LINUX_VMIN] = bts->c_cc[VMIN];
368 	lt->c_cc[LINUX_VSWTC] = 0;
369 
370 	/* XXX should be fixed someday */
371 	lt->c_line = 0;
372 }
373 
374 static void
375 #ifdef COMPAT_LINUX32
376 linux32_termios_to_bsd_termios(lts, bts)
377 	struct linux32_termios *lts;
378 	struct termios *bts;
379 #else
380 linux_termios_to_bsd_termios(lts, bts)
381 	struct linux_termios *lts;
382 	struct termios *bts;
383 #endif
384 {
385 	int index;
386 
387 	bts->c_iflag = 0;
388 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNBRK, IGNBRK);
389 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_BRKINT, BRKINT);
390 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNPAR, IGNPAR);
391 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_INPCK, INPCK);
392 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_ISTRIP, ISTRIP);
393 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_INLCR, INLCR);
394 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNCR, IGNCR);
395 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_ICRNL, ICRNL);
396 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXON, IXON);
397 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXANY, IXANY);
398 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXOFF, IXOFF);
399 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IMAXBEL, IMAXBEL);
400 
401 	bts->c_oflag = 0;
402 	bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_OPOST, OPOST);
403 	bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_ONLCR, ONLCR);
404 	bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_XTABS, OXTABS);
405 
406 	bts->c_cflag = 0;
407 	switch (lts->c_cflag & LINUX_CSIZE) {
408 	case LINUX_CS5:
409 		bts->c_cflag = CS5;
410 		break;
411 	case LINUX_CS6:
412 		bts->c_cflag = CS6;
413 		break;
414 	case LINUX_CS7:
415 		bts->c_cflag = CS7;
416 		break;
417 	case LINUX_CS8:
418 		bts->c_cflag = CS8;
419 		break;
420 	}
421 	bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CSTOPB, CSTOPB);
422 	bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CREAD, CREAD);
423 	bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_PARENB, PARENB);
424 	bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_PARODD, PARODD);
425 	bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_HUPCL, HUPCL);
426 	bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CLOCAL, CLOCAL);
427 	bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CRTSCTS, CRTSCTS);
428 
429 	bts->c_lflag = 0;
430 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ISIG, ISIG);
431 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ICANON, ICANON);
432 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHO, ECHO);
433 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOE, ECHOE);
434 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOK, ECHOK);
435 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHONL, ECHONL);
436 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_NOFLSH, NOFLSH);
437 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_TOSTOP, TOSTOP);
438 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOCTL, ECHOCTL);
439 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOPRT, ECHOPRT);
440 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOKE, ECHOKE);
441 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_FLUSHO, FLUSHO);
442 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_PENDIN, PENDIN);
443 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_IEXTEN, IEXTEN);
444 
445 	index = lts->c_cflag & LINUX_CBAUD;
446 	if (index & LINUX_CBAUDEX)
447 		index = (index & ~LINUX_CBAUDEX) + LINUX_NSPEEDS - 1;
448 	bts->c_ispeed = bts->c_ospeed = linux_speeds[index];
449 	/*
450 	 * A null c_ospeed causes NetBSD to hangup the terminal.
451 	 * Linux does not do this, and it sets c_ospeed to zero
452 	 * sometimes. If it is null, we store -1 in the kernel
453 	 */
454 	if (bts->c_ospeed == 0)
455 		bts->c_ospeed = -1;
456 
457 	bts->c_cc[VINTR] = lts->c_cc[LINUX_VINTR];
458 	bts->c_cc[VQUIT] = lts->c_cc[LINUX_VQUIT];
459 	bts->c_cc[VERASE] = lts->c_cc[LINUX_VERASE];
460 	bts->c_cc[VKILL] = lts->c_cc[LINUX_VKILL];
461 	bts->c_cc[VEOF] = lts->c_cc[LINUX_VEOF];
462 	bts->c_cc[VTIME] = lts->c_cc[LINUX_VTIME];
463 	bts->c_cc[VMIN] = lts->c_cc[LINUX_VMIN];
464 	bts->c_cc[VEOL] = lts->c_cc[LINUX_VEOL];
465 	bts->c_cc[VEOL2] = lts->c_cc[LINUX_VEOL2];
466 	bts->c_cc[VWERASE] = lts->c_cc[LINUX_VWERASE];
467 	bts->c_cc[VSUSP] = lts->c_cc[LINUX_VSUSP];
468 	bts->c_cc[VSTART] = lts->c_cc[LINUX_VSTART];
469 	bts->c_cc[VSTOP] = lts->c_cc[LINUX_VSTOP];
470 	bts->c_cc[VLNEXT] = lts->c_cc[LINUX_VLNEXT];
471 	bts->c_cc[VDISCARD] = lts->c_cc[LINUX_VDISCARD];
472 	bts->c_cc[VREPRINT] = lts->c_cc[LINUX_VREPRINT];
473 }
474 
475 static void
476 #ifdef COMPAT_LINUX32
477 bsd_termios_to_linux32_termios(bts, lts)
478 	struct termios *bts;
479 	struct linux32_termios *lts;
480 #else
481 bsd_termios_to_linux_termios(bts, lts)
482 	struct termios *bts;
483 	struct linux_termios *lts;
484 #endif
485 {
486 	int i, mask;
487 
488 	lts->c_iflag = 0;
489 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNBRK, LINUX_IGNBRK);
490 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, BRKINT, LINUX_BRKINT);
491 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNPAR, LINUX_IGNPAR);
492 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, INPCK, LINUX_INPCK);
493 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, ISTRIP, LINUX_ISTRIP);
494 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, INLCR, LINUX_INLCR);
495 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNCR, LINUX_IGNCR);
496 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, ICRNL, LINUX_ICRNL);
497 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXON, LINUX_IXON);
498 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXANY, LINUX_IXANY);
499 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXOFF, LINUX_IXOFF);
500 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IMAXBEL, LINUX_IMAXBEL);
501 
502 	lts->c_oflag = 0;
503 	lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, OPOST, LINUX_OPOST);
504 	lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, ONLCR, LINUX_ONLCR);
505 	lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, OXTABS, LINUX_XTABS);
506 
507 	switch (bts->c_cflag & CSIZE) {
508 	case CS5:
509 		lts->c_cflag = LINUX_CS5;
510 		break;
511 	case CS6:
512 		lts->c_cflag = LINUX_CS6;
513 		break;
514 	case CS7:
515 		lts->c_cflag = LINUX_CS7;
516 		break;
517 	case CS8:
518 		lts->c_cflag = LINUX_CS8;
519 		break;
520 	}
521 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS5, LINUX_CS5);
522 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS6, LINUX_CS6);
523 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS7, LINUX_CS7);
524 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS8, LINUX_CS8);
525 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CSTOPB, LINUX_CSTOPB);
526 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CREAD, LINUX_CREAD);
527 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARENB, LINUX_PARENB);
528 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARODD, LINUX_PARODD);
529 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, HUPCL, LINUX_HUPCL);
530 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CLOCAL, LINUX_CLOCAL);
531 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CRTSCTS, LINUX_CRTSCTS);
532 
533 	lts->c_lflag = 0;
534 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ISIG, LINUX_ISIG);
535 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ICANON, LINUX_ICANON);
536 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHO, LINUX_ECHO);
537 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOE, LINUX_ECHOE);
538 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOK, LINUX_ECHOK);
539 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHONL, LINUX_ECHONL);
540 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, NOFLSH, LINUX_NOFLSH);
541 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, TOSTOP, LINUX_TOSTOP);
542 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOCTL, LINUX_ECHOCTL);
543 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOPRT, LINUX_ECHOPRT);
544 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOKE, LINUX_ECHOKE);
545 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, FLUSHO, LINUX_FLUSHO);
546 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, PENDIN, LINUX_PENDIN);
547 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, IEXTEN, LINUX_IEXTEN);
548 
549 	mask = LINUX_B9600;	/* XXX default value */
550 	for (i = 0; i < sizeof (linux_speeds) / sizeof (speed_t); i++) {
551 		if (bts->c_ospeed == linux_speeds[i]) {
552 			mask = linux_spmasks[i];
553 			break;
554 		}
555 	}
556 	/*
557 	 * A null c_ospeed causes NetBSD to hangup the terminal.
558 	 * Linux does not do this, and it sets c_ospeed to zero
559 	 * sometimes. If it is null, we store -1 in the kernel
560 	 */
561 	if (bts->c_ospeed == -1)
562 		bts->c_ospeed = 0;
563 	lts->c_cflag |= mask;
564 
565 	lts->c_cc[LINUX_VINTR] = bts->c_cc[VINTR];
566 	lts->c_cc[LINUX_VQUIT] = bts->c_cc[VQUIT];
567 	lts->c_cc[LINUX_VERASE] = bts->c_cc[VERASE];
568 	lts->c_cc[LINUX_VKILL] = bts->c_cc[VKILL];
569 	lts->c_cc[LINUX_VEOF] = bts->c_cc[VEOF];
570 	lts->c_cc[LINUX_VTIME] = bts->c_cc[VTIME];
571 	lts->c_cc[LINUX_VMIN] = bts->c_cc[VMIN];
572 	lts->c_cc[LINUX_VEOL] = bts->c_cc[VEOL];
573 	lts->c_cc[LINUX_VEOL2] = bts->c_cc[VEOL2];
574 	lts->c_cc[LINUX_VWERASE] = bts->c_cc[VWERASE];
575 	lts->c_cc[LINUX_VSUSP] = bts->c_cc[VSUSP];
576 	lts->c_cc[LINUX_VSTART] = bts->c_cc[VSTART];
577 	lts->c_cc[LINUX_VSTOP] = bts->c_cc[VSTOP];
578 	lts->c_cc[LINUX_VLNEXT] = bts->c_cc[VLNEXT];
579 	lts->c_cc[LINUX_VDISCARD] = bts->c_cc[VDISCARD];
580 	lts->c_cc[LINUX_VREPRINT] = bts->c_cc[VREPRINT];
581 	lts->c_cc[LINUX_VSWTC] = 0;
582 
583 	/* XXX should be fixed someday */
584 	lts->c_line = 0;
585 }
586 #endif /* !_LINUX_TERMIOS_H */
587