int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
{
	struct snd_sg_buf *sgbuf = dmab->private_data;
	struct snd_dma_buffer tmpb;
	int i;

	if (! sgbuf)
		return -EINVAL;

	if (dmab->area)
		vunmap(dmab->area);
	dmab->area = NULL;

	tmpb.dev.type = SNDRV_DMA_TYPE_DEV;
	tmpb.dev.dev = sgbuf->dev;
	for (i = 0; i < sgbuf->pages; i++) {
		if (!(sgbuf->table[i].addr & ~PAGE_MASK))
			continue; /* continuous pages */
		tmpb.area = sgbuf->table[i].buf;
		tmpb.addr = sgbuf->table[i].addr & PAGE_MASK;
		tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT;
		snd_dma_free_pages(&tmpb);
	}

	kfree(sgbuf->table);
	kfree(sgbuf->page_table);
	kfree(sgbuf);
	dmab->private_data = NULL;

	return 0;
}
Пример #2
0
/*
 * try to allocate as the large pages as possible.
 * stores the resultant memory size in *res_size.
 *
 * the minimum size is snd_minimum_buffer.  it should be power of 2.
 */
static int preallocate_pcm_pages(snd_pcm_substream_t *substream, size_t size)
{
	struct snd_dma_buffer *dmab = &substream->dma_buffer;
	int err;

	snd_assert(size > 0, return -EINVAL);

	/* already reserved? */
	if (snd_dma_get_reserved_buf(dmab, substream->dma_buf_id) > 0) {
		if (dmab->bytes >= size)
			return 0; /* yes */
		/* no, free the reserved block */
		snd_dma_free_pages(dmab);
		dmab->bytes = 0;
	}

	do {
		if ((err = snd_dma_alloc_pages(dmab->dev.type, dmab->dev.dev,
					       size, dmab)) < 0) {
			if (err != -ENOMEM)
				return err; /* fatal error */
		} else
			return 0;
		size >>= 1;
	} while (size >= snd_minimum_buffer);
	dmab->bytes = 0; /* tell error */
	return 0;
}
Пример #3
0
/*
 * release the preallocated buffer if not yet done.
 */
static void snd_pcm_lib_preallocate_dma_free(struct snd_pcm_substream *substream)
{
	if (substream->dma_buffer.area == NULL)
		return;
	snd_dma_free_pages(&substream->dma_buffer);
	substream->dma_buffer.area = NULL;
}
Пример #4
0
int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
{
	struct snd_sg_buf *sgbuf = dmab->private_data;
	struct snd_dma_buffer tmpb;
	int i;

	if (! sgbuf)
		return -EINVAL;

	tmpb.dev.type = SNDRV_DMA_TYPE_DEV;
	tmpb.dev.dev = sgbuf->dev;
	for (i = 0; i < sgbuf->pages; i++) {
		tmpb.area = sgbuf->table[i].buf;
		tmpb.addr = sgbuf->table[i].addr;
		tmpb.bytes = PAGE_SIZE;
		snd_dma_free_pages(&tmpb);
	}
	if (dmab->area)
		vunmap(dmab->area);
	dmab->area = NULL;

	kfree(sgbuf->table);
	kfree(sgbuf->page_table);
	kfree(sgbuf);
	dmab->private_data = NULL;
	
	return 0;
}
Пример #5
0
/*
 * try to allocate as the large pages as possible.
 * stores the resultant memory size in *res_size.
 *
 * the minimum size is snd_minimum_buffer.  it should be power of 2.
 */
static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t size)
{
	struct snd_dma_buffer *dmab = &substream->dma_buffer;
	size_t orig_size = size;
	int err;

	/* already reserved? */
	if (snd_dma_get_reserved_buf(dmab, substream->dma_buf_id) > 0) {
		if (dmab->bytes >= size)
			return 0; /* yes */
		/* no, free the reserved block */
		snd_dma_free_pages(dmab);
		dmab->bytes = 0;
	}

	do {
		if ((err = snd_dma_alloc_pages(dmab->dev.type, dmab->dev.dev,
					       size, dmab)) < 0) {
			if (err != -ENOMEM)
				return err; /* fatal error */
		} else
			return 0;
		size >>= 1;
	} while (size >= snd_minimum_buffer);
	dmab->bytes = 0; /* tell error */
	pr_warn("ALSA pcmC%dD%d%c,%d:%s: cannot preallocate for size %zu\n",
		substream->pcm->card->number, substream->pcm->device,
		substream->stream ? 'c' : 'p', substream->number,
		substream->pcm->name, orig_size);
	return 0;
}
Пример #6
0
static void snd_bt87x_free_risc(bt87x_t *chip)
{
	if (chip->dma_risc.area) {
		snd_dma_free_pages(&chip->dma_risc);
		chip->dma_risc.area = NULL;
	}
}
Пример #7
0
/*
 * remove the ring buffer and release it if assigned
 */
