nfsd4: shut down callback queue outside state lock
[safe/jmp/linux-2.6] / drivers / media / video / videobuf-vmalloc.c
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)  if (unlikely((is) != (should))) \
34         { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); }
35
36 static int debug;
37 module_param(debug, int, 0644);
38
39 MODULE_DESCRIPTION("helper module to manage video4linux vmalloc buffers");
40 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
41 MODULE_LICENSE("GPL");
42
43 #define dprintk(level, fmt, arg...)     if (debug >= level) \
44         printk(KERN_DEBUG "vbuf-vmalloc: " fmt , ## arg)
45
46
47 /***************************************************************************/
48
49 static void
50 videobuf_vm_open(struct vm_area_struct *vma)
51 {
52         struct videobuf_mapping *map = vma->vm_private_data;
53
54         dprintk(2,"vm_open %p [count=%u,vma=%08lx-%08lx]\n",map,
55                 map->count,vma->vm_start,vma->vm_end);
56
57         map->count++;
58 }
59
60 static void videobuf_vm_close(struct vm_area_struct *vma)
61 {
62         struct videobuf_mapping *map = vma->vm_private_data;
63         struct videobuf_queue *q = map->q;
64         int i;
65
66         dprintk(2,"vm_close %p [count=%u,vma=%08lx-%08lx]\n", map,
67                 map->count, vma->vm_start, vma->vm_end);
68
69         map->count--;
70         if (0 == map->count) {
71                 struct videobuf_vmalloc_memory *mem;
72
73                 dprintk(1, "munmap %p q=%p\n", map, q);
74                 mutex_lock(&q->vb_lock);
75
76                 /* We need first to cancel streams, before unmapping */
77                 if (q->streaming)
78                         videobuf_queue_cancel(q);
79
80                 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
81                         if (NULL == q->bufs[i])
82                                 continue;
83
84                         if (q->bufs[i]->map != map)
85                                 continue;
86
87                         mem = q->bufs[i]->priv;
88                         if (mem) {
89                                 /* This callback is called only if kernel has
90                                    allocated memory and this memory is mmapped.
91                                    In this case, memory should be freed,
92                                    in order to do memory unmap.
93                                  */
94
95                                 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
96
97                                 /* vfree is not atomic - can't be
98                                    called with IRQ's disabled
99                                  */
100                                 dprintk(1, "%s: buf[%d] freeing (%p)\n",
101                                         __func__, i, mem->vmalloc);
102
103                                 vfree(mem->vmalloc);
104                                 mem->vmalloc = NULL;
105                         }
106
107                         q->bufs[i]->map   = NULL;
108                         q->bufs[i]->baddr = 0;
109                 }
110
111                 kfree(map);
112
113                 mutex_unlock(&q->vb_lock);
114         }
115
116         return;
117 }
118
119 static const struct vm_operations_struct videobuf_vm_ops =
120 {
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
135 static void *__videobuf_alloc(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
154 static 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->vmalloc) {
171                         printk(KERN_ERR "memory is not alloced/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 1
181                 if (vb->baddr) {
182                         printk(KERN_ERR "USERPTR is currently not supported\n");
183                         return -EINVAL;
184                 }
185 #endif
186
187                 /* The only USERPTR currently supported is the one needed for
188                    read() method.
189                  */
190
191                 mem->vmalloc = vmalloc_user(pages);
192                 if (!mem->vmalloc) {
193                         printk(KERN_ERR "vmalloc (%d pages) failed\n", pages);
194                         return -ENOMEM;
195                 }
196                 dprintk(1, "vmalloc is at addr %p (%d pages)\n",
197                         mem->vmalloc, pages);
198
199 #if 0
200                 int rc;
201                 /* Kernel userptr is used also by read() method. In this case,
202                    there's no need to remap, since data will be copied to user
203                  */
204                 if (!vb->baddr)
205                         return 0;
206
207                 /* FIXME: to properly support USERPTR, remap should occur.
208                    The code below won't work, since mem->vma = NULL
209                  */
210                 /* Try to remap memory */
211                 rc = remap_vmalloc_range(mem->vma, (void *)vb->baddr, 0);
212                 if (rc < 0) {
213                         printk(KERN_ERR "mmap: remap failed with error %d. ", rc);
214                         return -ENOMEM;
215                 }
216 #endif
217
218                 break;
219         case V4L2_MEMORY_OVERLAY:
220         default:
221                 dprintk(1, "%s memory method OVERLAY/unknown\n", __func__);
222
223                 /* Currently, doesn't support V4L2_MEMORY_OVERLAY */
224                 printk(KERN_ERR "Memory method currently unsupported.\n");
225                 return -EINVAL;
226         }
227
228         return 0;
229 }
230
231 static int __videobuf_sync(struct videobuf_queue *q,
232                            struct videobuf_buffer *buf)
233 {
234         return 0;
235 }
236
237 static int __videobuf_mmap_free(struct videobuf_queue *q)
238 {
239         unsigned int i;
240
241         dprintk(1, "%s\n", __func__);
242         for (i = 0; i < VIDEO_MAX_FRAME; i++) {
243                 if (q->bufs[i]) {
244                         if (q->bufs[i]->map)
245                                 return -EBUSY;
246                 }
247         }
248
249         return 0;
250 }
251
252 static int __videobuf_mmap_mapper(struct videobuf_queue *q,
253                          struct vm_area_struct *vma)
254 {
255         struct videobuf_vmalloc_memory *mem;
256         struct videobuf_mapping *map;
257         unsigned int first;
258         int retval, pages;
259         unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
260
261         dprintk(1, "%s\n", __func__);
262         if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
263                 return -EINVAL;
264
265         /* look for first buffer to map */
266         for (first = 0; first < VIDEO_MAX_FRAME; first++) {
267                 if (NULL == q->bufs[first])
268                         continue;
269
270                 if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
271                         continue;
272                 if (q->bufs[first]->boff == offset)
273                         break;
274         }
275         if (VIDEO_MAX_FRAME == first) {
276                 dprintk(1,"mmap app bug: offset invalid [offset=0x%lx]\n",
277                         (vma->vm_pgoff << PAGE_SHIFT));
278                 return -EINVAL;
279         }
280
281         /* create mapping + update buffer list */
282         map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
283         if (NULL == map)
284                 return -ENOMEM;
285
286         q->bufs[first]->map = map;
287         map->start = vma->vm_start;
288         map->end   = vma->vm_end;
289         map->q     = q;
290
291         q->bufs[first]->baddr = vma->vm_start;
292
293         mem = q->bufs[first]->priv;
294         BUG_ON(!mem);
295         MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
296
297         pages = PAGE_ALIGN(vma->vm_end - vma->vm_start);
298         mem->vmalloc = vmalloc_user(pages);
299         if (!mem->vmalloc) {
300                 printk(KERN_ERR "vmalloc (%d pages) failed\n", pages);
301                 goto error;
302         }
303         dprintk(1, "vmalloc is at addr %p (%d pages)\n",
304                 mem->vmalloc, pages);
305
306         /* Try to remap memory */
307         retval = remap_vmalloc_range(vma, mem->vmalloc, 0);
308         if (retval < 0) {
309                 printk(KERN_ERR "mmap: remap failed with error %d. ", retval);
310                 vfree(mem->vmalloc);
311                 goto error;
312         }
313
314         vma->vm_ops          = &videobuf_vm_ops;
315         vma->vm_flags       |= VM_DONTEXPAND | VM_RESERVED;
316         vma->vm_private_data = map;
317
318         dprintk(1,"mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
319                 map, q, vma->vm_start, vma->vm_end,
320                 (long int) q->bufs[first]->bsize,
321                 vma->vm_pgoff, first);
322
323         videobuf_vm_open(vma);
324
325         return 0;
326
327 error:
328         mem = NULL;
329         kfree(map);
330         return -ENOMEM;
331 }
332
333 static int __videobuf_copy_to_user ( struct videobuf_queue *q,
334                                 char __user *data, size_t count,
335                                 int nonblocking )
336 {
337         struct videobuf_vmalloc_memory *mem=q->read_buf->priv;
338         BUG_ON (!mem);
339         MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
340
341         BUG_ON (!mem->vmalloc);
342
343         /* copy to userspace */
344         if (count > q->read_buf->size - q->read_off)
345                 count = q->read_buf->size - q->read_off;
346
347         if (copy_to_user(data, mem->vmalloc+q->read_off, count))
348                 return -EFAULT;
349
350         return count;
351 }
352
353 static int __videobuf_copy_stream ( struct videobuf_queue *q,
354                                 char __user *data, size_t count, size_t pos,
355                                 int vbihack, int nonblocking )
356 {
357         unsigned int  *fc;
358         struct videobuf_vmalloc_memory *mem=q->read_buf->priv;
359         BUG_ON (!mem);
360         MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
361
362         if (vbihack) {
363                 /* dirty, undocumented hack -- pass the frame counter
364                         * within the last four bytes of each vbi data block.
365                         * We need that one to maintain backward compatibility
366                         * to all vbi decoding software out there ... */
367                 fc  = (unsigned int*)mem->vmalloc;
368                 fc += (q->read_buf->size>>2) -1;
369                 *fc = q->read_buf->field_count >> 1;
370                 dprintk(1,"vbihack: %d\n",*fc);
371         }
372
373         /* copy stuff using the common method */
374         count = __videobuf_copy_to_user (q,data,count,nonblocking);
375
376         if ( (count==-EFAULT) && (0 == pos) )
377                 return -EFAULT;
378
379         return count;
380 }
381
382 static struct videobuf_qtype_ops qops = {
383         .magic        = MAGIC_QTYPE_OPS,
384
385         .alloc        = __videobuf_alloc,
386         .iolock       = __videobuf_iolock,
387         .sync         = __videobuf_sync,
388         .mmap_free    = __videobuf_mmap_free,
389         .mmap_mapper  = __videobuf_mmap_mapper,
390         .video_copy_to_user = __videobuf_copy_to_user,
391         .copy_stream  = __videobuf_copy_stream,
392         .vmalloc      = videobuf_to_vmalloc,
393 };
394
395 void videobuf_queue_vmalloc_init(struct videobuf_queue* q,
396                          const struct videobuf_queue_ops *ops,
397                          struct device *dev,
398                          spinlock_t *irqlock,
399                          enum v4l2_buf_type type,
400                          enum v4l2_field field,
401                          unsigned int msize,
402                          void *priv)
403 {
404         videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
405                                  priv, &qops);
406 }
407
408 EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init);
409
410 void *videobuf_to_vmalloc (struct videobuf_buffer *buf)
411 {
412         struct videobuf_vmalloc_memory *mem=buf->priv;
413         BUG_ON (!mem);
414         MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
415
416         return mem->vmalloc;
417 }
418 EXPORT_SYMBOL_GPL(videobuf_to_vmalloc);
419
420 void videobuf_vmalloc_free (struct videobuf_buffer *buf)
421 {
422         struct videobuf_vmalloc_memory *mem = buf->priv;
423
424         /* mmapped memory can't be freed here, otherwise mmapped region
425            would be released, while still needed. In this case, the memory
426            release should happen inside videobuf_vm_close().
427            So, it should free memory only if the memory were allocated for
428            read() operation.
429          */
430         if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
431                 return;
432
433         if (!mem)
434                 return;
435
436         MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
437
438         vfree(mem->vmalloc);
439         mem->vmalloc = NULL;
440
441         return;
442 }
443 EXPORT_SYMBOL_GPL(videobuf_vmalloc_free);
444
445 /*
446  * Local variables:
447  * c-basic-offset: 8
448  * End:
449  */