diff options
| author | Cedric Van den Bergh <[email protected]> | 2026-07-08 12:47:03 +0100 |
|---|---|---|
| committer | Cedric Van den Bergh <[email protected]> | 2026-08-07 07:42:31 +0100 |
| commit | cf055c237a93d3308e1670285dfd2b629f0dd8af (patch) | |
| tree | b3631db8eb6b968939cca888372c243b9cbd1478 /src/device | |
| parent | fa750d6bf045f1df4314d283dfe0508d0d066559 (diff) | |
ncm: fix carrier lost on link-state notify collision
tud_network_link_state() delivered the NETWORK_CONNECTION notification
edge-triggered and fire-once: if a previous notification was still in
flight, notification_xmit() returned early and the notification for the
new link state was never queued. Because link_is_up is committed before
the send, the host could be left reporting a stale carrier state - e.g.
a permanent NO-CARRIER after a link up. The notification state was also
mutated from both the caller and the notify xfer-completion callback
with no serialisation, so on RTOS ports where tud_network_link_state()
runs in a task other than tud_task() the two could race.
Defer the whole link-state update onto the usbd task, so it can no
longer race the completion callback. A collision with an in-flight
notification is resolved by re-arming notification_xmit_state and
letting the existing completion callback drive it forward on the next
xfer completion, rather than adding a separate pending/retry flag.
A link toggle does not change the link speed, so strictly only the
NETWORK_CONNECTION notification needs (re)sending, but reusing the
existing speed-then-connection state machine keeps the fix on a single,
already-serialised code path.
Closes #3760
Diffstat (limited to 'src/device')
0 files changed, 0 insertions, 0 deletions
