Skip to content

Commit 34b9e89

Browse files
visitorckwgregkh
authored andcommitted
ALSA: hda: Fix headset detection failure due to unstable sort
commit 3b43095 upstream. The auto_parser assumed sort() was stable, but the kernel's sort() uses heapsort, which has never been stable. After commit 0e02ca2 ("lib/sort: optimize heapsort with double-pop variation"), the order of equal elements changed, causing the headset to fail to work. Fix the issue by recording the original order of elements before sorting and using it as a tiebreaker for equal elements in the comparison function. Fixes: b9030a0 ("ALSA: hda - Use standard sort function in hda_auto_parser.c") Reported-by: Austrum <austrum.lab@gmail.com> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219158 Tested-by: Austrum <austrum.lab@gmail.com> Cc: stable@vger.kernel.org Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com> Link: https://patch.msgid.link/20250128165415.643223-1-visitorckw@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent eb1502b commit 34b9e89

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed

sound/pci/hda/hda_auto_parser.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ static int compare_input_type(const void *ap, const void *bp)
8080

8181
/* In case one has boost and the other one has not,
8282
pick the one with boost first. */
83-
return (int)(b->has_boost_on_pin - a->has_boost_on_pin);
83+
if (a->has_boost_on_pin != b->has_boost_on_pin)
84+
return (int)(b->has_boost_on_pin - a->has_boost_on_pin);
85+
86+
/* Keep the original order */
87+
return a->order - b->order;
8488
}
8589

8690
/* Reorder the surround channels
@@ -400,6 +404,8 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
400404
reorder_outputs(cfg->speaker_outs, cfg->speaker_pins);
401405

402406
/* sort inputs in the order of AUTO_PIN_* type */
407+
for (i = 0; i < cfg->num_inputs; i++)
408+
cfg->inputs[i].order = i;
403409
sort(cfg->inputs, cfg->num_inputs, sizeof(cfg->inputs[0]),
404410
compare_input_type, NULL);
405411

sound/pci/hda/hda_auto_parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ struct auto_pin_cfg_item {
3737
unsigned int is_headset_mic:1;
3838
unsigned int is_headphone_mic:1; /* Mic-only in headphone jack */
3939
unsigned int has_boost_on_pin:1;
40+
int order;
4041
};
4142

4243
struct auto_pin_cfg;

0 commit comments

Comments
 (0)