Skip to content

Commit

Permalink
mxser: don't throttle manually
Browse files Browse the repository at this point in the history
First, checking tty->receive_room to signalize whether there is enough space
in the tty buffers does not make much sense. Provided the tty buffers
are in tty_port and those are not checked at all.

Second, if the rx path is throttled, with CRTSCTS, RTS is deasserted,
but is never asserted again. This leads to port "lockup", not accepting
any more input.

So:
1) stty -F /dev/ttyMI0 crtscts # the mxser port
2) stty -F /dev/ttyS6 crtscts # the connected port
3) cat /dev/ttyMI0
4) "write in a loop" to /dev/ttyS6
5) cat from 3) produces the bytes from 4)
6) killall -STOP cat (the 3)'s one)
7) wait for RTS to drop on /dev/ttyMI0
8) killall -CONT cat (again the 3)'s one)

cat erroneously produces no more output now (i.e. no data sent from
ttyS6 to ttyMI can be seen).

Note that the step 7) is performed twice: once from n_tty by
tty_throttle_safe(), once by mxser_stoprx() from the receive path. Then
after step 7), n_tty correctly unthrottles the input, but mxser calls
mxser_stoprx() again as there is still only a little space in n_tty
buffers (tty->receive_room mentioned at the beginning), but the device's
FIFO is/can be already filled.

After this patch, the output is correctly resumed, i.e. n_tty both
throttles and unthrottles without interfering with mxser's attempts.

This allows us to get rid of the non-standard ldisc_stop_rx flag from
struct mxser_port.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Link: https://lore.kernel.org/r/20211118073125.12283-15-jslaby@suse.cz
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Jiri Slaby authored and Greg Kroah-Hartman committed Nov 25, 2021
1 parent 49b798a commit c6693e6
Showing 1 changed file with 6 additions and 30 deletions.
36 changes: 6 additions & 30 deletions drivers/tty/mxser.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,6 @@ struct mxser_port {
u8 MCR; /* Modem control register */
u8 FCR; /* FIFO control register */

bool ldisc_stop_rx;

struct async_icount icount; /* kernel counters for 4 input interrupts */
unsigned int timeout;

Expand Down Expand Up @@ -1286,11 +1284,14 @@ static int mxser_get_icount(struct tty_struct *tty,
return 0;
}

static void mxser_stoprx(struct tty_struct *tty)
/*
* This routine is called by the upper-layer tty layer to signal that
* incoming characters should be throttled.
*/
static void mxser_throttle(struct tty_struct *tty)
{
struct mxser_port *info = tty->driver_data;

info->ldisc_stop_rx = true;
if (I_IXOFF(tty)) {
if (info->board->must_hwid) {
info->IER &= ~MOXA_MUST_RECV_ISR;
Expand All @@ -1309,21 +1310,11 @@ static void mxser_stoprx(struct tty_struct *tty)
}
}

/*
* This routine is called by the upper-layer tty layer to signal that
* incoming characters should be throttled.
*/
static void mxser_throttle(struct tty_struct *tty)
{
mxser_stoprx(tty);
}

static void mxser_unthrottle(struct tty_struct *tty)
{
struct mxser_port *info = tty->driver_data;

/* startrx */
info->ldisc_stop_rx = false;
if (I_IXOFF(tty)) {
if (info->x_char)
info->x_char = 0;
Expand Down Expand Up @@ -1515,9 +1506,6 @@ static bool mxser_receive_chars_new(struct tty_struct *tty,
if (hwid == MOXA_MUST_MU150_HWID)
gdl &= MOXA_MUST_GDL_MASK;

if (gdl >= tty->receive_room && !port->ldisc_stop_rx)
mxser_stoprx(tty);

while (gdl--) {
u8 ch = inb(port->ioaddr + UART_RX);
tty_insert_flip_char(&port->port, ch, 0);
Expand All @@ -1530,10 +1518,8 @@ static u8 mxser_receive_chars_old(struct tty_struct *tty,
struct mxser_port *port, u8 status)
{
enum mxser_must_hwid hwid = port->board->must_hwid;
int recv_room = tty->receive_room;
int ignored = 0;
int max = 256;
int cnt = 0;
u8 ch;

do {
Expand Down Expand Up @@ -1568,14 +1554,8 @@ static u8 mxser_receive_chars_old(struct tty_struct *tty,
port->icount.overrun++;
}
}
tty_insert_flip_char(&port->port, ch, flag);
cnt++;
if (cnt >= recv_room) {
if (!port->ldisc_stop_rx)
mxser_stoprx(tty);
if (!tty_insert_flip_char(&port->port, ch, flag))
break;
}

}

if (hwid)
Expand All @@ -1590,9 +1570,6 @@ static u8 mxser_receive_chars_old(struct tty_struct *tty,
static u8 mxser_receive_chars(struct tty_struct *tty,
struct mxser_port *port, u8 status)
{
if (tty->receive_room == 0 && !port->ldisc_stop_rx)
mxser_stoprx(tty);

if (!mxser_receive_chars_new(tty, port, status))
status = mxser_receive_chars_old(tty, port, status);

Expand Down Expand Up @@ -1798,7 +1775,6 @@ static void mxser_initbrd(struct mxser_board *brd, bool high_baud)
tty_port_init(&info->port);
info->port.ops = &mxser_port_ops;
info->board = brd;
info->ldisc_stop_rx = false;

/* Enhance mode enabled here */
if (brd->must_hwid != MOXA_OTHER_UART)
Expand Down

0 comments on commit c6693e6

Please sign in to comment.