V4L/DVB (7561): videobuf-vmalloc: stop streaming before unmap

Before the patch, there were a risk of freeing and unmapping userspace memory,
while there were pending requests.

Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index 5613e08..45a8cbd 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -901,7 +901,6 @@
 {
 	int i;
 
-
 	videobuf_queue_cancel(q);
 	__videobuf_mmap_free(q);
 	INIT_LIST_HEAD(&q->stream);
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index 73627d3..d68d027 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -72,6 +72,11 @@
 
 		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 @@
 				   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 @@
 			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 @@
 			      struct v4l2_framebuffer *fbuf)
 {
 	struct videobuf_vmalloc_memory *mem = vb->priv;
+	int pages;
 
 	BUG_ON(!mem);
 
@@ -154,8 +171,7 @@
 		}
 		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 @@
 #endif
 
 		break;
-	}
 	case V4L2_MEMORY_OVERLAY:
 	default:
 		dprintk(1, "%s memory method OVERLAY/unknown\n", __func__);