Skip to contentSkip to conversation

ALSA on MIPS platform

PATCH Songmao Tian 6 participants 16 messages Aug 1, 2007 – Aug 9, 2007

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

Hi,
In
http://www.linux-mips.org/archives/linux-mips/2007-04/msg00114.html,
Atsushi Nemoto pointed out the problem is discussed before, the thread can be found at http://lkml.org/lkml/2006/1/25/117. Thanks Atsushi Nemoto:)
The problem is clear:
1. dma_alloc_noncoherent() return a non-cached address, and virt_to_page() need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.

We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?

Regards,
Tian

sound/core/pcm_native.c +0 -0
index 59b29cd..fd0aa66 100644
@@ -3138,7 +3138,11 @@ static struct page 

*snd_pcm_mmap_data_nopage(struct vm_area_struct *area,

             return NOPAGE_OOM; /* XXX: is this really due to OOM? */
     } else {
         vaddr = runtime->dma_area + offset;
+#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT)
+        page = virt_to_page(CAC_ADDR(vaddr));
+#else
         page = virt_to_page(vaddr);
+#endif
     }
     get_page(page);
     if (type)
@@ -3254,6 +3258,11 @@ static int snd_pcm_mmap(struct file *file, struct 
vm_area_struct *area)
     substream = pcm_file->substream;
     snd_assert(substream != NULL, return -ENXIO);

+#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT)
+ /* all mmap using uncached mode */
+ area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
+#endif
+

     offset = area->vm_pgoff << PAGE_SHIFT;
     switch (offset) {
     case SNDRV_PCM_MMAP_OFFSET_STATUS:
sound/core/sgbuf.c +7 -0
index cefd228..2251e70 100644
@@ -91,12 +91,21 @@ void *snd_malloc_sgbuf_pages(struct device *device,
         }
         sgbuf->table[i].buf = tmpb.area;
         sgbuf->table[i].addr = tmpb.addr;
+#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT)
+        sgbuf->page_table[i] = virt_to_page(CAC_ADDR(tmpb.area));
+#else
         sgbuf->page_table[i] = virt_to_page(tmpb.area);
+#endif
         sgbuf->pages++;
     }
 
     sgbuf->size = size;
+#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT)
+    /* maybe we should use uncached accelerated mode */
+    dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, 

pgprot_noncached(PAGE_KERNEL));
+#else

     dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, 
PAGE_KERNEL);
+#endif
     if (! dmab->area)
         goto _failed;
     return dmab->area;
#1 lore raw
Quoted 7 lines · Songmao Tian

The problem is clear:
1. dma_alloc_noncoherent() return a non-cached address, and virt_to_page() need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.

We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?

virt_to_page() is used in many place in mm so making it robust might affect performance. IMHO virt_to_page() seems too low-level as DMA API.

If something like dma_virt_to_page(dev, cpu_addr) which can take a cpu address returned by dma_xxx APIs was defined, MIPS can implement it appropriately.

And then pgprot_noncached issues still exist...

---
Atsushi Nemoto

#2 lore raw
Quoted 15 lines · Atsushi Nemoto
Quoted 8 lines · Songmao Tian

The problem is clear:
1. dma_alloc_noncoherent() return a non-cached address, and virt_to_page() need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.

We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?

virt_to_page() is used in many place in mm so making it robust might affect performance. IMHO virt_to_page() seems too low-level as DMA API.

Quoted 12 lines

If something like dma_virt_to_page(dev, cpu_addr) which can take a cpu address returned by dma_xxx APIs was defined, MIPS can implement it appropriately.

And then pgprot_noncached issues still exist...

---
Atsushi Nemoto

I agree, and I am investigating to implement a dma_map_coherent, but It seems dma_map_coherent doesn't solve all the problem and will change a lot of code:(

dma_virt_to_page can be something like this.

include/asm-mips/page.h +1 -0
index b92dd8c..d2ead8a 100644
@@ -181,6 +181,8 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 #define virt_to_page(kaddr)    pfn_to_page(PFN_DOWN(virt_to_phys(kaddr)))
 #define virt_addr_valid(kaddr)    pfn_valid(PFN_DOWN(virt_to_phys(kaddr)))
 
+#define dma_virt_to_page(dma_addr) 

pfn_to_page(PFN_DOWN(virt_to_phys(CAC_ADDR(kaddr)))) +
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)

