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

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

parent 27abb210
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -861,6 +861,9 @@ int circbuf_mmap(struct file *file, struct vm_area_struct *vma)
			circbuf_priv[chn].phys_addr >> PAGE_SHIFT,
			vma->vm_end - vma->vm_start,
			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);
	if (ret) return -EAGAIN;
+23 −18
Original line number Diff line number Diff line
@@ -1230,23 +1230,33 @@ ssize_t iov_iter_get_pages_elphel(struct iov_iter *i,
		   struct page **pages, size_t maxsize, unsigned maxpages,
		   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
	// just testing, not thread -safe, not locking
	const struct page * circbuf0_page0 = phys_to_page(circbuf_pa[0]);
	size_t len;
	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 faddr = (unsigned long) iov->iov_base;
	unsigned long vaddr = (unsigned long) iov->iov_base;
	struct vm_area_struct *vm_area;

// *** Putting temporary address here
	struct page * cur_page = (struct page * ) circbuf0_page0;
	pr_debug("circbuf0_page0 = 0x%08x, circbuf0_page0->compound_head=0x%08lx, faddr=0x%08lx, mapcount=%u", \
			(int) circbuf0_page0, circbuf0_page0->compound_head, faddr ,page_mapcount((struct page *) circbuf0_page0));
	addr = 0;
	struct page * cur_page;
//	pr_debug("sizeof(struct vm_area_struct)=%d", sizeof(struct vm_area_struct));
	for (vm_area = current->mm->mmap; vm_area;  vm_area = vm_area-> vm_next) {
		if ((vaddr >= vm_area->vm_start) && (vaddr < vm_area->vm_end)) {
			pr_debug("physical address = 0x%08lx", (unsigned long) vm_area->vm_private_data);
			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;
	if (maxsize > i->count)
		maxsize = i->count;
@@ -1264,13 +1274,8 @@ ssize_t iov_iter_get_pages_elphel(struct iov_iter *i,
	len -= *start;
	pr_debug("iov_iter_get_pages_elphel()->0x%08x, n=%u, current->mm->map_count=%u",\
			len, n, current->mm->map_count);
	pr_debug("sizeof(struct vm_area_struct)=%d", sizeof(struct vm_area_struct));
	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));
		}
	pr_debug("len=%d", len);

	}
	return len;
}
EXPORT_SYMBOL(iov_iter_get_pages_elphel);