[linux-dvb] [PATCH 1/2] V4L: Fix videobuf_cgmbuf() locking

Brandon Philips brandon at ifup.org
Thu Nov 29 20:59:36 CET 2007


Minor fix-ups to videobuf_cgmbuf locking.  

e9hack, could you test this and the next patch on your hardware? Thanks.

Not fully tested, v4l1-compat doesn't work with the vivi driver!
videobuf-vmalloc.c needs fixing. 

Signed-off-by: Brandon Philips <bphilips at suse.de>
---

diff --git a/linux/drivers/media/video/videobuf-core.c b/linux/drivers/media/video/videobuf-core.c
--- a/linux/drivers/media/video/videobuf-core.c
+++ b/linux/drivers/media/video/videobuf-core.c
@@ -377,7 +377,7 @@ int videobuf_mmap_setup(struct videobuf_
 	return ret;
 }
 
-int videobuf_reqbufs(struct videobuf_queue *q,
+static int __videobuf_reqbufs(struct videobuf_queue *q,
 		 struct v4l2_requestbuffers *req)
 {
 	unsigned int size,count;
@@ -395,22 +395,18 @@ int videobuf_reqbufs(struct videobuf_que
 		return -EINVAL;
 	}
 
-	mutex_lock(&q->lock);
 	if (req->type != q->type) {
 		dprintk(1,"reqbufs: queue type invalid\n");
-		retval = -EINVAL;
-		goto done;
+		return -EINVAL;
 	}
 
 	if (q->streaming) {
 		dprintk(1,"reqbufs: streaming already exists\n");
-		retval = -EBUSY;
-		goto done;
+		return -EBUSY;
 	}
 	if (!list_empty(&q->stream)) {
 		dprintk(1,"reqbufs: stream running\n");
-		retval = -EBUSY;
-		goto done;
+		return -EBUSY;
 	}
 
 	count = req->count;
@@ -425,14 +421,22 @@ int videobuf_reqbufs(struct videobuf_que
 	retval = __videobuf_mmap_setup(q,count,size,req->memory);
 	if (retval < 0) {
 		dprintk(1,"reqbufs: mmap setup returned %d\n",retval);
-		goto done;
+		return retval;
 	}
 
 	req->count = retval;
 
- done:
-	mutex_unlock(&q->lock);
 	return retval;
+}
+
+int videobuf_reqbufs(struct videobuf_queue *q,
+		 struct v4l2_requestbuffers *req)
+{
+	int retval;
+	mutex_lock(&q->lock);
+	retval = __videobuf_reqbufs(q, req);
+ 	mutex_unlock(&q->lock);
+ 	return retval;
 }
 
 int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
@@ -1032,12 +1036,15 @@ int videobuf_cgmbuf(struct videobuf_queu
 	MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
 
 	memset(&req,0,sizeof(req));
+	mutex_lock(&q->lock);
 	req.type   = q->type;
 	req.count  = count;
 	req.memory = V4L2_MEMORY_MMAP;
-	rc = videobuf_reqbufs(q,&req);
-	if (rc < 0)
+	rc = __videobuf_reqbufs(q,&req);
+	if (rc < 0) {
+		mutex_unlock(&q->lock);
 		return rc;
+	}
 
 	mbuf->frames = req.count;
 	mbuf->size   = 0;
@@ -1046,6 +1053,7 @@ int videobuf_cgmbuf(struct videobuf_queu
 		mbuf->size       += q->bufs[i]->bsize;
 	}
 
+	mutex_unlock(&q->lock);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(videobuf_cgmbuf);



More information about the linux-dvb mailing list