rp2040: avoid device-mode state machine hang

Don't mark IN buffers as available during the last 200us of a full-speed
frame. This avoids a situation seen with the USB2.0 hub on a Raspberry
Pi 4 where a late IN token before the next full-speed SOF can cause port
babble and a corrupt ACK packet. The nature of the data corruption has a
chance to cause device lockup.

Use the next SOF to mark delayed buffers as available. This reduces
available Bulk IN bandwidth by approximately 20%, and requires that the
SOF interrupt is enabled while these transfers are ongoing.

Inherit the top-level enable from the corresponding Pico-SDK flag.
Applications that will not use the device in a situation where it could
be plugged into a Pi 4 or Pi 400 (for example, when directly connected
to a commodity hub or other host) can turn off the flag in the SDK.

v2: use a field in hw_endpoint to mark pending.

v3: Partial rewrite following review comments

- Stub functions out if the workaround is not required
- Only force-enable SOF while any vulnerable endpoints are active
- Respect dcd_sof_enable() functionality
- Get rid of all but necessary ifdef hackery
- Fix a bug where the "endpoint lock" was used with an uninitialised pointer.
This commit is contained in:
Jonathan Bell
2023-01-05 13:36:51 +00:00
parent c3e47c31cc
commit 73b0047efc
4 changed files with 96 additions and 8 deletions

View File

@@ -116,6 +116,7 @@ if (NOT TARGET _rp2040_family_inclusion_marker)
target_compile_definitions(tinyusb_additions INTERFACE
PICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1
PICO_RP2040_USB_DEVICE_UFRAME_FIX=1
)
if(DEFINED LOG)