18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/* termios.h: generic termios/termio user copying/translation
38c2ecf20Sopenharmony_ci */
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#ifndef _ASM_GENERIC_TERMIOS_BASE_H
68c2ecf20Sopenharmony_ci#define _ASM_GENERIC_TERMIOS_BASE_H
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/uaccess.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#ifndef __ARCH_TERMIO_GETPUT
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/*
138c2ecf20Sopenharmony_ci * Translate a "termio" structure into a "termios". Ugh.
148c2ecf20Sopenharmony_ci */
158c2ecf20Sopenharmony_cistatic inline int user_termio_to_kernel_termios(struct ktermios *termios,
168c2ecf20Sopenharmony_ci						struct termio __user *termio)
178c2ecf20Sopenharmony_ci{
188c2ecf20Sopenharmony_ci	unsigned short tmp;
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci	if (get_user(tmp, &termio->c_iflag) < 0)
218c2ecf20Sopenharmony_ci		goto fault;
228c2ecf20Sopenharmony_ci	termios->c_iflag = (0xffff0000 & termios->c_iflag) | tmp;
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci	if (get_user(tmp, &termio->c_oflag) < 0)
258c2ecf20Sopenharmony_ci		goto fault;
268c2ecf20Sopenharmony_ci	termios->c_oflag = (0xffff0000 & termios->c_oflag) | tmp;
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci	if (get_user(tmp, &termio->c_cflag) < 0)
298c2ecf20Sopenharmony_ci		goto fault;
308c2ecf20Sopenharmony_ci	termios->c_cflag = (0xffff0000 & termios->c_cflag) | tmp;
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci	if (get_user(tmp, &termio->c_lflag) < 0)
338c2ecf20Sopenharmony_ci		goto fault;
348c2ecf20Sopenharmony_ci	termios->c_lflag = (0xffff0000 & termios->c_lflag) | tmp;
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	if (get_user(termios->c_line, &termio->c_line) < 0)
378c2ecf20Sopenharmony_ci		goto fault;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	if (copy_from_user(termios->c_cc, termio->c_cc, NCC) != 0)
408c2ecf20Sopenharmony_ci		goto fault;
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	return 0;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci fault:
458c2ecf20Sopenharmony_ci	return -EFAULT;
468c2ecf20Sopenharmony_ci}
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci/*
498c2ecf20Sopenharmony_ci * Translate a "termios" structure into a "termio". Ugh.
508c2ecf20Sopenharmony_ci */
518c2ecf20Sopenharmony_cistatic inline int kernel_termios_to_user_termio(struct termio __user *termio,
528c2ecf20Sopenharmony_ci						struct ktermios *termios)
538c2ecf20Sopenharmony_ci{
548c2ecf20Sopenharmony_ci	if (put_user(termios->c_iflag, &termio->c_iflag) < 0 ||
558c2ecf20Sopenharmony_ci	    put_user(termios->c_oflag, &termio->c_oflag) < 0 ||
568c2ecf20Sopenharmony_ci	    put_user(termios->c_cflag, &termio->c_cflag) < 0 ||
578c2ecf20Sopenharmony_ci	    put_user(termios->c_lflag, &termio->c_lflag) < 0 ||
588c2ecf20Sopenharmony_ci	    put_user(termios->c_line,  &termio->c_line) < 0 ||
598c2ecf20Sopenharmony_ci	    copy_to_user(termio->c_cc, termios->c_cc, NCC) != 0)
608c2ecf20Sopenharmony_ci		return -EFAULT;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	return 0;
638c2ecf20Sopenharmony_ci}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci#ifndef user_termios_to_kernel_termios
668c2ecf20Sopenharmony_ci#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
678c2ecf20Sopenharmony_ci#endif
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci#ifndef kernel_termios_to_user_termios
708c2ecf20Sopenharmony_ci#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
718c2ecf20Sopenharmony_ci#endif
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
748c2ecf20Sopenharmony_ci#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci#endif	/* __ARCH_TERMIO_GETPUT */
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci#endif /* _ASM_GENERIC_TERMIOS_BASE_H */
79