Skip to content

Commit 3b43095

Browse files
visitorckwtiwai
authored andcommitted
ALSA: hda: Fix headset detection failure due to unstable sort
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 <[email protected]> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219158 Tested-by: Austrum <[email protected]> Cc: [email protected] Signed-off-by: Kuan-Wei Chiu <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 519b2b1 commit 3b43095

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)