/* Locking: Caller holds q->vb_lock */ static int __videobuf_read_start(struct videobuf_queue *q) { enum v4l2_field field; unsigned long flags = 0; unsigned int count = 0, size = 0; int err, i; q->ops->buf_setup(q, &count, &size); if (count < 2) count = 2; if (count > VIDEO_MAX_FRAME) count = VIDEO_MAX_FRAME; size = PAGE_ALIGN(size); err = __videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR); if (err < 0) return err; count = err; for (i = 0; i < count; i++) { field = videobuf_next_field(q); err = q->ops->buf_prepare(q, q->bufs[i], field); if (err) return err; list_add_tail(&q->bufs[i]->stream, &q->stream); } spin_lock_irqsave(q->irqlock, flags); for (i = 0; i < count; i++) q->ops->buf_queue(q, q->bufs[i]); spin_unlock_irqrestore(q->irqlock, flags); q->reading = 1; return 0; }
int videobuf_reqbufs(struct videobuf_queue *q, struct v4l2_requestbuffers *req) { unsigned int size, count; int retval; if (req->memory != V4L2_MEMORY_MMAP && req->memory != V4L2_MEMORY_USERPTR && req->memory != V4L2_MEMORY_OVERLAY) { dprintk(1, "reqbufs: memory type invalid\n"); return -EINVAL; } videobuf_queue_lock(q); if (req->type != q->type) { dprintk(1, "reqbufs: queue type invalid\n"); retval = -EINVAL; goto done; } if (q->streaming) { dprintk(1, "reqbufs: streaming already exists\n"); retval = -EBUSY; goto done; } if (!list_empty(&q->stream)) { dprintk(1, "reqbufs: stream running\n"); retval = -EBUSY; goto done; } if (req->count == 0) { dprintk(1, "reqbufs: count invalid (%d)\n", req->count); retval = __videobuf_free(q); goto done; } count = req->count; if (count > VIDEO_MAX_FRAME) count = VIDEO_MAX_FRAME; size = 0; q->ops->buf_setup(q, &count, &size); dprintk(1, "reqbufs: bufs=%d, size=0x%x [%u pages total]\n", count, size, (unsigned int)((count * PAGE_ALIGN(size)) >> PAGE_SHIFT)); retval = __videobuf_mmap_setup(q, count, size, req->memory); if (retval < 0) { dprintk(1, "reqbufs: mmap setup returned %d\n", retval); goto done; } req->count = retval; retval = 0; done: videobuf_queue_unlock(q); return retval; }
int videobuf_mmap_setup(struct videobuf_queue *q, unsigned int bcount, unsigned int bsize, enum v4l2_memory memory) { int ret; mutex_lock(&q->lock); ret = __videobuf_mmap_setup(q, bcount, bsize, memory); mutex_unlock(&q->lock); return ret; }