From 36b6ed8ff9035ad0c2e75de92e08799dc3a4b7ed Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Fri, 14 Jan 2022 09:44:38 +0100 Subject: [PATCH] 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. --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 10 ++++++++-- 1 file 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));