Skip to content

Commit 9f003e7

Browse files
committed
drivers: usb: udc: fix transmission on halted endpoints
Manage endpoint halt state explicitly in set/clear halt functions. Prevent transmissions on halted endpoints in enqueue function. Trigger retransmission post-halt clearance if applicable. Signed-off-by: IBEN EL HADJ MESSAOUD Marwa <[email protected]>
1 parent 9925808 commit 9f003e7

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

drivers/usb/udc/udc_stm32.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,14 @@ static int udc_stm32_ep_set_halt(const struct device *dev,
829829
return -EIO;
830830
}
831831

832+
/*
833+
* Mark non-control endpoint as halted
834+
* to indicate stall condition
835+
*/
836+
if (USB_EP_GET_IDX(cfg->addr) != 0) {
837+
cfg->stat.halted = true;
838+
}
839+
832840
return 0;
833841
}
834842

@@ -847,6 +855,22 @@ static int udc_stm32_ep_clear_halt(const struct device *dev,
847855
return -EIO;
848856
}
849857

858+
/* Clear halted state to resume normal operation */
859+
cfg->stat.halted = false;
860+
861+
if (USB_EP_GET_IDX(cfg->addr)) {
862+
struct net_buf *buf = udc_buf_peek(cfg);
863+
864+
/* Start IN (device-to-host) transfer if not busy */
865+
if (buf != NULL && USB_EP_DIR_IS_IN(cfg->addr) && !udc_ep_is_busy(cfg)) {
866+
udc_stm32_tx(dev, cfg, buf);
867+
}
868+
/* Prepare OUT (host-to-device) transfer if busy */
869+
else if (buf != NULL && USB_EP_DIR_IS_OUT(cfg->addr) && udc_ep_is_busy(cfg)) {
870+
udc_stm32_rx(dev, cfg, buf);
871+
}
872+
}
873+
850874
return 0;
851875
}
852876

@@ -879,8 +903,19 @@ static int udc_stm32_ep_enqueue(const struct device *dev,
879903

880904
lock_key = irq_lock();
881905

882-
if (USB_EP_DIR_IS_IN(epcfg->addr)) {
883-
ret = udc_stm32_tx(dev, epcfg, buf);
906+
if (USB_EP_DIR_IS_IN(epcfg->addr) != 0U) {
907+
if (!epcfg->stat.halted) {
908+
/* Endpoint is not halted, safe to transmit data */
909+
ret = udc_stm32_tx(dev, epcfg, buf);
910+
} else {
911+
/*
912+
* Endpoint is halted (stalled) by the host
913+
* Skip transmission to avoid protocol violations
914+
* and potential data corruption
915+
*/
916+
LOG_DBG("ep 0x%02x halted", epcfg->addr);
917+
ret = 0;
918+
}
884919
} else {
885920
ret = udc_stm32_rx(dev, epcfg, buf);
886921
}

0 commit comments

Comments
 (0)