Re: [PATCH] ALSA: hda: Reset pending verb count on response timeout
From: Takashi Iwai
Date: Fri Oct 09 2026 - 09:24:19 EST
On Fri, 09 Oct 2026 05:40:40 +0200,
songxiebing wrote:
>
> From: Bob Song <songxiebing@xxxxxxxxxx>
>
> On some controllers the HDA link reports a verb timeout and the driver
> falls back to polling mode. After that, every subsequent verb sent to
> that codec address keeps timing out (roughly one second per verb), while
> the hardware itself looks perfectly healthy: the RIRB write pointer keeps
> advancing, interrupts are still delivered, and verbs that carry no reply
> payload -- notably writes -- still take effect on the codec.
>
> The reason is that snd_hdac_bus_send_cmd() increments
> bus->rirb.cmds[addr] for every verb, but the counter is only decremented
> by snd_hdac_bus_update_rirb() when a matching RIRB response is read, with
> no rollback if the response never arrives.
>
> When a controller cannot fall back to single-command mode, i.e.
> chip->fallback_to_single_cmd is zero, azx_rirb_get_response() bails out
> with -EIO immediately and never reaches the bus-reset / single_cmd
> recovery that reinitializes CORB/RIRB and clears the counters (that path
> is guarded by the same flag). The ACPI platform, Tegra and CIX
> controllers never set that flag, so they are all exposed to this.
>
> A single lost response therefore poisons bus->rirb.cmds[addr]
> permanently: each later verb still gets one response that only brings the
> count back down to the stale baseline of 1, so
> snd_hdac_bus_get_response() keeps timing out even though the codec
> answers normally.
>
> Fix this by dropping the pending count for the codec address once the
> verb is known to be dead. A late response is then handled as a spurious
> response exactly as before, and the following verbs recover.
>
> Signed-off-by: Bob Song <songxiebing@xxxxxxxxxx>
Thanks for the patch.
I think, however, that it's better to fix in the hda core side,
i.e. snd_hdac_bus_exec_verb_unlocked(). When bus->ops->get_response()
gets an error, just reset bus->rirb.cmds[addr]. Maybe create a helper
(e.g. snd_hdac_bus_reset_response_counter(buf, addr)) in
sound/hda/core/controller.c, and call it instead of open-code to make
the meaning clearer.
In this way, it'll cover all HD-audio controllers, not only hda-intel.
Takashi