1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * helper functions for vmalloc video4linux capture buffers
4 *
5 * The functions expect the hardware being able to scatter gather
6 * (i.e. the buffers are not linear in physical memory, but fragmented
7 * into PAGE_SIZE chunks).  They also assume the driver does not need
8 * to touch the video data.
9 *
10 * (c) 2007 Mauro Carvalho Chehab <mchehab@kernel.org>
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/slab.h>
17#include <linux/interrupt.h>
18#include <linux/pgtable.h>
19
20#include <linux/pci.h>
21#include <linux/vmalloc.h>
22#include <linux/pagemap.h>
23#include <asm/page.h>
24
25#include <media/videobuf-vmalloc.h>
26
27#define MAGIC_DMABUF   0x17760309
28#define MAGIC_VMAL_MEM 0x18221223
29
30#define MAGIC_CHECK(is, should)						\
31	if (unlikely((is) != (should))) {				\
32		printk(KERN_ERR "magic mismatch: %x (expected %x)\n",	\
33				is, should);				\
34		BUG();							\
35	}
36
37static int debug;
38module_param(debug, int, 0644);
39
40MODULE_DESCRIPTION("helper module to manage video4linux vmalloc buffers");
41MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>");
42MODULE_LICENSE("GPL");
43
44#define dprintk(level, fmt, arg...)					\
45	if (debug >= level)						\
46		printk(KERN_DEBUG "vbuf-vmalloc: " fmt , ## arg)
47
48
49/***************************************************************************/
50
51static void videobuf_vm_open(struct vm_area_struct *vma)
52{
53	struct videobuf_mapping *map = vma->vm_private_data;
54
55	dprintk(2, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", map,
56		map->count, vma->vm_start, vma->vm_end);
57
58	map->count++;
59}
60
61static void videobuf_vm_close(struct vm_area_struct *vma)
62{
63	struct videobuf_mapping *map = vma->vm_private_data;
64	struct videobuf_queue *q = map->q;
65	int i;
66
67	dprintk(2, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", map,
68		map->count, vma->vm_start, vma->vm_end);
69
70	map->count--;
71	if (0 == map->count) {
72		struct videobuf_vmalloc_memory *mem;
73
74		dprintk(1, "munmap %p q=%p\n", map, q);
75		videobuf_queue_lock(q);
76
77		/* We need first to cancel streams, before unmapping */
78		if (q->streaming)
79			videobuf_queue_cancel(q);
80
81		for (i = 0; i < VIDEO_MAX_FRAME; i++) {
82			if (NULL == q->bufs[i])
83				continue;
84
85			if (q->bufs[i]->map != map)
86				continue;
87
88			mem = q->bufs[i]->priv;
89			if (mem) {
90				/* This callback is called only if kernel has
91				   allocated memory and this memory is mmapped.
92				   In this case, memory should be freed,
93				   in order to do memory unmap.
94				 */
95
96				MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
97
98				/* vfree is not atomic - can't be
99				   called with IRQ's disabled
100				 */
101				dprintk(1, "%s: buf[%d] freeing (%p)\n",
102					__func__, i, mem->vaddr);
103
104				vfree(mem->vaddr);
105				mem->vaddr = NULL;
106			}
107
108			q->bufs[i]->map   = NULL;
109			q->bufs[i]->baddr = 0;
110		}
111
112		kfree(map);
113
114		videobuf_queue_unlock(q);
115	}
116
117	return;
118}
119
120static const struct vm_operations_struct videobuf_vm_ops = {
121	.open     = videobuf_vm_open,
122	.close    = videobuf_vm_close,
123};
124
125/* ---------------------------------------------------------------------
126 * vmalloc handlers for the generic methods
127 */
128
129/* Allocated area consists on 3 parts:
130	struct video_buffer
131	struct <driver>_buffer (cx88_buffer, saa7134_buf, ...)
132	struct videobuf_dma_sg_memory
133 */
134
135static struct videobuf_buffer *__videobuf_alloc_vb(size_t size)
136{
137	struct videobuf_vmalloc_memory *mem;
138	struct videobuf_buffer *vb;
139
140	vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
141	if (!vb)
142		return vb;
143
144	mem = vb->priv = ((char *)vb) + size;
145	mem->magic = MAGIC_VMAL_MEM;
146
147	dprintk(1, "%s: allocated at %p(%ld+%ld) & %p(%ld)\n",
148		__func__, vb, (long)sizeof(*vb), (long)size - sizeof(*vb),
149		mem, (long)sizeof(*mem));
150
151	return vb;
152}
153
154static int __videobuf_iolock(struct videobuf_queue *q,
155			     struct videobuf_buffer *vb,
156			     struct v4l2_framebuffer *fbuf)
157{
158	struct videobuf_vmalloc_memory *mem = vb->priv;
159	int pages;
160
161	BUG_ON(!mem);
162
163	MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
164
165	switch (vb->memory) {
166	case V4L2_MEMORY_MMAP:
167		dprintk(1, "%s memory method MMAP\n", __func__);
168
169		/* All handling should be done by __videobuf_mmap_mapper() */
170		if (!mem->vaddr) {
171			printk(KERN_ERR "memory is not allocated/mmapped.\n");
172			return -EINVAL;
173		}
174		break;
175	case V4L2_MEMORY_USERPTR:
176		pages = PAGE_ALIGN(vb->size);
177
178		dprintk(1, "%s memory method USERPTR\n", __func__);
179
180		if (vb->baddr) {
181			printk(KERN_ERR "USERPTR is currently not supported\n");
182			return -EINVAL;
183		}
184
185		/* The only USERPTR currently supported is the one needed for
186		 * read() method.
187		 */
188
189		mem->vaddr = vmalloc_user(pages);
190		if (!mem->vaddr) {
191			printk(KERN_ERR "vmalloc (%d pages) failed\n", pages);
192			return -ENOMEM;
193		}
194		dprintk(1, "vmalloc is at addr %p (%d pages)\n",
195			mem->vaddr, pages);
196		break;
197	case V4L2_MEMORY_OVERLAY:
198	default:
199		dprintk(1, "%s memory method OVERLAY/unknown\n", __func__);
200
201		/* Currently, doesn't support V4L2_MEMORY_OVERLAY */
202		printk(KERN_ERR "Memory method currently unsupported.\n");
203		return -EINVAL;
204	}
205
206	return 0;
207}
208
209static int __videobuf_mmap_mapper(struct videobuf_queue *q,
210				  struct videobuf_buffer *buf,
211				  struct vm_area_struct *vma)
212{
213	struct videobuf_vmalloc_memory *mem;
214	struct videobuf_mapping *map;
215	int retval, pages;
216
217	dprintk(1, "%s\n", __func__);
218
219	/* create mapping + update buffer list */
220	map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
221	if (NULL == map)
222		return -ENOMEM;
223
224	buf->map = map;
225	map->q     = q;
226
227	buf->baddr = vma->vm_start;
228
229	mem = buf->priv;
230	BUG_ON(!mem);
231	MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
232
233	pages = PAGE_ALIGN(vma->vm_end - vma->vm_start);
234	mem->vaddr = vmalloc_user(pages);
235	if (!mem->vaddr) {
236		printk(KERN_ERR "vmalloc (%d pages) failed\n", pages);
237		goto error;
238	}
239	dprintk(1, "vmalloc is at addr %p (%d pages)\n", mem->vaddr, pages);
240
241	/* Try to remap memory */
242	retval = remap_vmalloc_range(vma, mem->vaddr, 0);
243	if (retval < 0) {
244		printk(KERN_ERR "mmap: remap failed with error %d. ", retval);
245		vfree(mem->vaddr);
246		goto error;
247	}
248
249	vma->vm_ops          = &videobuf_vm_ops;
250	vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP);
251	vma->vm_private_data = map;
252
253	dprintk(1, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
254		map, q, vma->vm_start, vma->vm_end,
255		(long int)buf->bsize,
256		vma->vm_pgoff, buf->i);
257
258	videobuf_vm_open(vma);
259
260	return 0;
261
262error:
263	mem = NULL;
264	kfree(map);
265	return -ENOMEM;
266}
267
268static struct videobuf_qtype_ops qops = {
269	.magic        = MAGIC_QTYPE_OPS,
270
271	.alloc_vb     = __videobuf_alloc_vb,
272	.iolock       = __videobuf_iolock,
273	.mmap_mapper  = __videobuf_mmap_mapper,
274	.vaddr        = videobuf_to_vmalloc,
275};
276
277void videobuf_queue_vmalloc_init(struct videobuf_queue *q,
278			 const struct videobuf_queue_ops *ops,
279			 struct device *dev,
280			 spinlock_t *irqlock,
281			 enum v4l2_buf_type type,
282			 enum v4l2_field field,
283			 unsigned int msize,
284			 void *priv,
285			 struct mutex *ext_lock)
286{
287	videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
288				 priv, &qops, ext_lock);
289}
290EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init);
291
292void *videobuf_to_vmalloc(struct videobuf_buffer *buf)
293{
294	struct videobuf_vmalloc_memory *mem = buf->priv;
295	BUG_ON(!mem);
296	MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
297
298	return mem->vaddr;
299}
300EXPORT_SYMBOL_GPL(videobuf_to_vmalloc);
301
302void videobuf_vmalloc_free(struct videobuf_buffer *buf)
303{
304	struct videobuf_vmalloc_memory *mem = buf->priv;
305
306	/* mmapped memory can't be freed here, otherwise mmapped region
307	   would be released, while still needed. In this case, the memory
308	   release should happen inside videobuf_vm_close().
309	   So, it should free memory only if the memory were allocated for
310	   read() operation.
311	 */
312	if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
313		return;
314
315	if (!mem)
316		return;
317
318	MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
319
320	vfree(mem->vaddr);
321	mem->vaddr = NULL;
322
323	return;
324}
325EXPORT_SYMBOL_GPL(videobuf_vmalloc_free);
326
327