MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
+ /* FIXME: This is required to avoid OOPS on some cases, since mmap_mapper()
+ method should be called before _iolock.
+ On some cases, the mmap_mapper() is called only after scheduling.
+
+ However, this way is just too dirty! Better to wait for some event.
+ */
+ schedule_timeout(HZ);
+
return CALL(q,iolock,q,vb,fbuf);
}
/* --------------------------------------------------------------------- */
-void videobuf_queue_init(struct videobuf_queue* q,
+void videobuf_queue_core_init(struct videobuf_queue* q,
struct videobuf_queue_ops *ops,
void *dev,
spinlock_t *irqlock,
enum v4l2_buf_type type,
enum v4l2_field field,
unsigned int msize,
- void *priv)
+ void *priv,
+ struct videobuf_qtype_ops *int_ops)
{
memset(q,0,sizeof(*q));
- q->irqlock = irqlock;
- q->dev = dev;
- q->type = type;
- q->field = field;
- q->msize = msize;
- q->ops = ops;
+ q->irqlock = irqlock;
+ q->dev = dev;
+ q->type = type;
+ q->field = field;
+ q->msize = msize;
+ q->ops = ops;
q->priv_data = priv;
+ q->int_ops = int_ops;
/* All buffer operations are mandatory */
BUG_ON (!q->ops->buf_setup);
BUG_ON (!q->ops->buf_queue);
BUG_ON (!q->ops->buf_release);
+ /* Having implementations for abstract methods are mandatory */
+ BUG_ON (!q->int_ops);
+
mutex_init(&q->lock);
INIT_LIST_HEAD(&q->stream);
}
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
if (NULL == q->bufs[i])
continue;
- if (CALL(q,is_mmapped,q->bufs[i])) {
+ if (q->bufs[i]->map) {
dprintk(1,"busy: buffer #%d mapped\n",i);
return 1;
}
}
b->flags = 0;
- if (CALL(q,is_mmapped,vb))
+ if (vb->map)
b->flags |= V4L2_BUF_FLAG_MAPPED;
switch (vb->state) {
return -EINVAL;
}
+ mutex_lock(&q->lock);
if (q->streaming) {
dprintk(1,"reqbufs: streaming already exists\n");
- return -EBUSY;
+ retval = -EBUSY;
+ goto done;
}
if (!list_empty(&q->stream)) {
dprintk(1,"reqbufs: stream running\n");
- return -EBUSY;
+ retval = -EBUSY;
+ goto done;
}
- mutex_lock(&q->lock);
count = req->count;
if (count > VIDEO_MAX_FRAME)
count = VIDEO_MAX_FRAME;
MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
+ if (b->memory == V4L2_MEMORY_MMAP)
+ down_read(¤t->mm->mmap_sem);
+
mutex_lock(&q->lock);
retval = -EBUSY;
if (q->reading) {
done:
mutex_unlock(&q->lock);
+
+ if (b->memory == V4L2_MEMORY_MMAP)
+ up_read(¤t->mm->mmap_sem);
+
return retval;
}
}
if (q->read_buf->state == STATE_DONE) {
- rc = CALL (q,copy_stream, q, data, count,
+ rc = CALL (q,copy_stream, q, data + retval, count,
retval, vbihack, nonblocking);
if (rc < 0) {
retval = rc;
EXPORT_SYMBOL_GPL(videobuf_alloc);
-EXPORT_SYMBOL_GPL(videobuf_queue_init);
+EXPORT_SYMBOL_GPL(videobuf_queue_core_init);
EXPORT_SYMBOL_GPL(videobuf_queue_cancel);
EXPORT_SYMBOL_GPL(videobuf_queue_is_busy);