diff options
author | U. Artie Eoff <ullysses.a.eoff@intel.com> | 2015-07-28 16:29:56 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-07-29 13:37:26 -0400 |
commit | 342e84490574cbb2a9c5b1d0886a112ad2bcf4d7 (patch) | |
tree | 39b96490d0d103e54602c3bb8d202f386b934c28 /sound | |
parent | 2d1cb7f658fb9c3ba8f9dab8aca297d4dfdec835 (diff) |
ALSA: hda - Fix race between PM ops and HDA init/probe
PM ops could be triggered before HDA is done initializing
and cause PM to set HDA controller to D3Hot. This can result
in "CORB reset timeout#2, CORBRP = 65535" and "no codecs
initialized". Additionally, PM ops can be triggered before
azx_probe_continue finishes (async probe). This can result
in a NULL deref kernel crash.
To fix this, avoid PM ops if !chip->running.
Signed-off-by: U. Artie Eoff <ullysses.a.eoff@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 735bdcb04ce8..c38c68f57938 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -867,7 +867,7 @@ static int azx_suspend(struct device *dev) | |||
867 | 867 | ||
868 | chip = card->private_data; | 868 | chip = card->private_data; |
869 | hda = container_of(chip, struct hda_intel, chip); | 869 | hda = container_of(chip, struct hda_intel, chip); |
870 | if (chip->disabled || hda->init_failed) | 870 | if (chip->disabled || hda->init_failed || !chip->running) |
871 | return 0; | 871 | return 0; |
872 | 872 | ||
873 | bus = azx_bus(chip); | 873 | bus = azx_bus(chip); |
@@ -902,7 +902,7 @@ static int azx_resume(struct device *dev) | |||
902 | 902 | ||
903 | chip = card->private_data; | 903 | chip = card->private_data; |
904 | hda = container_of(chip, struct hda_intel, chip); | 904 | hda = container_of(chip, struct hda_intel, chip); |
905 | if (chip->disabled || hda->init_failed) | 905 | if (chip->disabled || hda->init_failed || !chip->running) |
906 | return 0; | 906 | return 0; |
907 | 907 | ||
908 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL | 908 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL |
@@ -1027,7 +1027,7 @@ static int azx_runtime_idle(struct device *dev) | |||
1027 | return 0; | 1027 | return 0; |
1028 | 1028 | ||
1029 | if (!power_save_controller || !azx_has_pm_runtime(chip) || | 1029 | if (!power_save_controller || !azx_has_pm_runtime(chip) || |
1030 | azx_bus(chip)->codec_powered) | 1030 | azx_bus(chip)->codec_powered || !chip->running) |
1031 | return -EBUSY; | 1031 | return -EBUSY; |
1032 | 1032 | ||
1033 | return 0; | 1033 | return 0; |