static void atiixp_clear_dma_packets(atiixp_t *chip, atiixp_dma_t *dma, snd_pcm_substream_t *substream)
{
    if (dma->desc_buf.area) {
        writel(0, chip->remap_addr + dma->ops->llp_offset);
        snd_dma_free_pages(&dma->desc_buf);
        dma->desc_buf.area = NULL;
    }
}
Пример #8
0
static void cs5535audio_clear_dma_packets(struct cs5535audio *cs5535au,
					  struct cs5535audio_dma *dma,
					  struct snd_pcm_substream *substream)
{
	snd_dma_free_pages(&dma->desc_buf);
	dma->desc_buf.area = NULL;
	dma->substream = NULL;
}
Пример #9
0
int snd_p16v_free(struct snd_emu10k1 *chip)
{
	// release the data
	if (chip->p16v_buffer.area) {
		snd_dma_free_pages(&chip->p16v_buffer);
		//snd_printk("period lables free: %p\n", &chip->p16v_buffer);
	}
	return 0;
}
Пример #10
0
/*
 * release all the cards assigned to a manager instance
 */
static int snd_mixart_free(struct mixart_mgr *mgr)
{
	unsigned int i;

	for (i = 0; i < mgr->num_cards; i++) {
		if (mgr->chip[i])
			snd_card_free(mgr->chip[i]->card);
	}

	/* stop mailbox */
	snd_mixart_exit_mailbox(mgr);

	/* release irq  */
	if (mgr->irq >= 0)
		free_irq(mgr->irq, mgr);

	/* reset board if some firmware was loaded */
	if(mgr->dsp_loaded) {
		snd_mixart_reset_board(mgr);
		snd_printdd("reset miXart !\n");
	}

	/* release the i/o ports */
	for (i = 0; i < 2; i++) {
		if (mgr->mem[i].virt)
			iounmap(mgr->mem[i].virt);
	}
	pci_release_regions(mgr->pci);

	/* free flowarray */
	if(mgr->flowinfo.area) {
		snd_dma_free_pages(&mgr->flowinfo);
		mgr->flowinfo.area = NULL;
	}
	/* free bufferarray */
	if(mgr->bufferinfo.area) {
		snd_dma_free_pages(&mgr->bufferinfo);
		mgr->bufferinfo.area = NULL;
	}

	pci_disable_device(mgr->pci);
	kfree(mgr);
	return 0;
}
Пример #11
0
/*
 * release the preallocated buffer if not yet done.
 */
static void snd_pcm_lib_preallocate_dma_free(struct snd_pcm_substream *substream)
{
	if (substream->dma_buffer.area == NULL)
		return;
	if (substream->dma_buf_id)
		snd_dma_reserve_buf(&substream->dma_buffer, substream->dma_buf_id);
	else
		snd_dma_free_pages(&substream->dma_buffer);
	substream->dma_buffer.area = NULL;
}
Пример #12
0
static int clean_via_table(struct viadev *dev, struct snd_pcm_substream *substream,
			   struct pci_dev *pci)
{
	if (dev->table.area) {
		snd_dma_free_pages(&dev->table);
		dev->table.area = NULL;
	}
	kfree(dev->idx_table);
	dev->idx_table = NULL;
	return 0;
}
Пример #13
0
static int stm32_spdifrx_remove(struct platform_device *pdev)
{
	struct stm32_spdifrx_data *spdifrx = platform_get_drvdata(pdev);

	if (spdifrx->ctrl_chan)
		dma_release_channel(spdifrx->ctrl_chan);

	if (spdifrx->dmab)
		snd_dma_free_pages(spdifrx->dmab);

	return 0;
}
Пример #14
0
int snd_p16v_free(struct snd_emu10k1 *chip)
{
	// release the data
	if (chip->p16v_buffer.area) {
		snd_dma_free_pages(&chip->p16v_buffer);
		/*
		dev_dbg(chip->card->dev, "period lables free: %p\n",
			   &chip->p16v_buffer);
		*/
	}
	return 0;
}
Пример #15
0
/**
 * 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().
 *
 * Returns zero if successful, or a negative error code on failure.
 */
int snd_pcm_lib_free_pages(snd_pcm_substream_t *substream)
{
	snd_pcm_runtime_t *runtime;

	snd_assert(substream != NULL, return -EINVAL);
	runtime = substream->runtime;
	snd_assert(runtime != NULL, return -EINVAL);
	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;
}
Пример #16
0
/**
 * 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;
}
Пример #17
0
static void lola_free(struct lola *chip)
{
	if (chip->initialized)
		lola_stop_hw(chip);
	lola_free_pcm(chip);
	lola_free_mixer(chip);
	if (chip->irq >= 0)
		free_irq(chip->irq, (void *)chip);
	if (chip->bar[0].remap_addr)
		iounmap(chip->bar[0].remap_addr);
	if (chip->bar[1].remap_addr)
		iounmap(chip->bar[1].remap_addr);
	if (chip->rb.area)
		snd_dma_free_pages(&chip->rb);
	pci_release_regions(chip->pci);
	pci_disable_device(chip->pci);
	kfree(chip);
}
Пример #18
0
/*
 * write callback for prealloc proc file
 *
 * accepts the preallocation size in kB.
 */
