/** * vb2_dqbuf() - Dequeue a buffer to the userspace * @q: videobuf2 queue * @b: buffer structure passed from userspace to vidioc_dqbuf handler * in driver * @nonblocking: if true, this call will not sleep waiting for a buffer if no * buffers ready for dequeuing are present. Normally the driver * would be passing (file->f_flags & O_NONBLOCK) here * * Should be called from vidioc_dqbuf ioctl handler of a driver. * This function: * 1) verifies the passed buffer, * 2) calls buf_finish callback in the driver (if provided), in which * driver can perform any additional operations that may be required before * returning the buffer to userspace, such as cache sync, * 3) the buffer struct members are filled with relevant information for * the userspace. * * The return values from this function are intended to be directly returned * from vidioc_dqbuf handler in driver. */ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking) { if (vb2_fileio_is_active(q)) { dprintk(1, "file io in progress\n"); return -EBUSY; } return vb2_internal_dqbuf(q, b, nonblocking); }
/** * vb2_streamoff - stop streaming * @q: videobuf2 queue * @type: type argument passed from userspace to vidioc_streamoff handler * * Should be called from vidioc_streamoff handler of a driver. * This function: * 1) verifies current state, * 2) stop streaming and dequeues any queued buffers, including those previously * passed to the driver (after waiting for the driver to finish). * * This call can be used for pausing playback. * The return values from this function are intended to be directly returned * from vidioc_streamoff handler in the driver */ int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) { if (vb2_fileio_is_active(q)) { dprintk(1, "file io in progress\n"); return -EBUSY; } return vb2_core_streamoff(q, type); }
/** * 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) if necessary, 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) { if (vb2_fileio_is_active(q)) { dprintk(1, "file io in progress\n"); return -EBUSY; } return vb2_internal_qbuf(q, b); }
int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) { int ret; if (vb2_fileio_is_active(q)) { dprintk(1, "file io in progress\n"); return -EBUSY; } ret = vb2_queue_or_prepare_buf(q, b, "qbuf"); return ret ? ret : vb2_core_qbuf(q, b->index, b); }
int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking) { int ret; if (vb2_fileio_is_active(q)) { dprintk(1, "file io in progress\n"); return -EBUSY; } if (b->type != q->type) { dprintk(1, "invalid buffer type\n"); return -EINVAL; } ret = vb2_core_dqbuf(q, NULL, b, nonblocking); /* * After calling the VIDIOC_DQBUF V4L2_BUF_FLAG_DONE must be * cleared. */ b->flags &= ~V4L2_BUF_FLAG_DONE; return ret; }
/** * vb2_poll() - implements poll userspace operation * @q: videobuf2 queue * @file: file argument passed to the poll file operation handler * @wait: wait argument passed to the poll file operation handler * * This function implements poll file operation handler for a driver. * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will * be informed that the file descriptor of a video device is available for * reading. * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor * will be reported as available for writing. * * If the driver uses struct v4l2_fh, then vb2_poll() will also check for any * pending events. * * The return values from this function are intended to be directly returned * from poll handler in driver. */ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) { struct video_device *vfd = video_devdata(file); unsigned long req_events = poll_requested_events(wait); struct vb2_buffer *vb = NULL; unsigned int res = 0; unsigned long flags; if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) { struct v4l2_fh *fh = file->private_data; if (v4l2_event_pending(fh)) res = POLLPRI; else if (req_events & POLLPRI) poll_wait(file, &fh->wait, wait); } if (!q->is_output && !(req_events & (POLLIN | POLLRDNORM))) return res; if (q->is_output && !(req_events & (POLLOUT | POLLWRNORM))) return res; /* * Start file I/O emulator only if streaming API has not been used yet. */ if (q->num_buffers == 0 && !vb2_fileio_is_active(q)) { if (!q->is_output && (q->io_modes & VB2_READ) && (req_events & (POLLIN | POLLRDNORM))) { if (__vb2_init_fileio(q, 1)) return res | POLLERR; } if (q->is_output && (q->io_modes & VB2_WRITE) && (req_events & (POLLOUT | POLLWRNORM))) { if (__vb2_init_fileio(q, 0)) return res | POLLERR; /* * Write to OUTPUT queue can be done immediately. */ return res | POLLOUT | POLLWRNORM; } } /* * There is nothing to wait for if the queue isn't streaming, or if the * error flag is set. */ if (!vb2_is_streaming(q) || q->error) return res | POLLERR; /* * For compatibility with vb1: if QBUF hasn't been called yet, then * return POLLERR as well. This only affects capture queues, output * queues will always initialize waiting_for_buffers to false. */ if (q->waiting_for_buffers) return res | POLLERR; /* * For output streams you can call write() as long as there are fewer * buffers queued than there are buffers available. */ if (q->is_output && q->fileio && q->queued_count < q->num_buffers) return res | POLLOUT | POLLWRNORM; if (list_empty(&q->done_list)) { /* * If the last buffer was dequeued from a capture queue, * return immediately. DQBUF will return -EPIPE. */ if (q->last_buffer_dequeued) return res | POLLIN | POLLRDNORM; poll_wait(file, &q->done_wq, wait); } /* * Take first buffer available for dequeuing. */ spin_lock_irqsave(&q->done_lock, flags); if (!list_empty(&q->done_list)) vb = list_first_entry(&q->done_list, struct vb2_buffer, done_entry); spin_unlock_irqrestore(&q->done_lock, flags); if (vb && (vb->state == VB2_BUF_STATE_DONE || vb->state == VB2_BUF_STATE_ERROR)) { return (q->is_output) ? res | POLLOUT | POLLWRNORM : res | POLLIN | POLLRDNORM; } return res; }
/** * __vb2_perform_fileio() - perform a single file io (read or write) operation * @q: videobuf2 queue * @data: pointed to target userspace buffer * @count: number of bytes to read or write * @ppos: file handle position tracking pointer * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking) * @read: access mode selector (1 means read, 0 means write) */ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_t count, loff_t *ppos, int nonblock, int read) { struct vb2_fileio_data *fileio; struct vb2_fileio_buf *buf; bool is_multiplanar = q->is_multiplanar; /* * When using write() to write data to an output video node the vb2 core * should set timestamps if V4L2_BUF_FLAG_TIMESTAMP_COPY is set. Nobody * else is able to provide this information with the write() operation. */ bool set_timestamp = !read && (q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) == V4L2_BUF_FLAG_TIMESTAMP_COPY; int ret, index; dprintk(3, "mode %s, offset %ld, count %zd, %sblocking\n", read ? "read" : "write", (long)*ppos, count, nonblock ? "non" : ""); if (!data) return -EINVAL; /* * Initialize emulator on first call. */ if (!vb2_fileio_is_active(q)) { ret = __vb2_init_fileio(q, read); dprintk(3, "vb2_init_fileio result: %d\n", ret); if (ret) return ret; } fileio = q->fileio; /* * Check if we need to dequeue the buffer. */ index = fileio->cur_index; if (index >= q->num_buffers) { /* * Call vb2_dqbuf to get buffer back. */ memset(&fileio->b, 0, sizeof(fileio->b)); fileio->b.type = q->type; fileio->b.memory = q->memory; if (is_multiplanar) { memset(&fileio->p, 0, sizeof(fileio->p)); fileio->b.m.planes = &fileio->p; fileio->b.length = 1; } ret = vb2_internal_dqbuf(q, &fileio->b, nonblock); dprintk(5, "vb2_dqbuf result: %d\n", ret); if (ret) return ret; fileio->dq_count += 1; fileio->cur_index = index = fileio->b.index; buf = &fileio->bufs[index]; /* * Get number of bytes filled by the driver */ buf->pos = 0; buf->queued = 0; buf->size = read ? vb2_get_plane_payload(q->bufs[index], 0) : vb2_plane_size(q->bufs[index], 0); /* Compensate for data_offset on read in the multiplanar case. */ if (is_multiplanar && read && fileio->b.m.planes[0].data_offset < buf->size) { buf->pos = fileio->b.m.planes[0].data_offset; buf->size -= buf->pos; } } else { buf = &fileio->bufs[index]; } /* * Limit count on last few bytes of the buffer. */ if (buf->pos + count > buf->size) { count = buf->size - buf->pos; dprintk(5, "reducing read count: %zd\n", count); } /* * Transfer data to userspace. */ dprintk(3, "copying %zd bytes - buffer %d, offset %u\n", count, index, buf->pos); if (read) ret = copy_to_user(data, buf->vaddr + buf->pos, count); else ret = copy_from_user(buf->vaddr + buf->pos, data, count); if (ret) { dprintk(3, "error copying data\n"); return -EFAULT; } /* * Update counters. */ buf->pos += count; *ppos += count; /* * Queue next buffer if required. */ if (buf->pos == buf->size || (!read && fileio->write_immediately)) { /* * Check if this is the last buffer to read. */ if (read && fileio->read_once && fileio->dq_count == 1) { dprintk(3, "read limit reached\n"); return __vb2_cleanup_fileio(q); } /* * Call vb2_qbuf and give buffer to the driver. */ memset(&fileio->b, 0, sizeof(fileio->b)); fileio->b.type = q->type; fileio->b.memory = q->memory; fileio->b.index = index; fileio->b.bytesused = buf->pos; if (is_multiplanar) { memset(&fileio->p, 0, sizeof(fileio->p)); fileio->p.bytesused = buf->pos; fileio->b.m.planes = &fileio->p; fileio->b.length = 1; } if (set_timestamp) v4l2_get_timestamp(&fileio->b.timestamp); ret = vb2_internal_qbuf(q, &fileio->b); dprintk(5, "vb2_dbuf result: %d\n", ret); if (ret) return ret; /* * Buffer has been queued, update the status */ buf->pos = 0; buf->queued = 1; buf->size = vb2_plane_size(q->bufs[index], 0); fileio->q_count += 1; /* * If we are queuing up buffers for the first time, then * increase initial_index by one. */ if (fileio->initial_index < q->num_buffers) fileio->initial_index++; /* * The next buffer to use is either a buffer that's going to be * queued for the first time (initial_index < q->num_buffers) * or it is equal to q->num_buffers, meaning that the next * time we need to dequeue a buffer since we've now queued up * all the 'first time' buffers. */ fileio->cur_index = fileio->initial_index; } /* * Return proper number of bytes processed. */ if (ret == 0) ret = count; return ret; }