18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _ASM_GENERIC_TERMIOS_H
38c2ecf20Sopenharmony_ci#define _ASM_GENERIC_TERMIOS_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/uaccess.h>
78c2ecf20Sopenharmony_ci#include <uapi/asm-generic/termios.h>
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci/*	intr=^C		quit=^\		erase=del	kill=^U
108c2ecf20Sopenharmony_ci	eof=^D		vtime=\0	vmin=\1		sxtc=\0
118c2ecf20Sopenharmony_ci	start=^Q	stop=^S		susp=^Z		eol=\0
128c2ecf20Sopenharmony_ci	reprint=^R	discard=^U	werase=^W	lnext=^V
138c2ecf20Sopenharmony_ci	eol2=\0
148c2ecf20Sopenharmony_ci*/
158c2ecf20Sopenharmony_ci#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci/*
188c2ecf20Sopenharmony_ci * Translate a "termio" structure into a "termios". Ugh.
198c2ecf20Sopenharmony_ci */
208c2ecf20Sopenharmony_cistatic inline int user_termio_to_kernel_termios(struct ktermios *termios,
218c2ecf20Sopenharmony_ci						const struct termio __user *termio)
228c2ecf20Sopenharmony_ci{
238c2ecf20Sopenharmony_ci	unsigned short tmp;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	if (get_user(tmp, &termio->c_iflag) < 0)
268c2ecf20Sopenharmony_ci		goto fault;
278c2ecf20Sopenharmony_ci	termios->c_iflag = (0xffff0000 & termios->c_iflag) | tmp;
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	if (get_user(tmp, &termio->c_oflag) < 0)
308c2ecf20Sopenharmony_ci		goto fault;
318c2ecf20Sopenharmony_ci	termios->c_oflag = (0xffff0000 & termios->c_oflag) | tmp;
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	if (get_user(tmp, &termio->c_cflag) < 0)
348c2ecf20Sopenharmony_ci		goto fault;
358c2ecf20Sopenharmony_ci	termios->c_cflag = (0xffff0000 & termios->c_cflag) | tmp;
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	if (get_user(tmp, &termio->c_lflag) < 0)
388c2ecf20Sopenharmony_ci		goto fault;
398c2ecf20Sopenharmony_ci	termios->c_lflag = (0xffff0000 & termios->c_lflag) | tmp;
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	if (get_user(termios->c_line, &termio->c_line) < 0)
428c2ecf20Sopenharmony_ci		goto fault;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	if (copy_from_user(termios->c_cc, termio->c_cc, NCC) != 0)
458c2ecf20Sopenharmony_ci		goto fault;
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	return 0;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci fault:
508c2ecf20Sopenharmony_ci	return -EFAULT;
518c2ecf20Sopenharmony_ci}
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci/*
548c2ecf20Sopenharmony_ci * Translate a "termios" structure into a "termio". Ugh.
558c2ecf20Sopenharmony_ci */
568c2ecf20Sopenharmony_cistatic inline int kernel_termios_to_user_termio(struct termio __user *termio,
578c2ecf20Sopenharmony_ci						struct ktermios *termios)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	if (put_user(termios->c_iflag, &termio->c_iflag) < 0 ||
608c2ecf20Sopenharmony_ci	    put_user(termios->c_oflag, &termio->c_oflag) < 0 ||
618c2ecf20Sopenharmony_ci	    put_user(termios->c_cflag, &termio->c_cflag) < 0 ||
628c2ecf20Sopenharmony_ci	    put_user(termios->c_lflag, &termio->c_lflag) < 0 ||
638c2ecf20Sopenharmony_ci	    put_user(termios->c_line,  &termio->c_line) < 0 ||
648c2ecf20Sopenharmony_ci	    copy_to_user(termio->c_cc, termios->c_cc, NCC) != 0)
658c2ecf20Sopenharmony_ci		return -EFAULT;
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	return 0;
688c2ecf20Sopenharmony_ci}
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci#ifdef TCGETS2
718c2ecf20Sopenharmony_cistatic inline int user_termios_to_kernel_termios(struct ktermios *k,
728c2ecf20Sopenharmony_ci						 struct termios2 __user *u)
738c2ecf20Sopenharmony_ci{
748c2ecf20Sopenharmony_ci	return copy_from_user(k, u, sizeof(struct termios2));
758c2ecf20Sopenharmony_ci}
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_cistatic inline int kernel_termios_to_user_termios(struct termios2 __user *u,
788c2ecf20Sopenharmony_ci						 struct ktermios *k)
798c2ecf20Sopenharmony_ci{
808c2ecf20Sopenharmony_ci	return copy_to_user(u, k, sizeof(struct termios2));
818c2ecf20Sopenharmony_ci}
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_cistatic inline int user_termios_to_kernel_termios_1(struct ktermios *k,
848c2ecf20Sopenharmony_ci						   struct termios __user *u)
858c2ecf20Sopenharmony_ci{
868c2ecf20Sopenharmony_ci	return copy_from_user(k, u, sizeof(struct termios));
878c2ecf20Sopenharmony_ci}
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_cistatic inline int kernel_termios_to_user_termios_1(struct termios __user *u,
908c2ecf20Sopenharmony_ci						   struct ktermios *k)
918c2ecf20Sopenharmony_ci{
928c2ecf20Sopenharmony_ci	return copy_to_user(u, k, sizeof(struct termios));
938c2ecf20Sopenharmony_ci}
948c2ecf20Sopenharmony_ci#else /* TCGETS2 */
958c2ecf20Sopenharmony_cistatic inline int user_termios_to_kernel_termios(struct ktermios *k,
968c2ecf20Sopenharmony_ci						 struct termios __user *u)
978c2ecf20Sopenharmony_ci{
988c2ecf20Sopenharmony_ci	return copy_from_user(k, u, sizeof(struct termios));
998c2ecf20Sopenharmony_ci}
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_cistatic inline int kernel_termios_to_user_termios(struct termios __user *u,
1028c2ecf20Sopenharmony_ci						 struct ktermios *k)
1038c2ecf20Sopenharmony_ci{
1048c2ecf20Sopenharmony_ci	return copy_to_user(u, k, sizeof(struct termios));
1058c2ecf20Sopenharmony_ci}
1068c2ecf20Sopenharmony_ci#endif /* TCGETS2 */
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci#endif /* _ASM_GENERIC_TERMIOS_H */
109