include/linux/mm.h +4 -0
index 655094d..5e694dd 100644
@@ -39,6 +39,10 @@ extern int sysctl_legacy_va_layout;
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 
+#ifndef dma_virt_to_page
+#define dma_virt_to_page virt_to_page
+#endif
+
 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
 
 /*
sound/core/sgbuf.c +1 -1
index cefd228..8b29bfd 100644
@@ -91,7 +91,7 @@ void *snd_malloc_sgbuf_pages(struct device *device,
         }
         sgbuf->table[i].buf = tmpb.area;
         sgbuf->table[i].addr = tmpb.addr;
-        sgbuf->page_table[i] = virt_to_page(tmpb.area);
+        sgbuf->page_table[i] = dma_virt_to_page(tmpb.area);
         sgbuf->pages++;
     }
#3 lore raw

At Fri, 03 Aug 2007 21:50:36 +0800,

Quoted 30 lines · Songmao Tian
Quoted 15 lines · Atsushi Nemoto
Quoted 8 lines · Songmao Tian

The problem is clear:
1. dma_alloc_noncoherent() return a non-cached address, and virt_to_page() need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.

We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?

virt_to_page() is used in many place in mm so making it robust might affect performance. IMHO virt_to_page() seems too low-level as DMA API.

Quoted 12 lines

If something like dma_virt_to_page(dev, cpu_addr) which can take a cpu address returned by dma_xxx APIs was defined, MIPS can implement it appropriately.

And then pgprot_noncached issues still exist...

---
Atsushi Nemoto

Quoted 3 lines

I agree, and I am investigating to implement a dma_map_coherent, but It seems dma_map_coherent doesn't solve all the problem and will change a lot of code:(

It won't be that much. You'll need to change snd_pcm_default_mmap() in sound/core/pcm_native.c to call dma_mmap_coherent() directly instead of nopage ops. But, this won't work with SG-buffers, which requires some more additional works.

Takashi

#4 lore raw
Quoted 45 lines · Takashi Iwai

At Fri, 03 Aug 2007 21:50:36 +0800,

Quoted 31 lines · Songmao Tian
Quoted 16 lines · Atsushi Nemoto
Quoted 9 lines · Songmao Tian

The problem is clear:
1. dma_alloc_noncoherent() return a non-cached address, and virt_to_page() need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.

We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?

virt_to_page() is used in many place in mm so making it robust might affect performance. IMHO virt_to_page() seems too low-level as DMA API.

Quoted 13 lines

If something like dma_virt_to_page(dev, cpu_addr) which can take a cpu address returned by dma_xxx APIs was defined, MIPS can implement it appropriately.

And then pgprot_noncached issues still exist...

---
Atsushi Nemoto

Quoted 4 lines

I agree, and I am investigating to implement a dma_map_coherent, but It seems dma_map_coherent doesn't solve all the problem and will change a lot of code:(

It won't be that much. You'll need to change snd_pcm_default_mmap() in sound/core/pcm_native.c to call dma_mmap_coherent() directly instead of nopage ops. But, this won't work with SG-buffers, which requires some more additional works.

Quoted 8 lines

Takashi
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

I have no idea if the patch can work, the idea is not very clear now. And I use vt686b ac97 sound driver, the driver use sgbuf, so I will write a test program tomorrow. Good sleep...:)

And if any of you can take some time look into the patch, and give some review will be appreciated:)

arch/mips/mm/dma-default.c +0 -0
index 76903c7..f088a6b 100644
@@ -369,3 +369,23 @@ void dma_cache_sync(struct device *dev, void 

*vaddr, size_t size,
}

EXPORT_SYMBOL(dma_cache_sync);
+
+static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size)
+{
+ if (remap_pfn_range(vma, vma->vm_start,
+ PFN_DOWN(virt_to_phys(CAC_ADDR(cpu_addr))) +
vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot))
+ return -EAGAIN;
+ return 0;
+}
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
+}
+EXPORT_SYMBOL(dma_mmap_coherent);
+

sound/core/pcm_native.c +0 -0
index 59b29cd..af82a3b 100644
@@ -3152,6 +3152,8 @@ static struct vm_operations_struct 

snd_pcm_vm_ops_data =
.close = snd_pcm_mmap_data_close,
.nopage = snd_pcm_mmap_data_nopage,
};
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size);

/*
* mmap the DMA buffer on RAM
@@ -3159,9 +3161,10 @@ static struct vm_operations_struct snd_pcm_vm_ops_data =
static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *area)
{
- area->vm_ops = &snd_pcm_vm_ops_data;

+    struct snd_pcm_runtime *runtime = substream->runtime;
     area->vm_private_data = substream;
-    area->vm_flags |= VM_RESERVED;
+    dma_mmap_coherent(NULL, area, runtime->dma_area,
+            runtime->dma_addr, runtime->dma_bytes);
     atomic_inc(&substream->mmap_count);
     return 0;

}

#5 lore raw

At Fri, 03 Aug 2007 23:57:07 +0800,

Quoted 55 lines · Songmao Tian
Quoted 45 lines · Takashi Iwai

At Fri, 03 Aug 2007 21:50:36 +0800,

Quoted 31 lines · Songmao Tian
Quoted 16 lines · Atsushi Nemoto
Quoted 9 lines · Songmao Tian

The problem is clear:
1. dma_alloc_noncoherent() return a non-cached address, and virt_to_page() need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.

We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?

virt_to_page() is used in many place in mm so making it robust might affect performance. IMHO virt_to_page() seems too low-level as DMA API.

Quoted 13 lines

If something like dma_virt_to_page(dev, cpu_addr) which can take a cpu address returned by dma_xxx APIs was defined, MIPS can implement it appropriately.

And then pgprot_noncached issues still exist...

---
Atsushi Nemoto

Quoted 4 lines

I agree, and I am investigating to implement a dma_map_coherent, but It seems dma_map_coherent doesn't solve all the problem and will change a lot of code:(

It won't be that much. You'll need to change snd_pcm_default_mmap() in sound/core/pcm_native.c to call dma_mmap_coherent() directly instead of nopage ops. But, this won't work with SG-buffers, which requires some more additional works.

Quoted 8 lines

Takashi
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

Quoted 3 lines

I have no idea if the patch can work, the idea is not very clear now. And I use vt686b ac97 sound driver, the driver use sgbuf, so I will write a test program tomorrow. Good sleep...:)

Ah, that's a bad luck. Then your patch won't work as it is. We'll need another function for SG-buffer, that calls dma_mmap_coherent() for each page found in the given buffer.

Takashi

Quoted 66 lines

And if any of you can take some time look into the patch, and give some review will be appreciated:)

arch/mips/mm/dma-default.c +6 -0
index 76903c7..f088a6b 100644
@@ -369,3 +369,23 @@ void dma_cache_sync(struct device *dev, void 
 *vaddr, size_t size,
 }
 
 EXPORT_SYMBOL(dma_cache_sync);
+
+static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
+            void *cpu_addr, dma_addr_t dma_addr, size_t size)
+{
+    if (remap_pfn_range(vma, vma->vm_start,
+                  PFN_DOWN(virt_to_phys(CAC_ADDR(cpu_addr))) + 

vma->vm_pgoff,

arch/mips/mm/dma-default.c +14 -0
+                  vma->vm_end - vma->vm_start,
+                  vma->vm_page_prot))
+        return -EAGAIN;
+    return 0;
+}
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+              void *cpu_addr, dma_addr_t dma_addr, size_t size)
+{
+    vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+    return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
+}
+EXPORT_SYMBOL(dma_mmap_coherent);
+
sound/core/pcm_native.c +0 -0
index 59b29cd..af82a3b 100644
@@ -3152,6 +3152,8 @@ static struct vm_operations_struct 

snd_pcm_vm_ops_data =
.close = snd_pcm_mmap_data_close,
.nopage = snd_pcm_mmap_data_nopage,
};

sound/core/pcm_native.c +2 -0
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+              void *cpu_addr, dma_addr_t dma_addr, size_t size);
 
 /*
  * mmap the DMA buffer on RAM
@@ -3159,9 +3161,10 @@ static struct vm_operations_struct 

snd_pcm_vm_ops_data =
static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *area)
{

sound/core/pcm_native.c +3 -2
-    area->vm_ops = &snd_pcm_vm_ops_data;
+    struct snd_pcm_runtime *runtime = substream->runtime;
     area->vm_private_data = substream;
-    area->vm_flags |= VM_RESERVED;
+    dma_mmap_coherent(NULL, area, runtime->dma_area,
+            runtime->dma_addr, runtime->dma_bytes);
     atomic_inc(&substream->mmap_count);
     return 0;
 }

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#6 lore raw
In reply to Songmao Tian

I think this problem can be solved by revising the __pa macro like this:

include/asm-mips/page.h 2007-08-07 09:46:59.000000000 +0800 renamed from include/asm-mips/page.h 2007-08-07 09:45:00.000000000 +0800 +1 -1
@@ -150,7 +150,7 @@
 })
 #else
 #define __pa(x)
         \
-    ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET)
+    (((unsigned long)(x) & 0x1fffffff) + PHYS_OFFSET)
 #endif
 

So, the virt_to_page can accept all cached or uncached address.

Tan

2007/8/3, Songmao Tian <[email protected]>:

Quoted 79 lines
Quoted 15 lines · Atsushi Nemoto
Quoted 8 lines · Songmao Tian

The problem is clear:
1. dma_alloc_noncoherent() return a non-cached address, and virt_to_page() need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.

We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?

virt_to_page() is used in many place in mm so making it robust might affect performance. IMHO virt_to_page() seems too low-level as DMA API.

Quoted 12 lines

If something like dma_virt_to_page(dev, cpu_addr) which can take a cpu address returned by dma_xxx APIs was defined, MIPS can implement it appropriately.

And then pgprot_noncached issues still exist...

---
Atsushi Nemoto

I agree, and I am investigating to implement a dma_map_coherent, but It seems dma_map_coherent doesn't solve all the problem and will change a lot of code:(

dma_virt_to_page can be something like this.

include/asm-mips/page.h +2 -0
index b92dd8c..d2ead8a 100644
@@ -181,6 +181,8 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 #define virt_to_page(kaddr)    pfn_to_page(PFN_DOWN(virt_to_phys(kaddr)))
 #define virt_addr_valid(kaddr)    pfn_valid(PFN_DOWN(virt_to_phys(kaddr)))
 
+#define dma_virt_to_page(dma_addr)
 pfn_to_page(PFN_DOWN(virt_to_phys(CAC_ADDR(kaddr))))
+
 #define VM_DATA_DEFAULT_FLAGS    (VM_READ | VM_WRITE | VM_EXEC | \
                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
include/linux/mm.h +4 -0
index 655094d..5e694dd 100644
@@ -39,6 +39,10 @@ extern int sysctl_legacy_va_layout;
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 
+#ifndef dma_virt_to_page
+#define dma_virt_to_page virt_to_page
+#endif
+
 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
 
 /*
sound/core/sgbuf.c +1 -1
index cefd228..8b29bfd 100644
@@ -91,7 +91,7 @@ void *snd_malloc_sgbuf_pages(struct device *device,
         }
         sgbuf->table[i].buf = tmpb.area;
         sgbuf->table[i].addr = tmpb.addr;
-        sgbuf->page_table[i] = virt_to_page(tmpb.area);
+        sgbuf->page_table[i] = dma_virt_to_page(tmpb.area);
         sgbuf->pages++;
     }
 
#7 lore raw

Sorry, that aim at 2.6.18.

In the latest kernel:

include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 renamed from include/asm-mips/io.h 2007-08-07 10:18:03.000000000 +0800 +1 -1
@@ -116,7 +116,7 @@
  */
 static inline unsigned long virt_to_phys(volatile const void *address)
 {
-       return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET;
+       return ((unsigned long)address & 0x1fffffff) + PHYS_OFFSET;
 }
 

