fix(usbh_cdc/ecm): fix bulk pipe stalls for CDC-ECM on SW reboot and alt-setting switch#711
Open
siaffaf wants to merge 1 commit into
Open
fix(usbh_cdc/ecm): fix bulk pipe stalls for CDC-ECM on SW reboot and alt-setting switch#711siaffaf wants to merge 1 commit into
siaffaf wants to merge 1 commit into
Conversation
…alt-setting switch Three related fixes for CDC-ECM bulk data pipe reliability: 1. in_xfer_cb: handle CANCELED separately — resubmit the IN transfer so the receive chain restarts automatically after SET_INTERFACE flushes the endpoint during alt=0→alt=1 switch. Remove the retry logic from the default (error) case: leave the pipe HALTED so the USB host client's USBH_EP_CMD_FLUSH can run without hitting ESP_ERR_INVALID_STATE. 2. Add usbh_cdc_restart_in_transfer(): called by the ECM layer after SET_INTERFACE(alt=1) completes to clear the HALTED IN pipe and resubmit the IN transfer chain. 3. Add usbh_cdc_restart_out_transfer(): on a software reboot the device is not power-cycled, so the OUT pipe may be left HALTED from the previous session. Clears the halt and releases the semaphore, guarded by a semaphore-count check so it is a no-op on a healthy pipe (safe to call on both HW and SW reboots). 4. Set USB_TRANSFER_FLAG_ZERO_PACK on the bulk OUT transfer so a ZLP is sent when payload size is an exact multiple of the 64-byte MPS, as required by CDC-ECM spec §3.3.1. Both restart functions are called from iot_usbh_ecm after SET_INTERFACE(alt=1) completes. Tested on ESP32-S3 with a USB modem (VID:1F94 PID:3002),verified on both hardware power-cycle and software reboot (esp_restart()).
d22111c to
24a9f26
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When using
iot_usbh_ecmon ESP32-S3, two failure modes were observed:Software reboot (no power cycle): After
esp_restart(), the USBdevice is not power-cycled and retains its state. A failed OUT transfer
from the previous session leaves the bulk OUT pipe in HALTED state,
blocking all transmits permanently until a hardware power cycle.
IN transfer chain stops after SET_INTERFACE: The bulk IN endpoint
does not physically exist while the data interface is in alt=0. The
initial IN transfer fails with
STATUS_ERROR, leaving the pipe HALTED.After
SET_INTERFACE(alt=1)the endpoint becomes available but thereceive chain never restarts.
Missing ZLP on bulk OUT: Ethernet frames whose size is an exact
multiple of the 64-byte bulk MPS were not followed by a Zero Length
Packet, causing the device to wait indefinitely for more data
(CDC-ECM spec §3.3.1).
Fix
iot_usbh_cdc.c/iot_usbh_cdc.hin_xfer_cbCANCELED case: resubmit the IN transfer instead ofdropping it.
USB_TRANSFER_STATUS_CANCELEDfires when the USB hostflushes the endpoint during SET_INTERFACE — resubmitting here restarts
the chain automatically once alt=1 is active.
in_xfer_cbdefault (error) case: remove the_cdc_reset_transfer_endpoint+ resubmit retry. Leave the pipe HALTEDso the USB host client's internal
USBH_EP_CMD_FLUSHcan completewithout hitting
ESP_ERR_INVALID_STATE. The ECM layer restarts thetransfer explicitly after SET_INTERFACE.
usbh_cdc_restart_in_transfer()(new): clears the HALTED INpipe and resubmits the IN transfer. Called by the ECM layer after
SET_INTERFACE(alt=1) completes.
usbh_cdc_restart_out_transfer()(new): clears the HALTED OUTpipe and releases the semaphore only when the pipe is actually stalled
(
semaphore count == 0). Safe to call unconditionally on both HW andSW reboots — no-op when the pipe is healthy.
USB_TRANSFER_FLAG_ZERO_PACKset on the bulk OUT transfer atallocation time.
iot_usbh_ecm.cCall
usbh_cdc_restart_in_transfer()andusbh_cdc_restart_out_transfer()after
_ecm_config_intf()(i.e. after SET_INTERFACE(alt=1) completes).Testing
Tested on ESP32-S3 with a USB modem (VID:1F94, PID:3002).
esp_restart()): ECM now connects reliably ✓