瀏覽代碼

ALSA: hda - Fix Oops at codec reset/reconfig

snd_hda_codec_reset() calls restore_pincfgs() where the codec is
powered up again, which eventually tries to resume and initialize via
the callbacks of the codec.  However, it's the place just after codec
free callback, thus no codec callbacks should be called after that.
On a codec like CS4206, it results in Oops due to the access in init
callback.

This patch fixes the issue by clearing the codec callbacks properly
after freeing codec.

Reported-by: Daniel J Blueman <daniel@quora.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 12 年之前
父節點
當前提交
07dc59f098
共有 1 個文件被更改,包括 1 次插入1 次删除
  1. 1 1
      sound/pci/hda/hda_codec.c

+ 1 - 1
sound/pci/hda/hda_codec.c

@@ -2353,6 +2353,7 @@ int snd_hda_codec_reset(struct hda_codec *codec)
 	}
 	}
 	if (codec->patch_ops.free)
 	if (codec->patch_ops.free)
 		codec->patch_ops.free(codec);
 		codec->patch_ops.free(codec);
+	memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
 	snd_hda_jack_tbl_clear(codec);
 	snd_hda_jack_tbl_clear(codec);
 	codec->proc_widget_hook = NULL;
 	codec->proc_widget_hook = NULL;
 	codec->spec = NULL;
 	codec->spec = NULL;
@@ -2368,7 +2369,6 @@ int snd_hda_codec_reset(struct hda_codec *codec)
 	codec->num_pcms = 0;
 	codec->num_pcms = 0;
 	codec->pcm_info = NULL;
 	codec->pcm_info = NULL;
 	codec->preset = NULL;
 	codec->preset = NULL;
-	memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
 	codec->slave_dig_outs = NULL;
 	codec->slave_dig_outs = NULL;
 	codec->spdif_status_reset = 0;
 	codec->spdif_status_reset = 0;
 	module_put(codec->owner);
 	module_put(codec->owner);