summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiFiPhile <[email protected]>2025-09-12 14:25:44 +0200
committerHiFiPhile <[email protected]>2025-09-12 15:00:19 +0200
commit99bee6a900db60cf232766531e785108f50e614d (patch)
treeeb80a992ce75f1ad5b30a2bd42cf156f7078b9e6
parent4db2bdad07f55b03df8c40928a2b56536fa823e3 (diff)
ehci: fix removed qhd get reused
Signed-off-by: HiFiPhile <[email protected]>
-rw-r--r--src/host/usbh.c2
-rw-r--r--src/portable/ehci/ehci.c14
2 files changed, 12 insertions, 4 deletions
diff --git a/src/host/usbh.c b/src/host/usbh.c
index 1c63ac712..d09874d6e 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -844,7 +844,7 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t
const uint8_t ep_status = tu_edpt_addr(0, 1 - request->bmRequestType_bit.direction);
TU_ASSERT(hcd_edpt_xfer(rhport, daddr, ep_status, NULL, 0));
break;
- }
+ }
case CONTROL_STAGE_ACK: {
// Abort all pending transfers if SET_CONFIGURATION request
diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c
index 76b0142b2..953483583 100644
--- a/src/portable/ehci/ehci.c
+++ b/src/portable/ehci/ehci.c
@@ -35,6 +35,7 @@
#include "host/hcd.h"
#include "host/usbh.h"
+#include "host/usbh_pvt.h"
#include "ehci_api.h"
#include "ehci.h"
@@ -866,14 +867,21 @@ static ehci_qhd_t *qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr) {
}
ehci_qhd_t *qhd_pool = ehci_data.qhd_pool;
+
+ // protect qhd_pool since 'used' and 'removing' can be changed in isr
+ ehci_qhd_t *result = NULL;
+ usbh_spin_lock(false);
for (uint32_t i = 0; i < QHD_MAX; i++) {
if ((qhd_pool[i].dev_addr == dev_addr) &&
- ep_addr == qhd_ep_addr(&qhd_pool[i])) {
- return &qhd_pool[i];
+ ep_addr == qhd_ep_addr(&qhd_pool[i]) &&
+ qhd_pool[i].used && !qhd_pool[i].removing) {
+ result = &qhd_pool[i];
+ break;
}
}
+ usbh_spin_unlock(false);
- return NULL;
+ return result;
}
// Init queue head with endpoint descriptor