Commit 5ffd6dc5 authored by Andrey Filippov's avatar Andrey Filippov

Using vm_private_data to pass physical address of the mmap-ed area

parent 27abb210
...@@ -861,6 +861,9 @@ int circbuf_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -861,6 +861,9 @@ int circbuf_mmap(struct file *file, struct vm_area_struct *vma)
circbuf_priv[chn].phys_addr >> PAGE_SHIFT, circbuf_priv[chn].phys_addr >> PAGE_SHIFT,
vma->vm_end - vma->vm_start, vma->vm_end - vma->vm_start,
vma->vm_page_prot); vma->vm_page_prot);
vma->vm_private_data = (void *) circbuf_priv[chn].phys_addr; // for camogm to find phjysical address
dev_dbg(g_dev_ptr, "added vm_private_data = 0x%lx to tell file write with O_DIRECT physical address\n", \
(unsigned long) vma->vm_private_data);
dev_dbg(g_dev_ptr, "remap_pfn_range returned 0x%x\n", ret); dev_dbg(g_dev_ptr, "remap_pfn_range returned 0x%x\n", ret);
if (ret) return -EAGAIN; if (ret) return -EAGAIN;
......
...@@ -1230,23 +1230,33 @@ ssize_t iov_iter_get_pages_elphel(struct iov_iter *i, ...@@ -1230,23 +1230,33 @@ ssize_t iov_iter_get_pages_elphel(struct iov_iter *i,
struct page **pages, size_t maxsize, unsigned maxpages, struct page **pages, size_t maxsize, unsigned maxpages,
size_t *start) size_t *start)
{ {
// temporary - fixed physical addresses
unsigned long circbuf_pa [4]= {0x0ae00000, 0x0ee00000, 0x12e00000, 0x16e00000};
unsigned long circbuf_pages = 0x4000; // per channel
int indx, n; // page index int indx, n; // page index
// just testing, not thread -safe, not locking
const struct page * circbuf0_page0 = phys_to_page(circbuf_pa[0]);
size_t len; size_t len;
const struct iovec *iov = i->iov; // only use first in array - supposed to be a single-element const struct iovec *iov = i->iov; // only use first in array - supposed to be a single-element
unsigned long paddr = 0; // physical address where to write
unsigned long addr; unsigned long addr;
unsigned long faddr = (unsigned long) iov->iov_base; unsigned long vaddr = (unsigned long) iov->iov_base;
struct vm_area_struct *vm_area; struct vm_area_struct *vm_area;
struct page * cur_page;
// *** Putting temporary address here // pr_debug("sizeof(struct vm_area_struct)=%d", sizeof(struct vm_area_struct));
struct page * cur_page = (struct page * ) circbuf0_page0; for (vm_area = current->mm->mmap; vm_area; vm_area = vm_area-> vm_next) {
pr_debug("circbuf0_page0 = 0x%08x, circbuf0_page0->compound_head=0x%08lx, faddr=0x%08lx, mapcount=%u", \ if ((vaddr >= vm_area->vm_start) && (vaddr < vm_area->vm_end)) {
(int) circbuf0_page0, circbuf0_page0->compound_head, faddr ,page_mapcount((struct page *) circbuf0_page0)); pr_debug("physical address = 0x%08lx", (unsigned long) vm_area->vm_private_data);
addr = 0; print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, vm_area, sizeof(struct vm_area_struct));
paddr = (unsigned long) vm_area->vm_private_data;
if (paddr) {
paddr += vaddr - vm_area->vm_start; // added offset within buffer
}
break;
}
}
if (!paddr){
pr_warn("mmap-ed physical address is not specified in vm_area->vm_private_data, aborting");
return -EINVAL;
}
pr_debug("virtual address = 0x%08lx, physical address = 0x%08lx", vaddr, paddr);
cur_page = phys_to_page(paddr);
addr = vaddr;
len = iov->iov_len + (*start = addr & (PAGE_SIZE - 1)); // to inlude beginning of the page - for now 0; len = iov->iov_len + (*start = addr & (PAGE_SIZE - 1)); // to inlude beginning of the page - for now 0;
if (maxsize > i->count) if (maxsize > i->count)
maxsize = i->count; maxsize = i->count;
...@@ -1264,13 +1274,8 @@ ssize_t iov_iter_get_pages_elphel(struct iov_iter *i, ...@@ -1264,13 +1274,8 @@ ssize_t iov_iter_get_pages_elphel(struct iov_iter *i,
len -= *start; len -= *start;
pr_debug("iov_iter_get_pages_elphel()->0x%08x, n=%u, current->mm->map_count=%u",\ pr_debug("iov_iter_get_pages_elphel()->0x%08x, n=%u, current->mm->map_count=%u",\
len, n, current->mm->map_count); len, n, current->mm->map_count);
pr_debug("sizeof(struct vm_area_struct)=%d", sizeof(struct vm_area_struct)); pr_debug("len=%d", len);
for (vm_area = current->mm->mmap; vm_area; vm_area = vm_area-> vm_next) {
if ((faddr >= vm_area->vm_start) && (faddr < vm_area->vm_end)) {
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, vm_area, sizeof(struct vm_area_struct));
}
}
return len; return len;
} }
EXPORT_SYMBOL(iov_iter_get_pages_elphel); EXPORT_SYMBOL(iov_iter_get_pages_elphel);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment