lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 9 Jun 2016 20:40:32 +0530
From:	Bhuvanchandra DV <bhuvanchandra.dv@...adex.com>
To:	<gregkh@...uxfoundation.org>
CC:	<stefan@...er.ch>, <shawnguo@...nel.org>, <kernel@...gutronix.de>,
	<mturquette@...libre.com>, <sboyd@...eaurora.org>,
	<jslaby@...e.com>, <linux-arm-kernel@...ts.infradead.org>,
	<linux-clk@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
	<linux-serial@...r.kernel.org>
Subject: [PATCH 1/8] tty: serial: fsl_lpuart: consider TX FIFO too in tx_empty

From: Stefan Agner <stefan@...er.ch>

Currently the tx_empty callback only considers the Transmit Complete
Flag (TC). The reference manual is not quite clear if the TC flag
covers the TX FIFO too. Debug prints on real hardware have shown that
from time to time the TC flag is asserted (indicating Transmitter
idle) while there are still data in the TX FIFO. Hence, in this case
the serial core will call the shutdown callback even though there are
data remaining in the TX FIFO buffers.

Avoid early shutdowns by considering the TX FIFO empty flag too. Also
avoid theoretical race conditions between DMA and the driver by
checking whether the TX DMA is in progress too.

Signed-off-by: Stefan Agner <stefan@...er.ch>
---
 drivers/tty/serial/fsl_lpuart.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 3d79003..fabfa7e 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -810,8 +810,18 @@ static irqreturn_t lpuart32_int(int irq, void *dev_id)
 /* return TIOCSER_TEMT when transmitter is not busy */
 static unsigned int lpuart_tx_empty(struct uart_port *port)
 {
-	return (readb(port->membase + UARTSR1) & UARTSR1_TC) ?
-		TIOCSER_TEMT : 0;
+	struct lpuart_port *sport = container_of(port,
+			struct lpuart_port, port);
+	unsigned char sr1 = readb(port->membase + UARTSR1);
+	unsigned char sfifo = readb(port->membase + UARTSFIFO);
+
+	if (sport->dma_tx_in_progress)
+		return 0;
+
+	if (sr1 & UARTSR1_TC && sfifo & UARTSFIFO_TXEMPT)
+		return TIOCSER_TEMT;
+
+	return 0;
 }
 
 static unsigned int lpuart32_tx_empty(struct uart_port *port)
-- 
2.8.3

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