diff options
Diffstat (limited to 'pcm.c')
-rw-r--r-- | pcm.c | 35 |
1 files changed, 30 insertions, 5 deletions
@@ -67,6 +67,11 @@ static int pcm_open(struct snd_pcm_substream *substream) struct snd_pcm_hardware *hw; unsigned int chans = 0; + if (!snd_avirt_streams_sealed()) { + D_ERRORK("Cannot open PCM. Card is not sealed"); + return -EPERM; + } + // Find the Audio Path mapped to this device stream = snd_avirt_stream_find_by_device(substream->pcm->device); if (IS_ERR_VALUE(stream) || !stream) @@ -84,6 +89,10 @@ static int pcm_open(struct snd_pcm_substream *substream) // Setup remaining hw properties chans = stream->channels; + if (chans == 0) { + D_ERRORK("Channels cannot be 0"); + return -EINVAL; + } hw->channels_min = chans; hw->channels_max = chans; @@ -92,6 +101,22 @@ static int pcm_open(struct snd_pcm_substream *substream) } /** + * pcm_close - Implements 'close' callback for PCM middle layer + * @substream: pointer to ALSA PCM substream + * + * This is called when a PCM substream is closed. + * + * Returns 0 on success or error code otherwise. + */ +static int pcm_close(struct snd_pcm_substream *substream) +{ + // Do additional Audio Path 'close' callback + return DO_AUDIOPATH_CB( + (struct snd_avirt_audiopath *)PRIVATE_DATA(substream)->audiopath, + close, substream); +} + +/** * pcm_hw_params - Implements 'hw_params' callback for PCM middle layer * @substream: pointer to ALSA PCM substream * @hw_params: contains the hardware parameters for the PCM @@ -105,7 +130,6 @@ static int pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { int retval; - size_t bufsz; /* Check supported channels */ if ((params_channels(hw_params) < @@ -117,10 +141,8 @@ static int pcm_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - bufsz = params_buffer_bytes(hw_params) * - substream->runtime->hw.periods_max; - - retval = snd_pcm_lib_alloc_vmalloc_buffer(substream, bufsz); + retval = snd_pcm_lib_alloc_vmalloc_buffer( + substream, params_buffer_bytes(hw_params)); if (retval < 0) D_ERRORK("pcm: buffer allocation failed: %d", retval); @@ -144,6 +166,8 @@ static int pcm_hw_free(struct snd_pcm_substream *substream) err = DO_AUDIOPATH_CB( (struct snd_avirt_audiopath *)PRIVATE_DATA(substream)->audiopath, hw_free, substream); + if (err < 0) + return err; return snd_pcm_lib_free_vmalloc_buffer(substream); } @@ -154,6 +178,7 @@ static int pcm_hw_free(struct snd_pcm_substream *substream) */ struct snd_pcm_ops pcm_ops_avirt = { .open = pcm_open, + .close = pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = pcm_hw_params, .hw_free = pcm_hw_free, |