[alsa-devel] Difference between substream->dma_buffer and substream->runtime->dma_buffer_p?

Takashi Iwai tiwai at suse.de
Tue Jun 19 12:34:30 CEST 2007

At Thu, 14 Jun 2007 17:47:58 -0500,
Timur Tabi wrote:
> The snd_pcm_substream structure has a snd_dma_buffer structure.  snd_dma_buffer looks like 
> this:
> struct snd_dma_buffer {
> 	struct snd_dma_device dev;	/* device type */
> 	unsigned char *area;	/* virtual pointer */
> 	dma_addr_t addr;	/* physical address */
> 	size_t bytes;		/* buffer size in bytes */
> 	void *private_data;	/* private for allocator; don't touch */
> };
> snd_pcm_substream also has a snd_pcm_runtime structure, which looks like this:
> struct snd_pcm_runtime {
> ...
> 	/* -- DMA -- */
> 	unsigned char *dma_area;	/* DMA area */
> 	dma_addr_t dma_addr;		/* physical bus address (not accessible from main CPU) */
> 	size_t dma_bytes;		/* size of DMA area */
> 	struct snd_dma_buffer *dma_buffer_p;	/* allocated buffer */
> Why the redundancy?  Not only does snd_pcm_runtime have dma_area, dma_addr, and dma_bytes, 
> but it also has a pointer to a dns_dma_buffer structure, which also has this information!
> So given a snd_pcm_substream structure, you can obtain the physical address of the DMA 
> buffer three ways:
> substream->dma_buffer.addr
> substream->runtime->dma_addr
> substream->runtime->dma_buffer_p->addr

Some historical reasons.  The struct snd_dma_buffer was introduced
much later than the definition of struct snd_pcm.  Since many drivers
and core parts use runtime->dma_addr and runtime->dma_area, it was
easier to copy the struct dma_buffer members.

> When will these three variable contain different values?  If the answer is never, then why 
> do they all exist?

substream->dma_buffer is _not_ mandatory to be filled.  It's a
field to keep the buffer pool (buffer pre-allocation) information.
But this area isn't necessarily to be the buffer actually used.  When
a bigger buffer is required, the PCM core may allocate it dynamically
(and thus runtime->dma_addr points to a different address than
 pre-allocated area).

Also, some drivers don't need buffer pre-allocation but rather have
fixed buffers.  In such a case, substream->dma_buffer is
uninitialized, and dma_buffer_p is also NULL.

Hence, referring substream->dma_buffer from the driver is wrong in
general.  Ditto for runtime->dma_buffer_p.  Don't touch / look at them
in the driver code.  The driver code needs to take care of only
runtime->dma_addr and runtime->dma_area if needed.


More information about the Alsa-devel mailing list