[alsa-devel] Can DMA address, periods, buffer size, etc change after hw_params is called?
Hi,
I wonder if I must take care handling changes in DMA address, number of periods and period size in the prepare callback?
Or are these locked after the first time prepare is called?
The reason I ask is because I'm developing a new ALSA driver and I prepare a cyclic DMA transfer in the first prepare callback. Additional calls to prepare will not do anything DMA stuff.
The cyclic DMA transfer is then released in the close callback.
Should I after the open and hw_params calls be ready to handle any change at all regarding DMA buffer address, periods and/or number of periods?
I hope I made sense in this email (-:
Hans-Christian Egtvedt wrote:
I wonder if I must take care handling changes in DMA address, number of periods and period size in the prepare callback?
Or are these locked after the first time prepare is called?
The hardware parameters like buffer/period size and sample format are set by calling the hw_params callback; they are valid until a call to hw_free (or another call to hw_params), which doesn't happen while the stream is running.
The DMA address is selected by the driver in the hw_params callback, but most drivers let the framework handle this by calling snd_pcm_lib_malloc_pages().
The prepare and start/stop trigger callbacks are called only between hw_params/hw_free, but they could be called multiple times, so you should handle this stuff in the prepare callback only if your device requires that this is done every time before a stream is started.
Best regards, Clemens
On Thu, 29 Jan 2009 09:11:40 +0100 Clemens Ladisch clemens@ladisch.de wrote:
Hans-Christian Egtvedt wrote:
I wonder if I must take care handling changes in DMA address, number of periods and period size in the prepare callback?
Or are these locked after the first time prepare is called?
The hardware parameters like buffer/period size and sample format are set by calling the hw_params callback; they are valid until a call to hw_free (or another call to hw_params), which doesn't happen while the stream is running.
Is there a chance that the following might happen: - stop trigger, - hw_free - hw_params - prepare - start trigger
I.e. without calling close and open?
The DMA address is selected by the driver in the hw_params callback, but most drivers let the framework handle this by calling snd_pcm_lib_malloc_pages().
Yes, this is what I do today. I am considering if I should release the DMA stuff in hw_free and then in the prepare callback check if it needs to be prepared again (since it was released in hw_free).
The prepare and start/stop trigger callbacks are called only between hw_params/hw_free, but they could be called multiple times, so you should handle this stuff in the prepare callback only if your device requires that this is done every time before a stream is started.
Yes, I setup the cyclic DMA buffer the first time I get a prepare callback, and free the cyclic DMA buffer in the hw_free callback.
This works fine as it is now, but I just want to make sure I handle all cases which might appear on the way.
Hans-Christian Egtvedt wrote:
Is there a chance that the following might happen:
- stop trigger,
- hw_free
- hw_params
- prepare
- start trigger
I.e. without calling close and open?
Yes.
It is also possible that the same happens without hw_free, i.e., hw_params has to initialize _or_ to change the parameters.
Clemens Ladisch clemens@ladisch.de wrote:
The DMA address is selected by the driver in the hw_params callback, but most drivers let the framework handle this by calling snd_pcm_lib_malloc_pages().
Yes, this is what I do today. I am considering if I should release the DMA stuff in hw_free and then in the prepare callback check if it needs to be prepared again (since it was released in hw_free).
The framework guarantees that prepare is called only when the hardware parameters are set.
Best regards, Clemens
On Thu, 29 Jan 2009 09:58:10 +0100 Clemens Ladisch clemens@ladisch.de wrote:
Hans-Christian Egtvedt wrote:
Is there a chance that the following might happen:
- stop trigger,
- hw_free
- hw_params
- prepare
- start trigger
I.e. without calling close and open?
Yes.
It is also possible that the same happens without hw_free, i.e., hw_params has to initialize _or_ to change the parameters.
Okay, so to be sure I setup and release my cyclic DMA buffer safely I could use the following model:
in prepare callback setup the DMA buffer, once when called. The hardware parameters should not change at this point.
If I get a hw_params callback after a prepare, then release the DMA buffer, and set it up again in the prepare callback?
Final cleanup of the DMA buffer can/should be done in hw_free?
This sounds safe given my understanding of ALSA. Is there a flow chart which shows how the different callbacks can be called?
Clemens Ladisch clemens@ladisch.de wrote:
The DMA address is selected by the driver in the hw_params callback, but most drivers let the framework handle this by calling snd_pcm_lib_malloc_pages().
Yes, this is what I do today. I am considering if I should release the DMA stuff in hw_free and then in the prepare callback check if it needs to be prepared again (since it was released in hw_free).
The framework guarantees that prepare is called only when the hardware parameters are set.
Noted.
Hans-Christian Egtvedt wrote:
Okay, so to be sure I setup and release my cyclic DMA buffer safely I could use the following model:
in prepare callback setup the DMA buffer, once when called. The hardware parameters should not change at this point.
If I get a hw_params callback after a prepare, then release the DMA buffer, and set it up again in the prepare callback?
Final cleanup of the DMA buffer can/should be done in hw_free?
This would work, but doing it in the hw_params callback would be a little more simple: * In hw_params, free the old buffer (if it exists), then setup the buffer; * in hw_free, free the buffer.
As a rule of thumb, the callbacks open/close, hw_params/hw_free and start/stop trigger are mostly symmetrical, and any resources should be allocated and freed in the functions that belong together. (The start trigger is a special case because it uses two callbacks, prepare and trigger with TRIGGER_START.)
The hw_params and prepare callbacks can be called multiple times.
Is there a flow chart which shows how the different callbacks can be called?
Not yet.
Best regards, Clemens
On Thu, 29 Jan 2009 10:59:51 +0100 Clemens Ladisch clemens@ladisch.de wrote:
Hans-Christian Egtvedt wrote:
Okay, so to be sure I setup and release my cyclic DMA buffer safely I could use the following model:
in prepare callback setup the DMA buffer, once when called. The hardware parameters should not change at this point.
If I get a hw_params callback after a prepare, then release the DMA buffer, and set it up again in the prepare callback?
Final cleanup of the DMA buffer can/should be done in hw_free?
This would work, but doing it in the hw_params callback would be a little more simple:
- In hw_params, free the old buffer (if it exists), then setup the buffer;
I think I was not 100% clear, in addition to call snd_pcm_lib_malloc_pages() in hw_params, I also need to hand over the DMA buffer information to a prepare function in the DMA driver I use with this sound hardware.
So I follow the scheme for free/setup of buffers for my DMA controller setup as well.
hw_params, release DMA controller if exists, then prepare DMA controller.
- in hw_free, free the buffer.
Which I do by calling snd_pcm_lib_free_pages().
and then in hw_free, release DMA controller if exists.
As a rule of thumb, the callbacks open/close, hw_params/hw_free and start/stop trigger are mostly symmetrical, and any resources should be allocated and freed in the functions that belong together. (The start trigger is a special case because it uses two callbacks, prepare and trigger with TRIGGER_START.)
The hw_params and prepare callbacks can be called multiple times.
Noted, which means I should reprepare my DMA controller as well every time I get a hw_params callback and do snd_pcm_lib_malloc_pages().
Is there a flow chart which shows how the different callbacks can be called?
Not yet.
Would probably help me a lot to see the actual flow of the callbacks.
On Thu, Jan 29, 2009 at 1:18 AM, Hans-Christian Egtvedt hans-christian.egtvedt@atmel.com wrote:
Should I after the open and hw_params calls be ready to handle any change at all regarding DMA buffer address, periods and/or number of periods?
You would need to do this, if you allocate your DMA buffer in the hw_params function. However, I recommend that you allocate it in the _new/_open function instead (I can't remember what it's called) for the maximum size possible, and in _hw_params, just remember what the size is supposed to be. That way, you won't need to free/realloc your DMA buffer. Trust me, it's a lot easier this way.
Take a look at commit bf9c8c9ddef7ef761ae9747349175adad0ef16ce, where I modify my driver to move the DMA allocation from _hw_params to _open.
participants (3)
-
Clemens Ladisch
-
Hans-Christian Egtvedt
-
Timur Tabi