lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20211231134432.atwmuzeceqiklcoa@cae.in-ulm.de>
Date:   Fri, 31 Dec 2021 14:44:32 +0100
From:   "Christian A. Ehrhardt" <cae@...ilie-ehrhardt.de>
To:     alsa-devel@...a-project.org
Cc:     linux-kernel@...r.kernel.org,
        Lucas Tanure <tanureal@...nsource.cirrus.com>,
        Stefan Binding <sbinding@...nsource.cirrus.com>,
        Vitaly Rodionov <vitalyr@...nsource.cirrus.com>,
        Takashi Iwai <tiwai@...e.com>, Jaroslav Kysela <perex@...ex.cz>
Subject: hda/cs8904: Fix jack detection after resume


Hi,

while debugging something different, I found the following
jack detection related bug in the cs8904 driver on my DELL
Inspirion 3501:
- Plug in a headset, play some sound to make sure that
  the headset is detected.
- Stop the sound, wait for the codec to go into suspend (30s
  should be plenty enough time)
- Unplug the headset while the codec is in suspend.
- Try to play sound on the internal speakers. Notice that
  the the driver still thinks the headset is connected. As a result
  there is no sound on the internal speakers.

AFAICS the bug was introduced by the following commit:
| commit 424e531b47f83da87490464c5bf633dfb624fe6a
| Author: Stefan Binding <sbinding@...nsource.cirrus.com>
| Date:   Fri Aug 27 12:02:51 2021 +0100
| 
|     ALSA: hda/cs8409: Ensure Type Detection is only run on startup when
|     necessary

The bug is with the hp_jack_in and mic_jack_in flags that are used
to determine if jack detection should be run etc. These flags
are cleared in the suspend path. This prevents a status change from
being detected after resume as hp_jack_in is cleared by suspend and
there is no jack due to the unplug of the headset.

This status change was never reported to the HDA core, though.
On suspend this is not done, only hd_jack_in is cleared and on
resume the driver thinks that there is no change the needs reporting.

Proposed fix below, please consider inclusion.

     regards   Christian

>From 1dcf34c1d1c6c4852a86ec3ae189afa5d90ea09c Mon Sep 17 00:00:00 2001
From: "Christian A. Ehrhardt" <lk@...e.de>
Date: Fri, 31 Dec 2021 12:13:48 +0100
Subject: [PATCH 2/2] ALSA: hda/cs8409: Fix Jack detection after resume

The suspend code unconditionally sets ->hp_jack_in and ->mic_jack_in
to zero but without reporting this status change to the HDA core.
To compensate for this, always assume a status change on the
first unsol event after boot or resume.

Fixes:	424e531b47f8 ("ALSA: hda/cs8409: Ensure Type Detection is only run on startup when necessary")
Signed-off-by: Christian A. Ehrhardt <lk@...e.de>
---
 sound/pci/hda/patch_cs8409-tables.c | 3 +++
 sound/pci/hda/patch_cs8409.c        | 5 ++++-
 sound/pci/hda/patch_cs8409.h        | 1 +
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c
index 0fb0a428428b..df0b4522babf 100644
--- a/sound/pci/hda/patch_cs8409-tables.c
+++ b/sound/pci/hda/patch_cs8409-tables.c
@@ -252,6 +252,7 @@ struct sub_codec cs8409_cs42l42_codec = {
 	.init_seq_num = ARRAY_SIZE(cs42l42_init_reg_seq),
 	.hp_jack_in = 0,
 	.mic_jack_in = 0,
+	.force_status_change = 1,
 	.paged = 1,
 	.suspended = 1,
 	.no_type_dect = 0,
@@ -443,6 +444,7 @@ struct sub_codec dolphin_cs42l42_0 = {
 	.init_seq_num = ARRAY_SIZE(dolphin_c0_init_reg_seq),
 	.hp_jack_in = 0,
 	.mic_jack_in = 0,
+	.force_status_change = 1,
 	.paged = 1,
 	.suspended = 1,
 	.no_type_dect = 0,
@@ -456,6 +458,7 @@ struct sub_codec dolphin_cs42l42_1 = {
 	.init_seq_num = ARRAY_SIZE(dolphin_c1_init_reg_seq),
 	.hp_jack_in = 0,
 	.mic_jack_in = 0,
+	.force_status_change = 1,
 	.paged = 1,
 	.suspended = 1,
 	.no_type_dect = 1,
diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c
index bf5d7f0c6ba5..aff2b5abb81e 100644
--- a/sound/pci/hda/patch_cs8409.c
+++ b/sound/pci/hda/patch_cs8409.c
@@ -636,7 +636,9 @@ static void cs42l42_run_jack_detect(struct sub_codec *cs42l42)
 
 static int cs42l42_handle_tip_sense(struct sub_codec *cs42l42, unsigned int reg_ts_status)
 {
-	int status_changed = 0;
+	int status_changed = cs42l42->force_status_change;
+
+	cs42l42->force_status_change = 0;
 
 	/* TIP_SENSE INSERT/REMOVE */
 	switch (reg_ts_status) {
@@ -791,6 +793,7 @@ static void cs42l42_suspend(struct sub_codec *cs42l42)
 	cs42l42->last_page = 0;
 	cs42l42->hp_jack_in = 0;
 	cs42l42->mic_jack_in = 0;
+	cs42l42->force_status_change = 1;
 
 	/* Put CS42L42 into Reset */
 	gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0);
diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h
index ade2b838590c..d0b725c7285b 100644
--- a/sound/pci/hda/patch_cs8409.h
+++ b/sound/pci/hda/patch_cs8409.h
@@ -305,6 +305,7 @@ struct sub_codec {
 
 	unsigned int hp_jack_in:1;
 	unsigned int mic_jack_in:1;
+	unsigned int force_status_change:1;
 	unsigned int suspended:1;
 	unsigned int paged:1;
 	unsigned int last_page;
-- 
2.32.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