From: Takashi Iwai tiwai@suse.de
[ Upstream commit 4c267ae2ef349639b4d9ebf00dd28586a82fdbe6 ]
When the DMA mode is changed on the (still real!) SB AWE32 after playing a stream and closing, the previous DMA setup was still silently kept, and it can confuse the hardware, resulting in the unexpected noises. As a workaround, enforce the disablement of DMA setups when the DMA setup is changed by the kcontrol.
https://bugzilla.kernel.org/show_bug.cgi?id=218185 Link: https://patch.msgid.link/20250610064322.26787-2-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org ---
Based on my analysis of the commit message and code changes, here is my assessment:
**YES** - This commit should be backported to stable kernel trees.
## Extensive Explanation:
### 1. **Bug Fix Nature** This commit fixes a real bug that causes "unexpected noises" on SB AWE32 hardware when DMA mode is changed after playing a stream. The fix addresses a situation where "the previous DMA setup was still silently kept, and it can confuse the hardware."
### 2. **Code Change Analysis** The fix is minimal and surgical: ```c if (change) { snd_dma_disable(chip->dma8); snd_dma_disable(chip->dma16); } ``` This adds only 4 lines that disable both DMA channels when the DMA mode control changes. The fix is: - **Small and contained**: Only affects the `snd_sb16_dma_control_put()` function - **Low risk**: Simply ensures DMA channels are disabled during mode switches - **Clear purpose**: Prevents hardware confusion from stale DMA configurations
### 3. **Hardware Bug Context** The kernel repository analysis reveals this is addressing a known class of hardware issues with SB16 cards: - The driver documents hardware bugs with DMA mode switching (lines 14-18 in sb16_main.c) - The hardware has separate 8-bit and 16-bit DMA channels that cannot mix - Certain chip revisions have bugs where DMA transfers can block when switching modes
### 4. **Safety and Side Effects** The change has minimal side effects: - Only executes when user changes the DMA mode control - The driver already checks for active playback/capture before allowing changes (`if (chip->mode & (SB_MODE_PLAYBACK | SB_MODE_CAPTURE)) return -EBUSY;`) - `snd_dma_disable()` is a standard ISA DMA function that safely disables DMA transfers - The prepare functions already disable/enable DMAs during normal operation
### 5. **Stable Tree Criteria** This meets stable tree criteria: - **Fixes a real bug**: Users experience actual audio problems (unexpected noises) - **No new features**: Pure bug fix, no feature additions - **Minimal change**: 4 lines of straightforward code - **Low regression risk**: Only affects legacy ISA hardware (SB16/AWE32) - **Clear bug report**: References kernel bugzilla #218185
### 6. **Legacy Hardware Consideration** While SB16 is legacy hardware, it's still used: - The bug report is recent (bugzilla #218185) - The commit message states this affects "still real!" hardware - Linux maintains support for legacy hardware in stable trees - The fix prevents audio corruption which significantly impacts user experience
The commit follows the pattern of similar audio driver fixes that were backported (like commit #1 in the examples which fixed DMA synchronization issues). It's a targeted fix for a specific hardware problem with no architectural changes.
sound/isa/sb/sb16_main.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index c4930efd44e3a..5a083eecaa6b9 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c @@ -714,6 +714,10 @@ static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ct change = nval != oval; snd_sb16_set_dma_mode(chip, nval); spin_unlock_irqrestore(&chip->reg_lock, flags); + if (change) { + snd_dma_disable(chip->dma8); + snd_dma_disable(chip->dma16); + } return change; }