Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
[sfrench/cifs-2.6.git] / drivers / media / video / videobuf-dma-contig.c
1 /*
2  * helper functions for physically contiguous capture buffers
3  *
4  * The functions support hardware lacking scatter gather support
5  * (i.e. the buffers must be linear in physical memory)
6  *
7  * Copyright (c) 2008 Magnus Damm
8  *
9  * Based on videobuf-vmalloc.c,
10  * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2
15  */
16
17 #include <linux/init.h>
18 #include <linux/module.h>
19 #include <linux/mm.h>
20 #include <linux/pagemap.h>
21 #include <linux/dma-mapping.h>
22 #include <linux/sched.h>
23 #include <media/videobuf-dma-contig.h>
24
25 struct videobuf_dma_contig_memory {
26         u32 magic;
27         void *vaddr;
28         dma_addr_t dma_handle;
29         unsigned long size;
30         int is_userptr;
31 };
32
33 #define MAGIC_DC_MEM 0x0733ac61
34 #define MAGIC_CHECK(is, should)                                             \
35         if (unlikely((is) != (should))) {                                   \
36                 pr_err("magic mismatch: %x expected %x\n", (is), (should)); \
37                 BUG();                                                      \
38         }
39
40 static void
41 videobuf_vm_open(struct vm_area_struct *vma)
42 {
43         struct videobuf_mapping *map = vma->vm_private_data;
44
45         dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
46                 map, map->count, vma->vm_start, vma->vm_end);
47
48         map->count++;
49 }
50
51 static void videobuf_vm_close(struct vm_area_struct *vma)
52 {
53         struct videobuf_mapping *map = vma->vm_private_data;
54         struct videobuf_queue *q = map->q;
55         int i;
56
57         dev_dbg(map->q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
58                 map, map->count, vma->vm_start, vma->vm_end);
59
60         map->count--;
61         if (0 == map->count) {
62                 struct videobuf_dma_contig_memory *mem;
63
64                 dev_dbg(map->q->dev, "munmap %p q=%p\n", map, q);
65                 mutex_lock(&q->vb_lock);
66
67                 /* We need first to cancel streams, before unmapping */
68                 if (q->streaming)
69                         videobuf_queue_cancel(q);
70
71                 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
72                         if (NULL == q->bufs[i])
73                                 continue;
74
75                         if (q->bufs[i]->map != map)
76                                 continue;
77
78                         mem = q->bufs[i]->priv;
79                         if (mem) {
80                                 /* This callback is called only if kernel has
81                                    allocated memory and this memory is mmapped.
82                                    In this case, memory should be freed,
83                                    in order to do memory unmap.
84                                  */
85
86                                 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
87
88                                 /* vfree is not atomic - can't be
89                                    called with IRQ's disabled
90                                  */
91                                 dev_dbg(map->q->dev, "buf[%d] freeing %p\n",
92                                         i, mem->vaddr);
93
94                                 dma_free_coherent(q->dev, mem->size,
95                                                   mem->vaddr, mem->dma_handle);
96                                 mem->vaddr = NULL;
97                         }
98
99                         q->bufs[i]->map   = NULL;
100                         q->bufs[i]->baddr = 0;
101                 }
102
103                 kfree(map);
104
105                 mutex_unlock(&q->vb_lock);
106         }
107 }
108
109 static const struct vm_operations_struct videobuf_vm_ops = {
110         .open     = videobuf_vm_open,
111         .close    = videobuf_vm_close,
112 };
113
114 /**
115  * videobuf_dma_contig_user_put() - reset pointer to user space buffer
116  * @mem: per-buffer private videobuf-dma-contig data
117  *
118  * This function resets the user space pointer
119  */
120 static void videobuf_dma_contig_user_put(struct videobuf_dma_contig_memory *mem)
121 {
122         mem->is_userptr = 0;
123         mem->dma_handle = 0;
124         mem->size = 0;
125 }
126
127 /**
128  * videobuf_dma_contig_user_get() - setup user space memory pointer
129  * @mem: per-buffer private videobuf-dma-contig data
130  * @vb: video buffer to map
131  *
132  * This function validates and sets up a pointer to user space memory.
133  * Only physically contiguous pfn-mapped memory is accepted.
134  *
135  * Returns 0 if successful.
136  */
137 static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
138                                         struct videobuf_buffer *vb)
139 {
140         struct mm_struct *mm = current->mm;
141         struct vm_area_struct *vma;
142         unsigned long prev_pfn, this_pfn;
143         unsigned long pages_done, user_address;
144         int ret;
145
146         mem->size = PAGE_ALIGN(vb->size);
147         mem->is_userptr = 0;
148         ret = -EINVAL;
149
150         down_read(&mm->mmap_sem);
151
152         vma = find_vma(mm, vb->baddr);
153         if (!vma)
154                 goto out_up;
155
156         if ((vb->baddr + mem->size) > vma->vm_end)
157                 goto out_up;
158
159         pages_done = 0;
160         prev_pfn = 0; /* kill warning */
161         user_address = vb->baddr;
162
163         while (pages_done < (mem->size >> PAGE_SHIFT)) {
164                 ret = follow_pfn(vma, user_address, &this_pfn);
165                 if (ret)
166                         break;
167
168                 if (pages_done == 0)
169                         mem->dma_handle = this_pfn << PAGE_SHIFT;
170                 else if (this_pfn != (prev_pfn + 1))
171                         ret = -EFAULT;
172
173                 if (ret)
174                         break;
175
176                 prev_pfn = this_pfn;
177                 user_address += PAGE_SIZE;
178                 pages_done++;
179         }
180
181         if (!ret)
182                 mem->is_userptr = 1;
183
184  out_up:
185         up_read(&current->mm->mmap_sem);
186
187         return ret;
188 }
189
190 static void *__videobuf_alloc(size_t size)
191 {
192         struct videobuf_dma_contig_memory *mem;
193         struct videobuf_buffer *vb;
194
195         vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
196         if (vb) {
197                 mem = vb->priv = ((char *)vb) + size;
198                 mem->magic = MAGIC_DC_MEM;
199         }
200
201         return vb;
202 }
203
204 static void *__videobuf_to_vmalloc(struct videobuf_buffer *buf)
205 {
206         struct videobuf_dma_contig_memory *mem = buf->priv;
207
208         BUG_ON(!mem);
209         MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
210
211         return mem->vaddr;
212 }
213
214 static int __videobuf_iolock(struct videobuf_queue *q,
215                              struct videobuf_buffer *vb,
216                              struct v4l2_framebuffer *fbuf)
217 {
218         struct videobuf_dma_contig_memory *mem = vb->priv;
219
220         BUG_ON(!mem);
221         MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
222
223         switch (vb->memory) {
224         case V4L2_MEMORY_MMAP:
225                 dev_dbg(q->dev, "%s memory method MMAP\n", __func__);
226
227                 /* All handling should be done by __videobuf_mmap_mapper() */
228                 if (!mem->vaddr) {
229                         dev_err(q->dev, "memory is not alloced/mmapped.\n");
230                         return -EINVAL;
231                 }
232                 break;
233         case V4L2_MEMORY_USERPTR:
234                 dev_dbg(q->dev, "%s memory method USERPTR\n", __func__);
235
236                 /* handle pointer from user space */
237                 if (vb->baddr)
238                         return videobuf_dma_contig_user_get(mem, vb);
239
240                 /* allocate memory for the read() method */
241                 mem->size = PAGE_ALIGN(vb->size);
242                 mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
243                                                 &mem->dma_handle, GFP_KERNEL);
244                 if (!mem->vaddr) {
245                         dev_err(q->dev, "dma_alloc_coherent %ld failed\n",
246                                          mem->size);
247                         return -ENOMEM;
248                 }
249
250                 dev_dbg(q->dev, "dma_alloc_coherent data is at %p (%ld)\n",
251                         mem->vaddr, mem->size);
252                 break;
253         case V4L2_MEMORY_OVERLAY:
254         default:
255                 dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n",
256                         __func__);
257                 return -EINVAL;
258         }
259
260         return 0;
261 }
262
263 static int __videobuf_mmap_free(struct videobuf_queue *q)
264 {
265         unsigned int i;
266
267         dev_dbg(q->dev, "%s\n", __func__);
268         for (i = 0; i < VIDEO_MAX_FRAME; i++) {
269                 if (q->bufs[i] && q->bufs[i]->map)
270                         return -EBUSY;
271         }
272
273         return 0;
274 }
275
276 static int __videobuf_mmap_mapper(struct videobuf_queue *q,
277                                   struct vm_area_struct *vma)
278 {
279         struct videobuf_dma_contig_memory *mem;
280         struct videobuf_mapping *map;
281         unsigned int first;
282         int retval;
283         unsigned long size, offset = vma->vm_pgoff << PAGE_SHIFT;
284
285         dev_dbg(q->dev, "%s\n", __func__);
286         if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
287                 return -EINVAL;
288
289         /* look for first buffer to map */
290         for (first = 0; first < VIDEO_MAX_FRAME; first++) {
291                 if (!q->bufs[first])
292                         continue;
293
294                 if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
295                         continue;
296                 if (q->bufs[first]->boff == offset)
297                         break;
298         }
299         if (VIDEO_MAX_FRAME == first) {
300                 dev_dbg(q->dev, "invalid user space offset [offset=0x%lx]\n",
301                         offset);
302                 return -EINVAL;
303         }
304
305         /* create mapping + update buffer list */
306         map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
307         if (!map)
308                 return -ENOMEM;
309
310         q->bufs[first]->map = map;
311         map->start = vma->vm_start;
312         map->end = vma->vm_end;
313         map->q = q;
314
315         q->bufs[first]->baddr = vma->vm_start;
316
317         mem = q->bufs[first]->priv;
318         BUG_ON(!mem);
319         MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
320
321         mem->size = PAGE_ALIGN(q->bufs[first]->bsize);
322         mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
323                                         &mem->dma_handle, GFP_KERNEL);
324         if (!mem->vaddr) {
325                 dev_err(q->dev, "dma_alloc_coherent size %ld failed\n",
326                         mem->size);
327                 goto error;
328         }
329         dev_dbg(q->dev, "dma_alloc_coherent data is at addr %p (size %ld)\n",
330                 mem->vaddr, mem->size);
331
332         /* Try to remap memory */
333
334         size = vma->vm_end - vma->vm_start;
335         size = (size < mem->size) ? size : mem->size;
336
337         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
338         retval = remap_pfn_range(vma, vma->vm_start,
339                                  mem->dma_handle >> PAGE_SHIFT,
340                                  size, vma->vm_page_prot);
341         if (retval) {
342                 dev_err(q->dev, "mmap: remap failed with error %d. ", retval);
343                 dma_free_coherent(q->dev, mem->size,
344                                   mem->vaddr, mem->dma_handle);
345                 goto error;
346         }
347
348         vma->vm_ops          = &videobuf_vm_ops;
349         vma->vm_flags       |= VM_DONTEXPAND;
350         vma->vm_private_data = map;
351
352         dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
353                 map, q, vma->vm_start, vma->vm_end,
354                 (long int) q->bufs[first]->bsize,
355                 vma->vm_pgoff, first);
356
357         videobuf_vm_open(vma);
358
359         return 0;
360
361 error:
362         kfree(map);
363         return -ENOMEM;
364 }
365
366 static int __videobuf_copy_to_user(struct videobuf_queue *q,
367                                    char __user *data, size_t count,
368                                    int nonblocking)
369 {
370         struct videobuf_dma_contig_memory *mem = q->read_buf->priv;
371         void *vaddr;
372
373         BUG_ON(!mem);
374         MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
375         BUG_ON(!mem->vaddr);
376
377         /* copy to userspace */
378         if (count > q->read_buf->size - q->read_off)
379                 count = q->read_buf->size - q->read_off;
380
381         vaddr = mem->vaddr;
382
383         if (copy_to_user(data, vaddr + q->read_off, count))
384                 return -EFAULT;
385
386         return count;
387 }
388
389 static int __videobuf_copy_stream(struct videobuf_queue *q,
390                                   char __user *data, size_t count, size_t pos,
391                                   int vbihack, int nonblocking)
392 {
393         unsigned int  *fc;
394         struct videobuf_dma_contig_memory *mem = q->read_buf->priv;
395
396         BUG_ON(!mem);
397         MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
398
399         if (vbihack) {
400                 /* dirty, undocumented hack -- pass the frame counter
401                         * within the last four bytes of each vbi data block.
402                         * We need that one to maintain backward compatibility
403                         * to all vbi decoding software out there ... */
404                 fc = (unsigned int *)mem->vaddr;
405                 fc += (q->read_buf->size >> 2) - 1;
406                 *fc = q->read_buf->field_count >> 1;
407                 dev_dbg(q->dev, "vbihack: %d\n", *fc);
408         }
409
410         /* copy stuff using the common method */
411         count = __videobuf_copy_to_user(q, data, count, nonblocking);
412
413         if ((count == -EFAULT) && (pos == 0))
414                 return -EFAULT;
415
416         return count;
417 }
418
419 static struct videobuf_qtype_ops qops = {
420         .magic        = MAGIC_QTYPE_OPS,
421
422         .alloc        = __videobuf_alloc,
423         .iolock       = __videobuf_iolock,
424         .mmap_free    = __videobuf_mmap_free,
425         .mmap_mapper  = __videobuf_mmap_mapper,
426         .video_copy_to_user = __videobuf_copy_to_user,
427         .copy_stream  = __videobuf_copy_stream,
428         .vmalloc      = __videobuf_to_vmalloc,
429 };
430
431 void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
432                                     struct videobuf_queue_ops *ops,
433                                     struct device *dev,
434                                     spinlock_t *irqlock,
435                                     enum v4l2_buf_type type,
436                                     enum v4l2_field field,
437                                     unsigned int msize,
438                                     void *priv)
439 {
440         videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
441                                  priv, &qops);
442 }
443 EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init);
444
445 dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf)
446 {
447         struct videobuf_dma_contig_memory *mem = buf->priv;
448
449         BUG_ON(!mem);
450         MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
451
452         return mem->dma_handle;
453 }
454 EXPORT_SYMBOL_GPL(videobuf_to_dma_contig);
455
456 void videobuf_dma_contig_free(struct videobuf_queue *q,
457                               struct videobuf_buffer *buf)
458 {
459         struct videobuf_dma_contig_memory *mem = buf->priv;
460
461         /* mmapped memory can't be freed here, otherwise mmapped region
462            would be released, while still needed. In this case, the memory
463            release should happen inside videobuf_vm_close().
464            So, it should free memory only if the memory were allocated for
465            read() operation.
466          */
467         if (buf->memory != V4L2_MEMORY_USERPTR)
468                 return;
469
470         if (!mem)
471                 return;
472
473         MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
474
475         /* handle user space pointer case */
476         if (buf->baddr) {
477                 videobuf_dma_contig_user_put(mem);
478                 return;
479         }
480
481         /* read() method */
482         dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle);
483         mem->vaddr = NULL;
484 }
485 EXPORT_SYMBOL_GPL(videobuf_dma_contig_free);
486
487 MODULE_DESCRIPTION("helper module to manage video4linux dma contig buffers");
488 MODULE_AUTHOR("Magnus Damm");
489 MODULE_LICENSE("GPL");