Ejemplo n.º 1
0
static int nxp_video_streamon(struct file *file, void *fh,
        enum v4l2_buf_type i)
{
    int ret;
    u32 pad;
    struct nxp_video *me = file->private_data;
    struct v4l2_subdev *subdev = _get_remote_subdev(me, i, &pad);
    void *hostdata_back;

     vmsg("%s: me %p, %s\n", __func__, me, me->name);

    if (me->vbq) {
        ret = vb2_streamon(me->vbq, i);
        if (ret < 0) {
            pr_err("%s: failed to vb2_streamon()\n", __func__);
            return ret;
        }
    } else {
        struct vb2_queue *vq = v4l2_m2m_get_vq(me->m2m_ctx, i);
        ret = vb2_streamon(vq, i);
        if (ret < 0) {
            pr_err("%s: m2m, failed to vb2_streamon()\n", __func__);
            return ret;
        }
    }

    /* for mlc subdev */
    hostdata_back = v4l2_get_subdev_hostdata(subdev);
    v4l2_set_subdev_hostdata(subdev, me->name);
    ret = v4l2_subdev_call(subdev, video, s_stream, 1);
    v4l2_set_subdev_hostdata(subdev, hostdata_back);
    return ret;
}
Ejemplo n.º 2
0
/* Stream on */
static int vidioc_streamon(struct file *file, void *priv,
			   enum v4l2_buf_type type)
{
	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
	int ret = -EINVAL;

	mfc_debug_enter();
	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
		ret = vb2_streamon(&ctx->vq_src, type);
	else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
		ret = vb2_streamon(&ctx->vq_dst, type);
	mfc_debug_leave();
	return ret;
}
Ejemplo n.º 3
0
static int gsc_capture_streamon(struct file *file, void *priv,
				enum v4l2_buf_type type)
{
	struct gsc_dev *gsc = video_drvdata(file);
	struct gsc_pipeline *p = &gsc->pipeline;
	int ret;

	if (gsc_cap_active(gsc))
		return -EBUSY;

	if (p->disp) {
		gsc_pm_qos_ctrl(gsc, GSC_QOS_ON, 267000, 200000);
		media_entity_pipeline_start(&p->disp->entity, p->pipe);
	} else if (p->sensor) {
		media_entity_pipeline_start(&p->sensor->entity, p->pipe);
	} else {
		gsc_err("Error pipeline");
		return -EPIPE;
	}

	ret = gsc_cap_link_validate(gsc);
	if (ret)
		return ret;

	gsc_hw_set_sw_reset(gsc);
	ret= gsc_wait_reset(gsc);
	if (ret < 0) {
		gsc_err("gscaler s/w reset timeout");
		return ret;
	}
	gsc_hw_set_output_buf_mask_all(gsc);
	return vb2_streamon(&gsc->cap.vbq, type);
}
Ejemplo n.º 4
0
static int gsc_capture_streamon(struct file *file, void *priv,
				enum v4l2_buf_type type)
{
	struct gsc_dev *gsc = video_drvdata(file);
	struct gsc_pipeline *p = &gsc->pipeline;
	int ret;

	if (gsc_cap_active(gsc))
		return -EBUSY;

	if (p->disp) {
		media_entity_pipeline_start(&p->disp->entity, p->pipe);
	} else if (p->sensor) {
		media_entity_pipeline_start(&p->sensor->entity, p->pipe);
	} else {
		gsc_err("Error pipeline");
		return -EPIPE;
	}

	ret = gsc_cap_link_validate(gsc);
	if (ret)
		return ret;

