aboutsummaryrefslogtreecommitdiff
path: root/cores/arduino/USBCore.cpp
diff options
context:
space:
mode:
authorPaul Brook <paul@nowt.org>2014-03-20 22:44:41 +0000
committerCristian Maglie <c.maglie@bug.st>2014-05-24 00:34:56 +0200
commitb57b2ae3c163a855efca331bf817d566e328f88b (patch)
treed5a8415cbe0d0ff2a36b772eaec928a6846f15c5 /cores/arduino/USBCore.cpp
parent872c88bb5f643702edcc8d0ebfc1f6cd13bcf414 (diff)
Fix race condition in USB CDC transmit
If the Start of Frame interrupt triggers just after the call to USB_SendSpace in USB_Send then we can get data loss. When the first bank is full and the second partially full, the SOF handler will release the second bank via USB_Flush. Data is then lost due to overflow as USB_Send continues writing data to the now-closed bank. Fix this by re-checking the FIFO status inside LockEP, immediately before doing the data write. Signed-off-by: Paul Brook <paul@nowt.org>
Diffstat (limited to 'cores/arduino/USBCore.cpp')
-rw-r--r--cores/arduino/USBCore.cpp5
1 files changed, 4 insertions, 1 deletions
diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp
index d3e0170..76ceb01 100644
--- a/cores/arduino/USBCore.cpp
+++ b/cores/arduino/USBCore.cpp
@@ -290,9 +290,12 @@ int USB_Send(u8 ep, const void* d, int len)
if (n > len)
n = len;
- len -= n;
{
LockEP lock(ep);
+ // Frame may have been released by the SOF interrupt handler
+ if (!ReadWriteAllowed())
+ continue;
+ len -= n;
if (ep & TRANSFER_ZERO)
{
while (n--)