From bda8361453077a6db2f895eccd345f17bfabfb94 Mon Sep 17 00:00:00 2001 From: Stanislav Ponomarev Date: Fri, 17 Nov 2023 18:15:07 +0400 Subject: [PATCH] serial: Fix sp_flush_incoming for serprog TCP connections During the development of an esp32 serprog-compatible SPI programmer, and implementation of the TCP over Wi-Fi for serprog, I discovered that sp_flush_incoming() silently fails if the underlying sp_fd descriptor is a TCP socket. This patch adds a check for this case - tcflush returns ENOTTY, meaning tcflush is not supported for not terminal objects, in this case a fallback serialport_read_nonblock loop is used. TESTED=esp32-serprog, TCP-over-WiFi mode, ~90% connection attempts fail to synchronize without patch; no synchronization issues with patch applied. Signed-off-by: Stanislav Ponomarev Change-Id: I9724a2fcd4a41dede2c15f83877efa6c3b0b7fae Reviewed-on: https://review.coreboot.org/c/flashrom/+/79112 Reviewed-by: Anastasia Klimchuk Tested-by: build bot (Jenkins) --- serial.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/serial.c b/serial.c index 10d739a33..577ccf43c 100644 --- a/serial.c +++ b/serial.c @@ -377,10 +377,26 @@ void sp_flush_incoming(void) #if IS_WINDOWS PurgeComm(sp_fd, PURGE_RXCLEAR); #else - /* FIXME: error handling */ - tcflush(sp_fd, TCIFLUSH); + if (!tcflush(sp_fd, TCIFLUSH)) + return; + + if (errno == ENOTTY) { // TCP socket case: sp_fd is not a terminal descriptor - tcflush is not supported + unsigned char c; + int ret; + + do { + ret = serialport_read_nonblock(&c, 1, 1, NULL); + } while (ret == 0); + + // positive error code indicates no data available immediately - similar to EAGAIN/EWOULDBLOCK + // i.e. all buffered data was read + // negative error code indicates a permanent error + if (ret < 0) + msg_perr("Could not flush serial port incoming buffer: read has failed"); + } else { // any other errno indicates an unrecoverable sp_fd state + msg_perr_strerror("Could not flush serial port incoming buffer: "); + } #endif - return; } int serialport_shutdown(void *data)