mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-26 02:15:23 +07:00
d0ffb805b7
Alpha has had c_ispeed and c_ospeed, but still set speeds in c_cflags using arbitrary flags. Because BOTHER is not defined, the general Linux code doesn't allow setting arbitrary baud rates, and because CBAUDEX == 0, we can have an array overrun of the baud_rate[] table in drivers/tty/tty_baudrate.c if (c_cflags & CBAUD) == 037. Resolve both problems by #defining BOTHER to 037 on Alpha. However, userspace still needs to know if setting BOTHER is actually safe given legacy kernels (does anyone actually care about that on Alpha anymore?), so enable the TCGETS2/TCSETS*2 ioctls on Alpha, even though they use the same structure. Define struct termios2 just for compatibility; it is the exact same structure as struct termios. In a future patchset, this will be cleaned up so the uapi headers are usable from libc. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com> Cc: Jiri Slaby <jslaby@suse.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Richard Henderson <rth@twiddle.net> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Matt Turner <mattst88@gmail.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Kate Stewart <kstewart@linuxfoundation.org> Cc: Philippe Ombredanne <pombredanne@nexb.com> Cc: Eugene Syromiatnikov <esyr@redhat.com> Cc: <linux-alpha@vger.kernel.org> Cc: <linux-serial@vger.kernel.org> Cc: Johan Hovold <johan@kernel.org> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Cc: <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
88 lines
3.0 KiB
C
88 lines
3.0 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _ALPHA_TERMIOS_H
|
|
#define _ALPHA_TERMIOS_H
|
|
|
|
#include <uapi/asm/termios.h>
|
|
|
|
/* eof=^D eol=\0 eol2=\0 erase=del
|
|
werase=^W kill=^U reprint=^R sxtc=\0
|
|
intr=^C quit=^\ susp=^Z <OSF/1 VDSUSP>
|
|
start=^Q stop=^S lnext=^V discard=^U
|
|
vmin=\1 vtime=\0
|
|
*/
|
|
#define INIT_C_CC "\004\000\000\177\027\025\022\000\003\034\032\000\021\023\026\025\001\000"
|
|
|
|
/*
|
|
* Translate a "termio" structure into a "termios". Ugh.
|
|
*/
|
|
|
|
#define user_termio_to_kernel_termios(a_termios, u_termio) \
|
|
({ \
|
|
struct ktermios *k_termios = (a_termios); \
|
|
struct termio k_termio; \
|
|
int canon, ret; \
|
|
\
|
|
ret = copy_from_user(&k_termio, u_termio, sizeof(k_termio)); \
|
|
if (!ret) { \
|
|
/* Overwrite only the low bits. */ \
|
|
*(unsigned short *)&k_termios->c_iflag = k_termio.c_iflag; \
|
|
*(unsigned short *)&k_termios->c_oflag = k_termio.c_oflag; \
|
|
*(unsigned short *)&k_termios->c_cflag = k_termio.c_cflag; \
|
|
*(unsigned short *)&k_termios->c_lflag = k_termio.c_lflag; \
|
|
canon = k_termio.c_lflag & ICANON; \
|
|
\
|
|
k_termios->c_cc[VINTR] = k_termio.c_cc[_VINTR]; \
|
|
k_termios->c_cc[VQUIT] = k_termio.c_cc[_VQUIT]; \
|
|
k_termios->c_cc[VERASE] = k_termio.c_cc[_VERASE]; \
|
|
k_termios->c_cc[VKILL] = k_termio.c_cc[_VKILL]; \
|
|
k_termios->c_cc[VEOL2] = k_termio.c_cc[_VEOL2]; \
|
|
k_termios->c_cc[VSWTC] = k_termio.c_cc[_VSWTC]; \
|
|
k_termios->c_cc[canon ? VEOF : VMIN] = k_termio.c_cc[_VEOF]; \
|
|
k_termios->c_cc[canon ? VEOL : VTIME] = k_termio.c_cc[_VEOL]; \
|
|
} \
|
|
ret; \
|
|
})
|
|
|
|
/*
|
|
* Translate a "termios" structure into a "termio". Ugh.
|
|
*
|
|
* Note the "fun" _VMIN overloading.
|
|
*/
|
|
#define kernel_termios_to_user_termio(u_termio, a_termios) \
|
|
({ \
|
|
struct ktermios *k_termios = (a_termios); \
|
|
struct termio k_termio; \
|
|
int canon; \
|
|
\
|
|
k_termio.c_iflag = k_termios->c_iflag; \
|
|
k_termio.c_oflag = k_termios->c_oflag; \
|
|
k_termio.c_cflag = k_termios->c_cflag; \
|
|
canon = (k_termio.c_lflag = k_termios->c_lflag) & ICANON; \
|
|
\
|
|
k_termio.c_line = k_termios->c_line; \
|
|
k_termio.c_cc[_VINTR] = k_termios->c_cc[VINTR]; \
|
|
k_termio.c_cc[_VQUIT] = k_termios->c_cc[VQUIT]; \
|
|
k_termio.c_cc[_VERASE] = k_termios->c_cc[VERASE]; \
|
|
k_termio.c_cc[_VKILL] = k_termios->c_cc[VKILL]; \
|
|
k_termio.c_cc[_VEOF] = k_termios->c_cc[canon ? VEOF : VMIN]; \
|
|
k_termio.c_cc[_VEOL] = k_termios->c_cc[canon ? VEOL : VTIME]; \
|
|
k_termio.c_cc[_VEOL2] = k_termios->c_cc[VEOL2]; \
|
|
k_termio.c_cc[_VSWTC] = k_termios->c_cc[VSWTC]; \
|
|
\
|
|
copy_to_user(u_termio, &k_termio, sizeof(k_termio)); \
|
|
})
|
|
|
|
#define user_termios_to_kernel_termios(k, u) \
|
|
copy_from_user(k, u, sizeof(struct termios2))
|
|
|
|
#define kernel_termios_to_user_termios(u, k) \
|
|
copy_to_user(u, k, sizeof(struct termios2))
|
|
|
|
#define user_termios_to_kernel_termios_1(k, u) \
|
|
copy_from_user(k, u, sizeof(struct termios))
|
|
|
|
#define kernel_termios_to_user_termios_1(u, k) \
|
|
copy_to_user(u, k, sizeof(struct termios))
|
|
|
|
#endif /* _ALPHA_TERMIOS_H */
|