Re: [PATCH v6 12/18] media: intel/ipu6: input system video nodes and buffer queues

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Hans,

Thank you for the review.

On Sat, Apr 27, 2024 at 05:44:48PM +0200, Hans Verkuil wrote:
...
> > +static int queue_setup(struct vb2_queue *q, unsigned int *num_buffers,
> > +		       unsigned int *num_planes, unsigned int sizes[],
> > +		       struct device *alloc_devs[])
> > +{
> > +	struct ipu6_isys_queue *aq = vb2_queue_to_isys_queue(q);
> > +	struct ipu6_isys_video *av = ipu6_isys_queue_to_video(aq);
> > +	struct device *dev = &av->isys->adev->auxdev.dev;
> > +	u32 size = av->pix_fmt.sizeimage;
> > +
> > +	/* num_planes == 0: we're being called through VIDIOC_REQBUFS */
> > +	if (!*num_planes) {
> > +		sizes[0] = size;
> > +	} else if (sizes[0] < size) {
> > +		dev_err(dev, "%s: queue setup: size %u < %u\n",
> > +			av->vdev.name, sizes[0], size);
> > +		return -EINVAL;
> > +	}
> > +
> > +	*num_planes = 1;
> > +	alloc_devs[0] = aq->dev;
> 
> Don't set this. This is already done by the vb2 core. Setting this is only
> necessary for very weird hardware that uses a different device per plane.

I'll drop this from v7.

> > +static int start_streaming(struct vb2_queue *q, unsigned int count)
> > +{
> > +	struct ipu6_isys_queue *aq = vb2_queue_to_isys_queue(q);
> > +	struct ipu6_isys_video *av = ipu6_isys_queue_to_video(aq);
> > +	struct device *dev = &av->isys->adev->auxdev.dev;
> > +	struct ipu6_isys_buffer_list __bl, *bl = NULL;
> > +	struct ipu6_isys_stream *stream;
> > +	struct media_entity *source_entity = NULL;
> > +	int nr_queues, ret;
> > +
> > +	dev_dbg(dev, "stream: %s: width %u, height %u, css pixelformat %u\n",
> > +		av->vdev.name, av->pix_fmt.width, av->pix_fmt.height,
> > +		av->pfmt->css_pixelformat);
> > +
> > +	ret = ipu6_isys_setup_video(av, &source_entity, &nr_queues);
> > +	if (ret < 0) {
> > +		dev_err(dev, "failed to setup video\n");
> > +		goto out_return_buffers;
> > +	}
> > +
> > +	ret = ipu6_isys_link_fmt_validate(aq);
> > +	if (ret) {
> > +		dev_err(dev,
> > +			"%s: link format validation failed (%d)\n",
> > +			av->vdev.name, ret);
> > +		goto out_pipeline_stop;
> > +	}
> > +
> > +	ret = ipu6_isys_fw_open(av->isys);
> > +	if (ret)
> > +		goto out_pipeline_stop;
> > +
> > +	stream = av->stream;
> > +	mutex_lock(&stream->mutex);
> > +	if (!stream->nr_streaming) {
> > +		ret = ipu6_isys_video_prepare_stream(av, source_entity,
> > +						     nr_queues);
> > +		if (ret)
> > +			goto out_fw_close;
> > +	}
> > +
> > +	stream->nr_streaming++;
> > +	dev_dbg(dev, "queue %u of %u\n", stream->nr_streaming,
> > +		stream->nr_queues);
> > +
> > +	list_add(&aq->node, &stream->queues);
> > +	ipu6_isys_set_csi2_streams_status(av, true);
> > +	ipu6_isys_configure_stream_watermark(av, true);
> > +	ipu6_isys_update_stream_watermark(av, true);
> > +
> > +	if (stream->nr_streaming != stream->nr_queues)
> > +		goto out;
> > +
> > +	bl = &__bl;
> > +	ret = buffer_list_get(stream, bl);
> > +	if (ret < 0) {
> > +		dev_dbg(dev,
> > +			"no buffer available, postponing streamon\n");
> 
> You can ensure that start_streaming is only called when there is at least
> one buffer queued by setting q->min_queued_buffers to 1 in ipu6_isys_queue_init().
> That is the recommended method for dealing with such requirements.

Ack.

I'll still leave this as a sanity check and turn it into an error.

> 
> > +		goto out;
> > +	}
> > +
> > +	ret = ipu6_isys_stream_start(av, bl, false);
> > +	if (ret)
> > +		goto out_stream_start;
> > +
> > +out:
> > +	mutex_unlock(&stream->mutex);
> > +
> > +	return 0;
> > +
> > +out_stream_start:
> > +	ipu6_isys_update_stream_watermark(av, false);
> > +	list_del(&aq->node);
> > +	stream->nr_streaming--;
> > +
> > +out_fw_close:
> > +	mutex_unlock(&stream->mutex);
> > +	ipu6_isys_fw_close(av->isys);
> > +
> > +out_pipeline_stop:
> > +	ipu6_isys_stream_cleanup(av);
> > +
> > +out_return_buffers:
> > +	return_buffers(aq, VB2_BUF_STATE_QUEUED);
> > +
> > +	return ret;
> > +}

...

> > +static int vidioc_s_fmt_vid_cap(struct file *file, void *fh,
> > +				struct v4l2_format *f)
> > +{
> > +	struct ipu6_isys_video *av = video_drvdata(file);
> > +
> > +	if (av->aq.vbq.streaming)
> 
> This should call vb2_is_busy() instead of checking the streaming flag.
> 
> I'm pretty sure v4l2-compliance checks for that, but perhaps the current
> FAILs prevented it from getting that far.
> 
> According to the cover letter, those FAILs in v4l2-compliance are because
> of a limitation in v4l2-compliance: that should be fixed so that this
> driver can pass the full v4l2-compliance test. I suspect that not doing that
> causes this issue to be missed.

I'll switch to vb2_is_busy() in v7.

-- 
Kind regards,

Sakari Ailus




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux