|
@@ -195,6 +195,45 @@ int videobuf_queue_is_busy(struct videobuf_queue *q)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(videobuf_queue_is_busy);
|
|
|
|
|
|
+/**
|
|
|
+ * __videobuf_free() - free all the buffers and their control structures
|
|
|
+ *
|
|
|
+ * This function can only be called if streaming/reading is off, i.e. no buffers
|
|
|
+ * are under control of the driver.
|
|
|
+ */
|
|
|
+/* Locking: Caller holds q->vb_lock */
|
|
|
+static int __videobuf_free(struct videobuf_queue *q)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ dprintk(1, "%s\n", __func__);
|
|
|
+ if (!q)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (q->streaming || q->reading) {
|
|
|
+ dprintk(1, "Cannot free buffers when streaming or reading\n");
|
|
|
+ return -EBUSY;
|
|
|
+ }
|
|
|
+
|
|
|
+ MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
|
|
|
+
|
|
|
+ for (i = 0; i < VIDEO_MAX_FRAME; i++)
|
|
|
+ if (q->bufs[i] && q->bufs[i]->map) {
|
|
|
+ dprintk(1, "Cannot free mmapped buffers\n");
|
|
|
+ return -EBUSY;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < VIDEO_MAX_FRAME; i++) {
|
|
|
+ if (NULL == q->bufs[i])
|
|
|
+ continue;
|
|
|
+ q->ops->buf_release(q, q->bufs[i]);
|
|
|
+ kfree(q->bufs[i]);
|
|
|
+ q->bufs[i] = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/* Locking: Caller holds q->vb_lock */
|
|
|
void videobuf_queue_cancel(struct videobuf_queue *q)
|
|
|
{
|
|
@@ -308,36 +347,11 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
|
|
|
b->sequence = vb->field_count >> 1;
|
|
|
}
|
|
|
|
|
|
-/* Locking: Caller holds q->vb_lock */
|
|
|
-static int __videobuf_mmap_free(struct videobuf_queue *q)
|
|
|
-{
|
|
|
- int i;
|
|
|
-
|
|
|
- if (!q)
|
|
|
- return 0;
|
|
|
-
|
|
|
- MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
|
|
|
-
|
|
|
- for (i = 0; i < VIDEO_MAX_FRAME; i++)
|
|
|
- if (q->bufs[i] && q->bufs[i]->map)
|
|
|
- return -EBUSY;
|
|
|
-
|
|
|
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
|
|
|
- if (NULL == q->bufs[i])
|
|
|
- continue;
|
|
|
- q->ops->buf_release(q, q->bufs[i]);
|
|
|
- kfree(q->bufs[i]);
|
|
|
- q->bufs[i] = NULL;
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
int videobuf_mmap_free(struct videobuf_queue *q)
|
|
|
{
|
|
|
int ret;
|
|
|
mutex_lock(&q->vb_lock);
|
|
|
- ret = __videobuf_mmap_free(q);
|
|
|
+ ret = __videobuf_free(q);
|
|
|
mutex_unlock(&q->vb_lock);
|
|
|
return ret;
|
|
|
}
|
|
@@ -353,7 +367,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q,
|
|
|
|
|
|
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
|
|
|
|
|
|
- err = __videobuf_mmap_free(q);
|
|
|
+ err = __videobuf_free(q);
|
|
|
if (0 != err)
|
|
|
return err;
|
|
|
|
|
@@ -970,7 +984,7 @@ static void __videobuf_read_stop(struct videobuf_queue *q)
|
|
|
int i;
|
|
|
|
|
|
videobuf_queue_cancel(q);
|
|
|
- __videobuf_mmap_free(q);
|
|
|
+ __videobuf_free(q);
|
|
|
INIT_LIST_HEAD(&q->stream);
|
|
|
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
|
|
|
if (NULL == q->bufs[i])
|