Wendell Liu wrote:
I try to test a codec on the Davinci platform. Please someone give me a hint
what's this error means, and how to solve it?
The getphys implementation in the CMEM module is broken. In my patchset
posted here to run the demos against newer kernels, I rewrote how CMEM
get_phys works. I've attached just the cmemk-getphys.patch for you to
try. Depending on which version of the demos you have, you may have to
rework the patch slightly.
Kevin
Index: dvevm_1_00_00_32/cmem_1_00/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c
===================================================================
--- dvevm_1_00_00_32.orig/cmem_1_00/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c
+++ dvevm_1_00_00_32/cmem_1_00/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c
@@ -97,26 +97,44 @@ static struct file_operations cmem_fxns
/* Traverses the page tables and translates a virtual adress to a physical. */
static unsigned long get_phys(unsigned long virtp)
{
- pgd_t *pgd;
- pmd_t *pmd;
- pte_t *pte;
+ unsigned long physp = 0;
struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
- pgd = pgd_offset(mm, virtp);
- if (!(pgd_none(*pgd) || pgd_bad(*pgd))) {
- pmd = pmd_offset(pgd, virtp);
-
- if (!(pmd_none(*pmd) || pmd_bad(*pmd))) {
- pte = pte_offset_kernel(pmd, virtp);
-
- if (pte_present(*pte)) {
- return __pa(page_address(pte_page(*pte)) +
- (virtp & ~PAGE_MASK));
- }
- }
+ /* For kernel direct-mapped memory, take the easy way */
+ if (virtp >= PAGE_OFFSET) {
+ physp = virt_to_phys((void *)virtp);
+ }
+
+ /* this will catch, kernel-allocated, mmaped-to-usermode addresses */
+ else if ((vma = find_vma(mm, virtp)) &&
+ (vma->vm_flags & VM_IO) &&
+ (vma->vm_pgoff)) {
+ physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
+ }
+
+ /* otherwise, use get_user_pages() for general userland pages */
+ else {
+ int res, nr_pages = 1;
+ struct page *pages;
+ down_read(¤t->mm->mmap_sem);
+
+ res = get_user_pages(current, current->mm,
+ virtp, nr_pages,
+ 1, 0,
+ &pages, NULL);
+ up_read(¤t->mm->mmap_sem);
+
+ if (res == nr_pages) {
+ physp = __pa(page_address(&pages[0]) + (virtp & ~PAGE_MASK));
+ } else {
+ __E("%s: Unable to find phys addr for 0x%08lx\n",
+ __FUNCTION__, virtp);
+ __E("%s: get_user_pages() failed: %d\n", __FUNCTION__, res);
+ }
}
- return 0;
+ return physp;
}
/* Allocates space from the top "highmem" contiguous buffer for pool buffer. */
@@ -145,6 +163,7 @@ static unsigned long alloc_pool_buffer(u
return 0;
}
+#ifdef __DEBUG
/* Only for debug */
static void dump_lists(int idx)
{
@@ -175,6 +194,7 @@ static void dump_lists(int idx)
up(&cmem_mutex);
}
+#endif
static int proc_fxn(char *page, char **start, off_t offset, int len,
int *eof, void *data)
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source