/** * vb2_qbuf() - Queue a buffer from userspace * @q: videobuf2 queue * @b: buffer structure passed from userspace to vidioc_qbuf handler * in driver * * Should be called from vidioc_qbuf ioctl handler of a driver. * This function: * 1) verifies the passed buffer, * 2) calls buf_prepare callback in the driver (if provided), in which * driver-specific buffer initialization can be performed, * 3) if streaming is on, queues the buffer in driver by the means of buf_queue * callback for processing. * * The return values from this function are intended to be directly returned * from vidioc_qbuf handler in driver. */ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) { struct vb2_buffer *vb; int ret = 0; if (q->fileio) { dprintk(1, "qbuf: file io in progress\n"); return -EBUSY; } if (b->type != q->type) { dprintk(1, "qbuf: invalid buffer type\n"); return -EINVAL; } if (b->index >= q->num_buffers) { dprintk(1, "qbuf: buffer index out of range\n"); return -EINVAL; } vb = q->bufs[b->index]; if (NULL == vb) { /* Should never happen */ dprintk(1, "qbuf: buffer is NULL\n"); return -EINVAL; } if (b->memory != q->memory) { dprintk(1, "qbuf: invalid memory type\n"); return -EINVAL; } if (vb->state != VB2_BUF_STATE_DEQUEUED) { dprintk(1, "qbuf: buffer already in use\n"); return -EINVAL; } if (q->memory == V4L2_MEMORY_MMAP) ret = __qbuf_mmap(vb, b); else if (q->memory == V4L2_MEMORY_USERPTR) ret = __qbuf_userptr(vb, b); else { WARN(1, "Invalid queue type\n"); return -EINVAL; } if (ret) return ret; ret = call_qop(q, buf_prepare, vb); if (ret) { dprintk(1, "qbuf: buffer preparation failed\n"); return ret; } /* * Add to the queued buffers list, a buffer will stay on it until * dequeued in dqbuf. */ list_add_tail(&vb->queued_entry, &q->queued_list); vb->state = VB2_BUF_STATE_QUEUED; /* * If already streaming, give the buffer to driver for processing. * If not, the buffer will be given to driver on next streamon. */ if (q->streaming) __enqueue_in_driver(vb); dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index); return 0; }
int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) { struct vb2_buffer *vb; int ret = 0; if (q->fileio) { dprintk(1, "qbuf: file io in progress\n"); return -EBUSY; } if (b->type != q->type) { dprintk(1, "qbuf: invalid buffer type\n"); return -EINVAL; } if (b->index >= q->num_buffers) { dprintk(1, "qbuf: buffer index out of range\n"); return -EINVAL; } vb = q->bufs[b->index]; if (NULL == vb) { dprintk(1, "qbuf: buffer is NULL\n"); return -EINVAL; } if (b->memory != q->memory) { dprintk(1, "qbuf: invalid memory type\n"); return -EINVAL; } if (vb->state != VB2_BUF_STATE_DEQUEUED) { dprintk(1, "qbuf: buffer already in use\n"); return -EINVAL; } if (q->memory == V4L2_MEMORY_MMAP) ret = __qbuf_mmap(vb, b); else if (q->memory == V4L2_MEMORY_USERPTR) ret = __qbuf_userptr(vb, b); else { WARN(1, "Invalid queue type\n"); return -EINVAL; } if (ret) return ret; ret = call_qop(q, buf_prepare, vb); if (ret) { dprintk(1, "qbuf: buffer preparation failed\n"); return ret; } list_add_tail(&vb->queued_entry, &q->queued_list); vb->state = VB2_BUF_STATE_QUEUED; if (q->streaming) __enqueue_in_driver(vb); dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index); return 0; }