diff --git a/sys/include/usb/usbus/cdc/acm.h b/sys/include/usb/usbus/cdc/acm.h index c558fecf5460..244d7b06a157 100644 --- a/sys/include/usb/usbus/cdc/acm.h +++ b/sys/include/usb/usbus/cdc/acm.h @@ -41,6 +41,8 @@ */ #include +#include + #include "usb/cdc.h" #include "usb/usbus.h" #include "tsrb.h" @@ -198,9 +200,10 @@ void usbus_cdc_acm_init(usbus_t *usbus, usbus_cdcacm_device_t *cdcacm, * @param[in] buf buffer to submit * @param[in] len length of the submitted buffer * - * @return Number of bytes added to the CDC ACM ring buffer + * @retval -ECONNRESET Failed to submit data + * @retval >=0 Number of bytes added to the CDC ACM ring buffer */ -size_t usbus_cdc_acm_submit(usbus_cdcacm_device_t *cdcacm, +ssize_t usbus_cdc_acm_submit(usbus_cdcacm_device_t *cdcacm, const uint8_t *buf, size_t len); /** diff --git a/sys/picolibc_syscalls_default/syscalls.c b/sys/picolibc_syscalls_default/syscalls.c index 8277f3ba97f6..0849df03f841 100644 --- a/sys/picolibc_syscalls_default/syscalls.c +++ b/sys/picolibc_syscalls_default/syscalls.c @@ -180,10 +180,19 @@ static int picolibc_stdout_queued; static void _picolibc_flush(void) { - if (picolibc_stdout_queued) { - stdio_write(picolibc_stdout, picolibc_stdout_queued); - picolibc_stdout_queued = 0; + char *pos = picolibc_stdout; + char *end = pos + picolibc_stdout_queued; + while (pos < end) { + size_t left = (size_t)end - (size_t)pos; + ssize_t written = stdio_write(pos, left); + if (written < 0) { + /* failed to flush, drop data */ + break; + } + pos += written; } + + picolibc_stdout_queued = 0; } static int picolibc_put(char c, FILE *file) diff --git a/sys/usb/usbus/cdc/acm/cdc_acm.c b/sys/usb/usbus/cdc/acm/cdc_acm.c index 4c9b347f1515..b91872be93de 100644 --- a/sys/usb/usbus/cdc/acm/cdc_acm.c +++ b/sys/usb/usbus/cdc/acm/cdc_acm.c @@ -19,6 +19,7 @@ #define USB_H_USER_IS_RIOT_INTERNAL #include +#include #include #include "tsrb.h" @@ -148,12 +149,12 @@ static size_t _gen_full_acm_descriptor(usbus_t *usbus, void *arg) } /* Submit (ACM interface in) */ -size_t usbus_cdc_acm_submit(usbus_cdcacm_device_t *cdcacm, const uint8_t *buf, size_t len) +ssize_t usbus_cdc_acm_submit(usbus_cdcacm_device_t *cdcacm, const uint8_t *buf, size_t len) { - size_t n; + ssize_t n; unsigned old; if (cdcacm->state == USBUS_CDC_ACM_LINE_STATE_DISCONNECTED) { - return len; + return -ECONNRESET; } old = irq_disable(); diff --git a/sys/usb/usbus/cdc/acm/cdc_acm_stdio.c b/sys/usb/usbus/cdc/acm/cdc_acm_stdio.c index 64ab9bb1d700..ac1c8f3abcfe 100644 --- a/sys/usb/usbus/cdc/acm/cdc_acm_stdio.c +++ b/sys/usb/usbus/cdc/acm/cdc_acm_stdio.c @@ -24,7 +24,6 @@ #include #include -#include "log.h" #include "isrpipe.h" #include "stdio_base.h" @@ -36,15 +35,9 @@ static uint8_t _cdc_tx_buf_mem[CONFIG_USBUS_CDC_ACM_STDIO_BUF_SIZE]; static ssize_t _write(const void* buffer, size_t len) { - const char *start = buffer; - while (len) { - size_t n = usbus_cdc_acm_submit(&cdcacm, buffer, len); - usbus_cdc_acm_flush(&cdcacm); - /* Use tsrb and flush */ - buffer = (char *)buffer + n; - len -= n; - } - return (char *)buffer - start; + ssize_t retval = usbus_cdc_acm_submit(&cdcacm, buffer, len); + usbus_cdc_acm_flush(&cdcacm); + return retval; } static void _cdc_acm_rx_pipe(usbus_cdcacm_device_t *cdcacm,