[alsa-devel] mapping externally allocated Scatter Gather DMA buffers

Jaroslav Kysela perex at perex.cz
Thu Nov 11 11:30:44 CET 2010


On Thu, 11 Nov 2010, Manu Abraham wrote:

> On Wed, Nov 10, 2010 at 11:35 PM, Jaroslav Kysela <perex at perex.cz> wrote:
>> On Wed, 10 Nov 2010, Manu Abraham wrote:
>>
>>> On Wed, Nov 10, 2010 at 8:35 PM, Jaroslav Kysela <perex at perex.cz> wrote:
>>>>
>>>> On Wed, 10 Nov 2010, Manu Abraham wrote:
>>>>>
>>>>>        /* enable stream */
>>>>>        /* initializing 8 buffer with "pages" pages each .. */
>>>>>        stream = saa7231_stream_init(saa7231, AUDIO_CAPTURE, ADAPTER_INT,
>>>>> 0, pages);
>>>>>        if (!stream) {
>>>>>                dprintk(SAA7231_ERROR, 1, "ERROR: Registering stream");
>>>>>                return -ENOMEM;
>>>>>        }
>>>>>        audio->stream = stream;
>>>>>        buffer = stream->dmabuf;
>>>>>        saa7231_add_irqevent(saa7231, 43, SAA7231_EDGE_RISING,
>>>>> saa7231_audio_evhandler, "AS2D_AVIS");
>>>>>        dprintk(SAA7231_DEBUG, 1, "Mapping %d buffers with %d pages
>>>>> each",
>>>>> XS2D_BUFFERS, pages);
>>>>
>>>> Unfortunately, I don't understand the role of XS2D_BUFFERS. The ALSA
>>>> bufsize
>>>> is the whole DMA area (you should use params_buffer_bytes() to get this
>>>> value instead of calculating this using periods * period_size).
>>>>
>>>> It means: Just allocate number of pages required for buffer_bytes. Don't
>>>> play with periods (except the interrupts).
>>>
>>>
>>> There are 8 SG buffers for the hardware; the maximum size of each
>>> buffer can be 512 pages,
>>> the minimum can be a single page.
>>
>> Could you describe more the whole DMA layout, including IRQ acks?
>>
>> It seems to me:
>>
>> SG PAGE 1 points to 1 - 512 data pages (4096 bytes long)
>> SG PAGE 2 .....
>>    ....
>> SG PAGE 8 .....
>
>
> I adapted the whole thing to make the buffersize divided amongst the
> XS2D_BUFFERS (8):

Probably yes.

> I hope the mapping of the buffers is okay ? It looks thus, now ..

From information you sent me about hw privately, I think that the 
period_bytes must be 4096 or multiple of this value with minumum count of 
periods 8 (or multiple of 8). Otherwise you get a non-continuous memory 
area (the hw uses only portion of system memory page, thus there'll be 
gaps). The problem is that we have MMAP_COMPLEX mode, but no application 
can handle (does not implement) this mmap mode and I'm not sure, if we 
can even describe the DMA buffer size layout for this case for your 
specific hw.

I would use:

         snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
 				  4096);


 	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS,
 				   8);

And define periods_min = 8 (max to multiple 8 - choose your max limit) and 
period_bytes_min to 4096 (max to multiple 4096 - choose your max limit).

Note that -EIO means that your driver does not called 
snd_pcm_period_elapsed() and/or the pointer callback returns wrong 
position to the audio ring buffer.

 						Jaroslav

-----
Jaroslav Kysela <perex at perex.cz>
Linux Kernel Sound Maintainer
ALSA Project, Red Hat, Inc.


More information about the Alsa-devel mailing list