Skip to content

Commit

Permalink
[media] vb2: Provide helpers for mapping virtual addresses
Browse files Browse the repository at this point in the history
Provide simple helper functions to map virtual address range into an
array of pfns / pages.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  • Loading branch information
Jan Kara authored and Mauro Carvalho Chehab committed Aug 16, 2015
1 parent 8a677b6 commit 21fb0cb
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/media/v4l2-core/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ config VIDEOBUF2_CORE

config VIDEOBUF2_MEMOPS
tristate
select FRAME_VECTOR

config VIDEOBUF2_DMA_CONTIG
tristate
Expand Down
58 changes: 58 additions & 0 deletions drivers/media/v4l2-core/videobuf2-memops.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,64 @@ int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size,
}
EXPORT_SYMBOL_GPL(vb2_get_contig_userptr);

/**
* vb2_create_framevec() - map virtual addresses to pfns
* @start: Virtual user address where we start mapping
* @length: Length of a range to map
* @write: Should we map for writing into the area
*
* This function allocates and fills in a vector with pfns corresponding to
* virtual address range passed in arguments. If pfns have corresponding pages,
* page references are also grabbed to pin pages in memory. The function
* returns pointer to the vector on success and error pointer in case of
* failure. Returned vector needs to be freed via vb2_destroy_pfnvec().
*/
struct frame_vector *vb2_create_framevec(unsigned long start,
unsigned long length,
bool write)
{
int ret;
unsigned long first, last;
unsigned long nr;
struct frame_vector *vec;

first = start >> PAGE_SHIFT;
last = (start + length - 1) >> PAGE_SHIFT;
nr = last - first + 1;
vec = frame_vector_create(nr);
if (!vec)
return ERR_PTR(-ENOMEM);
ret = get_vaddr_frames(start, nr, write, 1, vec);
if (ret < 0)
goto out_destroy;
/* We accept only complete set of PFNs */
if (ret != nr) {
ret = -EFAULT;
goto out_release;
}
return vec;
out_release:
put_vaddr_frames(vec);
out_destroy:
frame_vector_destroy(vec);
return ERR_PTR(ret);
}
EXPORT_SYMBOL(vb2_create_framevec);

/**
* vb2_destroy_framevec() - release vector of mapped pfns
* @vec: vector of pfns / pages to release
*
* This releases references to all pages in the vector @vec (if corresponding
* pfns are backed by pages) and frees the passed vector.
*/
void vb2_destroy_framevec(struct frame_vector *vec)
{
put_vaddr_frames(vec);
frame_vector_destroy(vec);
}
EXPORT_SYMBOL(vb2_destroy_framevec);

/**
* vb2_common_vm_open() - increase refcount of the vma
* @vma: virtual memory region for the mapping
Expand Down
5 changes: 5 additions & 0 deletions include/media/videobuf2-memops.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define _MEDIA_VIDEOBUF2_MEMOPS_H

#include <media/videobuf2-core.h>
#include <linux/mm.h>

/**
* vb2_vmarea_handler - common vma refcount tracking handler
Expand All @@ -36,5 +37,9 @@ int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size,
struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma);
void vb2_put_vma(struct vm_area_struct *vma);

struct frame_vector *vb2_create_framevec(unsigned long start,
unsigned long length,
bool write);
void vb2_destroy_framevec(struct frame_vector *vec);

#endif

0 comments on commit 21fb0cb

Please sign in to comment.