static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
					       struct snd_info_buffer *buffer)
{
	struct snd_pcm_substream *substream = entry->private_data;
	char line[64], str[64];
	size_t size;
	struct snd_dma_buffer new_dmab;

	if (substream->runtime) {
		buffer->error = -EBUSY;
		return;
	}
	if (!snd_info_get_line(buffer, line, sizeof(line))) {
		snd_info_get_str(str, line, sizeof(str));
		size = simple_strtoul(str, NULL, 10) * 1024;
		if ((size != 0 && size < 8192) || size > substream->dma_max) {
			buffer->error = -EINVAL;
			return;
		}
		if (substream->dma_buffer.bytes == size)
			return;
		memset(&new_dmab, 0, sizeof(new_dmab));
		new_dmab.dev = substream->dma_buffer.dev;
		if (size > 0) {
			if (snd_dma_alloc_pages(substream->dma_buffer.dev.type,
						substream->dma_buffer.dev.dev,
						size, &new_dmab) < 0) {
				buffer->error = -ENOMEM;
				return;
			}
			substream->buffer_bytes_max = size;
		} else {
			substream->buffer_bytes_max = UINT_MAX;
		}
		if (substream->dma_buffer.area)
			snd_dma_free_pages(&substream->dma_buffer);
		substream->dma_buffer = new_dmab;
	} else {
		buffer->error = -EINVAL;
	}
}
Пример #19
0
static void dma_free_pages(struct azx *chip, struct snd_dma_buffer *buf)
{
	snd_dma_free_pages(buf);
}
Пример #20
0
static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf)
{
	snd_dma_free_pages(buf);
}
Пример #21
0
void lola_free_pcm(struct lola *chip)
{
	snd_dma_free_pages(&chip->pcm[0].bdl);
	snd_dma_free_pages(&chip->pcm[1].bdl);
}
Пример #22
0
static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci)
{
	if (dmab->area)
		snd_dma_free_pages(dmab);
}
Пример #23
0
static int stm32_spdifrx_probe(struct platform_device *pdev)
{
	struct stm32_spdifrx_data *spdifrx;
	struct reset_control *rst;
	const struct snd_dmaengine_pcm_config *pcm_config = NULL;
	int ret;

	spdifrx = devm_kzalloc(&pdev->dev, sizeof(*spdifrx), GFP_KERNEL);
	if (!spdifrx)
		return -ENOMEM;

	spdifrx->pdev = pdev;
	init_completion(&spdifrx->cs_completion);
	spin_lock_init(&spdifrx->lock);

	platform_set_drvdata(pdev, spdifrx);

	ret = stm_spdifrx_parse_of(pdev, spdifrx);
	if (ret)
		return ret;

	spdifrx->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "kclk",
						    spdifrx->base,
						    spdifrx->regmap_conf);
	if (IS_ERR(spdifrx->regmap)) {
		dev_err(&pdev->dev, "Regmap init failed\n");
		return PTR_ERR(spdifrx->regmap);
	}

	ret = devm_request_irq(&pdev->dev, spdifrx->irq, stm32_spdifrx_isr, 0,
			       dev_name(&pdev->dev), spdifrx);
	if (ret) {
		dev_err(&pdev->dev, "IRQ request returned %d\n", ret);
		return ret;
	}

	rst = devm_reset_control_get(&pdev->dev, NULL);
	if (!IS_ERR(rst)) {
		reset_control_assert(rst);
		udelay(2);
		reset_control_deassert(rst);
	}

	ret = devm_snd_soc_register_component(&pdev->dev,
					      &stm32_spdifrx_component,
					      stm32_spdifrx_dai,
					      ARRAY_SIZE(stm32_spdifrx_dai));
	if (ret)
		return ret;

	ret = stm32_spdifrx_dma_ctrl_register(&pdev->dev, spdifrx);
	if (ret)
		goto error;

	pcm_config = &stm32_spdifrx_pcm_config;
	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0);
	if (ret) {
		dev_err(&pdev->dev, "PCM DMA register returned %d\n", ret);
		goto error;
	}

	return 0;

error:
	if (spdifrx->ctrl_chan)
		dma_release_channel(spdifrx->ctrl_chan);
	if (spdifrx->dmab)
		snd_dma_free_pages(spdifrx->dmab);

	return ret;
}
Пример #24
0
/*
 * Release the DMA-able kernel memory ...
 */
static void free_dmabuf(struct snd_dma_buffer *buf)
{
	if (buf && buf->area)
		snd_dma_free_pages(buf);
}