Endpoints are not being closed on RP2040
Operating System
Others
Board
Raspberry Pi Pico
Firmware
What happened ?
The dcd_edpt_close() implementation in dcd_rp2040.c is incomplete. It was probably meant to call hw_endpoint_close, but that code remains commented out.
With USB audio playback it's common for the endpoints to close and reopen as needed. During silence, the driver selects alternate setting 0 to conserve bandwidth and the endpoint is closed. Then it's reopened when playback starts.
Because the endpoints are not properly closed on RP2040, there are warnings like:
WARN: starting new transfer on already active ep 1 out
and eventually it runs out of buffer space with failed assert hw_data_offset(next_buffer_ptr) <= USB_DPRAM_MAX.
How to reproduce ?
Close and reopen endpoints repeatedly.
Debug Log
Screenshots
Pull request submitted. A couple of notes:
- To keep is simple, buffer space is only reclaimed after all non-control endpoints have closed.
- If a transfer event gets delivered late, after closing the endpoint, it will be ignored. This never happened in my testing.
Why this (more complicated) partial fix that actually seems to introduce a new issue (see below) instead of simply not assigning endpoint buffers multiple times?
Assuming reset_non_control_endpoints() will be called at a safe time: in _hw_endpoint_alloc() an if (!ep->hw_data_buf) around the assignment from next_buffer_ptr would fix it for all cases, right? That is, the warning will remain but no panics anymore and everything keeps functioning as expected. Note that hw_endpoint_close() must be #if 0'ed again, but do keep the hard_assert.
if (!ep->hw_data_buf) {
ep->hw_data_buf = next_buffer_ptr;
next_buffer_ptr += size;
}
With the current fix and just an audio device I think I have the 'transfer event delivered late' bit reproducible, resulting in a "Can't continue xfer on inactive ep 0 out" panic. On a Raspberry Pi 3 I have a test application that transfers audio for 2 seconds then shuts down and is restarted after 1 second. The RP2040 is an audio device that simply echos audio received. The panic occurs mostly within one minute.