brintos

brintos / linux-shallow public Read only

0
0
Text · 3.7 KiB · f9a4ec4 Raw
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