I think virt_to_phys or __pa should accept kseg1 address.

Tan

2007/8/7, Dajie Tan <[email protected]>:

Quoted 99 lines

I think this problem can be solved by revising the __pa macro like this:

include/asm-mips/page.h 2007-08-07 09:46:59.000000000 +0800 renamed from include/asm-mips/page.h 2007-08-07 09:45:00.000000000 +0800 +1 -1
@@ -150,7 +150,7 @@
 })
 #else
 #define __pa(x)
         \
-    ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET)
+    (((unsigned long)(x) & 0x1fffffff) + PHYS_OFFSET)
 #endif
 

So, the virt_to_page can accept all cached or uncached address.

Tan

2007/8/3, Songmao Tian <[email protected]>:

Quoted 79 lines
Quoted 15 lines · Atsushi Nemoto
Quoted 8 lines · Songmao Tian

The problem is clear:
1. dma_alloc_noncoherent() return a non-cached address, and virt_to_page() need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.

We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?

virt_to_page() is used in many place in mm so making it robust might affect performance. IMHO virt_to_page() seems too low-level as DMA API.

Quoted 12 lines

If something like dma_virt_to_page(dev, cpu_addr) which can take a cpu address returned by dma_xxx APIs was defined, MIPS can implement it appropriately.

And then pgprot_noncached issues still exist...

