tools: kwboot: Properly finish xmodem transfer
authorPali Rohár <pali@kernel.org>
Fri, 24 Sep 2021 21:06:54 +0000 (23:06 +0200)
committerStefan Roese <sr@denx.de>
Fri, 1 Oct 2021 09:07:13 +0000 (11:07 +0200)
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 <pali@kernel.org>
[ refactored ]
Signed-off-by: Marek Behún <marek.behun@nic.cz>
Reviewed-by: Stefan Roese <sr@denx.de>
tools/kwboot.c

index 8c11dca..ad91afd 100644 (file)
@@ -404,6 +404,29 @@ _is_xm_reply(char c)
 }
 
 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 int
 kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm, int *non_xm_print)
 {
        int timeout = allow_non_xm ? KWBOOT_HDR_RSP_TIMEO : blk_rsp_timeo;
@@ -483,24 +506,29 @@ kwboot_xm_sendblock(int fd, struct kwboot_block *block, int allow_non_xm,
        if (non_xm_print)
                kwboot_printv("\n");
 
-       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 fd)
+{
+       int rc, retries;
+       char c;
 
-       return rc;
+       kwboot_printv("Finishing transfer\n");
+
+       retries = 16;
+       do {
+               rc = kwboot_tty_send_char(fd, EOT);
+               if (rc)
+                       return rc;
+
+               rc = kwboot_xm_recv_reply(fd, &c, 0, NULL);
+               if (rc)
+                       return rc;
+       } while (c == NAK && retries-- > 0);
+
+       return _xm_reply_to_error(c);
 }
 
 static int
@@ -577,7 +605,7 @@ kwboot_xmodem(int tty, const void *_img, size_t size)
        if (rc)
                return rc;
 
-       return kwboot_tty_send_char(tty, EOT);
+       return kwboot_xm_finish(tty);
 }
 
 static int