From: Pali Rohár <p...@kernel.org>

After kwboot sends EOT, BootROM sends back ACK. Add code for handling
this and retry sending EOT on error.

Signed-off-by: Pali Rohár <p...@kernel.org>
[ refactored ]
Signed-off-by: Marek Behún <marek.be...@nic.cz>
---
 tools/kwboot.c | 65 +++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 48 insertions(+), 17 deletions(-)

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 0e60cc8a70..6674a253ff 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -383,6 +383,28 @@ _is_xm_reply(char c)
        return c == ACK || c == NAK || c == CAN;
 }
 
+static int
+_xm_reply_to_error(int c) {
+       int rc = -1;
+
+       switch (c) {
+       case ACK:
+               rc = 0;
+               break;
+       case NAK:
+               errno = EBADMSG;
+               break;
+       case CAN:
+               errno = ECANCELED;
+               break;
+       default:
+               errno = EPROTO;
+               break;
+       }
+
+       return rc;
+}
+
 static uint64_t
 _now(void)
 {
@@ -463,24 +485,32 @@ kwboot_xm_sendblock(int fd, struct kwboot_block *block, 
int allow_non_xm,
                return -1;
        }
 
-       rc = -1;
+       return _xm_reply_to_error(c);
+}
 
-       switch (c) {
-       case ACK:
-               rc = 0;
-               break;
-       case NAK:
-               errno = EBADMSG;
-               break;
-       case CAN:
-               errno = ECANCELED;
-               break;
-       default:
-               errno = EPROTO;
-               break;
-       }
+static int
+kwboot_xm_finish(int tty)
+{
+       int rc, retries;
+       char c;
 
-       return rc;
+       retries = 16;
+       do {
+               rc = kwboot_tty_send_char(tty, EOT);
+               if (rc)
+                       return rc;
+
+               do {
+                       rc = kwboot_tty_recv(tty, &c, 1, blk_rsp_timeo);
+                       if (rc) {
+                               if (errno != ETIMEDOUT)
+                                       return rc;
+                               c = NAK;
+                       }
+               } while (!_is_xm_reply(c) && retries-- > 0);
+       } while (c == NAK && retries-- > 0);
+
+       return _xm_reply_to_error(c);
 }
 
 static int
@@ -557,7 +587,8 @@ kwboot_xmodem(int tty, const void *_img, size_t size)
        if (rc)
                return rc;
 
-       return kwboot_tty_send_char(tty, EOT);
+       kwboot_printv("Finishing transfer\n");
+       return kwboot_xm_finish(tty);
 }
 
 static int
-- 
2.31.1

Reply via email to