]> err.no Git - linux-2.6/blobdiff - drivers/media/video/videobuf-vmalloc.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / drivers / media / video / videobuf-vmalloc.c
index 73627d380f07f44677808b128b8b52322acfae79..a868b7ed75ff2cc60f09181c1b1812dd44888c56 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * helper functions for vmalloc video4linux capture buffers
  *
- * The functions expect the hardware being able to scatter gatter
+ * The functions expect the hardware being able to scatter gather
  * (i.e. the buffers are not linear in physical memory, but fragmented
  * into PAGE_SIZE chunks).  They also assume the driver does not need
  * to touch the video data.
@@ -72,6 +72,11 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
 
                dprintk(1, "munmap %p q=%p\n", map, q);
                mutex_lock(&q->vb_lock);
+
+               /* We need first to cancel streams, before unmapping */
+               if (q->streaming)
+                       videobuf_queue_cancel(q);
+
                for (i = 0; i < VIDEO_MAX_FRAME; i++) {
                        if (NULL == q->bufs[i])
                                continue;
@@ -86,7 +91,15 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
                                   In this case, memory should be freed,
                                   in order to do memory unmap.
                                 */
+
                                MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
+
+                               /* vfree is not atomic - can't be
+                                  called with IRQ's disabled
+                                */
+                               dprintk(1, "%s: buf[%d] freeing (%p)\n",
+                                       __func__, i, mem->vmalloc);
+
                                vfree(mem->vmalloc);
                                mem->vmalloc = NULL;
                        }
@@ -94,9 +107,12 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
                        q->bufs[i]->map   = NULL;
                        q->bufs[i]->baddr = 0;
                }
-               mutex_unlock(&q->vb_lock);
+
                kfree(map);
+
+               mutex_unlock(&q->vb_lock);
        }
+
        return;
 }
 
@@ -138,6 +154,7 @@ static int __videobuf_iolock (struct videobuf_queue* q,
                              struct v4l2_framebuffer *fbuf)
 {
        struct videobuf_vmalloc_memory *mem = vb->priv;
+       int pages;
 
        BUG_ON(!mem);
 
@@ -154,8 +171,7 @@ static int __videobuf_iolock (struct videobuf_queue* q,
                }
                break;
        case V4L2_MEMORY_USERPTR:
-       {
-               int pages = PAGE_ALIGN(vb->size);
+               pages = PAGE_ALIGN(vb->size);
 
                dprintk(1, "%s memory method USERPTR\n", __func__);
 
@@ -198,7 +214,6 @@ static int __videobuf_iolock (struct videobuf_queue* q,
 #endif
 
                break;
-       }
        case V4L2_MEMORY_OVERLAY:
        default:
                dprintk(1, "%s memory method OVERLAY/unknown\n", __func__);
@@ -372,6 +387,7 @@ static struct videobuf_qtype_ops qops = {
        .mmap_mapper  = __videobuf_mmap_mapper,
        .video_copy_to_user = __videobuf_copy_to_user,
        .copy_stream  = __videobuf_copy_stream,
+       .vmalloc      = videobuf_to_vmalloc,
 };
 
 void videobuf_queue_vmalloc_init(struct videobuf_queue* q,