GNU Linux-libre 6.8.9-gnu
[releases.git] / arch / sparc / kernel / termios.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/termios_internal.h>
3
4 /*
5  * c_cc characters in the termio structure.  Oh, how I love being
6  * backwardly compatible.  Notice that character 4 and 5 are
7  * interpreted differently depending on whether ICANON is set in
8  * c_lflag.  If it's set, they are used as _VEOF and _VEOL, otherwise
9  * as _VMIN and V_TIME.  This is for compatibility with OSF/1 (which
10  * is compatible with sysV)...
11  */
12 #define _VMIN   4
13 #define _VTIME  5
14
15 int kernel_termios_to_user_termio(struct termio __user *termio,
16                                                 struct ktermios *termios)
17 {
18         struct termio v;
19         memset(&v, 0, sizeof(struct termio));
20         v.c_iflag = termios->c_iflag;
21         v.c_oflag = termios->c_oflag;
22         v.c_cflag = termios->c_cflag;
23         v.c_lflag = termios->c_lflag;
24         v.c_line = termios->c_line;
25         memcpy(v.c_cc, termios->c_cc, NCC);
26         if (!(v.c_lflag & ICANON)) {
27                 v.c_cc[_VMIN] = termios->c_cc[VMIN];
28                 v.c_cc[_VTIME] = termios->c_cc[VTIME];
29         }
30         return copy_to_user(termio, &v, sizeof(struct termio));
31 }
32
33 int user_termios_to_kernel_termios(struct ktermios *k,
34                                                  struct termios2 __user *u)
35 {
36         int err;
37         err  = get_user(k->c_iflag, &u->c_iflag);
38         err |= get_user(k->c_oflag, &u->c_oflag);
39         err |= get_user(k->c_cflag, &u->c_cflag);
40         err |= get_user(k->c_lflag, &u->c_lflag);
41         err |= get_user(k->c_line,  &u->c_line);
42         err |= copy_from_user(k->c_cc, u->c_cc, NCCS);
43         if (k->c_lflag & ICANON) {
44                 err |= get_user(k->c_cc[VEOF], &u->c_cc[VEOF]);
45                 err |= get_user(k->c_cc[VEOL], &u->c_cc[VEOL]);
46         } else {
47                 err |= get_user(k->c_cc[VMIN],  &u->c_cc[_VMIN]);
48                 err |= get_user(k->c_cc[VTIME], &u->c_cc[_VTIME]);
49         }
50         err |= get_user(k->c_ispeed,  &u->c_ispeed);
51         err |= get_user(k->c_ospeed,  &u->c_ospeed);
52         return err;
53 }
54
55 int kernel_termios_to_user_termios(struct termios2 __user *u,
56                                                  struct ktermios *k)
57 {
58         int err;
59         err  = put_user(k->c_iflag, &u->c_iflag);
60         err |= put_user(k->c_oflag, &u->c_oflag);
61         err |= put_user(k->c_cflag, &u->c_cflag);
62         err |= put_user(k->c_lflag, &u->c_lflag);
63         err |= put_user(k->c_line, &u->c_line);
64         err |= copy_to_user(u->c_cc, k->c_cc, NCCS);
65         if (!(k->c_lflag & ICANON)) {
66                 err |= put_user(k->c_cc[VMIN],  &u->c_cc[_VMIN]);
67                 err |= put_user(k->c_cc[VTIME], &u->c_cc[_VTIME]);
68         } else {
69                 err |= put_user(k->c_cc[VEOF], &u->c_cc[VEOF]);
70                 err |= put_user(k->c_cc[VEOL], &u->c_cc[VEOL]);
71         }
72         err |= put_user(k->c_ispeed, &u->c_ispeed);
73         err |= put_user(k->c_ospeed, &u->c_ospeed);
74         return err;
75 }
76
77 int user_termios_to_kernel_termios_1(struct ktermios *k,
78                                                  struct termios __user *u)
79 {
80         int err;
81         err  = get_user(k->c_iflag, &u->c_iflag);
82         err |= get_user(k->c_oflag, &u->c_oflag);
83         err |= get_user(k->c_cflag, &u->c_cflag);
84         err |= get_user(k->c_lflag, &u->c_lflag);
85         err |= get_user(k->c_line,  &u->c_line);
86         err |= copy_from_user(k->c_cc, u->c_cc, NCCS);
87         if (k->c_lflag & ICANON) {
88                 err |= get_user(k->c_cc[VEOF], &u->c_cc[VEOF]);
89                 err |= get_user(k->c_cc[VEOL], &u->c_cc[VEOL]);
90         } else {
91                 err |= get_user(k->c_cc[VMIN],  &u->c_cc[_VMIN]);
92                 err |= get_user(k->c_cc[VTIME], &u->c_cc[_VTIME]);
93         }
94         return err;
95 }
96
97 int kernel_termios_to_user_termios_1(struct termios __user *u,
98                                                  struct ktermios *k)
99 {
100         int err;
101         err  = put_user(k->c_iflag, &u->c_iflag);
102         err |= put_user(k->c_oflag, &u->c_oflag);
103         err |= put_user(k->c_cflag, &u->c_cflag);
104         err |= put_user(k->c_lflag, &u->c_lflag);
105         err |= put_user(k->c_line, &u->c_line);
106         err |= copy_to_user(u->c_cc, k->c_cc, NCCS);
107         if (!(k->c_lflag & ICANON)) {
108                 err |= put_user(k->c_cc[VMIN],  &u->c_cc[_VMIN]);
109                 err |= put_user(k->c_cc[VTIME], &u->c_cc[_VTIME]);
110         } else {
111                 err |= put_user(k->c_cc[VEOF], &u->c_cc[VEOF]);
112                 err |= put_user(k->c_cc[VEOL], &u->c_cc[VEOL]);
113         }
114         return err;
115 }