	return vb2_streamon(&gsc->cap.vbq, type);
}
static int mxr_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
	struct mxr_layer *layer = video_drvdata(file);
	struct mxr_device *mdev = layer->mdev;

	switch (layer->idx) {
	case 0:
		mdev->layer_en.graph0 = 1;
		break;
	case 1:
		mdev->layer_en.graph1 = 1;
		break;
	case 2:
		mdev->layer_en.graph2 = 1;
		break;
	case 3:
		mdev->layer_en.graph3 = 1;
		break;
	default:
		mxr_err(mdev, "invalid layer number\n");
		return -EINVAL;
	}

	if ((mdev->layer_en.graph0 && mdev->layer_en.graph2) ||
	    (mdev->layer_en.graph1 && mdev->layer_en.graph3)) {
		mdev->frame_packing = 1;
		mxr_dbg(mdev, "frame packing mode\n");
	}

	mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
	return vb2_streamon(&layer->vb_queue, i);
}
Ejemplo n.º 6
0
static int wfdioc_streamon(struct file *filp, void *fh,
		enum v4l2_buf_type i)
{
	int rc = 0;
	struct wfd_inst *inst = filp->private_data;
	unsigned long flags;
	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
		WFD_MSG_ERR("stream on for buffer type = %d is not "
			"supported.\n", i);
		return -EINVAL;
	}

	spin_lock_irqsave(&inst->inst_lock, flags);
	inst->streamoff = false;
	spin_unlock_irqrestore(&inst->inst_lock, flags);
	/*TODO: Do we need to lock the instance here*/
	rc = vb2_streamon(&inst->vid_bufq, i);
	if (rc) {
		WFD_MSG_ERR("videobuf_streamon failed with err = %d\n", rc);
		goto vidbuf_streamon_failed;
	}
	inst->mdp_task = kthread_run(mdp_output_thread, filp,
				"mdp_output_thread");
	if (IS_ERR(inst->mdp_task)) {
		rc = PTR_ERR(inst->mdp_task);
		goto mdp_task_failed;
	}
	return rc;
mdp_task_failed:
	vb2_streamoff(&inst->vid_bufq, i);
vidbuf_streamon_failed:
	return rc;
}
Ejemplo n.º 7
0
/*
 * Enable or disable the video buffers queue.
 *
 * The queue must be enabled before starting video acquisition and must be
 * disabled after stopping it. This ensures that the video buffers queue
 * state can be properly initialized before buffers are accessed from the
 * interrupt handler.
 *
 * Enabling the video queue returns -EBUSY if the queue is already enabled.
 *
 * Disabling the video queue cancels the queue and removes all buffers from
 * the main queue.
 *
 * This function can't be called from interrupt context. Use
 * uvc_queue_cancel() instead.
 */
int uvc_queue_enable(struct uvc_video_queue *queue, int enable)
{
	unsigned long flags;
	int ret;

	mutex_lock(&queue->mutex);
	if (enable) {
		ret = vb2_streamon(&queue->queue, queue->queue.type);
		if (ret < 0)
			goto done;

		queue->buf_used = 0;
	} else {
		ret = vb2_streamoff(&queue->queue, queue->queue.type);
		if (ret < 0)
			goto done;

		spin_lock_irqsave(&queue->irqlock, flags);
		INIT_LIST_HEAD(&queue->irqqueue);
		spin_unlock_irqrestore(&queue->irqlock, flags);
	}

done:
	mutex_unlock(&queue->mutex);
	return ret;
}
Ejemplo n.º 8
0
/*
 * Enable or disable the video buffers queue.
 *
 * The queue must be enabled before starting video acquisition and must be
 * disabled after stopping it. This ensures that the video buffers queue
 * state can be properly initialized before buffers are accessed from the
 * interrupt handler.
 *
 * Enabling the video queue initializes parameters (such as sequence number,
 * sync pattern, ...). If the queue is already enabled, return -EBUSY.
 *
 * Disabling the video queue cancels the queue and removes all buffers from
 * the main queue.
 *
 * This function can't be called from interrupt context. Use
 * uvcg_queue_cancel() instead.
 */
