Re: 答复: [PATCH] xhci: sideband: check vdev liveness before removing endpoints on unregister
From: Wesley Cheng
Date: Mon Sep 21 2026 - 17:51:00 EST
On 9/15/2026 1:35 AM, 胡连勤 wrote:
Hi Michal,
Unfortunately, no. The reproduction rate is very low, and we have
not yet found a stable way to reproduce it — it requires the
device to be in a specific state where the port is disabled after
autosuspend resume, which happens rarely in the field.
Why are offloaded devices being suspended at all? Obviously, no
"sideband entity" can be using a suspended device, so it seems that:
- if the device is unused and meant to be suspended, sideband can be
removed before suspending
- if the device becomes suspended while in use, obviously it's a bug
You raise a valid point. Looking at the code:
The snd-usb-audio driver sets supports_autosuspend = 1
(card.c:1347), so the device can autosuspend when no audio stream
is active.
During suspend, usb_audio_suspend() calls
platform_ops->suspend_cb → qc_usb_audio_offload_suspend(),
which sends a QMI disconnect indication to the ADSP and waits for
dev->in_use to be cleared.
However, qc_usb_audio_offload_suspend() does not call
xhci_sideband_remove_endpoint() or xhci_sideband_unregister().
The sideband registration stays active during suspend — the
endpoint pointers to xHCI ring buffers remain in place.
Hi Lianqin,
Sorry for interjecting here, but just wanted to point out the detail that when we call qc_usb_audio_offload_suspend() --> uaudio_send_disconnect_ind() this will ensure that the audio stream is idle/not active. For example, if there is currently audio playback happening, then this will issue a command to the aDSP to stop the audio playback and disable the offload stream by issuing handle_uaudio_stream_req(req_msg->enable = 0). This will invoke the sideband remove endpoint path.
If the audio stream is already idle, then we shouldn't have an active endpoint registered to xhci sideband.
This is the root design issue: the sideband client assumes the
xHCI ring buffers remain valid across suspend/resume cycles. But
on reset-resume, usb_reset_and_verify_device() → hub_port_init()
→ xhci_discover_or_reset_device() frees and reallocates those
rings, invalidating the sideband's pointers.
Should be only mapped when audio offload is active. Also, we explicitly take a runtime PM reference on enable_audio_stream() using snd_usb_autoresume() and remove this reference on disable_audio_stream(), so minus a PM suspend transition, we shouldn't see the qc_usb_audio_offload_suspend() callback executing when audio playback is happening.
Thanks
Wesley Cheng