We found that our sc16is7xx on spi reported a TX fifo free space value (TXLVL_REG) of 255 ocassionally, which is obviously wrong, with a 64 byte fifo (and caused a buffer overrun, which is fixed seperately). To trigger this, a large write to the tty is sufficient. The fifo fills, TXLVL_REG reads zero, but the handle_tx function does a zero-data-length write to the TX fifo anyways through sc16is7xx_fifo_write. The next TXLVL_REG read then yields 255, for unknown reasons. A subsequent read is ok. Prevent zero-data-length writes if the TX fifo is full, because they are pointless, and because they trigger wrong TXLVL read-outs, and probably other unspecified effects. Signed-off-by: Florian Achleitner <achleitner.florian@xxxxxxxxxxx> --- I think this should not have any negative side-effect. In my setup, it is necessary. drivers/tty/serial/sc16is7xx.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index df45eb2..f1f6323 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -630,10 +630,18 @@ static void sc16is7xx_handle_tx(struct uart_port *port) if (likely(to_send)) { /* Limit to size of TX FIFO */ txlen = sc16is7xx_port_read(port, SC16IS7XX_TXLVL_REG); + if (txlen > SC16IS7XX_FIFO_SIZE) { + dev_err_ratelimited(port->dev, "chip reports %d free bytes in TX " + "fifo, but it only has %d", txlen, SC16IS7XX_FIFO_SIZE); + txlen = 0; + } to_send = (to_send > txlen) ? txlen : to_send; /* prevent buffer overrun if reported txlen is flawed */ to_send = (to_send > sizeof(s->buf)) ? sizeof(s->buf) : to_send; + /* don't send zero-length data */ + if (unlikely(!to_send)) + return; /* Add data to send */ port->icount.tx += to_send; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html