int uvcg_queue_enable(struct uvc_video_queue *queue, int enable)
{
	unsigned long flags;
	int ret = 0;

	mutex_lock(&queue->mutex);
	if (enable) {
		ret = vb2_streamon(&queue->queue, queue->queue.type);
		if (ret < 0)
			goto done;

		queue->sequence = 0;
		queue->buf_used = 0;
	} else {
		ret = vb2_streamoff(&queue->queue, queue->queue.type);
		if (ret < 0)
			goto done;

		spin_lock_irqsave(&queue->irqlock, flags);
		INIT_LIST_HEAD(&queue->irqqueue);

		/*
		 * FIXME: We need to clear the DISCONNECTED flag to ensure that
		 * applications will be able to queue buffers for the next
		 * streaming run. However, clearing it here doesn't guarantee
		 * that the device will be reconnected in the meantime.
		 */
		queue->flags &= ~UVC_QUEUE_DISCONNECTED;
		spin_unlock_irqrestore(&queue->irqlock, flags);
	}

done:
	mutex_unlock(&queue->mutex);
	return ret;
}
Ejemplo n.º 9
0
static int at91sam9x5_video_vidioc_streamon(struct file *filp,
		void *fh, enum v4l2_buf_type type)
{
	struct video_device *vdev = video_devdata(filp);
	struct at91sam9x5_video_priv *priv = video_get_drvdata(vdev);

	return vb2_streamon(&priv->queue, type);
}
Ejemplo n.º 10
0
static int fimc_is_isp_video_streamon(struct file *file, void *priv,
			     enum v4l2_buf_type type)
{
	struct fimc_is_dev *is_dev = video_drvdata(file);

	printk(KERN_DEBUG "%s\n", __func__);
	return vb2_streamon(&is_dev->video[FIMC_IS_VIDEO_NUM_BAYER].vbq, type);
}
Ejemplo n.º 11
0
int vb2_ioctl_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
	struct video_device *vdev = video_devdata(file);

	if (vb2_queue_is_busy(vdev, file))
		return -EBUSY;
	return vb2_streamon(vdev->queue, i);
}
Ejemplo n.º 12
0
int uvc_queue_streamon(struct uvc_video_queue *queue, enum v4l2_buf_type type)
{
	int ret;

	mutex_lock(&queue->mutex);
	ret = vb2_streamon(&queue->queue, type);
	mutex_unlock(&queue->mutex);

	return ret;
}
Ejemplo n.º 13
0
/* Stream on */
static int vidioc_streamon(struct file *file, void *priv,
			   enum v4l2_buf_type type)
{
	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
	struct s5p_mfc_dev *dev = ctx->dev;
	int ret = -EINVAL;

	mfc_debug_enter();
	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {

		if (ctx->state == MFCINST_INIT) {
			ctx->dst_bufs_cnt = 0;
			ctx->src_bufs_cnt = 0;
			ctx->capture_state = QUEUE_FREE;
			ctx->output_state = QUEUE_FREE;
			s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer,
					ctx);
			s5p_mfc_hw_call(dev->mfc_ops, alloc_dec_temp_buffers,
					ctx);
			set_work_bit_irqsave(ctx);
			s5p_mfc_clean_ctx_int_flags(ctx);
			s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);

			if (s5p_mfc_wait_for_done_ctx(ctx,
				S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) {
				/* Error or timeout */
				mfc_err("Error getting instance from hardware\n");
				s5p_mfc_hw_call(dev->mfc_ops,
						release_instance_buffer, ctx);
				s5p_mfc_hw_call(dev->mfc_ops,
						release_dec_desc_buffer, ctx);
				return -EIO;
			}
			mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
		}
		ret = vb2_streamon(&ctx->vq_src, type);
		}
	else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
		ret = vb2_streamon(&ctx->vq_dst, type);
	mfc_debug_leave();
	return ret;
}
Ejemplo n.º 14
0
static int
hwcam_dev_vo_streamon(
        struct file* filep,
        void* fh,
        enum v4l2_buf_type buf_type)
{
    hwcam_dev_t* cam = video_drvdata(filep);
	hwcam_user_t* user = VO2USER(fh);
	BUG_ON(!cam || !user);
    return vb2_streamon(&user->vb2q, buf_type);
}
static int gsc_capture_streamon(struct file *file, void *priv,
				enum v4l2_buf_type type)
{
	struct gsc_dev *gsc = video_drvdata(file);

	if (gsc_cap_active(gsc)) {
		gsc_err("gsc didn't stop complete");
		return -EBUSY;
	}

