From 9a0a32036b655784a8538d87d9b85daa0b7f7710 Mon Sep 17 00:00:00 2001 From: ayaka Date: Fri, 6 May 2016 18:11:22 -0400 Subject: s5p-mfc: don't close instance after free OUTPUT buffers User-space applications can use the VIDIOC_REQBUFS ioctl to determine if a memory mapped, user pointer or DMABUF based I/O is supported by the driver. So a set of VIDIOC_REQBUFS ioctl calls will be made with count 0 and then the real VIDIOC_REQBUFS call with count == n. But for count 0, the driver not only frees the buffer but also closes the MFC instance and s5p_mfc_ctx state is set to MFCINST_FREE. The VIDIOC_REQBUFS handler for the output device checks if the s5p_mfc_ctx state is set to MFCINST_INIT (which happens on an VIDIOC_S_FMT) and fails otherwise. So after a VIDIOC_REQBUFS(n), future VIDIOC_REQBUFS(n) calls will fails unless a VIDIOC_S_FMT ioctl calls happens before the reqbufs. But applications may first set the format and then attempt to determine the I/O methods supported by the driver (for example Gstramer does it) so the state won't be set to MFCINST_INIT again and VIDIOC_REQBUFS will fail. To avoid this issue, only free the buffers on VIDIOC_REQBUFS(0) but don't close the MFC instance to allow future VIDIOC_REQBUFS(n) calls to succeed. [javier: Rewrote changelog to explain the problem more detailed] Signed-off-by: ayaka Signed-off-by: Javier Martinez Canillas Acked-by: Nicolas Dufresne Tested-by: Marek Szyprowski Acked-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab [backport of mainline commit 9bd5d8696fd50a10d830e2ad7f9d4e67e0bbbae2] Signed-of-by: Marek Szyprowski Change-Id: I9bd5d8696fd50a10d830e2ad7f9d4e67e0bbbae2 --- drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index 73d7e0fa7619..1828e837c1c4 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c @@ -474,7 +474,6 @@ static int reqbufs_output(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx, ret = vb2_reqbufs(&ctx->vq_src, reqbufs); if (ret) goto out; - s5p_mfc_close_mfc_inst(dev, ctx); ctx->src_bufs_cnt = 0; ctx->output_state = QUEUE_FREE; } else if (ctx->output_state == QUEUE_FREE) { -- cgit v1.2.3