xref: /openbmc/linux/arch/sparc/kernel/termios.c (revision c9874d3f)
1*c9874d3fSAl Viro // SPDX-License-Identifier: GPL-2.0
2*c9874d3fSAl Viro #include <linux/termios_internal.h>
31d5d6682SAl Viro 
41d5d6682SAl Viro /*
51d5d6682SAl Viro  * c_cc characters in the termio structure.  Oh, how I love being
61d5d6682SAl Viro  * backwardly compatible.  Notice that character 4 and 5 are
71d5d6682SAl Viro  * interpreted differently depending on whether ICANON is set in
81d5d6682SAl Viro  * c_lflag.  If it's set, they are used as _VEOF and _VEOL, otherwise
91d5d6682SAl Viro  * as _VMIN and V_TIME.  This is for compatibility with OSF/1 (which
101d5d6682SAl Viro  * is compatible with sysV)...
111d5d6682SAl Viro  */
121d5d6682SAl Viro #define _VMIN	4
131d5d6682SAl Viro #define _VTIME	5
141d5d6682SAl Viro 
kernel_termios_to_user_termio(struct termio __user * termio,struct ktermios * termios)151d5d6682SAl Viro int kernel_termios_to_user_termio(struct termio __user *termio,
161d5d6682SAl Viro 						struct ktermios *termios)
171d5d6682SAl Viro {
181d5d6682SAl Viro 	struct termio v;
191d5d6682SAl Viro 	memset(&v, 0, sizeof(struct termio));
201d5d6682SAl Viro 	v.c_iflag = termios->c_iflag;
211d5d6682SAl Viro 	v.c_oflag = termios->c_oflag;
221d5d6682SAl Viro 	v.c_cflag = termios->c_cflag;
231d5d6682SAl Viro 	v.c_lflag = termios->c_lflag;
241d5d6682SAl Viro 	v.c_line = termios->c_line;
251d5d6682SAl Viro 	memcpy(v.c_cc, termios->c_cc, NCC);
261d5d6682SAl Viro 	if (!(v.c_lflag & ICANON)) {
271d5d6682SAl Viro 		v.c_cc[_VMIN] = termios->c_cc[VMIN];
281d5d6682SAl Viro 		v.c_cc[_VTIME] = termios->c_cc[VTIME];
291d5d6682SAl Viro 	}
301d5d6682SAl Viro 	return copy_to_user(termio, &v, sizeof(struct termio));
311d5d6682SAl Viro }
321d5d6682SAl Viro 
user_termios_to_kernel_termios(struct ktermios * k,struct termios2 __user * u)331d5d6682SAl Viro int user_termios_to_kernel_termios(struct ktermios *k,
341d5d6682SAl Viro 						 struct termios2 __user *u)
351d5d6682SAl Viro {
361d5d6682SAl Viro 	int err;
371d5d6682SAl Viro 	err  = get_user(k->c_iflag, &u->c_iflag);
381d5d6682SAl Viro 	err |= get_user(k->c_oflag, &u->c_oflag);
391d5d6682SAl Viro 	err |= get_user(k->c_cflag, &u->c_cflag);
401d5d6682SAl Viro 	err |= get_user(k->c_lflag, &u->c_lflag);
411d5d6682SAl Viro 	err |= get_user(k->c_line,  &u->c_line);
421d5d6682SAl Viro 	err |= copy_from_user(k->c_cc, u->c_cc, NCCS);
431d5d6682SAl Viro 	if (k->c_lflag & ICANON) {
441d5d6682SAl Viro 		err |= get_user(k->c_cc[VEOF], &u->c_cc[VEOF]);
451d5d6682SAl Viro 		err |= get_user(k->c_cc[VEOL], &u->c_cc[VEOL]);
461d5d6682SAl Viro 	} else {
471d5d6682SAl Viro 		err |= get_user(k->c_cc[VMIN],  &u->c_cc[_VMIN]);
481d5d6682SAl Viro 		err |= get_user(k->c_cc[VTIME], &u->c_cc[_VTIME]);
491d5d6682SAl Viro 	}
501d5d6682SAl Viro 	err |= get_user(k->c_ispeed,  &u->c_ispeed);
511d5d6682SAl Viro 	err |= get_user(k->c_ospeed,  &u->c_ospeed);
521d5d6682SAl Viro 	return err;
531d5d6682SAl Viro }
541d5d6682SAl Viro 
kernel_termios_to_user_termios(struct termios2 __user * u,struct ktermios * k)551d5d6682SAl Viro int kernel_termios_to_user_termios(struct termios2 __user *u,
561d5d6682SAl Viro 						 struct ktermios *k)
571d5d6682SAl Viro {
581d5d6682SAl Viro 	int err;
591d5d6682SAl Viro 	err  = put_user(k->c_iflag, &u->c_iflag);
601d5d6682SAl Viro 	err |= put_user(k->c_oflag, &u->c_oflag);
611d5d6682SAl Viro 	err |= put_user(k->c_cflag, &u->c_cflag);
621d5d6682SAl Viro 	err |= put_user(k->c_lflag, &u->c_lflag);
631d5d6682SAl Viro 	err |= put_user(k->c_line, &u->c_line);
641d5d6682SAl Viro 	err |= copy_to_user(u->c_cc, k->c_cc, NCCS);
651d5d6682SAl Viro 	if (!(k->c_lflag & ICANON)) {
661d5d6682SAl Viro 		err |= put_user(k->c_cc[VMIN],  &u->c_cc[_VMIN]);
671d5d6682SAl Viro 		err |= put_user(k->c_cc[VTIME], &u->c_cc[_VTIME]);
681d5d6682SAl Viro 	} else {
691d5d6682SAl Viro 		err |= put_user(k->c_cc[VEOF], &u->c_cc[VEOF]);
701d5d6682SAl Viro 		err |= put_user(k->c_cc[VEOL], &u->c_cc[VEOL]);
711d5d6682SAl Viro 	}
721d5d6682SAl Viro 	err |= put_user(k->c_ispeed, &u->c_ispeed);
731d5d6682SAl Viro 	err |= put_user(k->c_ospeed, &u->c_ospeed);
741d5d6682SAl Viro 	return err;
751d5d6682SAl Viro }
761d5d6682SAl Viro 
user_termios_to_kernel_termios_1(struct ktermios * k,struct termios __user * u)771d5d6682SAl Viro int user_termios_to_kernel_termios_1(struct ktermios *k,
781d5d6682SAl Viro 						 struct termios __user *u)
791d5d6682SAl Viro {
801d5d6682SAl Viro 	int err;
811d5d6682SAl Viro 	err  = get_user(k->c_iflag, &u->c_iflag);
821d5d6682SAl Viro 	err |= get_user(k->c_oflag, &u->c_oflag);
831d5d6682SAl Viro 	err |= get_user(k->c_cflag, &u->c_cflag);
841d5d6682SAl Viro 	err |= get_user(k->c_lflag, &u->c_lflag);
851d5d6682SAl Viro 	err |= get_user(k->c_line,  &u->c_line);
861d5d6682SAl Viro 	err |= copy_from_user(k->c_cc, u->c_cc, NCCS);
871d5d6682SAl Viro 	if (k->c_lflag & ICANON) {
881d5d6682SAl Viro 		err |= get_user(k->c_cc[VEOF], &u->c_cc[VEOF]);
891d5d6682SAl Viro 		err |= get_user(k->c_cc[VEOL], &u->c_cc[VEOL]);
901d5d6682SAl Viro 	} else {
911d5d6682SAl Viro 		err |= get_user(k->c_cc[VMIN],  &u->c_cc[_VMIN]);
921d5d6682SAl Viro 		err |= get_user(k->c_cc[VTIME], &u->c_cc[_VTIME]);
931d5d6682SAl Viro 	}
941d5d6682SAl Viro 	return err;
951d5d6682SAl Viro }
961d5d6682SAl Viro 
kernel_termios_to_user_termios_1(struct termios __user * u,struct ktermios * k)971d5d6682SAl Viro int kernel_termios_to_user_termios_1(struct termios __user *u,
981d5d6682SAl Viro 						 struct ktermios *k)
991d5d6682SAl Viro {
1001d5d6682SAl Viro 	int err;
1011d5d6682SAl Viro 	err  = put_user(k->c_iflag, &u->c_iflag);
1021d5d6682SAl Viro 	err |= put_user(k->c_oflag, &u->c_oflag);
1031d5d6682SAl Viro 	err |= put_user(k->c_cflag, &u->c_cflag);
1041d5d6682SAl Viro 	err |= put_user(k->c_lflag, &u->c_lflag);
1051d5d6682SAl Viro 	err |= put_user(k->c_line, &u->c_line);
1061d5d6682SAl Viro 	err |= copy_to_user(u->c_cc, k->c_cc, NCCS);
1071d5d6682SAl Viro 	if (!(k->c_lflag & ICANON)) {
1081d5d6682SAl Viro 		err |= put_user(k->c_cc[VMIN],  &u->c_cc[_VMIN]);
1091d5d6682SAl Viro 		err |= put_user(k->c_cc[VTIME], &u->c_cc[_VTIME]);
1101d5d6682SAl Viro 	} else {
1111d5d6682SAl Viro 		err |= put_user(k->c_cc[VEOF], &u->c_cc[VEOF]);
1121d5d6682SAl Viro 		err |= put_user(k->c_cc[VEOL], &u->c_cc[VEOL]);
1131d5d6682SAl Viro 	}
1141d5d6682SAl Viro 	return err;
1151d5d6682SAl Viro }
116