	return vb2_streamon(&gsc->cap.vbq, type);
}
Ejemplo n.º 16
0
/*
 * msm_fd_streamon - V4l2 ioctl stream on handler.
 * @file: Pointer to file struct.
 * @fh: V4l2 File handle.
 * @buf_type: V4l2 buffer type.
 */
static int msm_fd_streamon(struct file *file,
	void *fh, enum v4l2_buf_type buf_type)
{
	struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
	int ret;

	ret = vb2_streamon(&ctx->vb2_q, buf_type);
	if (ret < 0)
		dev_err(ctx->fd_device->dev, "Stream on fails\n");

	return ret;
}
Ejemplo n.º 17
0
/**
 * v4l2_m2m_streamon() - turn on streaming for a video queue
 */
int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
		      enum v4l2_buf_type type)
{
	struct vb2_queue *vq;
	int ret;

	vq = v4l2_m2m_get_vq(m2m_ctx, type);
	ret = vb2_streamon(vq, type);
	if (!ret)
		v4l2_m2m_try_schedule(m2m_ctx);

	return ret;
}
Ejemplo n.º 18
0
static int fimc_cap_streamon(struct file *file, void *priv,
                             enum v4l2_buf_type type)
{
    struct fimc_ctx *ctx = priv;
    struct fimc_dev *fimc = ctx->fimc_dev;

    if (fimc_capture_active(fimc) || !fimc->vid_cap.sd)
        return -EBUSY;

    if (!(ctx->state & FIMC_DST_FMT)) {
        v4l2_err(&fimc->vid_cap.v4l2_dev, "Format is not set\n");
        return -EINVAL;
    }

    return vb2_streamon(&fimc->vid_cap.vbq, type);
}
Ejemplo n.º 19
0
int fimc_is_video_streamon(struct file *file,
	struct fimc_is_video_ctx *vctx,
	enum v4l2_buf_type type)
{
	int ret = 0;
	struct vb2_queue *vbq;

	BUG_ON(!file);
	BUG_ON(!vctx);

	if (!(vctx->state & (BIT(FIMC_IS_VIDEO_S_BUFS) | BIT(FIMC_IS_VIDEO_STOP)))) {
		err("[V%02d] invalid streamon is requested(%lX)", vctx->video->id, vctx->state);
		return -EINVAL;
	}

	vbq = GET_QUEUE(vctx)->vbq;
	if (!vbq) {
		merr("vbq is NULL", vctx);
		ret = -EINVAL;
		goto p_err;
	}

	if (vbq->type != type) {
		merr("invalid stream type(%d != %d)", vctx, vbq->type, type);
		ret = -EINVAL;
		goto p_err;
	}

	if (vbq->streaming) {
		merr("streamon: already streaming", vctx);
		ret = -EINVAL;
		goto p_err;
	}

	ret = vb2_streamon(vbq, type);
	if (ret) {
		err("[V%02d] vb2_streamon is fail(%d)", vctx->video->id, ret);
		goto p_err;
	}

	vctx->state = BIT(FIMC_IS_VIDEO_START);

p_err:
	return ret;
}
static int camera_v4l2_streamon(struct file *filep, void *fh,
	enum v4l2_buf_type buf_type)
{
	struct v4l2_event event;
	int rc;
	struct camera_v4l2_private *sp = fh_to_private(fh);

	rc = vb2_streamon(&sp->vb2_q, buf_type);
	camera_pack_event(filep, MSM_CAMERA_SET_PARM,
		MSM_CAMERA_PRIV_STREAM_ON, -1, &event);

	rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
	if (rc < 0)
		return rc;

	rc = camera_check_event_status(&event);
	return rc;
}
Ejemplo n.º 21
0
/*
 * Enable or disable the video buffers queue.
 *
 * The queue must be enabled before starting video acquisition and must be
 * disabled after stopping it. This ensures that the video buffers queue
 * state can be properly initialized before buffers are accessed from the
 * interrupt handler.
 *
 * Enabling the video queue initializes parameters (such as sequence number,
 * sync pattern, ...). If the queue is already enabled, return -EBUSY.
 *
 * Disabling the video queue cancels the queue and removes all buffers from
 * the main queue.
 *
 * This function can't be called from interrupt context. Use
 * uvcg_queue_cancel() instead.
 */
