Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61ca4107 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: hda - Don't assume non-NULL PCM ops



The PCM ops might be set NULL, or cleared to NULL when the driver is
unbound.  Give a proper NULL check at each place to be more robust.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent bbbc7e85
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -4525,7 +4525,11 @@ int snd_hda_codec_prepare(struct hda_codec *codec,
{
	int ret;
	mutex_lock(&codec->bus->prepare_mutex);
	ret = hinfo->ops.prepare(hinfo, codec, stream, format, substream);
	if (hinfo->ops.prepare)
		ret = hinfo->ops.prepare(hinfo, codec, stream, format,
					 substream);
	else
		ret = -ENODEV;
	if (ret >= 0)
		purify_inactive_streams(codec);
	mutex_unlock(&codec->bus->prepare_mutex);
@@ -4546,6 +4550,7 @@ void snd_hda_codec_cleanup(struct hda_codec *codec,
			   struct snd_pcm_substream *substream)
{
	mutex_lock(&codec->bus->prepare_mutex);
	if (hinfo->ops.cleanup)
		hinfo->ops.cleanup(hinfo, codec, substream);
	mutex_unlock(&codec->bus->prepare_mutex);
}
+19 −11
Original line number Diff line number Diff line
@@ -416,6 +416,7 @@ static int azx_pcm_close(struct snd_pcm_substream *substream)
	azx_dev->running = 0;
	spin_unlock_irqrestore(&chip->reg_lock, flags);
	azx_release_device(azx_dev);
	if (hinfo->ops.close)
		hinfo->ops.close(hinfo, apcm->codec, substream);
	snd_hda_power_down(apcm->codec);
	mutex_unlock(&chip->open_mutex);
@@ -808,8 +809,8 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
	mutex_lock(&chip->open_mutex);
	azx_dev = azx_assign_device(chip, substream);
	if (azx_dev == NULL) {
		mutex_unlock(&chip->open_mutex);
		return -EBUSY;
		err = -EBUSY;
		goto unlock;
	}
	runtime->hw = azx_pcm_hw;
	runtime->hw.channels_min = hinfo->channels_min;
@@ -844,12 +845,13 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
				   buff_step);
	snd_hda_power_up(apcm->codec);
	if (hinfo->ops.open)
		err = hinfo->ops.open(hinfo, apcm->codec, substream);
	else
		err = -ENODEV;
	if (err < 0) {
		azx_release_device(azx_dev);
		snd_hda_power_down(apcm->codec);
		mutex_unlock(&chip->open_mutex);
		return err;
		goto powerdown;
	}
	snd_pcm_limit_hw_rates(runtime);
	/* sanity check */
@@ -858,10 +860,10 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
	    snd_BUG_ON(!runtime->hw.formats) ||
	    snd_BUG_ON(!runtime->hw.rates)) {
		azx_release_device(azx_dev);
		if (hinfo->ops.close)
			hinfo->ops.close(hinfo, apcm->codec, substream);
		snd_hda_power_down(apcm->codec);
		mutex_unlock(&chip->open_mutex);
		return -EINVAL;
		err = -EINVAL;
		goto powerdown;
	}

	/* disable LINK_ATIME timestamps for capture streams
@@ -880,6 +882,12 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
	snd_pcm_set_sync(substream);
	mutex_unlock(&chip->open_mutex);
	return 0;

 powerdown:
	snd_hda_power_down(apcm->codec);
 unlock:
	mutex_unlock(&chip->open_mutex);
	return err;
}

static int azx_pcm_mmap(struct snd_pcm_substream *substream,