* RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-09 18:01 Gerhard Pircher
2006-06-10 0:34 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 29+ messages in thread
From: Gerhard Pircher @ 2006-06-09 18:01 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel
Hi,
I'm trying to adapt Linux for the AmigaOne, which is a G3/G4 PPC desktop system with a non cache coherent northbridge (MAI ArticiaS), a VIA82C686B southbridge and the U-boot firmware. Due to the cache coherency problem I compiled in the CONFIG_NOT_COHERENT_CACHE option (arch/ppc/kernel/dma-mapping.c) in the AmigaOne Linux kernel.
While that fixes the DMA data corruption problem, it causes a kernel oops or a complete system lookup after starting sound playback. With kernel versions =<2.6.14 the oops messages refered to a BUG() entry in mm/rmap.c. Therefore I tried out a newer kernel (2.6.16.15), where the oops refers to the ALSA function snd_pcm_mmap_data_nopage() implemented in pcm_native.c.
Well, after searching a while in some old linux kernel threads, I found this thread here:
http://www.thisishull.net/showthread.php?t=22080&page=3&pp=10
Based on the information in this thread, I came to the conclusion that ALSA simply won't work on non cache coherent architectures (except ARM), because the generic DMA API was never expanded to support the functionality required by ALSA (namely mapping dma pages into user space with dma_mmap_coherent()).
This leads me to the question, if there are any plans to include the dma_mmap_coherent() function (for powerpc/ppc and/or any other platform) in one of the next kernel versions and if an adapation of the ALSA drivers is planned. Or is there a simple way (hack) to fix this problem?
Thanks!
Regards,
Gerhard
--
--
-- email : gerhard_pircher -AT- gmx -DOT- net
--
Echte DSL-Flatrate dauerhaft für 0,- Euro*!
"Feel free" mit GMX DSL! http://www.gmx.net/de/go/dsl
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
2006-06-09 18:01 Gerhard Pircher
@ 2006-06-10 0:34 ` Benjamin Herrenschmidt
2006-06-10 0:46 ` Lee Revell
0 siblings, 1 reply; 29+ messages in thread
From: Benjamin Herrenschmidt @ 2006-06-10 0:34 UTC (permalink / raw)
To: Gerhard Pircher; +Cc: linuxppc-dev, linux-kernel
> This leads me to the question, if there are any plans to include the dma_mmap_coherent() function (for powerpc/ppc and/or any other platform) in one of the next kernel versions and if an adapation of the ALSA drivers is planned. Or is there a simple way (hack) to fix this problem?
You are welcome to do a patch implementing this :)
Ben.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
2006-06-10 0:34 ` Benjamin Herrenschmidt
@ 2006-06-10 0:46 ` Lee Revell
0 siblings, 0 replies; 29+ messages in thread
From: Lee Revell @ 2006-06-10 0:46 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linux-kernel, linuxppc-dev
On Sat, 2006-06-10 at 10:34 +1000, Benjamin Herrenschmidt wrote:
> > This leads me to the question, if there are any plans to include the dma_mmap_coherent() function (for powerpc/ppc and/or any other platform) in one of the next kernel versions and if an adapation of the ALSA drivers is planned. Or is there a simple way (hack) to fix this problem?
>
> You are welcome to do a patch implementing this :)
Please cc: alsa-devel when you do so.
Lee
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-10 0:46 ` Lee Revell
0 siblings, 0 replies; 29+ messages in thread
From: Lee Revell @ 2006-06-10 0:46 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: Gerhard Pircher, linuxppc-dev, linux-kernel
On Sat, 2006-06-10 at 10:34 +1000, Benjamin Herrenschmidt wrote:
> > This leads me to the question, if there are any plans to include the dma_mmap_coherent() function (for powerpc/ppc and/or any other platform) in one of the next kernel versions and if an adapation of the ALSA drivers is planned. Or is there a simple way (hack) to fix this problem?
>
> You are welcome to do a patch implementing this :)
Please cc: alsa-devel when you do so.
Lee
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-10 8:22 Gerhard Pircher
2006-06-12 10:51 ` Takashi Iwai
0 siblings, 1 reply; 29+ messages in thread
From: Gerhard Pircher @ 2006-06-10 8:22 UTC (permalink / raw)
To: Lee Revell, benh; +Cc: linuxppc-dev, alsa-devel, linux-kernel
> -------- Original-Nachricht --------
> Datum: Fri, 09 Jun 2006 20:46:32 -0400
> Von: Lee Revell <rlrevell@joe-job.com>
> An: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Betreff: Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and
> ALSA?
>
> On Sat, 2006-06-10 at 10:34 +1000, Benjamin Herrenschmidt wrote:
> > > This leads me to the question, if there are any plans to include the
> > > dma_mmap_coherent() function (for powerpc/ppc and/or any other
> > > platform) in one of the next kernel versions and if an adapation of
> > > the ALSA drivers is planned. Or is there a simple way (hack) to fix
> > > this problem?
> >
> > You are welcome to do a patch implementing this :)
>
> Please cc: alsa-devel when you do so.
:)
Well, implementing the dma_mmap_coherent() function isn't the problem, because it is already implemented for the ARM architecture. But as far as I understand this would require a rewrite of all the ALSA drivers (or at least a rewrite of the ALSA's DMA helper functions).
Original mail included for alsa-devel mailing list:
> I'm trying to adapt Linux for the AmigaOne, which is a G3/G4 PPC desktop
> system with a non cache coherent northbridge (MAI ArticiaS), a VIA82C686B
> southbridge and the U-boot firmware. Due to the cache coherency problem I
> compiled in the CONFIG_NOT_COHERENT_CACHE option
> (arch/ppc/kernel/dma-mapping.c) in the AmigaOne Linux kernel.
> While that fixes the DMA data corruption problem, it causes a kernel oops
> or a complete system lookup after starting sound playback. With kernel
> versions =<2.6.14 the oops messages refered to a BUG() entry in
> mm/rmap.c. Therefore I tried out a newer kernel (2.6.16.15), where the
> oops refers to the ALSA function snd_pcm_mmap_data_nopage() implemented
> in pcm_native.c.
> Well, after searching a while in some old linux kernel threads, I found
> this thread here:
> http://www.thisishull.net/showthread.php?t=22080&page=3&pp=10
> Based on the information in this thread, I came to the conclusion that
> ALSA simply won't work on non cache coherent architectures (except ARM),
> because the generic DMA API was never expanded to support the
> functionality required by ALSA (namely mapping dma pages into user space > with dma_mmap_coherent()).
> This leads me to the question, if there are any plans to include the
> dma_mmap_coherent() function (for powerpc/ppc and/or any other platform)
> in one of the next kernel versions and if an adapation of the ALSA
> drivers is planned. Or is there a simple way (hack) to fix this problem?
Gerhard
--
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
2006-06-10 8:22 RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA? Gerhard Pircher
2006-06-12 10:51 ` Takashi Iwai
@ 2006-06-12 10:51 ` Takashi Iwai
0 siblings, 0 replies; 29+ messages in thread
From: Takashi Iwai @ 2006-06-12 10:51 UTC (permalink / raw)
To: Gerhard Pircher; +Cc: benh, Lee Revell, alsa-devel, linux-kernel, linuxppc-dev
At Sat, 10 Jun 2006 10:22:23 +0200,
Gerhard Pircher wrote:
>
> > -------- Original-Nachricht --------
> > Datum: Fri, 09 Jun 2006 20:46:32 -0400
> > Von: Lee Revell <rlrevell@joe-job.com>
> > An: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Betreff: Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and
> > ALSA?
> >
> > On Sat, 2006-06-10 at 10:34 +1000, Benjamin Herrenschmidt wrote:
> > > > This leads me to the question, if there are any plans to include the
> > > > dma_mmap_coherent() function (for powerpc/ppc and/or any other
> > > > platform) in one of the next kernel versions and if an adapation of
> > > > the ALSA drivers is planned. Or is there a simple way (hack) to fix
> > > > this problem?
> > >
> > > You are welcome to do a patch implementing this :)
> >
> > Please cc: alsa-devel when you do so.
>
> :)
>
> Well, implementing the dma_mmap_coherent() function isn't the
> problem, because it is already implemented for the ARM
> architecture.
Actually, I wrote dma_coherent_mmap patch long time ago but it has
been left forgotten. The patch attached below seems applicable to
2.6.17 tree, but I'm not sure whether it still works properly.
It's untested on most of architectures.
> But as far as I understand this would require a
> rewrite of all the ALSA drivers (or at least a rewrite of the ALSA's
> DMA helper functions).
Yes. The change of ALSA side has been also on my tree. But it was
still pending since I'm not satisfied with the design yet.
If you're interested in it, let me know. I'll post the patch.
Takashi
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index 4985466..17a3064 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -106,6 +106,14 @@ void dma_free_coherent(struct device *hw
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ return -ENXIO;
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
/*
* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index 671ce1e..d4a8326 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -37,6 +37,21 @@ void dma_free_coherent(struct device *hw
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn;
+
+ /* bus is equivalent with phys */
+ pfn = ((unsigned long)handle) >> PAGE_SHIFT;
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
/*
* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c
index f6b3c72..2b591e4 100644
--- a/arch/mips/mm/dma-coherent.c
+++ b/arch/mips/mm/dma-coherent.c
@@ -59,6 +59,24 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+ __attribute__((alias("dma_mmap_noncoherent")));
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/mips/mm/dma-ip27.c b/arch/mips/mm/dma-ip27.c
index 8da19fd..db453eb 100644
--- a/arch/mips/mm/dma-ip27.c
+++ b/arch/mips/mm/dma-ip27.c
@@ -64,6 +64,27 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return dma_mmap_noncoherent(dev, vma, cpu_addr, handle, size);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c
index ec54ed0..7cf348e 100644
--- a/arch/mips/mm/dma-ip32.c
+++ b/arch/mips/mm/dma-ip32.c
@@ -95,6 +95,29 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return dma_mmap_noncoherent(dev, vma,
+ (void *)CAC_ADDR((unsigned long)cpu_addr),
+ handle, size);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
static inline void __dma_sync(unsigned long addr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index cd4ea84..64ac8fd 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -79,6 +79,29 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return dma_mmap_noncoherent(dev, vma,
+ (void *)CAC_ADDR((unsigned long)cpu_addr),
+ handle, size);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
static inline void __dma_sync(unsigned long addr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index a6caf10..76481b3 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -396,6 +396,23 @@ static void pa11_dma_free_consistent (st
free_pages((unsigned long)__va(dma_handle), order);
}
+static int pa11_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = (unsigned long)handle >> PAGE_SHIFT;
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+static int pa11_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return pa11_mmap_noncoherent(dev, vma, cpu_addr, handle, size);
+}
+
static dma_addr_t pa11_dma_map_single(struct device *dev, void *addr, size_t size, enum dma_data_direction direction)
{
if (direction == DMA_NONE) {
@@ -509,6 +526,8 @@ struct hppa_dma_ops pcxl_dma_ops = {
.dma_sync_single_for_device = pa11_dma_sync_single_for_device,
.dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
.dma_sync_sg_for_device = pa11_dma_sync_sg_for_device,
+ .mmap_coherent = pa11_mmap_coherent,
+ .mmap_noncoherent = pa11_mmap_noncoherent,
};
static void *fail_alloc_consistent(struct device *dev, size_t size,
@@ -537,6 +556,12 @@ static void pa11_dma_free_noncoherent(st
return;
}
+static int fail_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ return -ENXIO;
+}
+
struct hppa_dma_ops pcx_dma_ops = {
.dma_supported = pa11_dma_supported,
.alloc_consistent = fail_alloc_consistent,
@@ -550,6 +575,8 @@ struct hppa_dma_ops pcx_dma_ops = {
.dma_sync_single_for_device = pa11_dma_sync_single_for_device,
.dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
.dma_sync_sg_for_device = pa11_dma_sync_sg_for_device,
+ .mmap_coherent = fail_mmap_coherent,
+ .mmap_noncoherent = fail_mmap_coherent,
};
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index ee73e30..097a0bf 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -59,6 +59,15 @@ void consistent_free(void *vaddr, size_t
}
}
+int consistent_mmap(struct vm_area_struct *vma, void *vaddr, size_t size)
+{
+ vaddr = (void *)P1SEGADDR((unsigned long)vaddr);
+ return remap_pfn_range(vma, vma->vm_start,
+ page_to_pfn(virt_to_page(vaddr)) + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
void consistent_sync(void *vaddr, size_t size, int direction)
{
void * p1addr = (void*) P1SEGADDR((unsigned long)vaddr);
@@ -80,5 +89,6 @@ void consistent_sync(void *vaddr, size_t
EXPORT_SYMBOL(consistent_alloc);
EXPORT_SYMBOL(consistent_free);
+EXPORT_SYMBOL(consistent_mmap);
EXPORT_SYMBOL(consistent_sync);
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index f9ff297..46e1fc3 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -508,6 +508,22 @@ void pci_free_consistent(struct pci_dev
free_pages(pgp, get_order(n));
}
+/* Mmap a consistent area allocated via pci_alloc_consistent */
+int pci_mmap_consistent(struct pci_dev *pdev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn;
+
+ /* calculate pfn from bus address */
+ pfn = pfn_base + (((unsigned long)handle - phys_base) >> PAGE_SHIFT);
+
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+
/* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
*
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 4b376fa..a48766a 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -198,6 +198,7 @@ EXPORT_SYMBOL(insl);
EXPORT_SYMBOL(outsl);
EXPORT_SYMBOL(pci_alloc_consistent);
EXPORT_SYMBOL(pci_free_consistent);
+EXPORT_SYMBOL(pci_mmap_consistent);
EXPORT_SYMBOL(pci_map_single);
EXPORT_SYMBOL(pci_unmap_single);
EXPORT_SYMBOL(pci_dma_sync_single_for_cpu);
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index 82e5455..50e4691 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -290,6 +290,18 @@ static void pci_4u_free_consistent(struc
free_pages((unsigned long)cpu, order);
}
+/* Mmap a consistent area allocated via pci_alloc_consistent */
+int pci_mmap_consistent(struct pci_dev *pdev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
/* Map a single buffer at PTR of SZ bytes for PCI DMA
* in streaming mode.
*/
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index 62d8a99..609abca 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -223,6 +223,7 @@ EXPORT_SYMBOL(isa_chain);
EXPORT_SYMBOL(pci_memspace_mask);
EXPORT_SYMBOL(pci_alloc_consistent);
EXPORT_SYMBOL(pci_free_consistent);
+EXPORT_SYMBOL(pci_mmap_consistent);
EXPORT_SYMBOL(pci_map_single);
EXPORT_SYMBOL(pci_unmap_single);
EXPORT_SYMBOL(pci_map_sg);
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c
index a9275c9..93f9120 100644
--- a/arch/x86_64/kernel/pci-dma.c
+++ b/arch/x86_64/kernel/pci-dma.c
@@ -166,6 +166,22 @@ void dma_free_coherent(struct device *de
}
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn;
+
+ if (dma_ops->mmap_coherent)
+ return dma_ops->mmap_coherent(dev, vma, cpu_addr, handle, size);
+
+ pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+EXPORT_SYMBOL(dma_mmap_coherent);
+
int dma_supported(struct device *dev, u64 mask)
{
if (dma_ops->dma_supported)
diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h
index 62d0d66..a2dc0a5 100644
--- a/include/asm-alpha/dma-mapping.h
+++ b/include/asm-alpha/dma-mapping.h
@@ -50,8 +50,20 @@ #define dma_mapping_error(addr) (0)
#endif /* !CONFIG_PCI */
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#define dma_is_consistent(dev) (1)
int dma_set_mask(struct device *dev, u64 mask);
diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h
index cbf1a98..d2a629e 100644
--- a/include/asm-cris/dma-mapping.h
+++ b/include/asm-cris/dma-mapping.h
@@ -12,6 +12,7 @@ #include <asm/scatterlist.h>
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#ifdef CONFIG_PCI
void *dma_alloc_coherent(struct device *dev, size_t size,
@@ -19,6 +20,18 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
#else
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
@@ -34,6 +47,15 @@ dma_free_coherent(struct device *dev, si
{
BUG();
}
+
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG();
+ return -ENXIO;
+}
+
#endif
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
diff --git a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h
index e9fc1d4..7cd67fb 100644
--- a/include/asm-frv/dma-mapping.h
+++ b/include/asm-frv/dma-mapping.h
@@ -9,12 +9,16 @@ #include <asm/io.h>
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
extern unsigned long __nongprelbss dma_coherent_mem_start;
extern unsigned long __nongprelbss dma_coherent_mem_end;
void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp);
void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle);
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
/*
* These macros should be used after a pci_map_sg call has been done
diff --git a/include/asm-generic/dma-mapping-broken.h b/include/asm-generic/dma-mapping-broken.h
index a7f1a55..fcf656e 100644
--- a/include/asm-generic/dma-mapping-broken.h
+++ b/include/asm-generic/dma-mapping-broken.h
@@ -19,4 +19,12 @@ dma_free_coherent(struct device *dev, si
BUG();
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG();
+ return -ENXIO;
+}
+
#endif /* _ASM_GENERIC_DMA_MAPPING_H */
diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h
index 1b35620..95d31d0 100644
--- a/include/asm-generic/dma-mapping.h
+++ b/include/asm-generic/dma-mapping.h
@@ -37,9 +37,13 @@ static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
gfp_t flag)
{
+#ifdef CONFIG_MMU
BUG_ON(dev->bus != &pci_bus_type);
return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle);
+#else
+ return -ENXIO;
+#endif
}
static inline void
@@ -51,6 +55,15 @@ dma_free_coherent(struct device *dev, si
pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG_ON(dev->bus != &pci_bus_type);
+
+ return pci_mmap_consistent(to_pci_dev(dev), vma, cpu_addr, handle, size);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
enum dma_data_direction direction)
@@ -181,6 +194,14 @@ dma_free_coherent(struct device *dev, si
BUG();
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG();
+ return -ENXIO;
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
enum dma_data_direction direction)
@@ -267,6 +288,7 @@ #endif
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#define dma_is_consistent(d) (1)
static inline int
diff --git a/include/asm-i386/dma-mapping.h b/include/asm-i386/dma-mapping.h
index 9cf20ca..144b5c7 100644
--- a/include/asm-i386/dma-mapping.h
+++ b/include/asm-i386/dma-mapping.h
@@ -10,6 +10,7 @@ #include <asm/bug.h>
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag);
@@ -17,6 +18,17 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
diff --git a/include/asm-ia64/dma-mapping.h b/include/asm-ia64/dma-mapping.h
index df67d40..d441031 100644
--- a/include/asm-ia64/dma-mapping.h
+++ b/include/asm-ia64/dma-mapping.h
@@ -12,6 +12,20 @@ #define dma_alloc_coherent platform_dma_
#define dma_alloc_noncoherent platform_dma_alloc_coherent /* coherent mem. is cheap */
#define dma_free_coherent platform_dma_free_coherent
#define dma_free_noncoherent platform_dma_free_coherent
+
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+#define dma_mmap_noncoherent dma_mmap_coherent
+
#define dma_map_single platform_dma_map_single
#define dma_map_sg platform_dma_map_sg
#define dma_unmap_single platform_dma_unmap_single
diff --git a/include/asm-m32r/dma-mapping.h b/include/asm-m32r/dma-mapping.h
index a7fa030..d00e400 100644
--- a/include/asm-m32r/dma-mapping.h
+++ b/include/asm-m32r/dma-mapping.h
@@ -1,23 +1 @@
-#ifndef _ASM_M32R_DMA_MAPPING_H
-#define _ASM_M32R_DMA_MAPPING_H
-
-/*
- * NOTE: Do not include <asm-generic/dma-mapping.h>
- * Because it requires PCI stuffs, but current M32R don't provide these.
- */
-
-static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- gfp_t flag)
-{
- return (void *)NULL;
-}
-
-static inline void
-dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
- dma_addr_t dma_handle)
-{
- return;
-}
-
-#endif /* _ASM_M32R_DMA_MAPPING_H */
+#include <asm-generic/dma-mapping-broken.h>
diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h
index 4328863..391abbd 100644
--- a/include/asm-mips/dma-mapping.h
+++ b/include/asm-mips/dma-mapping.h
@@ -16,6 +16,12 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction);
extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h
index 74d4ac6..c5cb337 100644
--- a/include/asm-parisc/dma-mapping.h
+++ b/include/asm-parisc/dma-mapping.h
@@ -20,6 +20,10 @@ struct hppa_dma_ops {
void (*dma_sync_single_for_device)(struct device *dev, dma_addr_t iova, unsigned long offset, size_t size, enum dma_data_direction direction);
void (*dma_sync_sg_for_cpu)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction);
void (*dma_sync_sg_for_device)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction);
+ int (*mmap_coherent)(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+ int (*mmap_noncoherent)(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
};
/*
@@ -75,6 +79,20 @@ dma_free_noncoherent(struct device *dev,
hppa_dma_ops->free_consistent(dev, size, vaddr, dma_handle);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ hppa_dma_ops->mmap_coherent(dev, vma, cpu_addr, handle, size);
+}
+
+static inline int
+dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ hppa_dma_ops->mmap_noncoherent(dev, vma, cpu_addr, handle, size);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 2ac63f5..7e74385 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -167,6 +167,17 @@ #define dma_unmap_sg(dev, sg, nents, dir
#endif /* CONFIG_PPC64 */
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
static inline void dma_sync_single_for_cpu(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
@@ -218,6 +229,7 @@ #endif
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#ifdef CONFIG_NOT_COHERENT_CACHE
#define dma_is_consistent(d) (0)
#else
diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h
index 48f1f42..7c84cbf 100644
--- a/include/asm-sh/dma-mapping.h
+++ b/include/asm-sh/dma-mapping.h
@@ -12,6 +12,7 @@ extern struct bus_type pci_bus_type;
/* arch/sh/mm/consistent.c */
extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle);
extern void consistent_free(void *vaddr, size_t size);
+extern int consistent_mmap(struct vm_area_struct *vma, void *vaddr, size_t size);
extern void consistent_sync(void *vaddr, size_t size, int direction);
#define dma_supported(dev, mask) (1)
@@ -54,6 +55,16 @@ static inline void dma_free_coherent(str
consistent_free(vaddr, size);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ if (sh_mv.mv_consistent_alloc)
+ return -ENXIO;
+ else
+ return consistent_mmap(vma, cpu_addr, size);
+}
+
static inline void dma_cache_sync(void *vaddr, size_t size,
enum dma_data_direction dir)
{
diff --git a/include/asm-sh64/dma-mapping.h b/include/asm-sh64/dma-mapping.h
index cc9a2e8..66cceaf 100644
--- a/include/asm-sh64/dma-mapping.h
+++ b/include/asm-sh64/dma-mapping.h
@@ -11,6 +11,8 @@ extern void *consistent_alloc(struct pci
dma_addr_t *dma_handle);
extern void consistent_free(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+extern int consistent_mmap(struct vm_area_struct *vma, void *vaddr,
+ dma_addr_t handle, size_t size);
#define dma_supported(dev, mask) (1)
@@ -36,6 +38,21 @@ static inline void dma_free_coherent(str
consistent_free(NULL, size, vaddr, dma_handle);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn;
+
+ /* dma_handle is equivalent with phys addr */
+ pfn = (unsigned long)handle >> PAGE_SHIFT;
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+
+}
+
static inline void dma_cache_sync(void *vaddr, size_t size,
enum dma_data_direction dir)
{
diff --git a/include/asm-sparc/dma-mapping.h b/include/asm-sparc/dma-mapping.h
index d7c3b0f..22380c0 100644
--- a/include/asm-sparc/dma-mapping.h
+++ b/include/asm-sparc/dma-mapping.h
@@ -6,20 +6,7 @@ #include <linux/config.h>
#ifdef CONFIG_PCI
#include <asm-generic/dma-mapping.h>
#else
-
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
-{
- BUG();
- return NULL;
-}
-
-static inline void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- BUG();
-}
-
+#include <asm-generic/dma-mapping-broken.h>
#endif /* PCI */
#endif /* _ASM_SPARC_DMA_MAPPING_H */
diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h
index a8d39f2..8ea0082 100644
--- a/include/asm-sparc64/dma-mapping.h
+++ b/include/asm-sparc64/dma-mapping.h
@@ -145,22 +145,7 @@ dma_mapping_error(dma_addr_t dma_addr)
}
#else
-
-struct device;
-
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
-{
- BUG();
- return NULL;
-}
-
-static inline void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- BUG();
-}
-
+#include <asm-generic/dma-mapping-broken.h>
#endif /* PCI */
#endif /* _ASM_SPARC64_DMA_MAPPING_H */
diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h
index 49a81a6..c3a9b25 100644
--- a/include/asm-x86_64/dma-mapping.h
+++ b/include/asm-x86_64/dma-mapping.h
@@ -49,6 +49,10 @@ struct dma_mapping_ops {
struct scatterlist *sg, int nents,
int direction);
int (*dma_supported)(struct device *hwdev, u64 mask);
+ int (*mmap_coherent)(struct device *hwdev,
+ struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle,
+ size_t size);
int is_phys;
};
@@ -69,6 +73,9 @@ extern void *dma_alloc_coherent(struct d
extern void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle);
+extern int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
static inline dma_addr_t
dma_map_single(struct device *hwdev, void *ptr, size_t size,
int direction)
diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h
index c425f10..e0b1ca9 100644
--- a/include/asm-xtensa/dma-mapping.h
+++ b/include/asm-xtensa/dma-mapping.h
@@ -33,6 +33,17 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ struct page *page = virt_to_page(bus_to_virt(handle));
+ return remap_pfn_range(vma, vma->vm_start,
+ page_to_pfn(page) + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-12 10:51 ` Takashi Iwai
0 siblings, 0 replies; 29+ messages in thread
From: Takashi Iwai @ 2006-06-12 10:51 UTC (permalink / raw)
To: Gerhard Pircher; +Cc: Lee Revell, alsa-devel, linux-kernel, linuxppc-dev
At Sat, 10 Jun 2006 10:22:23 +0200,
Gerhard Pircher wrote:
>
> > -------- Original-Nachricht --------
> > Datum: Fri, 09 Jun 2006 20:46:32 -0400
> > Von: Lee Revell <rlrevell@joe-job.com>
> > An: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Betreff: Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and
> > ALSA?
> >
> > On Sat, 2006-06-10 at 10:34 +1000, Benjamin Herrenschmidt wrote:
> > > > This leads me to the question, if there are any plans to include the
> > > > dma_mmap_coherent() function (for powerpc/ppc and/or any other
> > > > platform) in one of the next kernel versions and if an adapation of
> > > > the ALSA drivers is planned. Or is there a simple way (hack) to fix
> > > > this problem?
> > >
> > > You are welcome to do a patch implementing this :)
> >
> > Please cc: alsa-devel when you do so.
>
> :)
>
> Well, implementing the dma_mmap_coherent() function isn't the
> problem, because it is already implemented for the ARM
> architecture.
Actually, I wrote dma_coherent_mmap patch long time ago but it has
been left forgotten. The patch attached below seems applicable to
2.6.17 tree, but I'm not sure whether it still works properly.
It's untested on most of architectures.
> But as far as I understand this would require a
> rewrite of all the ALSA drivers (or at least a rewrite of the ALSA's
> DMA helper functions).
Yes. The change of ALSA side has been also on my tree. But it was
still pending since I'm not satisfied with the design yet.
If you're interested in it, let me know. I'll post the patch.
Takashi
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index 4985466..17a3064 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -106,6 +106,14 @@ void dma_free_coherent(struct device *hw
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ return -ENXIO;
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
/*
* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index 671ce1e..d4a8326 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -37,6 +37,21 @@ void dma_free_coherent(struct device *hw
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn;
+
+ /* bus is equivalent with phys */
+ pfn = ((unsigned long)handle) >> PAGE_SHIFT;
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
/*
* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c
index f6b3c72..2b591e4 100644
--- a/arch/mips/mm/dma-coherent.c
+++ b/arch/mips/mm/dma-coherent.c
@@ -59,6 +59,24 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+ __attribute__((alias("dma_mmap_noncoherent")));
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/mips/mm/dma-ip27.c b/arch/mips/mm/dma-ip27.c
index 8da19fd..db453eb 100644
--- a/arch/mips/mm/dma-ip27.c
+++ b/arch/mips/mm/dma-ip27.c
@@ -64,6 +64,27 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return dma_mmap_noncoherent(dev, vma, cpu_addr, handle, size);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c
index ec54ed0..7cf348e 100644
--- a/arch/mips/mm/dma-ip32.c
+++ b/arch/mips/mm/dma-ip32.c
@@ -95,6 +95,29 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return dma_mmap_noncoherent(dev, vma,
+ (void *)CAC_ADDR((unsigned long)cpu_addr),
+ handle, size);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
static inline void __dma_sync(unsigned long addr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index cd4ea84..64ac8fd 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -79,6 +79,29 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return dma_mmap_noncoherent(dev, vma,
+ (void *)CAC_ADDR((unsigned long)cpu_addr),
+ handle, size);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
static inline void __dma_sync(unsigned long addr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index a6caf10..76481b3 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -396,6 +396,23 @@ static void pa11_dma_free_consistent (st
free_pages((unsigned long)__va(dma_handle), order);
}
+static int pa11_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = (unsigned long)handle >> PAGE_SHIFT;
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+static int pa11_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return pa11_mmap_noncoherent(dev, vma, cpu_addr, handle, size);
+}
+
static dma_addr_t pa11_dma_map_single(struct device *dev, void *addr, size_t size, enum dma_data_direction direction)
{
if (direction == DMA_NONE) {
@@ -509,6 +526,8 @@ struct hppa_dma_ops pcxl_dma_ops = {
.dma_sync_single_for_device = pa11_dma_sync_single_for_device,
.dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
.dma_sync_sg_for_device = pa11_dma_sync_sg_for_device,
+ .mmap_coherent = pa11_mmap_coherent,
+ .mmap_noncoherent = pa11_mmap_noncoherent,
};
static void *fail_alloc_consistent(struct device *dev, size_t size,
@@ -537,6 +556,12 @@ static void pa11_dma_free_noncoherent(st
return;
}
+static int fail_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ return -ENXIO;
+}
+
struct hppa_dma_ops pcx_dma_ops = {
.dma_supported = pa11_dma_supported,
.alloc_consistent = fail_alloc_consistent,
@@ -550,6 +575,8 @@ struct hppa_dma_ops pcx_dma_ops = {
.dma_sync_single_for_device = pa11_dma_sync_single_for_device,
.dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
.dma_sync_sg_for_device = pa11_dma_sync_sg_for_device,
+ .mmap_coherent = fail_mmap_coherent,
+ .mmap_noncoherent = fail_mmap_coherent,
};
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index ee73e30..097a0bf 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -59,6 +59,15 @@ void consistent_free(void *vaddr, size_t
}
}
+int consistent_mmap(struct vm_area_struct *vma, void *vaddr, size_t size)
+{
+ vaddr = (void *)P1SEGADDR((unsigned long)vaddr);
+ return remap_pfn_range(vma, vma->vm_start,
+ page_to_pfn(virt_to_page(vaddr)) + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
void consistent_sync(void *vaddr, size_t size, int direction)
{
void * p1addr = (void*) P1SEGADDR((unsigned long)vaddr);
@@ -80,5 +89,6 @@ void consistent_sync(void *vaddr, size_t
EXPORT_SYMBOL(consistent_alloc);
EXPORT_SYMBOL(consistent_free);
+EXPORT_SYMBOL(consistent_mmap);
EXPORT_SYMBOL(consistent_sync);
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index f9ff297..46e1fc3 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -508,6 +508,22 @@ void pci_free_consistent(struct pci_dev
free_pages(pgp, get_order(n));
}
+/* Mmap a consistent area allocated via pci_alloc_consistent */
+int pci_mmap_consistent(struct pci_dev *pdev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn;
+
+ /* calculate pfn from bus address */
+ pfn = pfn_base + (((unsigned long)handle - phys_base) >> PAGE_SHIFT);
+
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+
/* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
*
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 4b376fa..a48766a 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -198,6 +198,7 @@ EXPORT_SYMBOL(insl);
EXPORT_SYMBOL(outsl);
EXPORT_SYMBOL(pci_alloc_consistent);
EXPORT_SYMBOL(pci_free_consistent);
+EXPORT_SYMBOL(pci_mmap_consistent);
EXPORT_SYMBOL(pci_map_single);
EXPORT_SYMBOL(pci_unmap_single);
EXPORT_SYMBOL(pci_dma_sync_single_for_cpu);
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index 82e5455..50e4691 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -290,6 +290,18 @@ static void pci_4u_free_consistent(struc
free_pages((unsigned long)cpu, order);
}
+/* Mmap a consistent area allocated via pci_alloc_consistent */
+int pci_mmap_consistent(struct pci_dev *pdev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
/* Map a single buffer at PTR of SZ bytes for PCI DMA
* in streaming mode.
*/
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index 62d8a99..609abca 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -223,6 +223,7 @@ EXPORT_SYMBOL(isa_chain);
EXPORT_SYMBOL(pci_memspace_mask);
EXPORT_SYMBOL(pci_alloc_consistent);
EXPORT_SYMBOL(pci_free_consistent);
+EXPORT_SYMBOL(pci_mmap_consistent);
EXPORT_SYMBOL(pci_map_single);
EXPORT_SYMBOL(pci_unmap_single);
EXPORT_SYMBOL(pci_map_sg);
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c
index a9275c9..93f9120 100644
--- a/arch/x86_64/kernel/pci-dma.c
+++ b/arch/x86_64/kernel/pci-dma.c
@@ -166,6 +166,22 @@ void dma_free_coherent(struct device *de
}
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn;
+
+ if (dma_ops->mmap_coherent)
+ return dma_ops->mmap_coherent(dev, vma, cpu_addr, handle, size);
+
+ pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+EXPORT_SYMBOL(dma_mmap_coherent);
+
int dma_supported(struct device *dev, u64 mask)
{
if (dma_ops->dma_supported)
diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h
index 62d0d66..a2dc0a5 100644
--- a/include/asm-alpha/dma-mapping.h
+++ b/include/asm-alpha/dma-mapping.h
@@ -50,8 +50,20 @@ #define dma_mapping_error(addr) (0)
#endif /* !CONFIG_PCI */
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#define dma_is_consistent(dev) (1)
int dma_set_mask(struct device *dev, u64 mask);
diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h
index cbf1a98..d2a629e 100644
--- a/include/asm-cris/dma-mapping.h
+++ b/include/asm-cris/dma-mapping.h
@@ -12,6 +12,7 @@ #include <asm/scatterlist.h>
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#ifdef CONFIG_PCI
void *dma_alloc_coherent(struct device *dev, size_t size,
@@ -19,6 +20,18 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
#else
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
@@ -34,6 +47,15 @@ dma_free_coherent(struct device *dev, si
{
BUG();
}
+
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG();
+ return -ENXIO;
+}
+
#endif
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
diff --git a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h
index e9fc1d4..7cd67fb 100644
--- a/include/asm-frv/dma-mapping.h
+++ b/include/asm-frv/dma-mapping.h
@@ -9,12 +9,16 @@ #include <asm/io.h>
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
extern unsigned long __nongprelbss dma_coherent_mem_start;
extern unsigned long __nongprelbss dma_coherent_mem_end;
void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp);
void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle);
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
/*
* These macros should be used after a pci_map_sg call has been done
diff --git a/include/asm-generic/dma-mapping-broken.h b/include/asm-generic/dma-mapping-broken.h
index a7f1a55..fcf656e 100644
--- a/include/asm-generic/dma-mapping-broken.h
+++ b/include/asm-generic/dma-mapping-broken.h
@@ -19,4 +19,12 @@ dma_free_coherent(struct device *dev, si
BUG();
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG();
+ return -ENXIO;
+}
+
#endif /* _ASM_GENERIC_DMA_MAPPING_H */
diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h
index 1b35620..95d31d0 100644
--- a/include/asm-generic/dma-mapping.h
+++ b/include/asm-generic/dma-mapping.h
@@ -37,9 +37,13 @@ static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
gfp_t flag)
{
+#ifdef CONFIG_MMU
BUG_ON(dev->bus != &pci_bus_type);
return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle);
+#else
+ return -ENXIO;
+#endif
}
static inline void
@@ -51,6 +55,15 @@ dma_free_coherent(struct device *dev, si
pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG_ON(dev->bus != &pci_bus_type);
+
+ return pci_mmap_consistent(to_pci_dev(dev), vma, cpu_addr, handle, size);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
enum dma_data_direction direction)
@@ -181,6 +194,14 @@ dma_free_coherent(struct device *dev, si
BUG();
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG();
+ return -ENXIO;
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
enum dma_data_direction direction)
@@ -267,6 +288,7 @@ #endif
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#define dma_is_consistent(d) (1)
static inline int
diff --git a/include/asm-i386/dma-mapping.h b/include/asm-i386/dma-mapping.h
index 9cf20ca..144b5c7 100644
--- a/include/asm-i386/dma-mapping.h
+++ b/include/asm-i386/dma-mapping.h
@@ -10,6 +10,7 @@ #include <asm/bug.h>
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag);
@@ -17,6 +18,17 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
diff --git a/include/asm-ia64/dma-mapping.h b/include/asm-ia64/dma-mapping.h
index df67d40..d441031 100644
--- a/include/asm-ia64/dma-mapping.h
+++ b/include/asm-ia64/dma-mapping.h
@@ -12,6 +12,20 @@ #define dma_alloc_coherent platform_dma_
#define dma_alloc_noncoherent platform_dma_alloc_coherent /* coherent mem. is cheap */
#define dma_free_coherent platform_dma_free_coherent
#define dma_free_noncoherent platform_dma_free_coherent
+
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+#define dma_mmap_noncoherent dma_mmap_coherent
+
#define dma_map_single platform_dma_map_single
#define dma_map_sg platform_dma_map_sg
#define dma_unmap_single platform_dma_unmap_single
diff --git a/include/asm-m32r/dma-mapping.h b/include/asm-m32r/dma-mapping.h
index a7fa030..d00e400 100644
--- a/include/asm-m32r/dma-mapping.h
+++ b/include/asm-m32r/dma-mapping.h
@@ -1,23 +1 @@
-#ifndef _ASM_M32R_DMA_MAPPING_H
-#define _ASM_M32R_DMA_MAPPING_H
-
-/*
- * NOTE: Do not include <asm-generic/dma-mapping.h>
- * Because it requires PCI stuffs, but current M32R don't provide these.
- */
-
-static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- gfp_t flag)
-{
- return (void *)NULL;
-}
-
-static inline void
-dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
- dma_addr_t dma_handle)
-{
- return;
-}
-
-#endif /* _ASM_M32R_DMA_MAPPING_H */
+#include <asm-generic/dma-mapping-broken.h>
diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h
index 4328863..391abbd 100644
--- a/include/asm-mips/dma-mapping.h
+++ b/include/asm-mips/dma-mapping.h
@@ -16,6 +16,12 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction);
extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h
index 74d4ac6..c5cb337 100644
--- a/include/asm-parisc/dma-mapping.h
+++ b/include/asm-parisc/dma-mapping.h
@@ -20,6 +20,10 @@ struct hppa_dma_ops {
void (*dma_sync_single_for_device)(struct device *dev, dma_addr_t iova, unsigned long offset, size_t size, enum dma_data_direction direction);
void (*dma_sync_sg_for_cpu)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction);
void (*dma_sync_sg_for_device)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction);
+ int (*mmap_coherent)(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+ int (*mmap_noncoherent)(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
};
/*
@@ -75,6 +79,20 @@ dma_free_noncoherent(struct device *dev,
hppa_dma_ops->free_consistent(dev, size, vaddr, dma_handle);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ hppa_dma_ops->mmap_coherent(dev, vma, cpu_addr, handle, size);
+}
+
+static inline int
+dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ hppa_dma_ops->mmap_noncoherent(dev, vma, cpu_addr, handle, size);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 2ac63f5..7e74385 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -167,6 +167,17 @@ #define dma_unmap_sg(dev, sg, nents, dir
#endif /* CONFIG_PPC64 */
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
static inline void dma_sync_single_for_cpu(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
@@ -218,6 +229,7 @@ #endif
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#ifdef CONFIG_NOT_COHERENT_CACHE
#define dma_is_consistent(d) (0)
#else
diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h
index 48f1f42..7c84cbf 100644
--- a/include/asm-sh/dma-mapping.h
+++ b/include/asm-sh/dma-mapping.h
@@ -12,6 +12,7 @@ extern struct bus_type pci_bus_type;
/* arch/sh/mm/consistent.c */
extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle);
extern void consistent_free(void *vaddr, size_t size);
+extern int consistent_mmap(struct vm_area_struct *vma, void *vaddr, size_t size);
extern void consistent_sync(void *vaddr, size_t size, int direction);
#define dma_supported(dev, mask) (1)
@@ -54,6 +55,16 @@ static inline void dma_free_coherent(str
consistent_free(vaddr, size);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ if (sh_mv.mv_consistent_alloc)
+ return -ENXIO;
+ else
+ return consistent_mmap(vma, cpu_addr, size);
+}
+
static inline void dma_cache_sync(void *vaddr, size_t size,
enum dma_data_direction dir)
{
diff --git a/include/asm-sh64/dma-mapping.h b/include/asm-sh64/dma-mapping.h
index cc9a2e8..66cceaf 100644
--- a/include/asm-sh64/dma-mapping.h
+++ b/include/asm-sh64/dma-mapping.h
@@ -11,6 +11,8 @@ extern void *consistent_alloc(struct pci
dma_addr_t *dma_handle);
extern void consistent_free(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+extern int consistent_mmap(struct vm_area_struct *vma, void *vaddr,
+ dma_addr_t handle, size_t size);
#define dma_supported(dev, mask) (1)
@@ -36,6 +38,21 @@ static inline void dma_free_coherent(str
consistent_free(NULL, size, vaddr, dma_handle);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn;
+
+ /* dma_handle is equivalent with phys addr */
+ pfn = (unsigned long)handle >> PAGE_SHIFT;
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+
+}
+
static inline void dma_cache_sync(void *vaddr, size_t size,
enum dma_data_direction dir)
{
diff --git a/include/asm-sparc/dma-mapping.h b/include/asm-sparc/dma-mapping.h
index d7c3b0f..22380c0 100644
--- a/include/asm-sparc/dma-mapping.h
+++ b/include/asm-sparc/dma-mapping.h
@@ -6,20 +6,7 @@ #include <linux/config.h>
#ifdef CONFIG_PCI
#include <asm-generic/dma-mapping.h>
#else
-
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
-{
- BUG();
- return NULL;
-}
-
-static inline void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- BUG();
-}
-
+#include <asm-generic/dma-mapping-broken.h>
#endif /* PCI */
#endif /* _ASM_SPARC_DMA_MAPPING_H */
diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h
index a8d39f2..8ea0082 100644
--- a/include/asm-sparc64/dma-mapping.h
+++ b/include/asm-sparc64/dma-mapping.h
@@ -145,22 +145,7 @@ dma_mapping_error(dma_addr_t dma_addr)
}
#else
-
-struct device;
-
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
-{
- BUG();
- return NULL;
-}
-
-static inline void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- BUG();
-}
-
+#include <asm-generic/dma-mapping-broken.h>
#endif /* PCI */
#endif /* _ASM_SPARC64_DMA_MAPPING_H */
diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h
index 49a81a6..c3a9b25 100644
--- a/include/asm-x86_64/dma-mapping.h
+++ b/include/asm-x86_64/dma-mapping.h
@@ -49,6 +49,10 @@ struct dma_mapping_ops {
struct scatterlist *sg, int nents,
int direction);
int (*dma_supported)(struct device *hwdev, u64 mask);
+ int (*mmap_coherent)(struct device *hwdev,
+ struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle,
+ size_t size);
int is_phys;
};
@@ -69,6 +73,9 @@ extern void *dma_alloc_coherent(struct d
extern void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle);
+extern int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
static inline dma_addr_t
dma_map_single(struct device *hwdev, void *ptr, size_t size,
int direction)
diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h
index c425f10..e0b1ca9 100644
--- a/include/asm-xtensa/dma-mapping.h
+++ b/include/asm-xtensa/dma-mapping.h
@@ -33,6 +33,17 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ struct page *page = virt_to_page(bus_to_virt(handle));
+ return remap_pfn_range(vma, vma->vm_start,
+ page_to_pfn(page) + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-12 10:51 ` Takashi Iwai
0 siblings, 0 replies; 29+ messages in thread
From: Takashi Iwai @ 2006-06-12 10:51 UTC (permalink / raw)
To: Gerhard Pircher; +Cc: Lee Revell, benh, linux-kernel, linuxppc-dev, alsa-devel
At Sat, 10 Jun 2006 10:22:23 +0200,
Gerhard Pircher wrote:
>
> > -------- Original-Nachricht --------
> > Datum: Fri, 09 Jun 2006 20:46:32 -0400
> > Von: Lee Revell <rlrevell@joe-job.com>
> > An: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Betreff: Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and
> > ALSA?
> >
> > On Sat, 2006-06-10 at 10:34 +1000, Benjamin Herrenschmidt wrote:
> > > > This leads me to the question, if there are any plans to include the
> > > > dma_mmap_coherent() function (for powerpc/ppc and/or any other
> > > > platform) in one of the next kernel versions and if an adapation of
> > > > the ALSA drivers is planned. Or is there a simple way (hack) to fix
> > > > this problem?
> > >
> > > You are welcome to do a patch implementing this :)
> >
> > Please cc: alsa-devel when you do so.
>
> :)
>
> Well, implementing the dma_mmap_coherent() function isn't the
> problem, because it is already implemented for the ARM
> architecture.
Actually, I wrote dma_coherent_mmap patch long time ago but it has
been left forgotten. The patch attached below seems applicable to
2.6.17 tree, but I'm not sure whether it still works properly.
It's untested on most of architectures.
> But as far as I understand this would require a
> rewrite of all the ALSA drivers (or at least a rewrite of the ALSA's
> DMA helper functions).
Yes. The change of ALSA side has been also on my tree. But it was
still pending since I'm not satisfied with the design yet.
If you're interested in it, let me know. I'll post the patch.
Takashi
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index 4985466..17a3064 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -106,6 +106,14 @@ void dma_free_coherent(struct device *hw
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ return -ENXIO;
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
/*
* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index 671ce1e..d4a8326 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -37,6 +37,21 @@ void dma_free_coherent(struct device *hw
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn;
+
+ /* bus is equivalent with phys */
+ pfn = ((unsigned long)handle) >> PAGE_SHIFT;
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
/*
* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c
index f6b3c72..2b591e4 100644
--- a/arch/mips/mm/dma-coherent.c
+++ b/arch/mips/mm/dma-coherent.c
@@ -59,6 +59,24 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+ __attribute__((alias("dma_mmap_noncoherent")));
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/mips/mm/dma-ip27.c b/arch/mips/mm/dma-ip27.c
index 8da19fd..db453eb 100644
--- a/arch/mips/mm/dma-ip27.c
+++ b/arch/mips/mm/dma-ip27.c
@@ -64,6 +64,27 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return dma_mmap_noncoherent(dev, vma, cpu_addr, handle, size);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c
index ec54ed0..7cf348e 100644
--- a/arch/mips/mm/dma-ip32.c
+++ b/arch/mips/mm/dma-ip32.c
@@ -95,6 +95,29 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return dma_mmap_noncoherent(dev, vma,
+ (void *)CAC_ADDR((unsigned long)cpu_addr),
+ handle, size);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
static inline void __dma_sync(unsigned long addr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index cd4ea84..64ac8fd 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -79,6 +79,29 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return dma_mmap_noncoherent(dev, vma,
+ (void *)CAC_ADDR((unsigned long)cpu_addr),
+ handle, size);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
static inline void __dma_sync(unsigned long addr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index a6caf10..76481b3 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -396,6 +396,23 @@ static void pa11_dma_free_consistent (st
free_pages((unsigned long)__va(dma_handle), order);
}
+static int pa11_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = (unsigned long)handle >> PAGE_SHIFT;
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+static int pa11_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return pa11_mmap_noncoherent(dev, vma, cpu_addr, handle, size);
+}
+
static dma_addr_t pa11_dma_map_single(struct device *dev, void *addr, size_t size, enum dma_data_direction direction)
{
if (direction == DMA_NONE) {
@@ -509,6 +526,8 @@ struct hppa_dma_ops pcxl_dma_ops = {
.dma_sync_single_for_device = pa11_dma_sync_single_for_device,
.dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
.dma_sync_sg_for_device = pa11_dma_sync_sg_for_device,
+ .mmap_coherent = pa11_mmap_coherent,
+ .mmap_noncoherent = pa11_mmap_noncoherent,
};
static void *fail_alloc_consistent(struct device *dev, size_t size,
@@ -537,6 +556,12 @@ static void pa11_dma_free_noncoherent(st
return;
}
+static int fail_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ return -ENXIO;
+}
+
struct hppa_dma_ops pcx_dma_ops = {
.dma_supported = pa11_dma_supported,
.alloc_consistent = fail_alloc_consistent,
@@ -550,6 +575,8 @@ struct hppa_dma_ops pcx_dma_ops = {
.dma_sync_single_for_device = pa11_dma_sync_single_for_device,
.dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
.dma_sync_sg_for_device = pa11_dma_sync_sg_for_device,
+ .mmap_coherent = fail_mmap_coherent,
+ .mmap_noncoherent = fail_mmap_coherent,
};
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index ee73e30..097a0bf 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -59,6 +59,15 @@ void consistent_free(void *vaddr, size_t
}
}
+int consistent_mmap(struct vm_area_struct *vma, void *vaddr, size_t size)
+{
+ vaddr = (void *)P1SEGADDR((unsigned long)vaddr);
+ return remap_pfn_range(vma, vma->vm_start,
+ page_to_pfn(virt_to_page(vaddr)) + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
void consistent_sync(void *vaddr, size_t size, int direction)
{
void * p1addr = (void*) P1SEGADDR((unsigned long)vaddr);
@@ -80,5 +89,6 @@ void consistent_sync(void *vaddr, size_t
EXPORT_SYMBOL(consistent_alloc);
EXPORT_SYMBOL(consistent_free);
+EXPORT_SYMBOL(consistent_mmap);
EXPORT_SYMBOL(consistent_sync);
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index f9ff297..46e1fc3 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -508,6 +508,22 @@ void pci_free_consistent(struct pci_dev
free_pages(pgp, get_order(n));
}
+/* Mmap a consistent area allocated via pci_alloc_consistent */
+int pci_mmap_consistent(struct pci_dev *pdev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn;
+
+ /* calculate pfn from bus address */
+ pfn = pfn_base + (((unsigned long)handle - phys_base) >> PAGE_SHIFT);
+
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+
/* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
*
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 4b376fa..a48766a 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -198,6 +198,7 @@ EXPORT_SYMBOL(insl);
EXPORT_SYMBOL(outsl);
EXPORT_SYMBOL(pci_alloc_consistent);
EXPORT_SYMBOL(pci_free_consistent);
+EXPORT_SYMBOL(pci_mmap_consistent);
EXPORT_SYMBOL(pci_map_single);
EXPORT_SYMBOL(pci_unmap_single);
EXPORT_SYMBOL(pci_dma_sync_single_for_cpu);
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index 82e5455..50e4691 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -290,6 +290,18 @@ static void pci_4u_free_consistent(struc
free_pages((unsigned long)cpu, order);
}
+/* Mmap a consistent area allocated via pci_alloc_consistent */
+int pci_mmap_consistent(struct pci_dev *pdev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
/* Map a single buffer at PTR of SZ bytes for PCI DMA
* in streaming mode.
*/
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index 62d8a99..609abca 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -223,6 +223,7 @@ EXPORT_SYMBOL(isa_chain);
EXPORT_SYMBOL(pci_memspace_mask);
EXPORT_SYMBOL(pci_alloc_consistent);
EXPORT_SYMBOL(pci_free_consistent);
+EXPORT_SYMBOL(pci_mmap_consistent);
EXPORT_SYMBOL(pci_map_single);
EXPORT_SYMBOL(pci_unmap_single);
EXPORT_SYMBOL(pci_map_sg);
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c
index a9275c9..93f9120 100644
--- a/arch/x86_64/kernel/pci-dma.c
+++ b/arch/x86_64/kernel/pci-dma.c
@@ -166,6 +166,22 @@ void dma_free_coherent(struct device *de
}
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn;
+
+ if (dma_ops->mmap_coherent)
+ return dma_ops->mmap_coherent(dev, vma, cpu_addr, handle, size);
+
+ pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+EXPORT_SYMBOL(dma_mmap_coherent);
+
int dma_supported(struct device *dev, u64 mask)
{
if (dma_ops->dma_supported)
diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h
index 62d0d66..a2dc0a5 100644
--- a/include/asm-alpha/dma-mapping.h
+++ b/include/asm-alpha/dma-mapping.h
@@ -50,8 +50,20 @@ #define dma_mapping_error(addr) (0)
#endif /* !CONFIG_PCI */
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#define dma_is_consistent(dev) (1)
int dma_set_mask(struct device *dev, u64 mask);
diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h
index cbf1a98..d2a629e 100644
--- a/include/asm-cris/dma-mapping.h
+++ b/include/asm-cris/dma-mapping.h
@@ -12,6 +12,7 @@ #include <asm/scatterlist.h>
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#ifdef CONFIG_PCI
void *dma_alloc_coherent(struct device *dev, size_t size,
@@ -19,6 +20,18 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
#else
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
@@ -34,6 +47,15 @@ dma_free_coherent(struct device *dev, si
{
BUG();
}
+
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG();
+ return -ENXIO;
+}
+
#endif
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
diff --git a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h
index e9fc1d4..7cd67fb 100644
--- a/include/asm-frv/dma-mapping.h
+++ b/include/asm-frv/dma-mapping.h
@@ -9,12 +9,16 @@ #include <asm/io.h>
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
extern unsigned long __nongprelbss dma_coherent_mem_start;
extern unsigned long __nongprelbss dma_coherent_mem_end;
void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp);
void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle);
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
/*
* These macros should be used after a pci_map_sg call has been done
diff --git a/include/asm-generic/dma-mapping-broken.h b/include/asm-generic/dma-mapping-broken.h
index a7f1a55..fcf656e 100644
--- a/include/asm-generic/dma-mapping-broken.h
+++ b/include/asm-generic/dma-mapping-broken.h
@@ -19,4 +19,12 @@ dma_free_coherent(struct device *dev, si
BUG();
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG();
+ return -ENXIO;
+}
+
#endif /* _ASM_GENERIC_DMA_MAPPING_H */
diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h
index 1b35620..95d31d0 100644
--- a/include/asm-generic/dma-mapping.h
+++ b/include/asm-generic/dma-mapping.h
@@ -37,9 +37,13 @@ static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
gfp_t flag)
{
+#ifdef CONFIG_MMU
BUG_ON(dev->bus != &pci_bus_type);
return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle);
+#else
+ return -ENXIO;
+#endif
}
static inline void
@@ -51,6 +55,15 @@ dma_free_coherent(struct device *dev, si
pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG_ON(dev->bus != &pci_bus_type);
+
+ return pci_mmap_consistent(to_pci_dev(dev), vma, cpu_addr, handle, size);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
enum dma_data_direction direction)
@@ -181,6 +194,14 @@ dma_free_coherent(struct device *dev, si
BUG();
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG();
+ return -ENXIO;
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
enum dma_data_direction direction)
@@ -267,6 +288,7 @@ #endif
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#define dma_is_consistent(d) (1)
static inline int
diff --git a/include/asm-i386/dma-mapping.h b/include/asm-i386/dma-mapping.h
index 9cf20ca..144b5c7 100644
--- a/include/asm-i386/dma-mapping.h
+++ b/include/asm-i386/dma-mapping.h
@@ -10,6 +10,7 @@ #include <asm/bug.h>
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag);
@@ -17,6 +18,17 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
diff --git a/include/asm-ia64/dma-mapping.h b/include/asm-ia64/dma-mapping.h
index df67d40..d441031 100644
--- a/include/asm-ia64/dma-mapping.h
+++ b/include/asm-ia64/dma-mapping.h
@@ -12,6 +12,20 @@ #define dma_alloc_coherent platform_dma_
#define dma_alloc_noncoherent platform_dma_alloc_coherent /* coherent mem. is cheap */
#define dma_free_coherent platform_dma_free_coherent
#define dma_free_noncoherent platform_dma_free_coherent
+
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+#define dma_mmap_noncoherent dma_mmap_coherent
+
#define dma_map_single platform_dma_map_single
#define dma_map_sg platform_dma_map_sg
#define dma_unmap_single platform_dma_unmap_single
diff --git a/include/asm-m32r/dma-mapping.h b/include/asm-m32r/dma-mapping.h
index a7fa030..d00e400 100644
--- a/include/asm-m32r/dma-mapping.h
+++ b/include/asm-m32r/dma-mapping.h
@@ -1,23 +1 @@
-#ifndef _ASM_M32R_DMA_MAPPING_H
-#define _ASM_M32R_DMA_MAPPING_H
-
-/*
- * NOTE: Do not include <asm-generic/dma-mapping.h>
- * Because it requires PCI stuffs, but current M32R don't provide these.
- */
-
-static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- gfp_t flag)
-{
- return (void *)NULL;
-}
-
-static inline void
-dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
- dma_addr_t dma_handle)
-{
- return;
-}
-
-#endif /* _ASM_M32R_DMA_MAPPING_H */
+#include <asm-generic/dma-mapping-broken.h>
diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h
index 4328863..391abbd 100644
--- a/include/asm-mips/dma-mapping.h
+++ b/include/asm-mips/dma-mapping.h
@@ -16,6 +16,12 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction);
extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h
index 74d4ac6..c5cb337 100644
--- a/include/asm-parisc/dma-mapping.h
+++ b/include/asm-parisc/dma-mapping.h
@@ -20,6 +20,10 @@ struct hppa_dma_ops {
void (*dma_sync_single_for_device)(struct device *dev, dma_addr_t iova, unsigned long offset, size_t size, enum dma_data_direction direction);
void (*dma_sync_sg_for_cpu)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction);
void (*dma_sync_sg_for_device)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction);
+ int (*mmap_coherent)(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+ int (*mmap_noncoherent)(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
};
/*
@@ -75,6 +79,20 @@ dma_free_noncoherent(struct device *dev,
hppa_dma_ops->free_consistent(dev, size, vaddr, dma_handle);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ hppa_dma_ops->mmap_coherent(dev, vma, cpu_addr, handle, size);
+}
+
+static inline int
+dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ hppa_dma_ops->mmap_noncoherent(dev, vma, cpu_addr, handle, size);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 2ac63f5..7e74385 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -167,6 +167,17 @@ #define dma_unmap_sg(dev, sg, nents, dir
#endif /* CONFIG_PPC64 */
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
static inline void dma_sync_single_for_cpu(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
@@ -218,6 +229,7 @@ #endif
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#ifdef CONFIG_NOT_COHERENT_CACHE
#define dma_is_consistent(d) (0)
#else
diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h
index 48f1f42..7c84cbf 100644
--- a/include/asm-sh/dma-mapping.h
+++ b/include/asm-sh/dma-mapping.h
@@ -12,6 +12,7 @@ extern struct bus_type pci_bus_type;
/* arch/sh/mm/consistent.c */
extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle);
extern void consistent_free(void *vaddr, size_t size);
+extern int consistent_mmap(struct vm_area_struct *vma, void *vaddr, size_t size);
extern void consistent_sync(void *vaddr, size_t size, int direction);
#define dma_supported(dev, mask) (1)
@@ -54,6 +55,16 @@ static inline void dma_free_coherent(str
consistent_free(vaddr, size);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ if (sh_mv.mv_consistent_alloc)
+ return -ENXIO;
+ else
+ return consistent_mmap(vma, cpu_addr, size);
+}
+
static inline void dma_cache_sync(void *vaddr, size_t size,
enum dma_data_direction dir)
{
diff --git a/include/asm-sh64/dma-mapping.h b/include/asm-sh64/dma-mapping.h
index cc9a2e8..66cceaf 100644
--- a/include/asm-sh64/dma-mapping.h
+++ b/include/asm-sh64/dma-mapping.h
@@ -11,6 +11,8 @@ extern void *consistent_alloc(struct pci
dma_addr_t *dma_handle);
extern void consistent_free(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+extern int consistent_mmap(struct vm_area_struct *vma, void *vaddr,
+ dma_addr_t handle, size_t size);
#define dma_supported(dev, mask) (1)
@@ -36,6 +38,21 @@ static inline void dma_free_coherent(str
consistent_free(NULL, size, vaddr, dma_handle);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn;
+
+ /* dma_handle is equivalent with phys addr */
+ pfn = (unsigned long)handle >> PAGE_SHIFT;
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+
+}
+
static inline void dma_cache_sync(void *vaddr, size_t size,
enum dma_data_direction dir)
{
diff --git a/include/asm-sparc/dma-mapping.h b/include/asm-sparc/dma-mapping.h
index d7c3b0f..22380c0 100644
--- a/include/asm-sparc/dma-mapping.h
+++ b/include/asm-sparc/dma-mapping.h
@@ -6,20 +6,7 @@ #include <linux/config.h>
#ifdef CONFIG_PCI
#include <asm-generic/dma-mapping.h>
#else
-
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
-{
- BUG();
- return NULL;
-}
-
-static inline void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- BUG();
-}
-
+#include <asm-generic/dma-mapping-broken.h>
#endif /* PCI */
#endif /* _ASM_SPARC_DMA_MAPPING_H */
diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h
index a8d39f2..8ea0082 100644
--- a/include/asm-sparc64/dma-mapping.h
+++ b/include/asm-sparc64/dma-mapping.h
@@ -145,22 +145,7 @@ dma_mapping_error(dma_addr_t dma_addr)
}
#else
-
-struct device;
-
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
-{
- BUG();
- return NULL;
-}
-
-static inline void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- BUG();
-}
-
+#include <asm-generic/dma-mapping-broken.h>
#endif /* PCI */
#endif /* _ASM_SPARC64_DMA_MAPPING_H */
diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h
index 49a81a6..c3a9b25 100644
--- a/include/asm-x86_64/dma-mapping.h
+++ b/include/asm-x86_64/dma-mapping.h
@@ -49,6 +49,10 @@ struct dma_mapping_ops {
struct scatterlist *sg, int nents,
int direction);
int (*dma_supported)(struct device *hwdev, u64 mask);
+ int (*mmap_coherent)(struct device *hwdev,
+ struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle,
+ size_t size);
int is_phys;
};
@@ -69,6 +73,9 @@ extern void *dma_alloc_coherent(struct d
extern void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle);
+extern int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
static inline dma_addr_t
dma_map_single(struct device *hwdev, void *ptr, size_t size,
int direction)
diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h
index c425f10..e0b1ca9 100644
--- a/include/asm-xtensa/dma-mapping.h
+++ b/include/asm-xtensa/dma-mapping.h
@@ -33,6 +33,17 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ struct page *page = virt_to_page(bus_to_virt(handle));
+ return remap_pfn_range(vma, vma->vm_start,
+ page_to_pfn(page) + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
2006-06-12 10:51 ` Takashi Iwai
(?)
(?)
@ 2006-06-12 14:42 ` Gerhard Pircher
2006-06-14 14:42 ` Takashi Iwai
-1 siblings, 1 reply; 29+ messages in thread
From: Gerhard Pircher @ 2006-06-12 14:42 UTC (permalink / raw)
To: Takashi Iwai; +Cc: linuxppc-dev, rlrevell, alsa-devel, linux-kernel, benh
> -------- Original-Nachricht --------
> Datum: Mon, 12 Jun 2006 12:51:16 +0200
> Von: Takashi Iwai <tiwai@suse.de>
> An: Gerhard Pircher <gerhard_pircher@gmx.net>
> Betreff: Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and
> ALSA?
>
> > Well, implementing the dma_mmap_coherent() function isn't the
> > problem, because it is already implemented for the ARM
> > architecture.
>
> Actually, I wrote dma_coherent_mmap patch long time ago but it has
> been left forgotten. The patch attached below seems applicable to
> 2.6.17 tree, but I'm not sure whether it still works properly.
> It's untested on most of architectures.
Thanks, that helps me a lot!
> > But as far as I understand this would require a rewrite of all the
> > ALSA drivers (or at least a rewrite of the ALSA's DMA helper
> > functions).
>
> Yes. The change of ALSA side has been also on my tree. But it was
> still pending since I'm not satisfied with the design yet.
> If you're interested in it, let me know. I'll post the patch.
Yes, please! Then I can test, if the dma_mmap_coherent() patch works on
my non cache coherent powerpc machine. Do you think the DMA Layer/ALSA patches will go upstream in one of the next ALSA/Linux kernel versions?
Thanks!
Gerhard
--
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
2006-06-12 14:42 ` Gerhard Pircher
@ 2006-06-14 14:42 ` Takashi Iwai
0 siblings, 0 replies; 29+ messages in thread
From: Takashi Iwai @ 2006-06-14 14:42 UTC (permalink / raw)
To: Gerhard Pircher; +Cc: linuxppc-dev, rlrevell, alsa-devel, linux-kernel, benh
At Mon, 12 Jun 2006 16:42:54 +0200,
Gerhard Pircher wrote:
>
> > > But as far as I understand this would require a rewrite of all the
> > > ALSA drivers (or at least a rewrite of the ALSA's DMA helper
> > > functions).
> >
> > Yes. The change of ALSA side has been also on my tree. But it was
> > still pending since I'm not satisfied with the design yet.
> > If you're interested in it, let me know. I'll post the patch.
>
> Yes, please! Then I can test, if the dma_mmap_coherent() patch works on
> my non cache coherent powerpc machine.
For using dma_mmap_coherent(), the patch below should suffice.
(Also you need to enable HAVE_DMA_MMAP_COHERENT there not only for
ARM.)
> Do you think the DMA Layer/ALSA patches will go upstream in one of
> the next ALSA/Linux kernel versions?
Definitely no 2.6.18 material yet.
Takashi
diff -r 08577d0b45ef sound/core/pcm_native.c
--- a/sound/core/pcm_native.c Tue Jun 13 12:01:14 2006 +0200
+++ b/sound/core/pcm_native.c Wed Jun 14 16:40:32 2006 +0200
@@ -3123,6 +3123,10 @@ static int snd_pcm_mmap_control(struct s
}
#endif /* coherent mmap */
+#if defined(CONFIG_ARM)
+#define HAVE_DMA_MMAP_COHERENT
+#endif
+
/*
* nopage callback for mmapping a RAM page
*/
@@ -3166,6 +3170,14 @@ static struct vm_operations_struct snd_p
.nopage = snd_pcm_mmap_data_nopage,
};
+#ifdef HAVE_DMA_MMAP_COHERENT
+static struct vm_operations_struct snd_pcm_vm_ops_data_one_map =
+{
+ .open = snd_pcm_mmap_data_open,
+ .close = snd_pcm_mmap_data_close,
+};
+#endif
+
/*
* mmap the DMA buffer on RAM
*/
@@ -3175,6 +3187,16 @@ static int snd_pcm_default_mmap(struct s
area->vm_ops = &snd_pcm_vm_ops_data;
area->vm_private_data = substream;
area->vm_flags |= VM_RESERVED;
+#ifdef HAVE_DMA_MMAP_COHERENT
+ if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) {
+ area->vm_ops = &snd_pcm_vm_ops_data_one_map;
+ if (dma_mmap_coherent(substream->dma_buffer.dev.dev, area,
+ substream->runtime->dma_area,
+ substream->runtime->dma_addr,
+ area->vm_end - area->vm_start))
+ return -EAGAIN;
+ }
+#endif
atomic_inc(&substream->mmap_count);
return 0;
}
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-28 20:27 ` Gerhard Pircher
0 siblings, 0 replies; 29+ messages in thread
From: Gerhard Pircher @ 2006-06-28 20:27 UTC (permalink / raw)
To: Takashi Iwai; +Cc: linuxppc-dev, rlrevell, alsa-devel, linux-kernel, benh
Hi,
It took a little bit longer to integrate the patch, as I didn't figure out first how to implement the __dma_mmap_coherent() function for PPC systems with CONFIG_NOT_COHERENT_CACHE defined. :)
Unfortunately my system still crashes within snd_pcm_mmap_data_nopage()
(sound/core/pcm_native.c), as you can see below. I guess it tries to remap
a DMA buffer allocated by the not cache coherent DMA memory allocation
function in arch/ppc/kernel/dma-mapping.c.
Jun 28 21:59:30 localhost kernel: [ 199.869609] Using dma_mmap_coherent for mmaping DMA buffer!
Jun 28 21:59:30 localhost kernel: [ 199.925075] Oops: kernel access of bad area, sig: 11 [#1]
Jun 28 21:59:30 localhost kernel: [ 199.925106] NIP: E226FF44 LR: E226FF94 CTR: E226FEA4
Jun 28 21:59:30 localhost kernel: [ 199.925116] REGS: d2577d30 TRAP: 0600 Not tainted (2.6.16.16-a1-2)
Jun 28 21:59:30 localhost kernel: [ 199.925121] MSR: 00009032 <EE,ME,IR,DR> CR: 44048444 XER: 00000000
Jun 28 21:59:30 localhost kernel: [ 199.925134] DAR: 99A9999D, DSISR: 00000120
Jun 28 21:59:30 localhost kernel: [ 199.925140] TASK = d242cd10[4338] 'totem' THREAD: d2576000
Jun 28 21:59:30 localhost kernel: [ 199.925144] GPR00: 99A9999D D2577DE0 D242CD10 C0C826A0 00000000 D2577E08 D275F000 D36DC328
Jun 28 21:59:30 localhost kernel: [ 199.925158] GPR08: 02000000 00004000 00000000 99A99999 84048444 10054698 00000000 10196A58
Jun 28 21:59:30 localhost kernel: [ 199.925172] GPR16: 00000000 00000000 00000000 D36DC328 02000000 329FE000 00000000 00000000
Jun 28 21:59:30 localhost kernel: [ 199.925184] GPR24: DE5A6B20 DFA63C80 329FE000 DFA63C80 D20AD804 D275F7F8 D2576000 D2577E08
Jun 28 21:59:30 localhost kernel: [ 199.925199] NIP [E226FF44] snd_pcm_mmap_data_nopage+0xa0/0x12c [snd_pcm]
Jun 28 21:59:30 localhost kernel: [ 199.925300] LR [E226FF94] snd_pcm_mmap_data_nopage+0xf0/0x12c [snd_pcm]
Jun 28 21:59:30 localhost kernel: [ 199.925325] Call Trace:
Jun 28 21:59:30 localhost kernel: [ 199.925330] [D2577DE0] [C0010050] update_mmu_cache+0xe4/0xf4 (unreliable)
Jun 28 21:59:30 localhost kernel: [ 199.925361] [D2577E00] [C004F1D8] do_no_page+0xa4/0x6a4
Jun 28 21:59:30 localhost kernel: [ 199.925387] [D2577E60] [C004FA24] __handle_mm_fault+0x12c/0x328
Jun 28 21:59:30 localhost kernel: [ 199.925398] [D2577E90] [C000F740] do_page_fault+0x140/0x384
Jun 28 21:59:30 localhost kernel: [ 199.925407] [D2577F40] [C0004AC0] handle_page_fault+0xc/0x80
Jun 28 21:59:30 localhost kernel: [ 199.925423] Instruction dump:
Jun 28 21:59:30 localhost kernel: [ 199.925427] 812a0218 3d60c038 800b938c 7d292214 3d294000 5529c9f4 7c604a14 80030000
Jun 28 21:59:30 localhost kernel: [ 199.925441] 7c6b1b78 70094000 40820044 380b0004 <7d200028> 31290001 7d20012d 40a2fff4
Comments?
Thanks!
Gerhard
-------- Original-Nachricht --------
Datum: Wed, 14 Jun 2006 16:42:48 +0200
Von: Takashi Iwai <tiwai@suse.de>
An: Gerhard Pircher <gerhard_pircher@gmx.net>
Betreff: Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
> At Mon, 12 Jun 2006 16:42:54 +0200,
> Gerhard Pircher wrote:
> >
> > > > But as far as I understand this would require a rewrite of all the
> > > > ALSA drivers (or at least a rewrite of the ALSA's DMA helper
> > > > functions).
> > >
> > > Yes. The change of ALSA side has been also on my tree. But it was
> > > still pending since I'm not satisfied with the design yet.
> > > If you're interested in it, let me know. I'll post the patch.
> >
> > Yes, please! Then I can test, if the dma_mmap_coherent() patch works on
> > my non cache coherent powerpc machine.
>
> For using dma_mmap_coherent(), the patch below should suffice.
> (Also you need to enable HAVE_DMA_MMAP_COHERENT there not only for
> ARM.)
>
> > Do you think the DMA Layer/ALSA patches will go upstream in one of
> > the next ALSA/Linux kernel versions?
>
> Definitely no 2.6.18 material yet.
>
>
> Takashi
--
Echte DSL-Flatrate dauerhaft für 0,- Euro*!
"Feel free" mit GMX DSL! http://www.gmx.net/de/go/dsl
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-28 20:27 ` Gerhard Pircher
0 siblings, 0 replies; 29+ messages in thread
From: Gerhard Pircher @ 2006-06-28 20:27 UTC (permalink / raw)
To: Takashi Iwai; +Cc: linuxppc-dev, rlrevell, alsa-devel, linux-kernel
Hi,
It took a little bit longer to integrate the patch, as I didn't figure out first how to implement the __dma_mmap_coherent() function for PPC systems with CONFIG_NOT_COHERENT_CACHE defined. :)
Unfortunately my system still crashes within snd_pcm_mmap_data_nopage()
(sound/core/pcm_native.c), as you can see below. I guess it tries to remap
a DMA buffer allocated by the not cache coherent DMA memory allocation
function in arch/ppc/kernel/dma-mapping.c.
Jun 28 21:59:30 localhost kernel: [ 199.869609] Using dma_mmap_coherent for mmaping DMA buffer!
Jun 28 21:59:30 localhost kernel: [ 199.925075] Oops: kernel access of bad area, sig: 11 [#1]
Jun 28 21:59:30 localhost kernel: [ 199.925106] NIP: E226FF44 LR: E226FF94 CTR: E226FEA4
Jun 28 21:59:30 localhost kernel: [ 199.925116] REGS: d2577d30 TRAP: 0600 Not tainted (2.6.16.16-a1-2)
Jun 28 21:59:30 localhost kernel: [ 199.925121] MSR: 00009032 <EE,ME,IR,DR> CR: 44048444 XER: 00000000
Jun 28 21:59:30 localhost kernel: [ 199.925134] DAR: 99A9999D, DSISR: 00000120
Jun 28 21:59:30 localhost kernel: [ 199.925140] TASK = d242cd10[4338] 'totem' THREAD: d2576000
Jun 28 21:59:30 localhost kernel: [ 199.925144] GPR00: 99A9999D D2577DE0 D242CD10 C0C826A0 00000000 D2577E08 D275F000 D36DC328
Jun 28 21:59:30 localhost kernel: [ 199.925158] GPR08: 02000000 00004000 00000000 99A99999 84048444 10054698 00000000 10196A58
Jun 28 21:59:30 localhost kernel: [ 199.925172] GPR16: 00000000 00000000 00000000 D36DC328 02000000 329FE000 00000000 00000000
Jun 28 21:59:30 localhost kernel: [ 199.925184] GPR24: DE5A6B20 DFA63C80 329FE000 DFA63C80 D20AD804 D275F7F8 D2576000 D2577E08
Jun 28 21:59:30 localhost kernel: [ 199.925199] NIP [E226FF44] snd_pcm_mmap_data_nopage+0xa0/0x12c [snd_pcm]
Jun 28 21:59:30 localhost kernel: [ 199.925300] LR [E226FF94] snd_pcm_mmap_data_nopage+0xf0/0x12c [snd_pcm]
Jun 28 21:59:30 localhost kernel: [ 199.925325] Call Trace:
Jun 28 21:59:30 localhost kernel: [ 199.925330] [D2577DE0] [C0010050] update_mmu_cache+0xe4/0xf4 (unreliable)
Jun 28 21:59:30 localhost kernel: [ 199.925361] [D2577E00] [C004F1D8] do_no_page+0xa4/0x6a4
Jun 28 21:59:30 localhost kernel: [ 199.925387] [D2577E60] [C004FA24] __handle_mm_fault+0x12c/0x328
Jun 28 21:59:30 localhost kernel: [ 199.925398] [D2577E90] [C000F740] do_page_fault+0x140/0x384
Jun 28 21:59:30 localhost kernel: [ 199.925407] [D2577F40] [C0004AC0] handle_page_fault+0xc/0x80
Jun 28 21:59:30 localhost kernel: [ 199.925423] Instruction dump:
Jun 28 21:59:30 localhost kernel: [ 199.925427] 812a0218 3d60c038 800b938c 7d292214 3d294000 5529c9f4 7c604a14 80030000
Jun 28 21:59:30 localhost kernel: [ 199.925441] 7c6b1b78 70094000 40820044 380b0004 <7d200028> 31290001 7d20012d 40a2fff4
Comments?
Thanks!
Gerhard
-------- Original-Nachricht --------
Datum: Wed, 14 Jun 2006 16:42:48 +0200
Von: Takashi Iwai <tiwai@suse.de>
An: Gerhard Pircher <gerhard_pircher@gmx.net>
Betreff: Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
> At Mon, 12 Jun 2006 16:42:54 +0200,
> Gerhard Pircher wrote:
> >
> > > > But as far as I understand this would require a rewrite of all the
> > > > ALSA drivers (or at least a rewrite of the ALSA's DMA helper
> > > > functions).
> > >
> > > Yes. The change of ALSA side has been also on my tree. But it was
> > > still pending since I'm not satisfied with the design yet.
> > > If you're interested in it, let me know. I'll post the patch.
> >
> > Yes, please! Then I can test, if the dma_mmap_coherent() patch works on
> > my non cache coherent powerpc machine.
>
> For using dma_mmap_coherent(), the patch below should suffice.
> (Also you need to enable HAVE_DMA_MMAP_COHERENT there not only for
> ARM.)
>
> > Do you think the DMA Layer/ALSA patches will go upstream in one of
> > the next ALSA/Linux kernel versions?
>
> Definitely no 2.6.18 material yet.
>
>
> Takashi
--
Echte DSL-Flatrate dauerhaft für 0,- Euro*!
"Feel free" mit GMX DSL! http://www.gmx.net/de/go/dsl
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-28 20:27 ` Gerhard Pircher
0 siblings, 0 replies; 29+ messages in thread
From: Gerhard Pircher @ 2006-06-28 20:27 UTC (permalink / raw)
To: Takashi Iwai; +Cc: linuxppc-dev, rlrevell, alsa-devel, linux-kernel, benh
Hi,
It took a little bit longer to integrate the patch, as I didn't figure out first how to implement the __dma_mmap_coherent() function for PPC systems with CONFIG_NOT_COHERENT_CACHE defined. :)
Unfortunately my system still crashes within snd_pcm_mmap_data_nopage()
(sound/core/pcm_native.c), as you can see below. I guess it tries to remap
a DMA buffer allocated by the not cache coherent DMA memory allocation
function in arch/ppc/kernel/dma-mapping.c.
Jun 28 21:59:30 localhost kernel: [ 199.869609] Using dma_mmap_coherent for mmaping DMA buffer!
Jun 28 21:59:30 localhost kernel: [ 199.925075] Oops: kernel access of bad area, sig: 11 [#1]
Jun 28 21:59:30 localhost kernel: [ 199.925106] NIP: E226FF44 LR: E226FF94 CTR: E226FEA4
Jun 28 21:59:30 localhost kernel: [ 199.925116] REGS: d2577d30 TRAP: 0600 Not tainted (2.6.16.16-a1-2)
Jun 28 21:59:30 localhost kernel: [ 199.925121] MSR: 00009032 <EE,ME,IR,DR> CR: 44048444 XER: 00000000
Jun 28 21:59:30 localhost kernel: [ 199.925134] DAR: 99A9999D, DSISR: 00000120
Jun 28 21:59:30 localhost kernel: [ 199.925140] TASK = d242cd10[4338] 'totem' THREAD: d2576000
Jun 28 21:59:30 localhost kernel: [ 199.925144] GPR00: 99A9999D D2577DE0 D242CD10 C0C826A0 00000000 D2577E08 D275F000 D36DC328
Jun 28 21:59:30 localhost kernel: [ 199.925158] GPR08: 02000000 00004000 00000000 99A99999 84048444 10054698 00000000 10196A58
Jun 28 21:59:30 localhost kernel: [ 199.925172] GPR16: 00000000 00000000 00000000 D36DC328 02000000 329FE000 00000000 00000000
Jun 28 21:59:30 localhost kernel: [ 199.925184] GPR24: DE5A6B20 DFA63C80 329FE000 DFA63C80 D20AD804 D275F7F8 D2576000 D2577E08
Jun 28 21:59:30 localhost kernel: [ 199.925199] NIP [E226FF44] snd_pcm_mmap_data_nopage+0xa0/0x12c [snd_pcm]
Jun 28 21:59:30 localhost kernel: [ 199.925300] LR [E226FF94] snd_pcm_mmap_data_nopage+0xf0/0x12c [snd_pcm]
Jun 28 21:59:30 localhost kernel: [ 199.925325] Call Trace:
Jun 28 21:59:30 localhost kernel: [ 199.925330] [D2577DE0] [C0010050] update_mmu_cache+0xe4/0xf4 (unreliable)
Jun 28 21:59:30 localhost kernel: [ 199.925361] [D2577E00] [C004F1D8] do_no_page+0xa4/0x6a4
Jun 28 21:59:30 localhost kernel: [ 199.925387] [D2577E60] [C004FA24] __handle_mm_fault+0x12c/0x328
Jun 28 21:59:30 localhost kernel: [ 199.925398] [D2577E90] [C000F740] do_page_fault+0x140/0x384
Jun 28 21:59:30 localhost kernel: [ 199.925407] [D2577F40] [C0004AC0] handle_page_fault+0xc/0x80
Jun 28 21:59:30 localhost kernel: [ 199.925423] Instruction dump:
Jun 28 21:59:30 localhost kernel: [ 199.925427] 812a0218 3d60c038 800b938c 7d292214 3d294000 5529c9f4 7c604a14 80030000
Jun 28 21:59:30 localhost kernel: [ 199.925441] 7c6b1b78 70094000 40820044 380b0004 <7d200028> 31290001 7d20012d 40a2fff4
Comments?
Thanks!
Gerhard
-------- Original-Nachricht --------
Datum: Wed, 14 Jun 2006 16:42:48 +0200
Von: Takashi Iwai <tiwai@suse.de>
An: Gerhard Pircher <gerhard_pircher@gmx.net>
Betreff: Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
> At Mon, 12 Jun 2006 16:42:54 +0200,
> Gerhard Pircher wrote:
> >
> > > > But as far as I understand this would require a rewrite of all the
> > > > ALSA drivers (or at least a rewrite of the ALSA's DMA helper
> > > > functions).
> > >
> > > Yes. The change of ALSA side has been also on my tree. But it was
> > > still pending since I'm not satisfied with the design yet.
> > > If you're interested in it, let me know. I'll post the patch.
> >
> > Yes, please! Then I can test, if the dma_mmap_coherent() patch works on
> > my non cache coherent powerpc machine.
>
> For using dma_mmap_coherent(), the patch below should suffice.
> (Also you need to enable HAVE_DMA_MMAP_COHERENT there not only for
> ARM.)
>
> > Do you think the DMA Layer/ALSA patches will go upstream in one of
> > the next ALSA/Linux kernel versions?
>
> Definitely no 2.6.18 material yet.
>
>
> Takashi
--
Echte DSL-Flatrate dauerhaft für 0,- Euro*!
"Feel free" mit GMX DSL! http://www.gmx.net/de/go/dsl
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
2006-06-28 20:27 ` Gerhard Pircher
(?)
@ 2006-06-29 9:27 ` Takashi Iwai
-1 siblings, 0 replies; 29+ messages in thread
From: Takashi Iwai @ 2006-06-29 9:27 UTC (permalink / raw)
To: Gerhard Pircher; +Cc: linuxppc-dev, rlrevell, alsa-devel, linux-kernel, benh
At Wed, 28 Jun 2006 22:27:53 +0200,
Gerhard Pircher wrote:
>
> Hi,
>
> It took a little bit longer to integrate the patch, as I didn't figure out first how to implement the __dma_mmap_coherent() function for PPC systems with CONFIG_NOT_COHERENT_CACHE defined. :)
>
> Unfortunately my system still crashes within snd_pcm_mmap_data_nopage()
> (sound/core/pcm_native.c), as you can see below. I guess it tries to remap
> a DMA buffer allocated by the not cache coherent DMA memory allocation
> function in arch/ppc/kernel/dma-mapping.c.
Strange, nopage will be never called if you apply my patch and modify
to use dma_mmap_coherent().
Takashi
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-29 9:27 ` Takashi Iwai
0 siblings, 0 replies; 29+ messages in thread
From: Takashi Iwai @ 2006-06-29 9:27 UTC (permalink / raw)
To: Gerhard Pircher; +Cc: linuxppc-dev, rlrevell, alsa-devel, linux-kernel
At Wed, 28 Jun 2006 22:27:53 +0200,
Gerhard Pircher wrote:
>
> Hi,
>
> It took a little bit longer to integrate the patch, as I didn't figure out first how to implement the __dma_mmap_coherent() function for PPC systems with CONFIG_NOT_COHERENT_CACHE defined. :)
>
> Unfortunately my system still crashes within snd_pcm_mmap_data_nopage()
> (sound/core/pcm_native.c), as you can see below. I guess it tries to remap
> a DMA buffer allocated by the not cache coherent DMA memory allocation
> function in arch/ppc/kernel/dma-mapping.c.
Strange, nopage will be never called if you apply my patch and modify
to use dma_mmap_coherent().
Takashi
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-29 9:27 ` Takashi Iwai
0 siblings, 0 replies; 29+ messages in thread
From: Takashi Iwai @ 2006-06-29 9:27 UTC (permalink / raw)
To: Gerhard Pircher; +Cc: linuxppc-dev, rlrevell, alsa-devel, linux-kernel, benh
At Wed, 28 Jun 2006 22:27:53 +0200,
Gerhard Pircher wrote:
>
> Hi,
>
> It took a little bit longer to integrate the patch, as I didn't figure out first how to implement the __dma_mmap_coherent() function for PPC systems with CONFIG_NOT_COHERENT_CACHE defined. :)
>
> Unfortunately my system still crashes within snd_pcm_mmap_data_nopage()
> (sound/core/pcm_native.c), as you can see below. I guess it tries to remap
> a DMA buffer allocated by the not cache coherent DMA memory allocation
> function in arch/ppc/kernel/dma-mapping.c.
Strange, nopage will be never called if you apply my patch and modify
to use dma_mmap_coherent().
Takashi
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
2006-06-29 9:27 ` Takashi Iwai
(?)
@ 2006-06-29 21:15 ` Gerhard Pircher
-1 siblings, 0 replies; 29+ messages in thread
From: Gerhard Pircher @ 2006-06-29 21:15 UTC (permalink / raw)
To: Takashi Iwai; +Cc: linuxppc-dev, rlrevell, alsa-devel, linux-kernel
-------- Original-Nachricht --------
Datum: Thu, 29 Jun 2006 11:27:15 +0200
Von: Takashi Iwai <tiwai@suse.de>
An: Gerhard Pircher <gerhard_pircher@gmx.net>
Betreff: Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
> At Wed, 28 Jun 2006 22:27:53 +0200,
> Gerhard Pircher wrote:
> >
> > Hi,
> >
> > It took a little bit longer to integrate the patch, as I didn't figure
> out first how to implement the __dma_mmap_coherent() function for PPC
> systems with CONFIG_NOT_COHERENT_CACHE defined. :)
> >
> > Unfortunately my system still crashes within snd_pcm_mmap_data_nopage()
> > (sound/core/pcm_native.c), as you can see below. I guess it tries to
> remap
> > a DMA buffer allocated by the not cache coherent DMA memory allocation
> > function in arch/ppc/kernel/dma-mapping.c.
>
> Strange, nopage will be never called if you apply my patch and modify
> to use dma_mmap_coherent().
>
>
> Takashi
>
That's indeed strange! I'm sure that the new code is called by the sound drivers. Should snd_pcm_mmap_data_nopage() not be used at all anymore, or are there any cases that could still trigger a call of snd_pcm_mmap_data_nopage()?
Gerhard
--
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-29 21:15 ` Gerhard Pircher
0 siblings, 0 replies; 29+ messages in thread
From: Gerhard Pircher @ 2006-06-29 21:15 UTC (permalink / raw)
To: Takashi Iwai; +Cc: linuxppc-dev, rlrevell, alsa-devel, linux-kernel
-------- Original-Nachricht --------
Datum: Thu, 29 Jun 2006 11:27:15 +0200
Von: Takashi Iwai <tiwai@suse.de>
An: Gerhard Pircher <gerhard_pircher@gmx.net>
Betreff: Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
> At Wed, 28 Jun 2006 22:27:53 +0200,
> Gerhard Pircher wrote:
> >
> > Hi,
> >
> > It took a little bit longer to integrate the patch, as I didn't figure
> out first how to implement the __dma_mmap_coherent() function for PPC
> systems with CONFIG_NOT_COHERENT_CACHE defined. :)
> >
> > Unfortunately my system still crashes within snd_pcm_mmap_data_nopage()
> > (sound/core/pcm_native.c), as you can see below. I guess it tries to
> remap
> > a DMA buffer allocated by the not cache coherent DMA memory allocation
> > function in arch/ppc/kernel/dma-mapping.c.
>
> Strange, nopage will be never called if you apply my patch and modify
> to use dma_mmap_coherent().
>
>
> Takashi
>
That's indeed strange! I'm sure that the new code is called by the sound drivers. Should snd_pcm_mmap_data_nopage() not be used at all anymore, or are there any cases that could still trigger a call of snd_pcm_mmap_data_nopage()?
Gerhard
--
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-29 21:15 ` Gerhard Pircher
0 siblings, 0 replies; 29+ messages in thread
From: Gerhard Pircher @ 2006-06-29 21:15 UTC (permalink / raw)
To: Takashi Iwai; +Cc: linux-kernel, alsa-devel, rlrevell, linuxppc-dev
-------- Original-Nachricht --------
Datum: Thu, 29 Jun 2006 11:27:15 +0200
Von: Takashi Iwai <tiwai@suse.de>
An: Gerhard Pircher <gerhard_pircher@gmx.net>
Betreff: Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
> At Wed, 28 Jun 2006 22:27:53 +0200,
> Gerhard Pircher wrote:
> >
> > Hi,
> >
> > It took a little bit longer to integrate the patch, as I didn't figure
> out first how to implement the __dma_mmap_coherent() function for PPC
> systems with CONFIG_NOT_COHERENT_CACHE defined. :)
> >
> > Unfortunately my system still crashes within snd_pcm_mmap_data_nopage()
> > (sound/core/pcm_native.c), as you can see below. I guess it tries to
> remap
> > a DMA buffer allocated by the not cache coherent DMA memory allocation
> > function in arch/ppc/kernel/dma-mapping.c.
>
> Strange, nopage will be never called if you apply my patch and modify
> to use dma_mmap_coherent().
>
>
> Takashi
>
That's indeed strange! I'm sure that the new code is called by the sound drivers. Should snd_pcm_mmap_data_nopage() not be used at all anymore, or are there any cases that could still trigger a call of snd_pcm_mmap_data_nopage()?
Gerhard
--
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
2006-06-29 21:15 ` Gerhard Pircher
(?)
@ 2006-06-30 9:12 ` Takashi Iwai
-1 siblings, 0 replies; 29+ messages in thread
From: Takashi Iwai @ 2006-06-30 9:12 UTC (permalink / raw)
To: Gerhard Pircher; +Cc: linuxppc-dev, rlrevell, alsa-devel, linux-kernel
At Thu, 29 Jun 2006 23:15:13 +0200,
Gerhard Pircher wrote:
>
>
> -------- Original-Nachricht --------
> Datum: Thu, 29 Jun 2006 11:27:15 +0200
> Von: Takashi Iwai <tiwai@suse.de>
> An: Gerhard Pircher <gerhard_pircher@gmx.net>
> Betreff: Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
>
> > At Wed, 28 Jun 2006 22:27:53 +0200,
> > Gerhard Pircher wrote:
> > >
> > > Hi,
> > >
> > > It took a little bit longer to integrate the patch, as I didn't figure
> > out first how to implement the __dma_mmap_coherent() function for PPC
> > systems with CONFIG_NOT_COHERENT_CACHE defined. :)
> > >
> > > Unfortunately my system still crashes within snd_pcm_mmap_data_nopage()
> > > (sound/core/pcm_native.c), as you can see below. I guess it tries to
> > remap
> > > a DMA buffer allocated by the not cache coherent DMA memory allocation
> > > function in arch/ppc/kernel/dma-mapping.c.
> >
> > Strange, nopage will be never called if you apply my patch and modify
> > to use dma_mmap_coherent().
> >
> >
> > Takashi
> >
> That's indeed strange! I'm sure that the new code is called by the
> sound drivers. Should snd_pcm_mmap_data_nopage() not be used at all
> anymore, or are there any cases that could still trigger a call of
> snd_pcm_mmap_data_nopage()?
What is the type of buffer are you using? If it's a buffer
pre-allocated via snd_pcm_lib_preallocate*() with SNDRV_DMA_TYPE_DEV,
there should be no snd_pcm_mmap_data_nopage call. For other types,
there can be. For example, the patch still doesn't solve the problems
with drivers using sg-buffer.
Takashi
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-30 9:12 ` Takashi Iwai
0 siblings, 0 replies; 29+ messages in thread
From: Takashi Iwai @ 2006-06-30 9:12 UTC (permalink / raw)
To: Gerhard Pircher; +Cc: linuxppc-dev, rlrevell, alsa-devel, linux-kernel
At Thu, 29 Jun 2006 23:15:13 +0200,
Gerhard Pircher wrote:
>
>
> -------- Original-Nachricht --------
> Datum: Thu, 29 Jun 2006 11:27:15 +0200
> Von: Takashi Iwai <tiwai@suse.de>
> An: Gerhard Pircher <gerhard_pircher@gmx.net>
> Betreff: Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
>
> > At Wed, 28 Jun 2006 22:27:53 +0200,
> > Gerhard Pircher wrote:
> > >
> > > Hi,
> > >
> > > It took a little bit longer to integrate the patch, as I didn't figure
> > out first how to implement the __dma_mmap_coherent() function for PPC
> > systems with CONFIG_NOT_COHERENT_CACHE defined. :)
> > >
> > > Unfortunately my system still crashes within snd_pcm_mmap_data_nopage()
> > > (sound/core/pcm_native.c), as you can see below. I guess it tries to
> > remap
> > > a DMA buffer allocated by the not cache coherent DMA memory allocation
> > > function in arch/ppc/kernel/dma-mapping.c.
> >
> > Strange, nopage will be never called if you apply my patch and modify
> > to use dma_mmap_coherent().
> >
> >
> > Takashi
> >
> That's indeed strange! I'm sure that the new code is called by the
> sound drivers. Should snd_pcm_mmap_data_nopage() not be used at all
> anymore, or are there any cases that could still trigger a call of
> snd_pcm_mmap_data_nopage()?
What is the type of buffer are you using? If it's a buffer
pre-allocated via snd_pcm_lib_preallocate*() with SNDRV_DMA_TYPE_DEV,
there should be no snd_pcm_mmap_data_nopage call. For other types,
there can be. For example, the patch still doesn't solve the problems
with drivers using sg-buffer.
Takashi
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-30 9:12 ` Takashi Iwai
0 siblings, 0 replies; 29+ messages in thread
From: Takashi Iwai @ 2006-06-30 9:12 UTC (permalink / raw)
To: Gerhard Pircher; +Cc: linux-kernel, alsa-devel, rlrevell, linuxppc-dev
At Thu, 29 Jun 2006 23:15:13 +0200,
Gerhard Pircher wrote:
>
>
> -------- Original-Nachricht --------
> Datum: Thu, 29 Jun 2006 11:27:15 +0200
> Von: Takashi Iwai <tiwai@suse.de>
> An: Gerhard Pircher <gerhard_pircher@gmx.net>
> Betreff: Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
>
> > At Wed, 28 Jun 2006 22:27:53 +0200,
> > Gerhard Pircher wrote:
> > >
> > > Hi,
> > >
> > > It took a little bit longer to integrate the patch, as I didn't figure
> > out first how to implement the __dma_mmap_coherent() function for PPC
> > systems with CONFIG_NOT_COHERENT_CACHE defined. :)
> > >
> > > Unfortunately my system still crashes within snd_pcm_mmap_data_nopage()
> > > (sound/core/pcm_native.c), as you can see below. I guess it tries to
> > remap
> > > a DMA buffer allocated by the not cache coherent DMA memory allocation
> > > function in arch/ppc/kernel/dma-mapping.c.
> >
> > Strange, nopage will be never called if you apply my patch and modify
> > to use dma_mmap_coherent().
> >
> >
> > Takashi
> >
> That's indeed strange! I'm sure that the new code is called by the
> sound drivers. Should snd_pcm_mmap_data_nopage() not be used at all
> anymore, or are there any cases that could still trigger a call of
> snd_pcm_mmap_data_nopage()?
What is the type of buffer are you using? If it's a buffer
pre-allocated via snd_pcm_lib_preallocate*() with SNDRV_DMA_TYPE_DEV,
there should be no snd_pcm_mmap_data_nopage call. For other types,
there can be. For example, the patch still doesn't solve the problems
with drivers using sg-buffer.
Takashi
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
2006-06-30 9:12 ` Takashi Iwai
@ 2006-06-30 18:21 ` Gerhard Pircher
-1 siblings, 0 replies; 29+ messages in thread
From: Gerhard Pircher @ 2006-06-30 18:21 UTC (permalink / raw)
To: Takashi Iwai; +Cc: linuxppc-dev, rlrevell, alsa-devel, linux-kernel
-------- Original-Nachricht --------
Datum: Fri, 30 Jun 2006 11:12:00 +0200
Von: Takashi Iwai <tiwai@suse.de>
An: Gerhard Pircher <gerhard_pircher@gmx.net>
Betreff: Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
>
> What is the type of buffer are you using? If it's a buffer
> pre-allocated via snd_pcm_lib_preallocate*() with SNDRV_DMA_TYPE_DEV,
> there should be no snd_pcm_mmap_data_nopage call. For other types,
> there can be. For example, the patch still doesn't solve the problems
> with drivers using sg-buffer.
>
I added a debug output and it shows a buffer of SNDRV_DMA_TYPE_DEV_SG type. Well, then I'll hack the kernel to use the normal DMA allocation functions for ALSA instead of the non cache coherent ones and will wait until the ALSA core has been adapted for dma_mmap_coherent().
Or what would have to be done to get it working for SG buffers?
Thanks!
Gerhard
--
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
@ 2006-06-30 18:21 ` Gerhard Pircher
0 siblings, 0 replies; 29+ messages in thread
From: Gerhard Pircher @ 2006-06-30 18:21 UTC (permalink / raw)
To: Takashi Iwai; +Cc: linuxppc-dev, rlrevell, alsa-devel, linux-kernel
-------- Original-Nachricht --------
Datum: Fri, 30 Jun 2006 11:12:00 +0200
Von: Takashi Iwai <tiwai@suse.de>
An: Gerhard Pircher <gerhard_pircher@gmx.net>
Betreff: Re: [Alsa-devel] RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA?
>
> What is the type of buffer are you using? If it's a buffer
> pre-allocated via snd_pcm_lib_preallocate*() with SNDRV_DMA_TYPE_DEV,
> there should be no snd_pcm_mmap_data_nopage call. For other types,
> there can be. For example, the patch still doesn't solve the problems
> with drivers using sg-buffer.
>
I added a debug output and it shows a buffer of SNDRV_DMA_TYPE_DEV_SG type. Well, then I'll hack the kernel to use the normal DMA allocation functions for ALSA instead of the non cache coherent ones and will wait until the ALSA core has been adapted for dma_mmap_coherent().
Or what would have to be done to get it working for SG buffers?
Thanks!
Gerhard
--
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
^ permalink raw reply [flat|nested] 29+ messages in thread
* [RFC] Porting AmigaOne platform code from ppc to powerpc
2006-06-30 18:21 ` [Alsa-devel] " Gerhard Pircher
(?)
@ 2006-10-19 13:24 ` Gerhard Pircher
2006-10-21 23:51 ` Benjamin Herrenschmidt
-1 siblings, 1 reply; 29+ messages in thread
From: Gerhard Pircher @ 2006-10-19 13:24 UTC (permalink / raw)
To: linuxppc-dev
Hi!
I'm working on the AmigaOne Linux kernel port. The AmigaOne is a G3/G4 desktop system and makes use of U-boot v1.1.0 as firmware. I intend to port the current code base of this platform to the powerpc architecture, but I'm not sure how to address this.
The "problem" is the device tree required by the powerpc architecture. The AmigaOne's U-boot version doesn't support the flattened device tree yet and also requires a special flash rom programmer tool (I guess it adds some sort of dongle code to the flash rom content). Otherwise users won't be able to boot AmigaOS4. Thus using a newer U-boot version is not really an option and AFAIK the OS4 developers are not going to update their U-boot version.
Well, some time ago I read about a CUIMAGE target that can be used to get powerpc-arch kernels working on old U-boot versions by using a precompiled/static device tree. I don't think that this approch makes sense for a desktop platform, which uses different CPUs (750FX, 750GX, 7410, 7450, 7455, etc..), PCI/AGP cards, etc.
Any advice for me in this case?
Regards,
Gerhard
--
GMX DSL-Flatrate 0,- Euro* - Überall, wo DSL verfügbar ist!
NEU: Jetzt bis zu 16.000 kBit/s! http://www.gmx.net/de/go/dsl
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [RFC] Porting AmigaOne platform code from ppc to powerpc
2006-10-19 13:24 ` [RFC] Porting AmigaOne platform code from ppc to powerpc Gerhard Pircher
@ 2006-10-21 23:51 ` Benjamin Herrenschmidt
2006-10-23 18:57 ` Crash with highmem support enabled Gerhard Pircher
0 siblings, 1 reply; 29+ messages in thread
From: Benjamin Herrenschmidt @ 2006-10-21 23:51 UTC (permalink / raw)
To: Gerhard Pircher; +Cc: linuxppc-dev
On Thu, 2006-10-19 at 15:24 +0200, Gerhard Pircher wrote:
> Hi!
>
> I'm working on the AmigaOne Linux kernel port. The AmigaOne is a G3/G4 desktop system and makes use of U-boot v1.1.0 as firmware. I intend to port the current code base of this platform to the powerpc architecture, but I'm not sure how to address this.
>
> The "problem" is the device tree required by the powerpc architecture. The AmigaOne's U-boot version doesn't support the flattened device tree yet and also requires a special flash rom programmer tool (I guess it adds some sort of dongle code to the flash rom content). Otherwise users won't be able to boot AmigaOS4. Thus using a newer U-boot version is not really an option and AFAIK the OS4 developers are not going to update their U-boot version.
>
> Well, some time ago I read about a CUIMAGE target that can be used to get powerpc-arch kernels working on old U-boot versions by using a precompiled/static device tree. I don't think that this approch makes sense for a desktop platform, which uses different CPUs (750FX, 750GX, 7410, 7450, 7455, etc..), PCI/AGP cards, etc.
>
> Any advice for me in this case?
You can also look at the rework being done currently on zImage wrappers.
Among others, they have the ability to embed a device-tree.
Ben.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Crash with highmem support enabled
2006-10-21 23:51 ` Benjamin Herrenschmidt
@ 2006-10-23 18:57 ` Gerhard Pircher
2006-10-25 5:34 ` Paul Mackerras
0 siblings, 1 reply; 29+ messages in thread
From: Gerhard Pircher @ 2006-10-23 18:57 UTC (permalink / raw)
To: linuxppc-dev
Hi,
I'm trying to get highmem support working on my AmigaOne. The machine is equipped with 1.5G RAM. Unfortunately the kernel crashes early in the boot process, so I couldn't save the crash log. But it seems to crash during the initialization of the radeonfb driver.
I guess this has something to do with the IO block mapping, which is implemented in the amigaone_setup.c file and looks like this:
{
/* Remap ISA/PCI IO space first to get it mapped by BATs. */
io_block_mapping(0xfe000000, 0xfe000000, 0x01000000, _PAGE_IO);
/* Remap ISA memory for framebuffer (U-boot framebuffer). */
io_block_mapping(0xfd000000, 0xfd000000, 0x01000000, _PAGE_IO);
/* Remap PROM I/O space to 0xfc000000, to get a window for non
* cache coherent DMA support at 0xff100000.
*/
io_block_mapping(0xfc000000, 0xff000000, 0x01000000, _PAGE_IO);
}
The addresses below 0xfc000000 belong to the PCI memory space (0x80000000-0xfbffffff).
Thus I moved the highmem base to 0xfc000000, since the PCI memory is not ioremap'd. But the kernel still crashes.
Can somebody give me a hint how to get highmem working? I'm not sure what the real problem is, as also other platforms (PReP, sandpoint) ioremap the address space from 0xfe000000 to 0xffffffff.
Gerhard
--
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Crash with highmem support enabled
2006-10-23 18:57 ` Crash with highmem support enabled Gerhard Pircher
@ 2006-10-25 5:34 ` Paul Mackerras
2006-10-25 7:45 ` Gerhard Pircher
0 siblings, 1 reply; 29+ messages in thread
From: Paul Mackerras @ 2006-10-25 5:34 UTC (permalink / raw)
To: Gerhard Pircher; +Cc: linuxppc-dev
Gerhard Pircher writes:
> I guess this has something to do with the IO block mapping, which is
> implemented in the amigaone_setup.c file and looks like this:
Why on earth are you still using io_block_mapping?
Paul.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Crash with highmem support enabled
2006-10-25 5:34 ` Paul Mackerras
@ 2006-10-25 7:45 ` Gerhard Pircher
0 siblings, 0 replies; 29+ messages in thread
From: Gerhard Pircher @ 2006-10-25 7:45 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
-------- Original-Nachricht --------
Datum: Wed, 25 Oct 2006 15:34:50 +1000
Von: Paul Mackerras <paulus@samba.org>
An: "Gerhard Pircher" <gerhard_pircher@gmx.net>
Betreff: Re: Crash with highmem support enabled
> Gerhard Pircher writes:
>
> > I guess this has something to do with the IO block mapping, which is
> > implemented in the amigaone_setup.c file and looks like this:
>
> Why on earth are you still using io_block_mapping?
What should be used instead? ioremap()? The io_block_mapping() code was copied over from the PReP platform code in arch/ppc/platforms/.
In the meantime I found out that highmem failed due to the IO block mapping (sometimes it is good to look at the code ;). The mapping is needed for the AmigaOne/U-boot framebuffer to be able to access the ISA memory and I/O. Where and when can I savely remap (no 1:1 remapping) the ISA space so that the framebuffer survives the MMU initialization?
thanks!
Gerhard
--
GMX DSL-Flatrate 0,- Euro* - Überall, wo DSL verfügbar ist!
NEU: Jetzt bis zu 16.000 kBit/s! http://www.gmx.net/de/go/dsl
^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2006-10-25 7:45 UTC | newest]
Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-28 20:27 RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA? Gerhard Pircher
2006-06-28 20:27 ` Re: [Alsa-devel] " Gerhard Pircher
2006-06-28 20:27 ` Gerhard Pircher
2006-06-29 9:27 ` Takashi Iwai
2006-06-29 9:27 ` [Alsa-devel] " Takashi Iwai
2006-06-29 9:27 ` Takashi Iwai
2006-06-29 21:15 ` Gerhard Pircher
2006-06-29 21:15 ` [Alsa-devel] " Gerhard Pircher
2006-06-29 21:15 ` Gerhard Pircher
2006-06-30 9:12 ` Takashi Iwai
2006-06-30 9:12 ` [Alsa-devel] " Takashi Iwai
2006-06-30 9:12 ` Takashi Iwai
2006-06-30 18:21 ` Gerhard Pircher
2006-06-30 18:21 ` [Alsa-devel] " Gerhard Pircher
2006-10-19 13:24 ` [RFC] Porting AmigaOne platform code from ppc to powerpc Gerhard Pircher
2006-10-21 23:51 ` Benjamin Herrenschmidt
2006-10-23 18:57 ` Crash with highmem support enabled Gerhard Pircher
2006-10-25 5:34 ` Paul Mackerras
2006-10-25 7:45 ` Gerhard Pircher
-- strict thread matches above, loose matches on Subject: below --
2006-06-10 8:22 RFC: dma_mmap_coherent() for powerpc/ppc architecture and ALSA? Gerhard Pircher
2006-06-12 10:51 ` Takashi Iwai
2006-06-12 10:51 ` Takashi Iwai
2006-06-12 10:51 ` Takashi Iwai
2006-06-12 14:42 ` Gerhard Pircher
2006-06-14 14:42 ` Takashi Iwai
2006-06-09 18:01 Gerhard Pircher
2006-06-10 0:34 ` Benjamin Herrenschmidt
2006-06-10 0:46 ` Lee Revell
2006-06-10 0:46 ` Lee Revell
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.