int uvcg_queue_enable(struct uvc_video_queue *queue, int enable)
{
	unsigned long flags;
	int ret = 0;

	if (enable) {
		ret = vb2_streamon(&queue->queue, queue->queue.type);
		if (ret < 0)
			return ret;

		queue->sequence = 0;
		queue->buf_used = 0;
	} else {
		ret = vb2_streamoff(&queue->queue, queue->queue.type);
		if (ret < 0)
			return ret;

		spin_lock_irqsave(&queu
Ejemplo n.º 22
0
static int fimc_cap_streamon(struct file *file, void *priv,
			     enum v4l2_buf_type type)
{
	struct fimc_dev *fimc = video_drvdata(file);
	struct fimc_pipeline *p = &fimc->pipeline;
	int ret;

	if (fimc_capture_active(fimc))
		return -EBUSY;

	media_entity_pipeline_start(&p->sensor->entity, p->pipe);

	if (fimc->vid_cap.user_subdev_api) {
		ret = fimc_pipeline_validate(fimc);
		if (ret)
			return ret;
	}
	return vb2_streamon(&fimc->vid_cap.vbq, type);
}
Ejemplo n.º 23
0
static int
xvip_dma_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
{
	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_streamon(&dma->queue, type);

done:
	mutex_unlock(&dma->lock);
	return ret;
}
Ejemplo n.º 24
0
static int fimc_lite_streamon(struct file *file, void *priv,
			      enum v4l2_buf_type type)
{
	struct fimc_lite *fimc = video_drvdata(file);
	struct v4l2_subdev *sensor = fimc->pipeline.subdevs[IDX_SENSOR];
	struct fimc_pipeline *p = &fimc->pipeline;
	int ret;

	if (fimc_lite_active(fimc))
		return -EBUSY;

	ret = media_entity_pipeline_start(&sensor->entity, p->m_pipeline);
	if (ret < 0)
		return ret;

	ret = fimc_pipeline_validate(fimc);
	if (ret) {
		media_entity_pipeline_stop(&sensor->entity);
		return ret;
	}

	return vb2_streamon(&fimc->vb_queue, type);
}
int fimc_is_video_streamon(struct file *file,
	struct fimc_is_video_ctx *vctx,
	enum v4l2_buf_type type)
{
	int ret = 0;
	struct fimc_is_queue *queue;
	struct vb2_queue *vbq;

	BUG_ON(!file);
	BUG_ON(!vctx);

	queue = GET_QUEUE(vctx, type);
	vbq = queue->vbq;
	if (!vbq) {
		merr("vbq is NULL", vctx);
		ret = -EINVAL;
		goto p_err;
	}

	if (vbq->type != type) {
		merr("invalid stream type(%d != %d)", vctx, vbq->type, type);
		ret = -EINVAL;
		goto p_err;
	}

	if (vbq->streaming) {
		merr("streamon: already streaming", vctx);
		ret = -EINVAL;
		goto p_err;
	}

	ret = vb2_streamon(vbq, type);

p_err:
	return ret;
}
Ejemplo n.º 26
0
static int fimc_cap_streamon(struct file *file, void *priv,
			     enum v4l2_buf_type type)
{
	struct fimc_dev *fimc = video_drvdata(file);
	struct fimc_pipeline *p = &fimc->pipeline;
	struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR];
	int ret;

	if (fimc_capture_active(fimc))
		return -EBUSY;

	ret = media_entity_pipeline_start(&sd->entity, p->m_pipeline);
	if (ret < 0)
		return ret;

	if (fimc->vid_cap.user_subdev_api) {
		ret = fimc_pipeline_validate(fimc);
		if (ret < 0) {
			media_entity_pipeline_stop(&sd->entity);
			return ret;
		}
	}
	return vb2_streamon(&fimc->vid_cap.vbq, type);
}
static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
	struct vcap_client_data *c_data = file->private_data;
	int rc;

	dprintk(3, "In Stream ON\n");
	if (determine_mode(c_data) != c_data->op_mode) {
		pr_err("VCAP Error: %s: s_fmt called after req_buf", __func__);
		return -ENOTRECOVERABLE;
	}

	switch (c_data->op_mode) {
	case VC_VCAP_OP:
		c_data->dev->vc_client = c_data;
		config_vc_format(c_data);
		return vb2_streamon(&c_data->vc_vidq, i);
	case VP_VCAP_OP:
		rc = streamon_validate_q(&c_data->vp_in_vidq);
		if (rc < 0)
			return rc;
		rc = streamon_validate_q(&c_data->vp_out_vidq);
		if (rc < 0)
			return rc;

		c_data->dev->vp_client = c_data;

		rc = config_vp_format(c_data);
		if (rc < 0)
			return rc;
		rc = init_motion_buf(c_data);
		if (rc < 0)
			return rc;
		if (c_data->vid_vp_action.nr_enabled) {
			rc = init_nr_buf(c_data);
			if (rc < 0)
				goto s_on_deinit_m_buf;
		}

		c_data->vid_vp_action.vp_state = VP_FRAME1;

		rc = vb2_streamon(&c_data->vp_in_vidq,
				V4L2_BUF_TYPE_INTERLACED_IN_DECODER);
		if (rc < 0)
			goto s_on_deinit_nr_buf;

		rc = vb2_streamon(&c_data->vp_out_vidq,
				V4L2_BUF_TYPE_VIDEO_OUTPUT);
		if (rc < 0)
			goto s_on_deinit_nr_buf;
		return rc;
	case VC_AND_VP_VCAP_OP:
		rc = streamon_validate_q(&c_data->vc_vidq);
		if (rc < 0)
			return rc;
		rc = streamon_validate_q(&c_data->vp_in_vidq);
		if (rc < 0)
			return rc;
		rc = streamon_validate_q(&c_data->vp_out_vidq);
		if (rc < 0)
			return rc;

		c_data->dev->vc_client = c_data;
		c_data->dev->vp_client = c_data;
		c_data->dev->vc_to_vp_work.cd = c_data;

		rc = config_vc_format(c_data);
		if (rc < 0)
			return rc;
		rc = config_vp_format(c_data);
		if (rc < 0)
			return rc;
		rc = init_motion_buf(c_data);
		if (rc < 0)
			return rc;
		if (c_data->vid_vp_action.nr_enabled) {
			rc = init_nr_buf(c_data);
			if (rc < 0)
				goto s_on_deinit_m_buf;
		}
		c_data->streaming = 1;

		c_data->vid_vp_action.vp_state = VP_FRAME1;

		/* These stream on calls should not fail */
		rc = vb2_streamon(&c_data->vc_vidq,
				V4L2_BUF_TYPE_VIDEO_CAPTURE);
		if (rc < 0)
			goto s_on_deinit_nr_buf;

		rc = vb2_streamon(&c_data->vp_in_vidq,
				V4L2_BUF_TYPE_INTERLACED_IN_DECODER);
		if (rc < 0)
			goto s_on_deinit_nr_buf;

		rc = vb2_streamon(&c_data->vp_out_vidq,
				V4L2_BUF_TYPE_VIDEO_OUTPUT);
		if (rc < 0)
			goto s_on_deinit_nr_buf;
		return rc;
	default:
		pr_err("VCAP Error: %s: Operation Mode type", __func__);
		return -ENOTRECOVERABLE;
	}
	return 0;

s_on_deinit_nr_buf:
	if (c_data->vid_vp_action.nr_enabled)
		deinit_nr_buf(c_data);
s_on_deinit_m_buf:
	deinit_motion_buf(c_data);
	return rc;
}
Ejemplo n.º 28
0
/**
 * __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;
}
Ejemplo n.º 29
0
/**
 * __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;
}
Ejemplo n.º 30
0
static int myvivi_vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
	return vb2_streamon(&myvivi_vb_vidqueue, i);
}