[PATCH v2] ALSA: hda/realtek: add missing error checks for COEF index reads in alc269
songxiebing <[email protected]>
| Newsgroups | org.kernel.vger.linux-sound,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Bob Song <[email protected]> alc_read_coef_idx() and alc_read_coefex_idx() can return -1 on error via snd_hda_codec_read(). Several codec initialization and shutdown functions save these return values and later write them back to hardware registers without checking for errors, potentially corrupting COEF register state on a read failure. Add error checks in: - alc282_init() and alc282_shutup(): check coef78 before write-back - alc285_hp_init(): check coef38/coef0d/coef36 before update, check val before write-back, and break polling loop on error - alc294_hp_init(): break polling loop on read error Signed-off-by: Bob Song <[email protected]> --- v2: - Separate processing of return values from reading COEF and null pointer detection for device. --- sound/hda/codecs/realtek/alc269.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c index 379e1458f4ac..4645793b64ac 100644 --- a/sound/hda/codecs/realtek/alc269.c +++ b/sound/hda/codecs/realtek/alc269.c @@ -296,7 +296,8 @@ static void alc282_init(struct hda_codec *codec) msleep(100); /* Headphone capless set to normal mode */ - alc_write_coef_idx(codec, 0x78, coef78); + if (coef78 != -1) + alc_write_coef_idx(codec, 0x78, coef78); } static void alc282_shutup(struct hda_codec *codec) @@ -333,7 +334,8 @@ static void alc282_shutup(struct hda_codec *codec) alc_auto_setup_eapd(codec, false); alc_shutup_pins(codec); - alc_write_coef_idx(codec, 0x78, coef78); + if (coef78 != -1) + alc_write_coef_idx(codec, 0x78, coef78); } static const struct coef_fw alc283_coefs[] = { @@ -585,15 +587,19 @@ static void alc285_hp_init(struct hda_codec *codec) alc_write_coefex_idx(codec, 0x58, 0x00, 0xf888); /* HP depop procedure start */ val = alc_read_coefex_idx(codec, 0x58, 0x00); - for (i = 0; i < 20 && val & 0x8000; i++) { + for (i = 0; i < 20 && val != -1 && val & 0x8000; i++) { msleep(50); val = alc_read_coefex_idx(codec, 0x58, 0x00); } /* Wait for depop procedure finish */ - alc_write_coefex_idx(codec, 0x58, 0x00, val); /* write back the result */ - alc_update_coef_idx(codec, 0x38, 1<<4, coef38); - alc_update_coef_idx(codec, 0x0d, 0x110, coef0d); - alc_update_coef_idx(codec, 0x36, 3<<13, coef36); + if (val != -1) + alc_write_coefex_idx(codec, 0x58, 0x00, val); /* write back the result */ + if (coef38 != -1) + alc_update_coef_idx(codec, 0x38, 1<<4, coef38); + if (coef0d != -1) + alc_update_coef_idx(codec, 0x0d, 0x110, coef0d); + if (coef36 != -1) + alc_update_coef_idx(codec, 0x36, 3<<13, coef36); msleep(50); alc_update_coef_idx(codec, 0x4a, 1<<15, 0); @@ -858,7 +864,7 @@ static void alc294_hp_init(struct hda_codec *codec) /* Wait for depop procedure finish */ val = alc_read_coefex_idx(codec, 0x58, 0x01); - for (i = 0; i < 20 && val & 0x0080; i++) { + for (i = 0; i < 20 && val != -1 && val & 0x0080; i++) { msleep(50); val = alc_read_coefex_idx(codec, 0x58, 0x01); } -- 2.25.1