From 2133f7cf2920d94b827f57cb34b7194b92045404 Mon Sep 17 00:00:00 2001 From: Andrew Kozlik Date: Wed, 12 Feb 2020 17:42:47 +0100 Subject: [PATCH] core: Prevent data loss when writing to USB VCP. --- core/embed/firmware/mphalport.c | 3 ++- core/embed/trezorhal/usb_vcp-impl.h | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/core/embed/firmware/mphalport.c b/core/embed/firmware/mphalport.c index 0451805c6d..7f364f8b42 100644 --- a/core/embed/firmware/mphalport.c +++ b/core/embed/firmware/mphalport.c @@ -33,7 +33,8 @@ int mp_hal_stdin_rx_chr(void) { void mp_hal_stdout_tx_strn(const char *str, size_t len) { if (vcp_iface_num >= 0) { - int r = usb_vcp_write_blocking(vcp_iface_num, (const uint8_t *)str, len, 0); + int r = + usb_vcp_write_blocking(vcp_iface_num, (const uint8_t *)str, len, 500); (void)r; } } diff --git a/core/embed/trezorhal/usb_vcp-impl.h b/core/embed/trezorhal/usb_vcp-impl.h index befeb967ce..b2c11eefcc 100644 --- a/core/embed/trezorhal/usb_vcp-impl.h +++ b/core/embed/trezorhal/usb_vcp-impl.h @@ -297,7 +297,7 @@ int usb_vcp_write(uint8_t iface_num, const uint8_t *buf, uint32_t len) { b->write++; } - return len; + return i; } int usb_vcp_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, @@ -315,13 +315,19 @@ int usb_vcp_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, int usb_vcp_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len, int timeout) { uint32_t start = HAL_GetTick(); - while (sectrue != usb_vcp_can_write(iface_num)) { - if (timeout >= 0 && HAL_GetTick() - start >= timeout) { - return 0; // Timeout + uint32_t i = 0; + while (i < len) { + while (sectrue != usb_vcp_can_write(iface_num)) { + if (timeout >= 0 && HAL_GetTick() - start >= timeout) { + return i; // Timeout + } + __WFI(); // Enter sleep mode, waiting for interrupt } - __WFI(); // Enter sleep mode, waiting for interrupt + int ret = usb_vcp_write(iface_num, buf + i, len - i); + if (ret < 0) return ret; + i += ret; } - return usb_vcp_write(iface_num, buf, len); + return i; } static void usb_vcp_class_init(USBD_HandleTypeDef *dev, usb_vcp_state_t *state,