From patchwork Fri Mar 1 21:21:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19602 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 0E6C8C3260 for ; Fri, 1 Mar 2024 21:21:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A84B562B3D; Fri, 1 Mar 2024 22:21:37 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="XkoeKNse"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1C21262876 for ; Fri, 1 Mar 2024 22:21:36 +0100 (CET) Received: from pendragon.ideasonboard.com (89-27-53-110.bb.dnainternet.fi [89.27.53.110]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A60B2A9A; Fri, 1 Mar 2024 22:21:21 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1709328081; bh=A/vx4y0whQuSO5nLGsivMVu/Kx0cQsMGQuhbBsWnia0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XkoeKNseZEN9MMX0Y/V8QbrdKU340a6GRbfejF5UaI2jk56ID/ucR8m/A+Kf1IJz9 hlclj0e+b5ijjSqxwqQobZNCcUnxNual8FIUhvSGlP9n/yDXcahp8Xqj+aCpfL0/En 2fDqApccTghfbthZOn0vlOhaYuBtQuCX8Yy1rAKY= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH/RFC 11/32] libcamera: v4l2_subdevice: Update to the new kernel routing API Date: Fri, 1 Mar 2024 23:21:00 +0200 Message-ID: <20240301212121.9072-12-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240301212121.9072-1-laurent.pinchart@ideasonboard.com> References: <20240301212121.9072-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Sakari Ailus Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The subdev embedded data support series includes a change to the VIDIOC_SUBDEV_G_ROUTING and VIDIOC_SUBDEV_S_ROUTING ioctls that impacts the userspace API. Update to the new API. Backward compatibility can't be easily preserved as the ioctl structure size has changed. This is not a major issue, as the routing API isn't enabled in any upstream kernel. Signed-off-by: Laurent Pinchart --- src/libcamera/v4l2_subdevice.cpp | 43 ++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index 3653f57a7d10..d5d400cdfd58 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -1332,19 +1332,23 @@ int V4L2Subdevice::getRouting(Routing *routing, Whence whence) rt.which = whence; int ret = ioctl(VIDIOC_SUBDEV_G_ROUTING, &rt); - if (ret == 0 || ret == -ENOTTY) - return ret; - - if (ret != -ENOSPC) { - LOG(V4L2, Error) - << "Failed to retrieve number of routes: " - << strerror(-ret); + if (ret) { + if (ret != -ENOTTY) + LOG(V4L2, Error) + << "Failed to retrieve number of routes: " + << strerror(-ret); return ret; } + if (!rt.num_routes) + return 0; + std::vector routes{ rt.num_routes }; rt.routes = reinterpret_cast(routes.data()); + rt.len_routes = rt.num_routes; + rt.num_routes = 0; + ret = ioctl(VIDIOC_SUBDEV_G_ROUTING, &rt); if (ret) { LOG(V4L2, Error) @@ -1391,6 +1395,7 @@ int V4L2Subdevice::setRouting(Routing *routing, Whence whence) struct v4l2_subdev_routing rt = {}; rt.which = whence; + rt.len_routes = routes.size(); rt.num_routes = routes.size(); rt.routes = reinterpret_cast(routes.data()); @@ -1400,7 +1405,29 @@ int V4L2Subdevice::setRouting(Routing *routing, Whence whence) return ret; } - routes.resize(rt.num_routes); + /* + * The kernel wants to return more routes than we have space for. We + * need to issue a VIDIOC_SUBDEV_G_ROUTING call. + */ + if (rt.num_routes > routes.size()) { + routes.resize(rt.num_routes); + + rt.len_routes = rt.num_routes; + rt.num_routes = 0; + + ret = ioctl(VIDIOC_SUBDEV_G_ROUTING, &rt); + if (ret) { + LOG(V4L2, Error) + << "Failed to retrieve routes: " << strerror(-ret); + return ret; + } + } + + if (rt.num_routes != routes.size()) { + LOG(V4L2, Error) << "Invalid number of routes"; + return -EINVAL; + } + routing->resize(rt.num_routes); for (const auto &[i, route] : utils::enumerate(routes))