Received: by 2002:ab2:6857:0:b0:1ef:ffd0:ce49 with SMTP id l23csp487023lqp; Thu, 21 Mar 2024 07:14:59 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCXVB740f1Bb6aCnDk/6WSNhM7nKi04mABt6pKiYZ0pZDLpAPy5rxRreNbUUf9xBfaz/PEfntDK3//EUY/gEW6K94MnAzemVu1iLlsyjnA== X-Google-Smtp-Source: AGHT+IEFbttoA6+WXY1i5z+Af5fsRcVmG6Lzr0ejnrK2RE6cIm+ydFjpgakAefUJ8FX2KkpRVgHt X-Received: by 2002:a05:620a:40d0:b0:788:5e6f:53d0 with SMTP id g16-20020a05620a40d000b007885e6f53d0mr7051227qko.44.1711030499126; Thu, 21 Mar 2024 07:14:59 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1711030499; cv=pass; d=google.com; s=arc-20160816; b=Eg0UOI9XNUYnjcdBDA4QuVGgeMSvFS8lxrPugSzO3KXMTrIfKsOBeerpv0nvR8uUcA wrnzotddE0JsSyfpkAodDVjtcL/flXrgYSsLYW9+9k5DonBzQnyPcmGWm1cLzuc7DOEM IffwwwDte6lUim3VDDWvF0vYKAlObAKhD8HpA78UHVaoJe2C+Fh6L0e9+5+DsuHjR6GC mpUfhEplxHzM4gLB2Avqfb1Q3tbiboq1uyJKewRDIEw/l1QrsQymIS0smFNjqoVyTH0R Z8qgJLtfyk/PIw4fSoJvzojU67uYUqexMjy5kuIF5vFMOEhKBTBS0SVM4cZpnnB3IwUk FvWQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :subject:cc:to:from:date:dkim-signature; bh=N0H+eGN0Jw87qvS83zkoOG1FuQh8WdJhK+6mZx+pdrk=; fh=HXJ4WdWAz9u5jZKNTzTfhGSlMZZq4N5151a/CsolYBg=; b=dIcyrcOp9JCSWeBE4WpXgqUD8e7mwB1N1ns2LvhzG1eiMIN8Yo5X0bQxKI2aUtqPZo rQcyW7/NGtNcCntMdS9Ku4H8VrFVuf11ohv7hrPZBR8Ow9lnCqH4Z0djt6pCqwEy4zTN 6decRYDIdd6z74vZ9+/9bFakZgpwImptsPqXDnesLpQSMDD5Ji0y4FPJJLxPuu4yalNl ypCOUKGJWpFBdyJIIGLJspwvhmaazvcObBB5vQVhQthr5UcocW6HDmRkBltm9YcjTws8 Z54F99ezTGPAj3r5xX/RChNdhlPkhk72R/EoXUxMex/VeTCQq63hSwRoAIsOLTlIPqfT bowQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Ssu68iBy; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-110130-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-110130-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id bq30-20020a05620a469e00b0078a31934b3fsi1150979qkb.567.2024.03.21.07.14.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Mar 2024 07:14:59 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-110130-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Ssu68iBy; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-110130-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-110130-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id C5AE61C20EE0 for ; Thu, 21 Mar 2024 14:14:58 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5CE2F84FDE; Thu, 21 Mar 2024 14:14:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ssu68iBy" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5BA6134CD; Thu, 21 Mar 2024 14:14:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711030488; cv=none; b=lNh1UnDji26a3L3squJD4BIK4gvz0f0nJAY7BejsN8q00T1esQgBeiaF0DVMFJzuUsmwcX+lusP7VjEmnFcBRPgs+K97WCr29BMfHF+JQCazrarFDCaaXmLFbGRuDYc5IuMyLCzSeTwjnN4j4KOoQ8Rf8QCbRpWq4ukxh1OgW58= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711030488; c=relaxed/simple; bh=OG1T8ESCsm4Q0tp/27u+HfMw1pqjvUXhy/QMJ4val6g=; h=Date:From:To:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ckZo2F4JF8IslXstU5h19XAQ4NSLOWgWem8Y9NPjMkXKNbStzqYZ3sFUSzcQSiVeEIyYjZ1sv4oPiAwjERgkq/XiTZI6iZ4DQNCCyPfD2as+MR5AhrZJ+K6ZLw/zMCYTgCUNgNbbXw8S6rgSxvLrzwNt81MEgf491jK5BSMt61g= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ssu68iBy; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1676DC433C7; Thu, 21 Mar 2024 14:14:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1711030488; bh=OG1T8ESCsm4Q0tp/27u+HfMw1pqjvUXhy/QMJ4val6g=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=Ssu68iBy/rb5IHbUm+J/WIpB4zin7AsFAGNzk58omr+kglstufP0X6WgeRGgPV/RT IFMxPQHzg27MeZSbmy1c8H3ZTCv7bR3Sf0HwgOY76rM87jxw4GKK0roiHs+vpIWuV2 Mvc0X8sgKrBZ6Nte6sSEsQAw8r8wSS+YIcb83zKBbmue4aBPSl9BRFThTCkAMuT1g0 w4dLDgnrqK/dwvjaftKlJECi9duVrROvIW0Ot/k45L8HbiiF+JrwhpVUcBHpUN7RsS r89r9Hqi0rZt9fH9OYXnXjj3ilKOqZTt4IYxijiNieAcFodc+yPmOIV2MyztN8Xplb 5jc6owph89PHw== Date: Thu, 21 Mar 2024 15:14:42 +0100 From: Mauro Carvalho Chehab To: Benjamin Gaignard Cc: tfiga@chromium.org, m.szyprowski@samsung.com, ezequiel@vanguardiasur.com.ar, p.zabel@pengutronix.de, hverkuil-cisco@xs4all.nl, nicolas@ndufresne.ca, linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, kernel@collabora.com Subject: Re: [PATCH v21 7/9] media: v4l2: Add REMOVE_BUFS ioctl Message-ID: <20240321151442.0487b53f@coco.lan> In-Reply-To: <20240314153226.197445-8-benjamin.gaignard@collabora.com> References: <20240314153226.197445-1-benjamin.gaignard@collabora.com> <20240314153226.197445-8-benjamin.gaignard@collabora.com> X-Mailer: Claws Mail 4.2.0 (GTK 3.24.41; x86_64-redhat-linux-gnu) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Em Thu, 14 Mar 2024 16:32:24 +0100 Benjamin Gaignard escreveu: > VIDIOC_REMOVE_BUFS ioctl allows to remove buffers from a queue. > The number of buffers to remove in given by count field of > struct v4l2_remove_buffers and the range start at the index > specified in the same structure. > > Signed-off-by: Benjamin Gaignard > --- > changes in version 21: > - Be more careful about checking remove_bufs type field vs queue type. > - Add documentation about type checking error. > - Always set capabilities flags field. > > .../userspace-api/media/v4l/user-func.rst | 1 + > .../media/v4l/vidioc-remove-bufs.rst | 85 +++++++++++++++++++ > .../media/v4l/vidioc-reqbufs.rst | 1 + > .../media/common/videobuf2/videobuf2-core.c | 38 +++++++++ > .../media/common/videobuf2/videobuf2-v4l2.c | 20 ++++- > drivers/media/v4l2-core/v4l2-dev.c | 3 + > drivers/media/v4l2-core/v4l2-ioctl.c | 30 +++++++ > include/media/v4l2-ioctl.h | 4 + > include/media/videobuf2-core.h | 10 +++ > include/media/videobuf2-v4l2.h | 2 + > include/uapi/linux/videodev2.h | 17 ++++ > 11 files changed, 210 insertions(+), 1 deletion(-) > create mode 100644 Documentation/userspace-api/media/v4l/vidioc-remove-bufs.rst > > diff --git a/Documentation/userspace-api/media/v4l/user-func.rst b/Documentation/userspace-api/media/v4l/user-func.rst > index 15ff0bf7bbe6..6f661138801c 100644 > --- a/Documentation/userspace-api/media/v4l/user-func.rst > +++ b/Documentation/userspace-api/media/v4l/user-func.rst > @@ -62,6 +62,7 @@ Function Reference > vidioc-query-dv-timings > vidioc-querystd > vidioc-reqbufs > + vidioc-remove-bufs > vidioc-s-hw-freq-seek > vidioc-streamon > vidioc-subdev-enum-frame-interval > diff --git a/Documentation/userspace-api/media/v4l/vidioc-remove-bufs.rst b/Documentation/userspace-api/media/v4l/vidioc-remove-bufs.rst > new file mode 100644 > index 000000000000..0cbc8c7313b7 > --- /dev/null > +++ b/Documentation/userspace-api/media/v4l/vidioc-remove-bufs.rst > @@ -0,0 +1,85 @@ > +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later > +.. c:namespace:: V4L > + > +.. _VIDIOC_REMOVE_BUFS: > + > +************************ > +ioctl VIDIOC_REMOVE_BUFS > +************************ > + > +Name > +==== > + > +VIDIOC_REMOVE_BUFS - Removes buffers from a queue > + > +Synopsis > +======== > + > +.. c:macro:: VIDIOC_REMOVE_BUFS > + > +``int ioctl(int fd, VIDIOC_REMOVE_BUFS, struct v4l2_remove_buffers *argp)`` > + > +Arguments > +========= > + > +``fd`` > + File descriptor returned by :c:func:`open()`. > + > +``argp`` > + Pointer to struct :c:type:`v4l2_remove_buffers`. > + > +Description > +=========== > + > +Applications can optionally call the :ref:`VIDIOC_REMOVE_BUFS` ioctl to > +remove buffers from a queue. > +:ref:`VIDIOC_CREATE_BUFS` ioctl support is mandatory to enable :ref:`VIDIOC_REMOVE_BUFS`. > +This ioctl is available if the ``V4L2_BUF_CAP_SUPPORTS_REMOVE_BUFS`` capability > +is set on the queue when :c:func:`VIDIOC_REQBUFS` or :c:func:`VIDIOC_CREATE_BUFS` > +are invoked. > + > +.. c:type:: v4l2_remove_buffers > + > +.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.5cm}| > + > +.. flat-table:: struct v4l2_remove_buffers > + :header-rows: 0 > + :stub-columns: 0 > + :widths: 1 1 2 > + > + * - __u32 > + - ``index`` > + - The starting buffer index to remove. This field is ignored if count == 0. > + * - __u32 > + - ``count`` > + - The number of buffers to be removed with indices 'index' until 'index + count - 1'. > + All buffers in this range must be valid and in DEQUEUED state. > + :ref:`VIDIOC_REMOVE_BUFS` will always check the validity of ``type`, if it is > + invalid it returns ``EINVAL`` error code. > + If count is set to 0 :ref:`VIDIOC_REMOVE_BUFS` will do nothing and return 0. > + * - __u32 > + - ``type`` > + - Type of the stream or buffers, this is the same as the struct > + :c:type:`v4l2_format` ``type`` field. See > + :c:type:`v4l2_buf_type` for valid values. > + * - __u32 > + - ``reserved``\ [13] > + - A place holder for future extensions. Drivers and applications > + must set the array to zero. > + > +Return Value > +============ > + > +On success 0 is returned, on error -1 and the ``errno`` variable is set > +appropriately. The generic error codes are described at the > +:ref:`Generic Error Codes ` chapter. It is not enough to just return an error code. it should also describe what will be the expected behavior after the call. Something like: If an error occurs, no buffers will be freed and one of the error codes below will be returned: > + > +EBUSY > + File I/O is in progress. > + One or more of the buffers in the range ``index`` to ``index + count - 1`` are not > + in DEQUEUED state. > + > +EINVAL > + One or more of the buffers in the range ``index`` to ``index + count - 1`` do not > + exist in the queue. > + The buffer type (``type`` field) is not valid. IMO, it needs also another error code: as there's a minimal number of buffers to be queued (let's say, 2), what happens if there are currently 3 buffers allocated and an ioctl is called to free 2 buffers? IMO, it shall return an error code and not free any buffers. The best would be to return a code different than EINVAL. Maybe E2BIG? > diff --git a/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst b/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst > index 0b3a41a45d05..bbc22dd76032 100644 > --- a/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst > +++ b/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst > @@ -121,6 +121,7 @@ aborting or finishing any DMA in progress, an implicit > .. _V4L2-BUF-CAP-SUPPORTS-M2M-HOLD-CAPTURE-BUF: > .. _V4L2-BUF-CAP-SUPPORTS-MMAP-CACHE-HINTS: > .. _V4L2-BUF-CAP-SUPPORTS-MAX-NUM-BUFFERS: > +.. _V4L2-BUF-CAP-SUPPORTS-REMOVE-BUFS: > > .. raw:: latex > > diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c > index 009cea95d662..0b2b48e1b2df 100644 > --- a/drivers/media/common/videobuf2/videobuf2-core.c > +++ b/drivers/media/common/videobuf2/videobuf2-core.c > @@ -1691,6 +1691,44 @@ int vb2_core_prepare_buf(struct vb2_queue *q, struct vb2_buffer *vb, void *pb) > } > EXPORT_SYMBOL_GPL(vb2_core_prepare_buf); > > +int vb2_core_remove_bufs(struct vb2_queue *q, unsigned int start, unsigned int count) > +{ > + unsigned int i, ret = 0; > + unsigned int q_num_bufs = vb2_get_num_buffers(q); > + > + if (count == 0) > + return 0; > + > + if (count > q_num_bufs) > + return -EINVAL; It also needs: if (q_num_bufs - count < q->min_reqbufs_allocation && q_num_bufs != count) return ; e. g. it shall not accept keeping, for instance, just one buffer allocated. > + > + if (start > q->max_num_buffers - count) > + return -EINVAL; > + > + mutex_lock(&q->mmap_lock); > + > + /* Check that all buffers in the range exist */ > + for (i = start; i < start + count; i++) { > + struct vb2_buffer *vb = vb2_get_buffer(q, i); > + > + if (!vb) { > + ret = -EINVAL; > + goto unlock; > + } > + if (vb->state != VB2_BUF_STATE_DEQUEUED) { > + ret = -EBUSY; > + goto unlock; > + } > + } > + __vb2_queue_free(q, start, count); > + dprintk(q, 2, "%u buffers removed\n", count); > + > +unlock: > + mutex_unlock(&q->mmap_lock); > + return ret; > +} > +EXPORT_SYMBOL_GPL(vb2_core_remove_bufs); > + > /* > * vb2_start_streaming() - Attempt to start streaming. > * @q: videobuf2 queue > diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c > index 03e8080a68a8..293f3d5f1c4e 100644 > --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c > +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c > @@ -685,7 +685,7 @@ static void vb2_set_flags_and_caps(struct vb2_queue *q, u32 memory, > *flags &= V4L2_MEMORY_FLAG_NON_COHERENT; > } > > - *caps = V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS; > + *caps |= V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS; > if (q->io_modes & VB2_MMAP) > *caps |= V4L2_BUF_CAP_SUPPORTS_MMAP; > if (q->io_modes & VB2_USERPTR) > @@ -1001,6 +1001,24 @@ EXPORT_SYMBOL_GPL(vb2_poll); > > /* vb2 ioctl helpers */ > > +int vb2_ioctl_remove_bufs(struct file *file, void *priv, > + struct v4l2_remove_buffers *d) > +{ > + struct video_device *vdev = video_devdata(file); > + > + if (vdev->queue->type != d->type) > + return -EINVAL; > + > + if (d->count == 0) > + return 0; > + > + if (vb2_queue_is_busy(vdev->queue, file)) > + return -EBUSY; > + > + return vb2_core_remove_bufs(vdev->queue, d->index, d->count); > +} > +EXPORT_SYMBOL_GPL(vb2_ioctl_remove_bufs); > + > int vb2_ioctl_reqbufs(struct file *file, void *priv, > struct v4l2_requestbuffers *p) > { > diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c > index d13954bd31fd..e39e9742fdb5 100644 > --- a/drivers/media/v4l2-core/v4l2-dev.c > +++ b/drivers/media/v4l2-core/v4l2-dev.c > @@ -722,6 +722,9 @@ static void determine_valid_ioctls(struct video_device *vdev) > SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf); > SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon); > SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff); > + /* VIDIOC_CREATE_BUFS support is mandatory to enable VIDIOC_REMOVE_BUFS */ > + if (ops->vidioc_create_bufs) > + SET_VALID_IOCTL(ops, VIDIOC_REMOVE_BUFS, vidioc_remove_bufs); > } > > if (is_vid || is_vbi || is_meta) { > diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c > index 6e7b8b682d13..5aeff5519407 100644 > --- a/drivers/media/v4l2-core/v4l2-ioctl.c > +++ b/drivers/media/v4l2-core/v4l2-ioctl.c > @@ -489,6 +489,14 @@ static void v4l_print_create_buffers(const void *arg, bool write_only) > v4l_print_format(&p->format, write_only); > } > > +static void v4l_print_remove_buffers(const void *arg, bool write_only) > +{ > + const struct v4l2_remove_buffers *p = arg; > + > + pr_cont("type=%s, index=%u, count=%u\n", > + prt_names(p->type, v4l2_type_names), p->index, p->count); > +} > + > static void v4l_print_streamparm(const void *arg, bool write_only) > { > const struct v4l2_streamparm *p = arg; > @@ -2092,6 +2100,7 @@ static int v4l_overlay(const struct v4l2_ioctl_ops *ops, > static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops, > struct file *file, void *fh, void *arg) > { > + struct video_device *vfd = video_devdata(file); > struct v4l2_requestbuffers *p = arg; > int ret = check_fmt(file, p->type); > > @@ -2100,6 +2109,10 @@ static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops, > > memset_after(p, 0, flags); > > + p->capabilities = 0; > + if (is_valid_ioctl(vfd, VIDIOC_REMOVE_BUFS)) > + p->capabilities = V4L2_BUF_CAP_SUPPORTS_REMOVE_BUFS; > + > return ops->vidioc_reqbufs(file, fh, p); > } > > @@ -2133,6 +2146,7 @@ static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops, > static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops, > struct file *file, void *fh, void *arg) > { > + struct video_device *vfd = video_devdata(file); > struct v4l2_create_buffers *create = arg; > int ret = check_fmt(file, create->format.type); > > @@ -2143,6 +2157,10 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops, > > v4l_sanitize_format(&create->format); > > + create->capabilities = 0; > + if (is_valid_ioctl(vfd, VIDIOC_REMOVE_BUFS)) > + create->capabilities = V4L2_BUF_CAP_SUPPORTS_REMOVE_BUFS; > + > ret = ops->vidioc_create_bufs(file, fh, create); > > if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE || > @@ -2161,6 +2179,17 @@ static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops, > return ret ? ret : ops->vidioc_prepare_buf(file, fh, b); > } > > +static int v4l_remove_bufs(const struct v4l2_ioctl_ops *ops, > + struct file *file, void *fh, void *arg) > +{ > + struct v4l2_remove_buffers *remove = arg; > + > + if (ops->vidioc_remove_bufs) > + return ops->vidioc_remove_bufs(file, fh, remove); > + > + return -ENOTTY; > +} > + > static int v4l_g_parm(const struct v4l2_ioctl_ops *ops, > struct file *file, void *fh, void *arg) > { > @@ -2910,6 +2939,7 @@ static const struct v4l2_ioctl_info v4l2_ioctls[] = { > IOCTL_INFO(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0), > IOCTL_INFO(VIDIOC_DBG_G_CHIP_INFO, v4l_dbg_g_chip_info, v4l_print_dbg_chip_info, INFO_FL_CLEAR(v4l2_dbg_chip_info, match)), > IOCTL_INFO(VIDIOC_QUERY_EXT_CTRL, v4l_query_ext_ctrl, v4l_print_query_ext_ctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_query_ext_ctrl, id)), > + IOCTL_INFO(VIDIOC_REMOVE_BUFS, v4l_remove_bufs, v4l_print_remove_buffers, INFO_FL_PRIO | INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_remove_buffers, type)), > }; > #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) > > diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h > index edb733f21604..bdbb7e542321 100644 > --- a/include/media/v4l2-ioctl.h > +++ b/include/media/v4l2-ioctl.h > @@ -163,6 +163,8 @@ struct v4l2_fh; > * :ref:`VIDIOC_CREATE_BUFS ` ioctl > * @vidioc_prepare_buf: pointer to the function that implements > * :ref:`VIDIOC_PREPARE_BUF ` ioctl > + * @vidioc_remove_bufs: pointer to the function that implements > + * :ref:`VIDIOC_REMOVE_BUFS ` ioctl > * @vidioc_overlay: pointer to the function that implements > * :ref:`VIDIOC_OVERLAY ` ioctl > * @vidioc_g_fbuf: pointer to the function that implements > @@ -422,6 +424,8 @@ struct v4l2_ioctl_ops { > struct v4l2_create_buffers *b); > int (*vidioc_prepare_buf)(struct file *file, void *fh, > struct v4l2_buffer *b); > + int (*vidioc_remove_bufs)(struct file *file, void *fh, > + struct v4l2_remove_buffers *d); > > int (*vidioc_overlay)(struct file *file, void *fh, unsigned int i); > int (*vidioc_g_fbuf)(struct file *file, void *fh, > diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h > index b9333e2c7797..955237ac503d 100644 > --- a/include/media/videobuf2-core.h > +++ b/include/media/videobuf2-core.h > @@ -870,6 +870,16 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, > */ > int vb2_core_prepare_buf(struct vb2_queue *q, struct vb2_buffer *vb, void *pb); > > +/** > + * vb2_core_remove_bufs() - > + * @q: pointer to &struct vb2_queue with videobuf2 queue. > + * @start: first index of the range of buffers to remove. > + * @count: number of buffers to remove. > + * > + * Return: returns zero on success; an error code otherwise. > + */ > +int vb2_core_remove_bufs(struct vb2_queue *q, unsigned int start, unsigned int count); > + > /** > * vb2_core_qbuf() - Queue a buffer from userspace > * > diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h > index 5a845887850b..77ce8238ab30 100644 > --- a/include/media/videobuf2-v4l2.h > +++ b/include/media/videobuf2-v4l2.h > @@ -334,6 +334,8 @@ int vb2_ioctl_streamon(struct file *file, void *priv, enum v4l2_buf_type i); > int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i); > int vb2_ioctl_expbuf(struct file *file, void *priv, > struct v4l2_exportbuffer *p); > +int vb2_ioctl_remove_bufs(struct file *file, void *priv, > + struct v4l2_remove_buffers *p); > > /* struct v4l2_file_operations helpers */ > > diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h > index a8015e5e7fa4..2663213b76a4 100644 > --- a/include/uapi/linux/videodev2.h > +++ b/include/uapi/linux/videodev2.h > @@ -1036,6 +1036,7 @@ struct v4l2_requestbuffers { > #define V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF (1 << 5) > #define V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS (1 << 6) > #define V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS (1 << 7) > +#define V4L2_BUF_CAP_SUPPORTS_REMOVE_BUFS (1 << 8) > > /** > * struct v4l2_plane - plane info for multi-planar buffers > @@ -2624,6 +2625,20 @@ struct v4l2_create_buffers { > __u32 reserved[5]; > }; > > +/** > + * struct v4l2_remove_buffers - VIDIOC_REMOVE_BUFS argument > + * @index: the first buffer to be removed > + * @count: number of buffers to removed > + * @type: enum v4l2_buf_type > + * @reserved: future extensions > + */ > +struct v4l2_remove_buffers { > + __u32 index; > + __u32 count; > + __u32 type; > + __u32 reserved[13]; > +}; > + > /* > * I O C T L C O D E S F O R V I D E O D E V I C E S > * > @@ -2723,6 +2738,8 @@ struct v4l2_create_buffers { > #define VIDIOC_DBG_G_CHIP_INFO _IOWR('V', 102, struct v4l2_dbg_chip_info) > > #define VIDIOC_QUERY_EXT_CTRL _IOWR('V', 103, struct v4l2_query_ext_ctrl) > +#define VIDIOC_REMOVE_BUFS _IOWR('V', 104, struct v4l2_remove_buffers) > + > > /* Reminder: when adding new ioctls please add support for them to > drivers/media/v4l2-core/v4l2-compat-ioctl32.c as well! */ Thanks, Mauro