stop_streaming() waits for all queued buffers to be finished. But SMFC
driver as a mem2mem device, may wait for the queued buffer of the
current vb2_queue while no buffer is queued in the other vb2_queue.
If .stop_streaming() is called in that situation, it waits for a
buffer to be queued to the other vb2_queue infinitely.
However it will never happen because no user will queue a buffer
during stopping operations on the device. Therefore, the driver
should see if other vb2_queue has a queued buffer when this vb2_queue
is stopping streaming. If the other vb2_queue has no queued buffer,
stop_streaming() should cancel all queued buffers in the current
vb2_queue.
Change-Id: I3b07916707a0b0d238a3238621fea631df8b942d
Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
static void smfc_vb2_stop_streaming(struct vb2_queue *vq)
{
+ struct smfc_ctx *ctx = vb2_get_drv_priv(vq);
+
+ if ((V4L2_TYPE_IS_OUTPUT(vq->type) &&
+ !v4l2_m2m_num_dst_bufs_ready(ctx->m2mctx)) ||
+ (!V4L2_TYPE_IS_OUTPUT(vq->type) &&
+ !v4l2_m2m_num_src_bufs_ready(ctx->m2mctx))) {
+ unsigned int i;
+ /* cancel all queued buffers */
+ for (i = 0; i < vq->num_buffers; ++i)
+ vb2_buffer_done(vq->bufs[i], VB2_BUF_STATE_ERROR);
+ }
+
vb2_wait_for_all_buffers(vq);
}