-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
work around possible RP2040 erratum #2492
Conversation
8e14712
to
dc8cb27
Compare
I'll have to revise this patch, both to clear the ABORT_DONE bits, and to only use ABORT on hardware B2 or later. See adafruit/circuitpython#8824 for details. |
RP2040 device controller does not seem to clear pending transactions configured in EP0 buffer controls when the host aborts a control transfer. This causes assertion failures, including when a buffer AVAILABLE flag set for a previous transfer causes an unexpected transaction completion.
dc8cb27
to
473d400
Compare
thank you I am able to reproduce the issue mentioned in adafruit/circuitpython#8824 with stock cdc_dual_ports example using my intel macbook (os 12.6) using tio quit. Indeed this seems to be macos specific issue (probably related to how its serial driver is implemented). I will investigate more and review suggested fix by this PR. |
as expected, macos send 2 setup consecutive probably due to late response from rp2040. Per USB specs, host can send up to 3 setup packet consecutively, for this tinyusb should drop the previous setup request, abort pending transfer and process this one instead. (Note: since the 2 setup packets are indentical, we can actuall drop the 2nd setup and continue to process which is simpler). |
Standard timeout for control requests with no data stage is 50ms. The second SETUP arrives within the same millisecond as the ACK for the first. This is more likely the host application (probably actually the kernel serial driver) cancelling the control request IRP before completion. I don't think we can depend on the second control request being identical to the first, in that case, so it's safer to process both. Skipping the data or status stages when the interrupt flags show that a SETUP packet has arrived might also be a good addition to my current patch. |
USB 2.0 §5.5.5
|
- rename reset_ep0_pid() to reset_ep0() - minor update log message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
superb! Thank you very much for investigation and fixing the issue. I have also made some tweaks to the PR
- only abort ep0 transfer if it is currently active
- only process the last setup packet in event queues. While testing, I found that some time macos send 2 setup packets fast enough that the 1st setup isn't processed yet. Which can still cause issue
- other minor log
For B0, B1 variant since we cannot abort the current transfer, setting buffer control can cause unexpected behavior, but I guess those variant will fade away anyway.
RP2040 device controller does not seem to clear pending transactions configured in EP0 buffer controls when the host aborts a control transfer. This causes assertion failures, including when a buffer AVAILABLE flag set for a previous transfer causes an unexpected transaction completion.
Describe the PR
Fix assertion failures or panics in the RP2040 DCD when handling aborted control transfers.
Additional context
See adafruit/circuitpython#8824 for analysis and traces.
It's possible this is a hardware erratum. There is no documentation in the RP2040 datasheet about how aborted control transfers are handled. The datasheet does say that the STALL bits are cleared, but nothing about the buffer controls.
There is still a possibility of a race condition, if the control request IRQ isn't serviced before the previously set buffer control configuration causes the peripheral to do a transaction.