static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) { struct vcap_client_data *c_data = file->private_data; struct vb2_buffer *vb; struct vb2_queue *q; int rc; dprintk(3, "In Q Buf %08x\n", (unsigned int)p->type); switch (p->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: if (c_data->op_mode == VC_AND_VP_VCAP_OP) { /* If buffer in vp_in_q it will be coming back */ q = &c_data->vp_in_vidq; if (p->index >= q->num_buffers) { dprintk(1, "qbuf: buffer index out of range\n"); return -EINVAL; } vb = q->bufs[p->index]; if (NULL == vb) { dprintk(1, "qbuf: buffer is NULL\n"); return -EINVAL; } if (vb->state != VB2_BUF_STATE_DEQUEUED) { dprintk(1, "qbuf: buffer already in use\n"); return -EINVAL; } } rc = get_phys_addr(c_data->dev, &c_data->vc_vidq, p); if (rc < 0) return rc; rc = vb2_qbuf(&c_data->vc_vidq, p); if (rc < 0) free_ion_handle(c_data->dev, &c_data->vc_vidq, p); return rc; case V4L2_BUF_TYPE_INTERLACED_IN_DECODER: if (c_data->op_mode == VC_AND_VP_VCAP_OP) return -EINVAL; rc = get_phys_addr(c_data->dev, &c_data->vp_in_vidq, p); if (rc < 0) return rc; rc = vb2_qbuf(&c_data->vp_in_vidq, p); if (rc < 0) free_ion_handle(c_data->dev, &c_data->vp_in_vidq, p); return rc; case V4L2_BUF_TYPE_VIDEO_OUTPUT: rc = get_phys_addr(c_data->dev, &c_data->vp_out_vidq, p); if (rc < 0) return rc; rc = vb2_qbuf(&c_data->vp_out_vidq, p); if (rc < 0) free_ion_handle(c_data->dev, &c_data->vp_out_vidq, p); return rc; default: pr_err("VCAP Error: %s: Unknown buffer type\n", __func__); return -EINVAL; } return 0; }
static int nxp_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b) { struct nxp_video *me = file->private_data; pr_debug("%s: %s, index %d\n", __func__, me->name, b->index); if (me->vbq) { return vb2_qbuf(me->vbq, b); } else { struct vb2_queue *vq = v4l2_m2m_get_vq(me->m2m_ctx, b->type); return vb2_qbuf(vq, b); } }
/* Queue a buffer */ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); if (ctx->state == MFCINST_ERROR) { mfc_err("Call on QBUF after unrecoverable error\n"); return -EIO; } if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) return vb2_qbuf(&ctx->vq_src, buf); else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) return vb2_qbuf(&ctx->vq_dst, buf); return -EINVAL; }
static int iss_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b) { struct iss_video_fh *vfh = to_iss_video_fh(fh); return vb2_qbuf(&vfh->queue, b); }
static int fimc_lite_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { struct fimc_lite *fimc = video_drvdata(file); return vb2_qbuf(&fimc->vb_queue, buf); }
static int fimc_cap_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { struct fimc_ctx *ctx = priv; struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap; return vb2_qbuf(&cap->vbq, buf); }
int fimc_is_video_qbuf(struct file *file, struct fimc_is_video_ctx *vctx, struct v4l2_buffer *buf) { int ret = 0; struct fimc_is_queue *queue; struct vb2_queue *vbq; struct vb2_buffer *vb; BUG_ON(!file); BUG_ON(!vctx); BUG_ON(!buf); buf->flags &= ~V4L2_BUF_FLAG_USE_SYNC; queue = GET_VCTX_QUEUE(vctx, buf); vbq = queue->vbq; if (!vbq) { merr("vbq is NULL", vctx); ret = -EINVAL; goto p_err; } if (vbq->fileio) { merr("file io in progress", vctx); ret = -EBUSY; goto p_err; } if (buf->type != queue->vbq->type) { merr("buf type is invalid(%d != %d)", vctx, buf->type, queue->vbq->type); ret = -EINVAL; goto p_err; } if (buf->index >= vbq->num_buffers) { merr("buffer index%d out of range", vctx, buf->index); ret = -EINVAL; goto p_err; } if (buf->memory != vbq->memory) { merr("invalid memory type%d", vctx, buf->memory); ret = -EINVAL; goto p_err; } vb = vbq->bufs[buf->index]; if (!vb) { merr("vb is NULL", vctx); ret = -EINVAL; goto p_err; } ret = vb2_qbuf(queue->vbq, buf); p_err: return ret; }
/* * msm_fd_qbuf - V4l2 ioctl queue buffer handler. * @file: Pointer to file struct. * @fh: V4l2 File handle. * @pb: Pointer to v4l2_buffer struct. */ static int msm_fd_qbuf(struct file *file, void *fh, struct v4l2_buffer *pb) { struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh); return vb2_qbuf(&ctx->vb2_q, pb); }
static int fimc_cap_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { struct fimc_dev *fimc = video_drvdata(file); return vb2_qbuf(&fimc->vid_cap.vbq, buf); }
int vb2_ioctl_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) { struct video_device *vdev = video_devdata(file); if (vb2_queue_is_busy(vdev, file)) return -EBUSY; return vb2_qbuf(vdev->queue, p); }
static int gsc_capture_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { struct gsc_dev *gsc = video_drvdata(file); struct gsc_capture_device *cap = &gsc->cap; return vb2_qbuf(&cap->vbq, buf); }
static int at91sam9x5_video_vidioc_qbuf(struct file *filp, void *fh, struct v4l2_buffer *b) { struct video_device *vdev = filp->private_data; struct at91sam9x5_video_priv *priv = video_get_drvdata(vdev); return vb2_qbuf(&priv->queue, b); }
static int fimc_is_isp_video_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { struct fimc_is_video_dev *video = file->private_data; printk(KERN_DEBUG "%s\n", __func__); return vb2_qbuf(&video->vbq, buf); }
int uvc_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf) { int ret; mutex_lock(&queue->mutex); ret = vb2_qbuf(&queue->queue, buf); mutex_unlock(&queue->mutex); return ret; }
static int hwcam_dev_vo_qbuf( struct file* filep, void* fh, struct v4l2_buffer* pb) { hwcam_dev_t* cam = video_drvdata(filep); hwcam_user_t* user = VO2USER(fh); BUG_ON(!cam || !user); return vb2_qbuf(&user->vb2q, pb); }
/** * v4l2_m2m_qbuf() - enqueue a source or destination buffer, depending on * the type */ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf) { struct vb2_queue *vq; int ret; vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); ret = vb2_qbuf(vq, buf); if (!ret) v4l2_m2m_try_schedule(m2m_ctx); return ret; }
int uvcg_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf) { unsigned long flags; int ret; ret = vb2_qbuf(&queue->queue, buf); if (ret < 0) return ret; spin_lock_irqsave(&queue->irqlock, flags); ret = (queue->flags & UVC_QUEUE_PAUSED) != 0; queue->flags &= ~UVC_QUEUE_PAUSED; spin_unlock_irqrestore(&queue->irqlock, flags); return ret; }
static int camera_v4l2_qbuf(struct file *filep, void *fh, struct v4l2_buffer *pb) { int ret; struct msm_session *session; struct camera_v4l2_private *sp = fh_to_private(fh); struct msm_video_device *pvdev = video_drvdata(filep); unsigned int session_id = pvdev->vdev->num; session = msm_session_find(session_id); if (WARN_ON(!session)) return -EIO; mutex_lock(&session->lock); ret = vb2_qbuf(&sp->vb2_q, pb); mutex_unlock(&session->lock); return ret; }
static int xvip_dma_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct v4l2_fh *vfh = file->private_data; struct xvip_dma *dma = to_xvip_dma(vfh->vdev); int ret; mutex_lock(&dma->lock); if (dma->queue.owner && dma->queue.owner != vfh) { ret = -EBUSY; goto done; } ret = vb2_qbuf(&dma->queue, buf); done: mutex_unlock(&dma->lock); return ret; }
static int wfdioc_qbuf(struct file *filp, void *fh, struct v4l2_buffer *b) { int rc = 0; struct wfd_inst *inst = filp->private_data; if (!inst || !b || !b->reserved || (b->index < 0 || b->index >= inst->buf_count)) { WFD_MSG_ERR("Invalid input parameters to QBUF IOCTL\n"); return -EINVAL; } if (!inst->vid_bufq.streaming) { if (copy_from_user(inst->minfo[b->index], (void *)b->reserved, sizeof(struct mem_info))) { WFD_MSG_ERR(" copy_from_user failed. Populate" " v4l2_buffer->reserved with meminfo\n"); return -EINVAL; } } rc = vb2_qbuf(&inst->vid_bufq, b); if (rc) WFD_MSG_ERR("Failed to queue buffer\n"); return rc; }
static int mxr_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) { struct mxr_layer *layer = video_drvdata(file); return vb2_qbuf(&layer->vb_queue, p); }
static int __vb2_init_fileio(struct vb2_queue *q, int read) { struct vb2_fileio_data *fileio; int i, ret; unsigned int count = 0; if ((read && !(q->io_modes & VB2_READ)) || (!read && !(q->io_modes & VB2_WRITE))) BUG(); if (!q->mem_ops->vaddr) return -EBUSY; if (q->streaming || q->num_buffers > 0) return -EBUSY; count = 1; dprintk(3, "setting up file io: mode %s, count %d, flags %08x\n", (read) ? "read" : "write", count, q->io_flags); fileio = kzalloc(sizeof(struct vb2_fileio_data), GFP_KERNEL); if (fileio == NULL) return -ENOMEM; fileio->flags = q->io_flags; fileio->req.count = count; fileio->req.memory = V4L2_MEMORY_MMAP; fileio->req.type = q->type; ret = vb2_reqbufs(q, &fileio->req); if (ret) goto err_kfree; if (q->bufs[0]->num_planes != 1) { fileio->req.count = 0; ret = -EBUSY; goto err_reqbufs; } for (i = 0; i < q->num_buffers; i++) { fileio->bufs[i].vaddr = vb2_plane_vaddr(q->bufs[i], 0); if (fileio->bufs[i].vaddr == NULL) goto err_reqbufs; fileio->bufs[i].size = vb2_plane_size(q->bufs[i], 0); } if (read) { for (i = 0; i < q->num_buffers; i++) { struct v4l2_buffer *b = &fileio->b; memset(b, 0, sizeof(*b)); b->type = q->type; b->memory = q->memory; b->index = i; ret = vb2_qbuf(q, b); if (ret) goto err_reqbufs; fileio->bufs[i].queued = 1; } ret = vb2_streamon(q, q->type); if (ret) goto err_reqbufs; } q->fileio = fileio; return ret; err_reqbufs: vb2_reqbufs(q, &fileio->req); err_kfree: kfree(fileio); return ret; }
/** * __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; int ret, index; dprintk(3, "file io: 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 (!q->fileio) { ret = __vb2_init_fileio(q, read); dprintk(3, "file io: vb2_init_fileio result: %d\n", ret); if (ret) return ret; } fileio = q->fileio; /* * Hack fileio context to enable direct calls to vb2 ioctl interface. * The pointer will be restored before returning from this function. */ q->fileio = NULL; index = fileio->index; buf = &fileio->bufs[index]; /* * Check if we need to dequeue the buffer. */ if (buf->queued) { struct vb2_buffer *vb; /* * Call vb2_dqbuf to get buffer back. */ memset(&fileio->b, 0, sizeof(fileio->b)); fileio->b.type = q->type; fileio->b.memory = q->memory; fileio->b.index = index; ret = vb2_dqbuf(q, &fileio->b, nonblock); dprintk(5, "file io: vb2_dqbuf result: %d\n", ret); if (ret) goto end; fileio->dq_count += 1; /* * Get number of bytes filled by the driver */ vb = q->bufs[index]; buf->size = vb2_get_plane_payload(vb, 0); buf->queued = 0; } /* * 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, "file io: 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, "file io: error copying data\n"); ret = -EFAULT; goto end; } /* * Update counters. */ buf->pos += count; *ppos += count; /* * Queue next buffer if required. */ if (buf->pos == buf->size || (!read && (fileio->flags & VB2_FILEIO_WRITE_IMMEDIATELY))) { /* * Check if this is the last buffer to read. */ if (read && (fileio->flags & VB2_FILEIO_READ_ONCE) && fileio->dq_count == 1) { dprintk(3, "file io: read limit reached\n"); /* * Restore fileio pointer and release the context. */ q->fileio = fileio; 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; ret = vb2_qbuf(q, &fileio->b); dprintk(5, "file io: vb2_dbuf result: %d\n", ret); if (ret) goto end; /* * Buffer has been queued, update the status */ buf->pos = 0; buf->queued = 1; buf->size = q->bufs[0]->v4l2_planes[0].length; fileio->q_count += 1; /* * Switch to the next buffer */ fileio->index = (index + 1) % q->num_buffers; /* * Start streaming if required. */ if (!read && !q->streaming) { ret = vb2_streamon(q, q->type); if (ret) goto end; } } /* * Return proper number of bytes processed. */ if (ret == 0) ret = count; end: /* * Restore the fileio context and block vb2 ioctl interface. */ q->fileio = fileio; return ret; }
/** * __vb2_init_fileio() - initialize file io emulator * @q: videobuf2 queue * @read: mode selector (1 means read, 0 means write) */ static int __vb2_init_fileio(struct vb2_queue *q, int read) { struct vb2_fileio_data *fileio; int i, ret; unsigned int count = 0; /* * Sanity check */ if ((read && !(q->io_modes & VB2_READ)) || (!read && !(q->io_modes & VB2_WRITE))) BUG(); /* * Check if device supports mapping buffers to kernel virtual space. */ if (!q->mem_ops->vaddr) return -EBUSY; /* * Check if streaming api has not been already activated. */ if (q->streaming || q->num_buffers > 0) return -EBUSY; /* * Start with count 1, driver can increase it in queue_setup() */ count = 1; dprintk(3, "setting up file io: mode %s, count %d, flags %08x\n", (read) ? "read" : "write", count, q->io_flags); fileio = kzalloc(sizeof(struct vb2_fileio_data), GFP_KERNEL); if (fileio == NULL) return -ENOMEM; fileio->flags = q->io_flags; /* * Request buffers and use MMAP type to force driver * to allocate buffers by itself. */ fileio->req.count = count; fileio->req.memory = V4L2_MEMORY_MMAP; fileio->req.type = q->type; ret = vb2_reqbufs(q, &fileio->req); if (ret) goto err_kfree; /* * Check if plane_count is correct * (multiplane buffers are not supported). */ if (q->bufs[0]->num_planes != 1) { fileio->req.count = 0; ret = -EBUSY; goto err_reqbufs; } /* * Get kernel address of each buffer. */ for (i = 0; i < q->num_buffers; i++) { fileio->bufs[i].vaddr = vb2_plane_vaddr(q->bufs[i], 0); if (fileio->bufs[i].vaddr == NULL) goto err_reqbufs; fileio->bufs[i].size = vb2_plane_size(q->bufs[i], 0); } /* * Read mode requires pre queuing of all buffers. */ if (read) { /* * Queue all buffers. */ for (i = 0; i < q->num_buffers; i++) { struct v4l2_buffer *b = &fileio->b; memset(b, 0, sizeof(*b)); b->type = q->type; b->memory = q->memory; b->index = i; ret = vb2_qbuf(q, b); if (ret) goto err_reqbufs; fileio->bufs[i].queued = 1; } /* * Start streaming. */ ret = vb2_streamon(q, q->type); if (ret) goto err_reqbufs; } q->fileio = fileio; return ret; err_reqbufs: vb2_reqbufs(q, &fileio->req); err_kfree: kfree(fileio); return ret; }
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; int ret, index; dprintk(3, "file io: mode %s, offset %ld, count %zd, %sblocking\n", read ? "read" : "write", (long)*ppos, count, nonblock ? "non" : ""); if (!data) return -EINVAL; if (!q->fileio) { ret = __vb2_init_fileio(q, read); dprintk(3, "file io: vb2_init_fileio result: %d\n", ret); if (ret) return ret; } fileio = q->fileio; q->fileio = NULL; index = fileio->index; buf = &fileio->bufs[index]; if (buf->queued) { struct vb2_buffer *vb; memset(&fileio->b, 0, sizeof(fileio->b)); fileio->b.type = q->type; fileio->b.memory = q->memory; fileio->b.index = index; ret = vb2_dqbuf(q, &fileio->b, nonblock); dprintk(5, "file io: vb2_dqbuf result: %d\n", ret); if (ret) goto end; fileio->dq_count += 1; vb = q->bufs[index]; buf->size = vb2_get_plane_payload(vb, 0); buf->queued = 0; } if (buf->pos + count > buf->size) { count = buf->size - buf->pos; dprintk(5, "reducing read count: %zd\n", count); } dprintk(3, "file io: 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, "file io: error copying data\n"); ret = -EFAULT; goto end; } buf->pos += count; *ppos += count; if (buf->pos == buf->size || (!read && (fileio->flags & VB2_FILEIO_WRITE_IMMEDIATELY))) { if (read && (fileio->flags & VB2_FILEIO_READ_ONCE) && fileio->dq_count == 1) { dprintk(3, "file io: read limit reached\n"); q->fileio = fileio; return __vb2_cleanup_fileio(q); } 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; ret = vb2_qbuf(q, &fileio->b); dprintk(5, "file io: vb2_dbuf result: %d\n", ret); if (ret) goto end; buf->pos = 0; buf->queued = 1; buf->size = q->bufs[0]->v4l2_planes[0].length; fileio->q_count += 1; fileio->index = (index + 1) % q->num_buffers; if (!read && !q->streaming) { ret = vb2_streamon(q, q->type); if (ret) goto end; } } if (ret == 0) ret = count; end: q->fileio = fileio; return ret; }
/* 将buffer放入队列 */ static int myvivi_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) { return vb2_qbuf(&myvivi_vb_vidqueue, p); }