* snd_pcm_lib_preallocate_pages_for_all
@ 2004-07-05 7:03 Bo Henriksen
2004-07-05 8:15 ` snd_pcm_lib_preallocate_pages_for_all Russell King
0 siblings, 1 reply; 8+ messages in thread
From: Bo Henriksen @ 2004-07-05 7:03 UTC (permalink / raw)
To: alsa-devel
[-- Attachment #1: Type: text/plain, Size: 3032 bytes --]
Hi,
I am writing an ALSA driver for the Wolfson AC97 codec family
(WM9703/11) for the SHARP LH7A404 processor on the LPD SDK-LH7A404
development board. The driver is written using the 2.6.7 kernel. I
followed the document by Takashi Iwai, "Writing an ALSA Driver" and got
stuck where I have to pre-allocate the DMA buffer (in the
snd_mychip_new_pcm function). I am confused about the second and third
parameter in the snd_pcm_lib_preallocate_pages_for_all function. I used
the sa11xx-uda1341.c as reference on how to allocate the buffer. The
problem is that I am no longer able to allocated ISA buffers using the
SNDRV_DMA_TYPE_ISA as the second parameter. I looked at an updated
version of the uda1341 from handhelds.org and saw they were using
snd_pcm_lib_preallocate_isa_pages_for_all. However, this function is
also not available in ALSA anymore. I then tried to allocate
like this:
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
NULL,
64*1024, 64*1024);
with the third parameter set to NULL. This crashes the kernel with
following backtrace:
-SNIP-
Backtrace:
[<bf025040>] (mark_pages+0x0/0xa8 [snd_page_alloc]) from [<bf0252b8>]
(snd_mallo
c_dev_pages+0x4c/0x54 [snd_page_alloc])
r4 = FFC14000
[<bf02526c>] (snd_malloc_dev_pages+0x0/0x54 [snd_page_alloc]) from
[<bf025438>]
(snd_dma_alloc_pages+0x64/0xb4 [snd_page_alloc])
r5 = 00000000 r4 = C1C6F48C
[<bf0253d4>] (snd_dma_alloc_pages+0x0/0xb4 [snd_page_alloc]) from
[<bf0355ec>] (
preallocate_pcm_pages+0x58/0x9c [snd_pcm])
...
..
-SNIP-
If I insert "_dev" on the third parameter the function completes with
following output 6 times:
lh7a40x-aac lh7a40x-aac0: coherent DMA mask is unset
I looked at the __dma_alloc function for arm (arch/arm/mm/consisten.c)
and saw that it returns NULL because the corherent_dma_mask is not set.
-SNIP at Ln 149 consistent.c:
if (dev) {
mask = dev->coherent_dma_mask;
if (mask == 0) {
dev_warn(dev, "coherent DMA mask is
unset\n");
return NULL;
}
}
-SNIP-
Now, I am not totally familiar with the new DMA interface in Linux 2.6
and there is properly something I am missing here. In theory I just need
to allocate some buffer and give the physical buffer address to the DMA
controller so it can start its function. Should I instead try to
preallocate the buffer myself, using dma_alloc_writecombine and then
pre-set the parameters in the substream->dma_buffer before calling
snd_pcm_lib_malloc_pages from snd_mychip_pcm_hw_params?
Am I missing DMA interface in the 2.6 kernel that I need to implement
for Linux to work correctly?
Regards,
Bo Henriksen
[-- Attachment #2: Type: text/html, Size: 12057 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: snd_pcm_lib_preallocate_pages_for_all
2004-07-05 7:03 snd_pcm_lib_preallocate_pages_for_all Bo Henriksen
@ 2004-07-05 8:15 ` Russell King
0 siblings, 0 replies; 8+ messages in thread
From: Russell King @ 2004-07-05 8:15 UTC (permalink / raw)
To: Bo Henriksen; +Cc: alsa-devel
On Mon, Jul 05, 2004 at 10:03:32AM +0300, Bo Henriksen wrote:
> If I insert "_dev" on the third parameter the function completes with
> following output 6 times:
>
> lh7a40x-aac lh7a40x-aac0: coherent DMA mask is unset
In order to allocate DMA memory, we must know the DMA mask, which
in turn gives us the allowable physical address range for the DMA
allocation.
If you have no restriction, set the coherent DMA mask to ~0.
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial core
-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 -
digital self defense, top technical experts, no vendor pitches,
unmatched networking opportunities. Visit www.blackhat.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: snd_pcm_lib_preallocate_pages_for_all
@ 2004-07-05 8:56 Bo Henriksen
2004-07-05 9:00 ` snd_pcm_lib_preallocate_pages_for_all Russell King
0 siblings, 1 reply; 8+ messages in thread
From: Bo Henriksen @ 2004-07-05 8:56 UTC (permalink / raw)
To: Russell King; +Cc: alsa-devel
Hi,
Ok, I added the coherent_dma_mask = 0xffffffffUL in
arch/arm/mach-lh7a40x/arch.c:
static u64 lh7a40x_ac97_dma_mask = 0xffffffffUL;
static struct platform_device lh7a40x_ac97_device = {
.name = "lh7a40x-aac",
.id = 0,
.dev = {
.dma_mask = &lh7a40x_ac97_dma_mask,
.coherent_dma_mask = 0xffffffffUL,
},
.num_resources = ARRAY_SIZE (lh7a40x_ac97_resources),
.resource = lh7a40x_ac97_resources,
};
It now crashes again. I have tried to preallocate the buffer using
dma_alloc_coherent and free it with dma_free_coherent. This succeeds and
I am using this in other drivers as well. I guess I am missing something
else?
Backtrace:
[<bf025040>] (mark_pages+0x0/0xa8 [snd_page_alloc]) from [<bf0252b8>]
(snd_malloc_d
ev_pages+0x4c/0x54 [snd_page_alloc])
r4 = FFC27000
[<bf02526c>] (snd_malloc_dev_pages+0x0/0x54 [snd_page_alloc]) from
[<bf025438>] (sn
d_dma_alloc_pages+0x64/0xb4 [snd_page_alloc])
r5 = 00000000 r4 = C1F00CCC
...
..
.
-
Bo Henriksen
-----Original Message-----
From: Russell King [mailto:rmk+alsa@arm.linux.org.uk]
Sent: Monday, July 05, 2004 11:16 AM
To: Bo Henriksen
Cc: alsa-devel@lists.sourceforge.net
Subject: Re: [Alsa-devel] snd_pcm_lib_preallocate_pages_for_all
On Mon, Jul 05, 2004 at 10:03:32AM +0300, Bo Henriksen wrote:
> If I insert "_dev" on the third parameter the function completes with
> following output 6 times:
>
> lh7a40x-aac lh7a40x-aac0: coherent DMA mask is unset
In order to allocate DMA memory, we must know the DMA mask, which
in turn gives us the allowable physical address range for the DMA
allocation.
If you have no restriction, set the coherent DMA mask to ~0.
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial core
-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 -
digital self defense, top technical experts, no vendor pitches,
unmatched networking opportunities. Visit www.blackhat.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: snd_pcm_lib_preallocate_pages_for_all
2004-07-05 8:56 snd_pcm_lib_preallocate_pages_for_all Bo Henriksen
@ 2004-07-05 9:00 ` Russell King
2004-07-05 9:17 ` snd_pcm_lib_preallocate_pages_for_all Takashi Iwai
0 siblings, 1 reply; 8+ messages in thread
From: Russell King @ 2004-07-05 9:00 UTC (permalink / raw)
To: Bo Henriksen; +Cc: alsa-devel
On Mon, Jul 05, 2004 at 11:56:25AM +0300, Bo Henriksen wrote:
> It now crashes again. I have tried to preallocate the buffer using
> dma_alloc_coherent and free it with dma_free_coherent. This succeeds and
> I am using this in other drivers as well. I guess I am missing something
> else?
Yes, ALSA assumes that memory returned from dma_alloc_coherent is
kernel direct mapped memory. ALSA is wrong in that assumption.
Hopefully ALSA people can help you further.
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial core
-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 -
digital self defense, top technical experts, no vendor pitches,
unmatched networking opportunities. Visit www.blackhat.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: snd_pcm_lib_preallocate_pages_for_all
2004-07-05 9:00 ` snd_pcm_lib_preallocate_pages_for_all Russell King
@ 2004-07-05 9:17 ` Takashi Iwai
0 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2004-07-05 9:17 UTC (permalink / raw)
To: alsa-devel
At Mon, 5 Jul 2004 10:00:39 +0100,
Russell King wrote:
>
> On Mon, Jul 05, 2004 at 11:56:25AM +0300, Bo Henriksen wrote:
> > It now crashes again. I have tried to preallocate the buffer using
> > dma_alloc_coherent and free it with dma_free_coherent. This succeeds and
> > I am using this in other drivers as well. I guess I am missing something
> > else?
>
> Yes, ALSA assumes that memory returned from dma_alloc_coherent is
> kernel direct mapped memory. ALSA is wrong in that assumption.
> Hopefully ALSA people can help you further.
The simplest solution is to disable mmap on your driver.
(i.e. removing SNDRV_PCM_INFO_MMAP from info field of hw struct).
The ALSA core part believes that the buffer is mmappable as long as
that flag is set, regardless whether it's allocated via
dma_alloc_coherent() or anything else.
I have a hack on my local tree to adapt the new dma_to_*() macros for
ARM, but it's not clean enough yet for merging to the main ALSA tree.
I hope in future the kernel will have a support function for easier
mmap as Russell proposed on lkml.
Takashi
-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 -
digital self defense, top technical experts, no vendor pitches,
unmatched networking opportunities. Visit www.blackhat.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: snd_pcm_lib_preallocate_pages_for_all
@ 2004-07-05 10:57 Bo Henriksen
2004-07-05 11:10 ` snd_pcm_lib_preallocate_pages_for_all Takashi Iwai
0 siblings, 1 reply; 8+ messages in thread
From: Bo Henriksen @ 2004-07-05 10:57 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel
The simplest solution is to disable mmap on your driver.
(i.e. removing SNDRV_PCM_INFO_MMAP from info field of hw struct).
The ALSA core part believes that the buffer is mmappable as long as
that flag is set, regardless whether it's allocated via
dma_alloc_coherent() or anything else.
I have a hack on my local tree to adapt the new dma_to_*() macros for
ARM, but it's not clean enough yet for merging to the main ALSA tree.
I hope in future the kernel will have a support function for easier
mmap as Russell proposed on lkml.
Takashi
-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 -
digital self defense, top technical experts, no vendor pitches,
unmatched networking opportunities. Visit www.blackhat.com
_______________________________________________
Alsa-devel mailing list
Alsa-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-devel
>From my understanding you are saying that I can get my driver working
with the current ALSA by removing the _MMAP_ flags.
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
However, I do not have a pointer to the runtime or the substream at this
stage. How do I change the HW permissions before I call
snd_pcm_lib_preallocate_pages_for_all, where everything crashes, which
is called in snd_mychip_new_pcm? I believe they are set only in the open
callback in the example from the documentation.
Best regards,
Bo Henriksen
-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 -
digital self defense, top technical experts, no vendor pitches,
unmatched networking opportunities. Visit www.blackhat.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: snd_pcm_lib_preallocate_pages_for_all
2004-07-05 10:57 snd_pcm_lib_preallocate_pages_for_all Bo Henriksen
@ 2004-07-05 11:10 ` Takashi Iwai
2004-07-06 8:34 ` snd_pcm_lib_preallocate_pages_for_all Jaroslav Kysela
0 siblings, 1 reply; 8+ messages in thread
From: Takashi Iwai @ 2004-07-05 11:10 UTC (permalink / raw)
To: Bo Henriksen; +Cc: alsa-devel
[-- Attachment #1: Type: text/plain, Size: 772 bytes --]
At Mon, 5 Jul 2004 13:57:22 +0300,
Bo Henriksen wrote:
>
>
> From my understanding you are saying that I can get my driver working
> with the current ALSA by removing the _MMAP_ flags.
>
> runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
>
> However, I do not have a pointer to the runtime or the substream at this
> stage. How do I change the HW permissions before I call
> snd_pcm_lib_preallocate_pages_for_all, where everything crashes, which
> is called in snd_mychip_new_pcm? I believe they are set only in the open
> callback in the example from the documentation.
Ah, of course, the crash in snd_pcm_lib_preallocate_pages_for_all has
nothing to do with mmap. I overlooked the point of crash.
The attached patch should fix it.
Takashi
[-- Attachment #2: Type: text/plain, Size: 3657 bytes --]
Index: alsa-kernel/core/memalloc.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/memalloc.c,v
retrieving revision 1.34
diff -u -r1.34 memalloc.c
--- alsa-kernel/core/memalloc.c 2 Jul 2004 13:17:39 -0000 1.34
+++ alsa-kernel/core/memalloc.c 5 Jul 2004 11:06:31 -0000
@@ -160,24 +160,6 @@
static long snd_allocated_pages; /* holding the number of allocated pages */
-static void mark_pages(void *res, int order)
-{
- struct page *page = virt_to_page(res);
- struct page *last_page = page + (1 << order);
- while (page < last_page)
- SetPageReserved(page++);
- snd_allocated_pages += 1 << order;
-}
-
-static void unmark_pages(void *res, int order)
-{
- struct page *page = virt_to_page(res);
- struct page *last_page = page + (1 << order);
- while (page < last_page)
- ClearPageReserved(page++);
- snd_allocated_pages -= 1 << order;
-}
-
/**
* snd_malloc_pages - allocate pages with the given size
* @size: the size to allocate in bytes
@@ -190,15 +172,11 @@
void *snd_malloc_pages(size_t size, unsigned int gfp_flags)
{
int pg;
- void *res;
snd_assert(size > 0, return NULL);
snd_assert(gfp_flags != 0, return NULL);
- for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
- if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) {
- mark_pages(res, pg);
- }
- return res;
+ pg = get_order(size);
+ return (void *) __get_free_pages(gfp_flags, pg);
}
/**
@@ -243,8 +221,7 @@
if (ptr == NULL)
return;
- for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
- unmark_pages(ptr, pg);
+ pg = get_order(size);
free_pages((unsigned long) ptr, pg);
}
@@ -254,10 +231,10 @@
*
*/
+/* allocate the coherent DMA pages */
static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *dma)
{
int pg;
- void *res;
unsigned int gfp_flags;
snd_assert(size > 0, return NULL);
@@ -266,11 +243,7 @@
gfp_flags = GFP_KERNEL;
if (pg > 0)
gfp_flags |= __GFP_NOWARN;
- res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags);
- if (res != NULL)
- mark_pages(res, pg);
-
- return res;
+ return dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags);
}
static void *snd_malloc_dev_pages_fallback(struct device *dev, size_t size,
@@ -289,6 +262,7 @@
return NULL;
}
+/* free the coherent DMA pages */
static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr,
dma_addr_t dma)
{
@@ -297,7 +271,6 @@
if (ptr == NULL)
return;
pg = get_order(size);
- unmark_pages(ptr, pg);
dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma);
}
@@ -308,16 +281,11 @@
{
struct sbus_dev *sdev = (struct sbus_dev *)dev;
int pg;
- void *res;
snd_assert(size > 0, return NULL);
snd_assert(dma_addr != NULL, return NULL);
- for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
- res = sbus_alloc_consistent(sdev, PAGE_SIZE * (1 << pg), dma_addr);
- if (res != NULL) {
- mark_pages(res, pg);
- }
- return res;
+ pg = get_order(size);
+ return sbus_alloc_consistent(sdev, PAGE_SIZE * (1 << pg), dma_addr);
}
static void *snd_malloc_sbus_pages_fallback(struct device *dev, size_t size,
@@ -344,8 +312,7 @@
if (ptr == NULL)
return;
- for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
- unmark_pages(ptr, pg);
+ pg = get_order(size);
sbus_free_consistent(sdev, PAGE_SIZE * (1 << pg), ptr, dma_addr);
}
@@ -474,7 +441,7 @@
/**
* snd_dma_free_pages - release the allocated buffer
* @dev: the buffer device info
- * @dmbab: the buffer allocation record to release
+ * @dmab: the buffer allocation record to release
*
* Releases the allocated buffer via snd_dma_alloc_pages().
*/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: snd_pcm_lib_preallocate_pages_for_all
2004-07-05 11:10 ` snd_pcm_lib_preallocate_pages_for_all Takashi Iwai
@ 2004-07-06 8:34 ` Jaroslav Kysela
0 siblings, 0 replies; 8+ messages in thread
From: Jaroslav Kysela @ 2004-07-06 8:34 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel
On Mon, 5 Jul 2004, Takashi Iwai wrote:
> Ah, of course, the crash in snd_pcm_lib_preallocate_pages_for_all has
> nothing to do with mmap. I overlooked the point of crash.
>
> The attached patch should fix it.
The patch looks wrong. Some architectures does not mark pages as reserved
and other do it. I discussed this problem with Russell and it seems that
there is no way to distinct these diferences using a generic way, so we
need to add #ifdefs for some platforms.
Jaroslav
-----
Jaroslav Kysela <perex@suse.cz>
Linux Kernel Sound Maintainer
ALSA Project, SUSE Labs
-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 -
digital self defense, top technical experts, no vendor pitches,
unmatched networking opportunities. Visit www.blackhat.com
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2004-07-06 8:34 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-05 8:56 snd_pcm_lib_preallocate_pages_for_all Bo Henriksen
2004-07-05 9:00 ` snd_pcm_lib_preallocate_pages_for_all Russell King
2004-07-05 9:17 ` snd_pcm_lib_preallocate_pages_for_all Takashi Iwai
-- strict thread matches above, loose matches on Subject: below --
2004-07-05 10:57 snd_pcm_lib_preallocate_pages_for_all Bo Henriksen
2004-07-05 11:10 ` snd_pcm_lib_preallocate_pages_for_all Takashi Iwai
2004-07-06 8:34 ` snd_pcm_lib_preallocate_pages_for_all Jaroslav Kysela
2004-07-05 7:03 snd_pcm_lib_preallocate_pages_for_all Bo Henriksen
2004-07-05 8:15 ` snd_pcm_lib_preallocate_pages_for_all Russell King
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.