diff options
Diffstat (limited to 'drivers/staging/line6/playback.c')
-rw-r--r-- | drivers/staging/line6/playback.c | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c index 9a51b92c094..4152db2328b 100644 --- a/drivers/staging/line6/playback.c +++ b/drivers/staging/line6/playback.c @@ -351,6 +351,31 @@ void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) wait_clear_audio_out_urbs(line6pcm); } +int line6_alloc_playback_buffer(struct snd_line6_pcm *line6pcm) +{ + /* We may be invoked multiple times in a row so allocate once only */ + if (line6pcm->buffer_out) + return 0; + + line6pcm->buffer_out = + kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * + line6pcm->max_packet_size, GFP_KERNEL); + + if (!line6pcm->buffer_out) { + dev_err(line6pcm->line6->ifcdev, + "cannot malloc playback buffer\n"); + return -ENOMEM; + } + + return 0; +} + +void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm) +{ + kfree(line6pcm->buffer_out); + line6pcm->buffer_out = NULL; +} + /* Callback for completed playback URB. */ @@ -459,16 +484,11 @@ static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream, } /* -- [FD] end */ - /* We may be invoked multiple times in a row so allocate once only */ - if (!line6pcm->buffer_out) - line6pcm->buffer_out = - kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * - line6pcm->max_packet_size, GFP_KERNEL); + if ((line6pcm->flags & MASK_PLAYBACK) == 0) { + ret = line6_alloc_playback_buffer(line6pcm); - if (!line6pcm->buffer_out) { - dev_err(line6pcm->line6->ifcdev, - "cannot malloc playback buffer\n"); - return -ENOMEM; + if (ret < 0) + return ret; } ret = snd_pcm_lib_malloc_pages(substream, @@ -485,9 +505,11 @@ static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream) { struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); - line6_unlink_wait_clear_audio_out_urbs(line6pcm); - kfree(line6pcm->buffer_out); - line6pcm->buffer_out = NULL; + if ((line6pcm->flags & MASK_PLAYBACK) == 0) { + line6_unlink_wait_clear_audio_out_urbs(line6pcm); + line6_free_playback_buffer(line6pcm); + } + return snd_pcm_lib_free_pages(substream); } |