diff mbox series

[2/4] serial: do not overwrite not-consumed characters in rx buffer

Message ID 20241003141029.920035-3-ravi@prevas.dk
State New
Delegated to: Tom Rini
Headers show
Series some serial rx buffer patches | expand

Commit Message

Rasmus Villemoes Oct. 3, 2024, 2:10 p.m. UTC
Before the previous patch, pasting a string of length x >
CONFIG_SERIAL_RX_BUFFER_SIZE results in getting the
last (x%CONFIG_SERIAL_RX_BUFFER_SIZE) characters from that string.

With the previous patch, one instead gets the last
CONFIG_SERIAL_RX_BUFFER_SIZE characters repeatedly until the ->rd_ptr
catches up.

Both behaviours are counter-intuitive, and happen because the code
that checks for a character available from the hardware does not
account for whether there is actually room in the software buffer to
receive it. Fix that by adding such accounting. This also brings the
software buffering more in line with how most hardware FIFOs
behave (first received characters are kept, overflowing characters are
dropped).

Signed-off-by: Rasmus Villemoes <ravi@prevas.dk>
---
 drivers/serial/serial-uclass.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 05fe9645bee..28d7a202afc 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -328,10 +328,11 @@  static int __serial_tstc(struct udevice *dev)
 static int _serial_tstc(struct udevice *dev)
 {
 	struct serial_dev_priv *upriv = dev_get_uclass_priv(dev);
-	uint wr;
+	uint wr, avail;
 
-	/* Read all available chars into the RX buffer */
-	while (__serial_tstc(dev)) {
+	/* Read all available chars into the RX buffer while there's room */
+	avail = CONFIG_SERIAL_RX_BUFFER_SIZE - (upriv->wr_ptr - upriv->rd_ptr);
+	while (avail-- && __serial_tstc(dev)) {
 		wr = upriv->wr_ptr++ % CONFIG_SERIAL_RX_BUFFER_SIZE;
 		upriv->buf[wr] = __serial_getc(dev);
 	}