---
Atsushi Nemoto

I agree, and I am investigating to implement a dma_map_coherent, but It seems dma_map_coherent doesn't solve all the problem and will change a lot of code:(

dma_virt_to_page can be something like this.

include/asm-mips/page.h +2 -0
index b92dd8c..d2ead8a 100644
@@ -181,6 +181,8 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 #define virt_to_page(kaddr)    pfn_to_page(PFN_DOWN(virt_to_phys(kaddr)))
 #define virt_addr_valid(kaddr)    pfn_valid(PFN_DOWN(virt_to_phys(kaddr)))
 
+#define dma_virt_to_page(dma_addr)
 pfn_to_page(PFN_DOWN(virt_to_phys(CAC_ADDR(kaddr))))
+
 #define VM_DATA_DEFAULT_FLAGS    (VM_READ | VM_WRITE | VM_EXEC | \
                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
include/linux/mm.h +4 -0
index 655094d..5e694dd 100644
@@ -39,6 +39,10 @@ extern int sysctl_legacy_va_layout;
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 
+#ifndef dma_virt_to_page
+#define dma_virt_to_page virt_to_page
+#endif
+
 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
 
 /*
sound/core/sgbuf.c +1 -1
index cefd228..8b29bfd 100644
@@ -91,7 +91,7 @@ void *snd_malloc_sgbuf_pages(struct device *device,
         }
         sgbuf->table[i].buf = tmpb.area;
         sgbuf->table[i].addr = tmpb.addr;
-        sgbuf->page_table[i] = virt_to_page(tmpb.area);
+        sgbuf->page_table[i] = dma_virt_to_page(tmpb.area);
         sgbuf->pages++;
     }
 
Signature · 4 lines
为天地立心
为生民立命
为往圣继绝学
为万世开太平
#8 lore raw

include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 line 120

Quoted 5 lines · Dajie Tan

static inline unsigned long virt_to_phys(volatile const void *address) {

include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 renamed from include/asm-mips/io.h 2007-08-07 10:18:03.000000000 +0800 +1 -1
-       return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET;
+       return ((unsigned long)address & 0x1fffffff) + PHYS_OFFSET;
 }

This makes virt_to_phys() a bit slower, and more importantly, breaks 64-bit kernel.

---
Atsushi Nemoto

#9 lore raw
Quoted 9 lines · Atsushi Nemoto

include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 line 120

Quoted 5 lines · Dajie Tan

static inline unsigned long virt_to_phys(volatile const void *address) {

include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 renamed from include/asm-mips/io.h 2007-08-07 10:18:03.000000000 +0800 +1 -1
-       return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET;
+       return ((unsigned long)address & 0x1fffffff) + PHYS_OFFSET;
 }

This makes virt_to_phys() a bit slower, and more importantly, breaks 64-bit kernel.

It's ALSA that is doing funny things here so there is no point in fixing the arch code to work for ALSA.

Ralf

#10 lore raw

At Tue, 7 Aug 2007 18:54:02 +0100,

Quoted 10 lines · Ralf Baechle
Quoted 7 lines · Atsushi Nemoto
Quoted 5 lines · Dajie Tan

static inline unsigned long virt_to_phys(volatile const void *address) {

include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 renamed from include/asm-mips/io.h 2007-08-07 10:18:03.000000000 +0800 +1 -1
-       return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET;
+       return ((unsigned long)address & 0x1fffffff) + PHYS_OFFSET;
 }
Quoted 5 lines
Quoted 2 lines

This makes virt_to_phys() a bit slower, and more importantly, breaks 64-bit kernel.

It's ALSA that is doing funny things here so there is no point in fixing the arch code to work for ALSA.

Yep, but OTOH, the arch code doesn't provide a proper standard way to mmap the pages allocated via dma_alloc_coherent(). That's the missing piece, especially on mips and sparc. ARM has already one.

My wish is implementing dma_mmap_coherent() on all architectures, so that the driver can use it safely without messy ifdefs.

Takashi

#11 lore raw
Quoted 9 lines · Takashi Iwai
Quoted 2 lines

It's ALSA that is doing funny things here so there is no point in fixing the arch code to work for ALSA.

Yep, but OTOH, the arch code doesn't provide a proper standard way to mmap the pages allocated via dma_alloc_coherent(). That's the missing piece, especially on mips and sparc. ARM has already one.

My wish is implementing dma_mmap_coherent() on all architectures, so that the driver can use it safely without messy ifdefs.

Adding dma_mmap_coherent has been proposed in 2004 but the discussion for some reason went nowhere because it apparently isn't implementable on PARISC due to cache synonyms - on MIPS we'd solve those issues where they exist by using uncached or writethrough mappings, as apropriate.

Ralf

#12 lore raw
Quoted 11 lines · Ralf Baechle
Quoted 6 lines

Yep, but OTOH, the arch code doesn't provide a proper standard way to mmap the pages allocated via dma_alloc_coherent(). That's the missing piece, especially on mips and sparc. ARM has already one.

My wish is implementing dma_mmap_coherent() on all architectures, so that the driver can use it safely without messy ifdefs.

Adding dma_mmap_coherent has been proposed in 2004 but the discussion for some reason went nowhere because it apparently isn't implementable on PARISC due to cache synonyms - on MIPS we'd solve those issues where they exist by using uncached or writethrough mappings, as apropriate.

Hmm, why should everybody suffer from some limitation of some peculiar
architecture? I would suggest to let them find an architecture-specific way of addressing the problem -- they surely have a good control over their own code and can implement a workaround that would not impede all the others.

Ralf, do you have an idea about what their issue exactly is?

Maciej

#13 lore raw
In reply to Ralf Baechle

At Wed, 8 Aug 2007 12:58:52 +0100,

Quoted 10 lines · Ralf Baechle
Quoted 7 lines · Takashi Iwai
Quoted 2 lines

It's ALSA that is doing funny things here so there is no point in fixing the arch code to work for ALSA.

Yep, but OTOH, the arch code doesn't provide a proper standard way to mmap the pages allocated via dma_alloc_coherent(). That's the missing piece, especially on mips and sparc. ARM has already one.

Quoted 7 lines
Quoted 2 lines

My wish is implementing dma_mmap_coherent() on all architectures, so that the driver can use it safely without messy ifdefs.

Adding dma_mmap_coherent has been proposed in 2004 but the discussion for some reason went nowhere because it apparently isn't implementable on PARISC due to cache synonyms - on MIPS we'd solve those issues where they exist by using uncached or writethrough mappings, as apropriate.

Actually, if it cannot be implemented (or not yet implemented properly) on some architectures, it's fine. Then we can simply drop the mmap support just for such an architecture. I suppose an inlined dma_mmap_coherent() that always returns an error, just like the earlier version of asm-generic/dma-mapping-broken.h, would work well.

But, currently, the driver has no idea which architecture is OK and which not, and which method to choose. That is where we got stuck.

Takashi

#14 lore raw
In reply to Ralf Baechle
Quoted 11 lines · Ralf Baechle
Quoted 8 lines · Atsushi Nemoto
Quoted 6 lines · Dajie Tan

static inline unsigned long virt_to_phys(volatile const void *address) {

include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 renamed from include/asm-mips/io.h 2007-08-07 10:18:03.000000000 +0800 +1 -1
-       return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET;
+       return ((unsigned long)address & 0x1fffffff) + PHYS_OFFSET;
 }
Quoted 11 lines
Quoted 3 lines

This makes virt_to_phys() a bit slower, and more importantly, breaks 64-bit kernel.

It's ALSA that is doing funny things here so there is no point in fixing the arch code to work for ALSA.

Ralf

arm has made a dma_mmap_coherent, but I don't quite understand the code and I am not sure the situation is the same.

Tian

#15 lore raw
In reply to Atsushi Nemoto
Quoted 9 lines · Atsushi Nemoto

include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 line 120

Quoted 6 lines · Dajie Tan

static inline unsigned long virt_to_phys(volatile const void *address) {

include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 renamed from include/asm-mips/io.h 2007-08-07 10:18:03.000000000 +0800 +1 -1
-       return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET;
+       return ((unsigned long)address & 0x1fffffff) + PHYS_OFFSET;
 }
Quoted 3 lines

This makes virt_to_phys() a bit slower, and more importantly, breaks 64-bit kernel.

I have tried this way, and disassemble result show 32-bit kernel add only one instruction.
But I don't really insist on this patch, for it doesn't resolve some driver code requirement.

Quoted 9 lines

---
Atsushi Nemoto
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel