From ff9ab52b21d5b5a62abb6ce8120e0b6a7630c3bd Mon Sep 17 00:00:00 2001 From: salalaika Date: Fri, 17 Jul 2026 10:53:23 +0800 Subject: [PATCH] cdc: handle short writes in flush instead of asserting ep_writev can return fewer bytes than requested. The old assert was stripped in release builds, silently dropping data on short writes. Now we keep the unsent tail in the buffer and retry on the next flush. --- core/src/core/usb/drivers/CDC.zig | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/src/core/usb/drivers/CDC.zig b/core/src/core/usb/drivers/CDC.zig index e9ffe1c68..d26561442 100644 --- a/core/src/core/usb/drivers/CDC.zig +++ b/core/src/core/usb/drivers/CDC.zig @@ -204,10 +204,17 @@ pub fn flush(self: *@This()) bool { return false; self.tx_ready.store(false, .seq_cst); - assert(self.tx_end == self.device.ep_writev( + const written = self.device.ep_writev( self.descriptor.ep_in.endpoint.num, &.{self.tx_data[0..self.tx_end]}, - )); + ); + if (written < self.tx_end) { + // Short write: move unsent data to front of buffer + const remaining = self.tx_end - written; + std.mem.copyForwards(u8, self.tx_data[0..remaining], self.tx_data[written..][0..remaining]); + self.tx_end = remaining; + return false; + } self.tx_end = 0; return true; }