Commit 3fdfa165 authored by Jiri Slaby's avatar Jiri Slaby Committed by Greg Kroah-Hartman
Browse files

mxser: restore baud rate if its setting fails



If a user tries to set a too high rate, it fails due to check in
mxser_set_baud(). But the high rate remains set in termios, so the user
might think everything went smooth. Restore the baud rate from the
old_termios if this happens, so that user knows nothing was changed in
fact.

It used to behave the correct way many years ago, but somehow the
restoration vanished with commit 1c45607a (Char: mxser, remove it)
-- the commit removed mxser's older clone.

Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
Link: https://lore.kernel.org/r/20210922075938.31390-1-jslaby@suse.cz


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9136c683
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -559,14 +559,20 @@ static void mxser_handle_cts(struct tty_struct *tty, struct mxser_port *info,
 * This routine is called to set the UART divisor registers to match
 * the specified baud rate for a serial port.
 */
static void mxser_change_speed(struct tty_struct *tty)
static void mxser_change_speed(struct tty_struct *tty, struct ktermios *old_termios)
{
	struct mxser_port *info = tty->driver_data;
	unsigned cflag, cval, fcr;

	cflag = tty->termios.c_cflag;

	mxser_set_baud(tty, tty_get_baud_rate(tty));
	if (mxser_set_baud(tty, tty_get_baud_rate(tty))) {
		/* Use previous rate on a failure */
		if (old_termios) {
			speed_t baud = tty_termios_baud_rate(old_termios);
			tty_encode_baud_rate(tty, baud, baud);
		}
	}

	/* byte size and parity */
	switch (cflag & CSIZE) {
@@ -791,7 +797,7 @@ static int mxser_activate(struct tty_port *port, struct tty_struct *tty)
	/*
	 * and set the speed of the serial port
	 */
	mxser_change_speed(tty);
	mxser_change_speed(tty, NULL);
	spin_unlock_irqrestore(&info->slock, flags);

	return 0;
@@ -1119,7 +1125,7 @@ static int mxser_set_serial_info(struct tty_struct *tty,
	if (tty_port_initialized(port)) {
		if (old_speed != (port->flags & ASYNC_SPD_MASK)) {
			spin_lock_irqsave(&info->slock, sl_flags);
			mxser_change_speed(tty);
			mxser_change_speed(tty, NULL);
			spin_unlock_irqrestore(&info->slock, sl_flags);
		}
	} else {
@@ -1425,7 +1431,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi
	unsigned long flags;

	spin_lock_irqsave(&info->slock, flags);
	mxser_change_speed(tty);
	mxser_change_speed(tty, old_termios);
	spin_unlock_irqrestore(&info->slock, flags);

	if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) {