dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
if (dmxdev->may_do_mmap)
dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr",
+ &dmxdev->mutex,
file->f_flags & O_NONBLOCK);
dvbdev->readers--;
}
dmxdev->may_do_mmap = 0;
#endif
+ /*
+ * The mutex passed to dvb_vb2_init is unlocked when a buffer
+ * is in a blocking wait. However, dmxdevfilter has two mutexes:
+ * dmxdevfilter->mutex and dmxdev->mutex. So this will not work.
+ * The solution would be to support unlocking two mutexes in vb2,
+ * but since this problem has been here since the beginning and
+ * nobody ever complained, we leave it as-is rather than adding
+ * that second mutex pointer to vb2.
+ *
+ * In the unlikely event that someone complains about this, then
+ * this comment will hopefully help.
+ */
dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
dvb_vb2_init(&dmxdevfilter->vb2_ctx, "demux_filter",
- file->f_flags & O_NONBLOCK);
+ &dmxdevfilter->mutex, file->f_flags & O_NONBLOCK);
dmxdevfilter->type = DMXDEV_TYPE_NONE;
dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
timer_setup(&dmxdevfilter->timer, dvb_dmxdev_filter_timeout, 0);
spin_unlock_irqrestore(&ctx->slock, flags);
}
-static void _dmxdev_lock(struct vb2_queue *vq)
-{
- struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
-
- mutex_lock(&ctx->mutex);
- dprintk(3, "[%s]\n", ctx->name);
-}
-
-static void _dmxdev_unlock(struct vb2_queue *vq)
-{
- struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
-
- if (mutex_is_locked(&ctx->mutex))
- mutex_unlock(&ctx->mutex);
- dprintk(3, "[%s]\n", ctx->name);
-}
-
static const struct vb2_ops dvb_vb2_qops = {
.queue_setup = _queue_setup,
.buf_prepare = _buffer_prepare,
.buf_queue = _buffer_queue,
.start_streaming = _start_streaming,
.stop_streaming = _stop_streaming,
- .wait_prepare = _dmxdev_unlock,
- .wait_finish = _dmxdev_lock,
};
static void _fill_dmx_buffer(struct vb2_buffer *vb, void *pb)
};
/*
- * Videobuf operations
+ * vb2 operations
*/
-int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int nonblocking)
+int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name,
+ struct mutex *mutex, int nonblocking)
{
struct vb2_queue *q = &ctx->vb_q;
int ret;
q->ops = &dvb_vb2_qops;
q->mem_ops = &vb2_vmalloc_memops;
q->buf_ops = &dvb_vb2_buf_ops;
- ret = vb2_core_queue_init(q);
- if (ret) {
- ctx->state = DVB_VB2_STATE_NONE;
- dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
- return ret;
- }
-
- mutex_init(&ctx->mutex);
+ q->lock = mutex;
spin_lock_init(&ctx->slock);
INIT_LIST_HEAD(&ctx->dvb_q);
ctx->nonblocking = nonblocking;
ctx->state = DVB_VB2_STATE_INIT;
+ ret = vb2_core_queue_init(q);
+ if (ret) {
+ ctx->state = DVB_VB2_STATE_NONE;
+ dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
+ return ret;
+ }
+
dprintk(3, "[%s]\n", ctx->name);
return 0;
/**
* struct dvb_vb2_ctx - control struct for VB2 handler
* @vb_q: pointer to &struct vb2_queue with videobuf2 queue.
- * @mutex: mutex to serialize vb2 operations. Used by
- * vb2 core %wait_prepare and %wait_finish operations.
* @slock: spin lock used to protect buffer filling at dvb_vb2.c.
* @dvb_q: List of buffers that are not filled yet.
* @buf: Pointer to the buffer that are currently being filled.
*/
struct dvb_vb2_ctx {
struct vb2_queue vb_q;
- struct mutex mutex;
spinlock_t slock;
struct list_head dvb_q;
struct dvb_buffer *buf;
};
#ifndef CONFIG_DVB_MMAP
-static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx,
- const char *name, int non_blocking)
+static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name,
+ struct mutex *mutex, int non_blocking)
{
return 0;
};
*
* @ctx: control struct for VB2 handler
* @name: name for the VB2 handler
+ * @mutex: pointer to the mutex that serializes vb2 ioctls
* @non_blocking:
* if not zero, it means that the device is at non-blocking mode
*/
-int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int non_blocking);
+int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name,
+ struct mutex *mutex, int non_blocking);
/**
* dvb_vb2_release - Releases the VB2 handler allocated resources and