summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerzy Kasenberg <[email protected]>2022-01-14 09:44:38 +0100
committerJerzy Kasenberg <[email protected]>2022-01-19 09:48:04 +0100
commit36b6ed8ff9035ad0c2e75de92e08799dc3a4b7ed (patch)
tree579f70351115b119f26e51847c3110497a2cdfe1
parent980ffe3b4e41ce5e43c3e8ae13f605f7d7b50b7f (diff)
nrf5x: Fix EP OUT race conditions in OS build
When two tasks entered dcd_edpt_xfer() it was possible that first disabled interrupt to setup total_len and actual_len but second task for another endpoint enabled interrupt between total_len and actual_len resulting in race condition with interrupt, hence mutex is added on top of interrupt being blocked.
-rw-r--r--src/portable/nordic/nrf5x/dcd_nrf5x.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c
index e70565a02..024ea0d90 100644
--- a/src/portable/nordic/nrf5x/dcd_nrf5x.c
+++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c
@@ -463,11 +463,17 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
xfer_td_t* xfer = get_td(epnum, dir);
- dcd_int_disable(rhport);
+ if (!is_in_isr()) {
+ osal_mutex_lock(dcd_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
+ dcd_int_disable(rhport);
+ }
xfer->buffer = buffer;
xfer->total_len = total_bytes;
xfer->actual_len = 0;
- dcd_int_enable(rhport);
+ if (!is_in_isr()) {
+ dcd_int_enable(rhport);
+ osal_mutex_unlock(dcd_mutex);
+ }
// Control endpoint with zero-length packet and opposite direction to 1st request byte --> status stage
bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE));