1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _SPARC_TERMIOS_H 3 #define _SPARC_TERMIOS_H 4 5 #include <uapi/asm/termios.h> 6 7 8 /* 9 * c_cc characters in the termio structure. Oh, how I love being 10 * backwardly compatible. Notice that character 4 and 5 are 11 * interpreted differently depending on whether ICANON is set in 12 * c_lflag. If it's set, they are used as _VEOF and _VEOL, otherwise 13 * as _VMIN and V_TIME. This is for compatibility with OSF/1 (which 14 * is compatible with sysV)... 15 */ 16 #define _VMIN 4 17 #define _VTIME 5 18 19 /* intr=^C quit=^\ erase=del kill=^U 20 eof=^D eol=\0 eol2=\0 sxtc=\0 21 start=^Q stop=^S susp=^Z dsusp=^Y 22 reprint=^R discard=^U werase=^W lnext=^V 23 vmin=\1 vtime=\0 24 */ 25 #define INIT_C_CC "\003\034\177\025\004\000\000\000\021\023\032\031\022\025\027\026\001" 26 27 /* 28 * Translate a "termio" structure into a "termios". Ugh. 29 */ 30 #define user_termio_to_kernel_termios(termios, termio) \ 31 ({ \ 32 unsigned short tmp; \ 33 int err; \ 34 err = get_user(tmp, &(termio)->c_iflag); \ 35 (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \ 36 err |= get_user(tmp, &(termio)->c_oflag); \ 37 (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \ 38 err |= get_user(tmp, &(termio)->c_cflag); \ 39 (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \ 40 err |= get_user(tmp, &(termio)->c_lflag); \ 41 (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \ 42 err |= copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ 43 err; \ 44 }) 45 46 /* 47 * Translate a "termios" structure into a "termio". Ugh. 48 * 49 * Note the "fun" _VMIN overloading. 50 */ 51 #define kernel_termios_to_user_termio(termio, termios) \ 52 ({ \ 53 int err; \ 54 err = put_user((termios)->c_iflag, &(termio)->c_iflag); \ 55 err |= put_user((termios)->c_oflag, &(termio)->c_oflag); \ 56 err |= put_user((termios)->c_cflag, &(termio)->c_cflag); \ 57 err |= put_user((termios)->c_lflag, &(termio)->c_lflag); \ 58 err |= put_user((termios)->c_line, &(termio)->c_line); \ 59 err |= copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ 60 if (!((termios)->c_lflag & ICANON)) { \ 61 err |= put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \ 62 err |= put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \ 63 } \ 64 err; \ 65 }) 66 67 #define user_termios_to_kernel_termios(k, u) \ 68 ({ \ 69 int err; \ 70 err = get_user((k)->c_iflag, &(u)->c_iflag); \ 71 err |= get_user((k)->c_oflag, &(u)->c_oflag); \ 72 err |= get_user((k)->c_cflag, &(u)->c_cflag); \ 73 err |= get_user((k)->c_lflag, &(u)->c_lflag); \ 74 err |= get_user((k)->c_line, &(u)->c_line); \ 75 err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ 76 if ((k)->c_lflag & ICANON) { \ 77 err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ 78 err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ 79 } else { \ 80 err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ 81 err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ 82 } \ 83 err |= get_user((k)->c_ispeed, &(u)->c_ispeed); \ 84 err |= get_user((k)->c_ospeed, &(u)->c_ospeed); \ 85 err; \ 86 }) 87 88 #define kernel_termios_to_user_termios(u, k) \ 89 ({ \ 90 int err; \ 91 err = put_user((k)->c_iflag, &(u)->c_iflag); \ 92 err |= put_user((k)->c_oflag, &(u)->c_oflag); \ 93 err |= put_user((k)->c_cflag, &(u)->c_cflag); \ 94 err |= put_user((k)->c_lflag, &(u)->c_lflag); \ 95 err |= put_user((k)->c_line, &(u)->c_line); \ 96 err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ 97 if (!((k)->c_lflag & ICANON)) { \ 98 err |= put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ 99 err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ 100 } else { \ 101 err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ 102 err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ 103 } \ 104 err |= put_user((k)->c_ispeed, &(u)->c_ispeed); \ 105 err |= put_user((k)->c_ospeed, &(u)->c_ospeed); \ 106 err; \ 107 }) 108 109 #define user_termios_to_kernel_termios_1(k, u) \ 110 ({ \ 111 int err; \ 112 err = get_user((k)->c_iflag, &(u)->c_iflag); \ 113 err |= get_user((k)->c_oflag, &(u)->c_oflag); \ 114 err |= get_user((k)->c_cflag, &(u)->c_cflag); \ 115 err |= get_user((k)->c_lflag, &(u)->c_lflag); \ 116 err |= get_user((k)->c_line, &(u)->c_line); \ 117 err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ 118 if ((k)->c_lflag & ICANON) { \ 119 err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ 120 err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ 121 } else { \ 122 err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ 123 err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ 124 } \ 125 err; \ 126 }) 127 128 #define kernel_termios_to_user_termios_1(u, k) \ 129 ({ \ 130 int err; \ 131 err = put_user((k)->c_iflag, &(u)->c_iflag); \ 132 err |= put_user((k)->c_oflag, &(u)->c_oflag); \ 133 err |= put_user((k)->c_cflag, &(u)->c_cflag); \ 134 err |= put_user((k)->c_lflag, &(u)->c_lflag); \ 135 err |= put_user((k)->c_line, &(u)->c_line); \ 136 err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ 137 if (!((k)->c_lflag & ICANON)) { \ 138 err |= put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ 139 err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ 140 } else { \ 141 err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ 142 err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ 143 } \ 144 err; \ 145 }) 146 147 #endif /* _SPARC_TERMIOS_H */ 148