static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel, void *dev_id, int size, enum s3c2410_dma_buffresult result) { struct snd_pcm_substream *substream = dev_id; struct s3c24xx_runtime_data *prtd; pr_debug("Entered %s\n", __func__); if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) return; if (PCM_RUNTIME_CHECK(substream)) return; prtd = substream->runtime->private_data; if (substream) snd_pcm_period_elapsed(substream); spin_lock(&prtd->lock); if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { prtd->dma_loaded--; if (!s3c_dma_has_infiniteloop()) s3c_dma_enqueue(substream); } spin_unlock(&prtd->lock); }
/** * snd_pcm_lib_free_vmalloc_buffer - free vmalloc buffer * @substream: the substream with a buffer allocated by * snd_pcm_lib_alloc_vmalloc_buffer() * * Return: Zero if successful, or a negative error code on failure. */ int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; if (PCM_RUNTIME_CHECK(substream)) return -EINVAL; runtime = substream->runtime; vfree(runtime->dma_area); runtime->dma_area = NULL; return 0; }
static int snd_user_ioctl32(struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { struct snd_pcm_runtime *runtime; int err = -ENOIOCTLCMD; if (PCM_RUNTIME_CHECK(substream)) return -ENXIO; runtime = substream->runtime; if (substream->ops->compat_ioctl) err = substream->ops->compat_ioctl(substream, cmd, arg); return err; }
/** * snd_pcm_lib_free_pages - release the allocated DMA buffer. * @substream: the substream to release the DMA buffer * * Releases the DMA buffer allocated via snd_pcm_lib_malloc_pages(). * * Return: Zero if successful, or a negative error code on failure. */ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; if (PCM_RUNTIME_CHECK(substream)) return -EINVAL; runtime = substream->runtime; if (runtime->dma_area == NULL) return 0; if (runtime->dma_buffer_p != &substream->dma_buffer) { /* it's a newly allocated buffer. release it now. */ snd_dma_free_pages(runtime->dma_buffer_p); kfree(runtime->dma_buffer_p); } snd_pcm_set_runtime_buffer(substream, NULL); return 0; }
static int snd_compressed_ioctl32(struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { struct snd_pcm_runtime *runtime; int err = 0; if (PCM_RUNTIME_CHECK(substream)) return -ENXIO; runtime = substream->runtime; if (substream->ops->compat_ioctl) { err = substream->ops->compat_ioctl(substream, cmd, arg); } else { err = -ENOIOCTLCMD; pr_err("%s failed cmd = %d\n", __func__, cmd); } pr_debug("%s called with cmd = %d\n", __func__, cmd); return err; }
int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream, size_t size, gfp_t gfp_flags) { struct snd_pcm_runtime *runtime; if (PCM_RUNTIME_CHECK(substream)) return -EINVAL; runtime = substream->runtime; if (runtime->dma_area) { if (runtime->dma_bytes >= size) return 0; /* already large enough */ vfree(runtime->dma_area); } runtime->dma_area = __vmalloc(size, gfp_flags, PAGE_KERNEL); if (!runtime->dma_area) return -ENOMEM; runtime->dma_bytes = size; return 1; }
/** * snd_pcm_lib_malloc_pages - allocate the DMA buffer * @substream: the substream to allocate the DMA buffer to * @size: the requested buffer size in bytes * * Allocates the DMA buffer on the BUS type given earlier to * snd_pcm_lib_preallocate_xxx_pages(). * * Return: 1 if the buffer is changed, 0 if not changed, or a negative * code on failure. */ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size) { struct snd_pcm_runtime *runtime; struct snd_dma_buffer *dmab = NULL; if (PCM_RUNTIME_CHECK(substream)) return -EINVAL; if (snd_BUG_ON(substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_UNKNOWN)) return -EINVAL; runtime = substream->runtime; if (runtime->dma_buffer_p) { /* perphaps, we might free the large DMA memory region to save some space here, but the actual solution costs us less time */ if (runtime->dma_buffer_p->bytes >= size) { runtime->dma_bytes = size; return 0; /* ok, do not change */ } snd_pcm_lib_free_pages(substream); } if (substream->dma_buffer.area != NULL && substream->dma_buffer.bytes >= size) { dmab = &substream->dma_buffer; /* use the pre-allocated buffer */ } else { dmab = kzalloc(sizeof(*dmab), GFP_KERNEL); if (! dmab) return -ENOMEM; dmab->dev = substream->dma_buffer.dev; if (snd_dma_alloc_pages(substream->dma_buffer.dev.type, substream->dma_buffer.dev.dev, size, dmab) < 0) { kfree(dmab); return -ENOMEM; } } snd_pcm_set_runtime_buffer(substream, dmab); runtime->dma_bytes = size; return 1; /* area was changed */ }