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