[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.
Takashi
More information about the Alsa-devel
mailing list