From 4a292ac0dacc6ebbfc05b95e8bce0091530028e2 Mon Sep 17 00:00:00 2001 From: Rahix <rahix@rahix.de> Date: Sun, 21 Jul 2019 23:02:45 +0200 Subject: [PATCH] workaround(cdcacm): Fix CDC-ACM lockup on host hangup This patch is a workaround for #54. A lockup is detected if more than 4096 attempts to write to the USB FIFO fail. If this condition is detected, CDC-ACM is disabled until the next reboot. Signed-off-by: Rahix <rahix@rahix.de> --- epicardium/cdcacm.c | 12 ++++++++---- lib/sdk/Libraries/MAXUSB/src/devclass/cdc_acm.c | 6 ++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/epicardium/cdcacm.c b/epicardium/cdcacm.c index 19b1dcfe..cead3780 100644 --- a/epicardium/cdcacm.c +++ b/epicardium/cdcacm.c @@ -199,10 +199,14 @@ uint8_t cdcacm_read(void) void cdcacm_write(uint8_t *data, int len) { - while (acm_present()) { - // TODO: This might fail horribly - if (acm_write(data, len) == len) { - break; + static int lockup_disable = 0; + if (acm_present() && !lockup_disable) { + int ret = acm_write(data, len); + if (ret < 0) { + LOG_ERR("cdcacm", "fifo lockup detected"); + lockup_disable = 1; + } else if (ret != len) { + LOG_WARN("cdcacm", "write length mismatch, got %d", ret); } } } diff --git a/lib/sdk/Libraries/MAXUSB/src/devclass/cdc_acm.c b/lib/sdk/Libraries/MAXUSB/src/devclass/cdc_acm.c index 92bf8df2..c85ca2b8 100644 --- a/lib/sdk/Libraries/MAXUSB/src/devclass/cdc_acm.c +++ b/lib/sdk/Libraries/MAXUSB/src/devclass/cdc_acm.c @@ -329,10 +329,12 @@ int acm_read(uint8_t *buf, unsigned int len) int acm_write(uint8_t *buf, unsigned int len) { unsigned int i = 0; + unsigned int failcount = 0; /* Write data into the FIFO */ while (len > 0) { if (fifo_put8(&wfifo, buf[i]) == 0) { + failcount = 0; /* Success */ i++; len--; } else { @@ -340,6 +342,10 @@ int acm_write(uint8_t *buf, unsigned int len) if (wreq.reqlen == 0) { svc_in_to_host(&wreq); } + + if (failcount++ > 4096) { + return -1; + } } } -- GitLab