tools: kwboot: Properly finish xmodem transfer

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>
This commit is contained in:
Pali Rohár 2021-09-24 23:06:54 +02:00 committed by Stefan Roese
parent 819cd3281d
commit 9cdc264e2c

View file

@ -403,6 +403,29 @@ _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 int
kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm, int *non_xm_print)
{
@ -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;
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