132 lines · c
1/*2 * videobuf2-memops.c - generic memory handling routines for videobuf23 *4 * Copyright (C) 2010 Samsung Electronics5 *6 * Author: Pawel Osciak <pawel@osciak.com>7 * Marek Szyprowski <m.szyprowski@samsung.com>8 *9 * This program is free software; you can redistribute it and/or modify10 * it under the terms of the GNU General Public License as published by11 * the Free Software Foundation.12 */13 14#include <linux/slab.h>15#include <linux/module.h>16#include <linux/dma-mapping.h>17#include <linux/vmalloc.h>18#include <linux/mm.h>19#include <linux/sched.h>20#include <linux/file.h>21 22#include <media/videobuf2-v4l2.h>23#include <media/videobuf2-memops.h>24 25/**26 * vb2_create_framevec() - map virtual addresses to pfns27 * @start: Virtual user address where we start mapping28 * @length: Length of a range to map29 * @write: Should we map for writing into the area30 *31 * This function allocates and fills in a vector with pfns corresponding to32 * virtual address range passed in arguments. If pfns have corresponding pages,33 * page references are also grabbed to pin pages in memory. The function34 * returns pointer to the vector on success and error pointer in case of35 * failure. Returned vector needs to be freed via vb2_destroy_pfnvec().36 */37struct frame_vector *vb2_create_framevec(unsigned long start,38 unsigned long length,39 bool write)40{41 int ret;42 unsigned long first, last;43 unsigned long nr;44 struct frame_vector *vec;45 46 first = start >> PAGE_SHIFT;47 last = (start + length - 1) >> PAGE_SHIFT;48 nr = last - first + 1;49 vec = frame_vector_create(nr);50 if (!vec)51 return ERR_PTR(-ENOMEM);52 ret = get_vaddr_frames(start & PAGE_MASK, nr, write, vec);53 if (ret < 0)54 goto out_destroy;55 /* We accept only complete set of PFNs */56 if (ret != nr) {57 ret = -EFAULT;58 goto out_release;59 }60 return vec;61out_release:62 put_vaddr_frames(vec);63out_destroy:64 frame_vector_destroy(vec);65 return ERR_PTR(ret);66}67EXPORT_SYMBOL(vb2_create_framevec);68 69/**70 * vb2_destroy_framevec() - release vector of mapped pfns71 * @vec: vector of pfns / pages to release72 *73 * This releases references to all pages in the vector @vec (if corresponding74 * pfns are backed by pages) and frees the passed vector.75 */76void vb2_destroy_framevec(struct frame_vector *vec)77{78 put_vaddr_frames(vec);79 frame_vector_destroy(vec);80}81EXPORT_SYMBOL(vb2_destroy_framevec);82 83/**84 * vb2_common_vm_open() - increase refcount of the vma85 * @vma: virtual memory region for the mapping86 *87 * This function adds another user to the provided vma. It expects88 * struct vb2_vmarea_handler pointer in vma->vm_private_data.89 */90static void vb2_common_vm_open(struct vm_area_struct *vma)91{92 struct vb2_vmarea_handler *h = vma->vm_private_data;93 94 pr_debug("%s: %p, refcount: %d, vma: %08lx-%08lx\n",95 __func__, h, refcount_read(h->refcount), vma->vm_start,96 vma->vm_end);97 98 refcount_inc(h->refcount);99}100 101/**102 * vb2_common_vm_close() - decrease refcount of the vma103 * @vma: virtual memory region for the mapping104 *105 * This function releases the user from the provided vma. It expects106 * struct vb2_vmarea_handler pointer in vma->vm_private_data.107 */108static void vb2_common_vm_close(struct vm_area_struct *vma)109{110 struct vb2_vmarea_handler *h = vma->vm_private_data;111 112 pr_debug("%s: %p, refcount: %d, vma: %08lx-%08lx\n",113 __func__, h, refcount_read(h->refcount), vma->vm_start,114 vma->vm_end);115 116 h->put(h->arg);117}118 119/*120 * vb2_common_vm_ops - common vm_ops used for tracking refcount of mmapped121 * video buffers122 */123const struct vm_operations_struct vb2_common_vm_ops = {124 .open = vb2_common_vm_open,125 .close = vb2_common_vm_close,126};127EXPORT_SYMBOL_GPL(vb2_common_vm_ops);128 129MODULE_DESCRIPTION("common memory handling routines for videobuf2");130MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>");131MODULE_LICENSE("GPL");132