When executing header code (which contains U-Boot SPL in most cases), wait 10s after every non-xmodem character received (i.e. printed by U-Boot SPL) before timing out.
Sometimes DDR training, which runs in SPL, may be slow. Signed-off-by: Marek Behún <marek.be...@nic.cz> --- tools/kwboot.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/tools/kwboot.c b/tools/kwboot.c index 2e16db83fa..0e60cc8a70 100644 --- a/tools/kwboot.c +++ b/tools/kwboot.c @@ -24,6 +24,7 @@ #include <unistd.h> #include <stdint.h> #include <termios.h> +#include <time.h> #include <sys/mman.h> #include <sys/stat.h> @@ -68,6 +69,7 @@ struct kwboot_block { } __packed; #define KWBOOT_BLK_RSP_TIMEO 1000 /* ms */ +#define KWBOOT_HDR_RSP_TIMEO 10000 /* ms */ static int kwboot_verbose; @@ -381,12 +383,35 @@ _is_xm_reply(char c) return c == ACK || c == NAK || c == CAN; } +static uint64_t +_now(void) +{ + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts)) { + static int err_print; + + if (!err_print) { + perror("clock_gettime() does not work"); + err_print = 1; + } + + /* this will just make the timeout not work */ + return -1ULL; + } + + return ts.tv_sec * 1000 + (ts.tv_nsec + 500000) / 1000000; +} + static int kwboot_xm_sendblock(int fd, struct kwboot_block *block, int allow_non_xm, int *done_print) { + int recv_timeo = allow_non_xm ? KWBOOT_HDR_RSP_TIMEO : blk_rsp_timeo; int non_xm_print = 0; + uint64_t timeout = 0; int rc, retries; + int err; char c; *done_print = 0; @@ -404,14 +429,22 @@ kwboot_xm_sendblock(int fd, struct kwboot_block *block, int allow_non_xm, } do { - rc = kwboot_tty_recv(fd, &c, 1, blk_rsp_timeo); + err = 0; + rc = kwboot_tty_recv(fd, &c, 1, recv_timeo); if (rc) { - if (errno != ETIMEDOUT) + if (errno != ETIMEDOUT) { return rc; - c = NAK; + } else if (timeout && timeout < _now()) { + errno = ETIMEDOUT; + return -1; + } else { + err = errno; + c = NAK; + } } if (!_is_xm_reply(c) && allow_non_xm) { + timeout = _now() + recv_timeo; putchar(c); fflush(stdout); non_xm_print = 1; @@ -425,6 +458,11 @@ kwboot_xm_sendblock(int fd, struct kwboot_block *block, int allow_non_xm, if (non_xm_print) kwboot_printv("\n"); + if (err) { + errno = err; + return -1; + } + rc = -1; switch (c) { -- 2.31.1