Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp3838336yba; Mon, 29 Apr 2019 09:19:15 -0700 (PDT) X-Google-Smtp-Source: APXvYqz8sY6EWVhNiVV1UBD0UAbd/pUbQhRfT7IjqtdR1WWfLlvpqLzvyZxbGCoEHPetcjleN6Bl X-Received: by 2002:a17:902:1d4a:: with SMTP id u10mr36631008plu.272.1556554755460; Mon, 29 Apr 2019 09:19:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1556554755; cv=none; d=google.com; s=arc-20160816; b=CLTL0IBkFiHdERrWCOhPwI7AlgQlZTSByZdhY8wJ9b4J8xtsN5KDZJmAWP/7bIe+6o SM3em05+5wP/yEKPyO2HgiLauEkj547oiDYl8jgyVjqaGzut2CHacPxhI8/fDL2KbS91 GBwdKlqa00ds2+NEzqJWeYwQ0WM64ZN7rEbfulV6MNH/wvvoMYyImV5qFaZFuawWN2i2 9kF2L6UU+Hp8D0btc4xh1QC5MNRNQR7JdzLkboSAqHvYVoezJSWVjviFeIBVpEc+asfc etXFGIUWHzqoUnahNUBu1Woe9k8HN6HH3VKbXihK0LueKj2K8/fQBZRvgQAA5emHwqHL noFQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=QagX9VfNAn+aqZtriRl20OfrJt/QUcgokSFjYB2jX3A=; b=V22aqh1mS2LjkjdASynlK1pVtRJjJyD9vDi93jUiXK8JN3R+8raZseg9y1OxIeN8Rm oxOUl35HQleC4FIRDER6AAqPcvNQdGeRhZU/1o8IvuDbFtQOTUH0sc/yrfUEQQ+w3JNU RcYJlfyKG/8T2L2OgeXBIOcYvAeSi7OBFBT+UiXoSESYZsFMs0LMa8K3D/sX0k4SvK1N fBa804Wt+5PuEViJcr2ix7gJsTQlABdWJ8CuXVIUu+RpwqUJ3u7dTFsy+rz+NExPibyr vacD0b8K4nDs/3nE49beJjJXeJvwfpIjwF6ZKYzhN3A0N5X6muQzadideFXjpec4QRvQ vfNg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e22si30967356pgv.323.2019.04.29.09.18.59; Mon, 29 Apr 2019 09:19:15 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728861AbfD2QRi (ORCPT + 99 others); Mon, 29 Apr 2019 12:17:38 -0400 Received: from vps-vb.mhejs.net ([37.28.154.113]:56322 "EHLO vps-vb.mhejs.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728846AbfD2QRg (ORCPT ); Mon, 29 Apr 2019 12:17:36 -0400 Received: from MUA by vps-vb.mhejs.net with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1hL8yE-0002q5-Bc; Mon, 29 Apr 2019 18:17:34 +0200 From: "Maciej S. Szmigiero" To: Michael Krufky , Mauro Carvalho Chehab Cc: Andy Walls , linux-kernel , linux-media@vger.kernel.org, Hans Verkuil Subject: [PATCH v12 5/8] cx25840: set_fmt operation should clamp out-of-range picture sizes Date: Mon, 29 Apr 2019 18:16:56 +0200 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org According to V4L2 API set_fmt subdev operation should not return an error on out-of-range picture sizes, the values should be clamped instead to the supported range. The cx25840 datasheet says that the chip is capable of scaling down the picture width and height, respectively, 16 and 8 times. These values agree with what the old implementation enforced. Signed-off-by: Maciej S. Szmigiero --- drivers/media/i2c/cx25840/cx25840-core.c | 59 ++++++++++++++++-------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index f03bd637b795..371ac6bb265a 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -1702,7 +1702,8 @@ static int cx25840_set_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt = &format->format; struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - int HSC, VSC, Vsrc, Hsrc, filter, Vlines; + u32 HSC, VSC, Vsrc, Hsrc, Vadd; + int filter; int is_50Hz = !(state->std & V4L2_STD_525_60); if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED) @@ -1727,28 +1728,46 @@ static int cx25840_set_fmt(struct v4l2_subdev *sd, Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4; } - Vlines = fmt->height; - if (!state->generic_mode) - Vlines += is_50Hz ? 4 : 7; + if (!state->generic_mode) { + Vadd = is_50Hz ? 4 : 7; - /* - * We keep 1 margin for the Vsrc < Vlines check since the - * cx23888 reports a Vsrc of 486 instead of 487 for the NTSC - * height. Without that margin the cx23885 fails in this - * check. - */ - if ((fmt->width == 0) || (Vlines == 0) || - (fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) || - (Vlines * 8 < Vsrc) || (Vsrc + 1 < Vlines)) { - v4l_err(client, "%dx%d is not a valid size!\n", - fmt->width, fmt->height); - return -ERANGE; + /* + * cx23888 in 525-line mode is programmed for 486 active lines + * while other chips use 487 active lines. + * + * See reg 0x428 bits [21:12] in cx23888_std_setup() vs + * vactive in cx25840_std_setup(). + */ + if (is_cx23888(state) && !is_50Hz) + Vadd--; + } else + Vadd = 0; + + if (Hsrc == 0 || + Vsrc <= Vadd) { + v4l_err(client, + "chip reported picture size (%u x %u) is far too small\n", + (unsigned int)Hsrc, (unsigned int)Vsrc); + /* + * that's the best we can do since the output picture + * size is completely unknown in this case + */ + return -EINVAL; } + + fmt->width = clamp(fmt->width, (Hsrc + 15) / 16, Hsrc); + + if (Vadd * 8 >= Vsrc) + fmt->height = clamp(fmt->height, (u32)1, Vsrc - Vadd); + else + fmt->height = clamp(fmt->height, (Vsrc - Vadd * 8 + 7) / 8, + Vsrc - Vadd); + if (format->which == V4L2_SUBDEV_FORMAT_TRY) return 0; HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20); - VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); + VSC = (1 << 16) - (Vsrc * (1 << 9) / (fmt->height + Vadd) - (1 << 9)); VSC &= 0x1fff; if (fmt->width >= 385) @@ -1760,8 +1779,10 @@ static int cx25840_set_fmt(struct v4l2_subdev *sd, else filter = 3; - v4l_dbg(1, cx25840_debug, client, "decoder set size %dx%d -> scale %ux%u\n", - fmt->width, fmt->height, HSC, VSC); + v4l_dbg(1, cx25840_debug, client, + "decoder set size %u x %u with scale %x x %x\n", + (unsigned int)fmt->width, (unsigned int)fmt->height, + (unsigned int)HSC, (unsigned int)VSC); /* HSCALE=HSC */ if (is_cx23888(state)) {