Received: by 10.223.185.116 with SMTP id b49csp219960wrg; Mon, 19 Feb 2018 20:50:04 -0800 (PST) X-Google-Smtp-Source: AH8x225isy9dZNyRT0XvTyix7BCyLc9st/d3LL72doSC6ZqdmGBv38BJSbtq9Br1JCq9cP+MnQ8a X-Received: by 10.98.166.85 with SMTP id t82mr9341155pfe.237.1519102204698; Mon, 19 Feb 2018 20:50:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519102204; cv=none; d=google.com; s=arc-20160816; b=fKB/4hwh+/H77IpWcOM9fiprgaJd7LsJ0p2PCSVd2t+TEuV0Cfmn7odZ7/26O/tVD2 iurS3qCdiZrBVmDOVWWk4Gfrf4LMDBrEoBBPAUj8KDy13vn9D4S/uGMmnfM2M6z2/nMK YAkPU1WcjFPL5/jeEdqyGTH6wFVpubkL/24JAyn/VhHbwmbNXyLpBKqWegMTHcfmlQ9c VS6bE2B2csUS/GkE3TTlCF8t8S5mUCZUICHysO5s0hc9Ka1d2+xa9C7QlKrKL2ql1uE7 2Py6uonqyIRbuK8zTA+7QXOP3VVTTdHrs5FRbFPLtBA2W3kLGq16NRUz/UgNIwFvGhiK m6Jg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=qKQRcz0Rc3iEqo8QsoQFYA5BRY782Da9lg+coMYknXU=; b=MWG4meomq3vLRoWHVtdbIg4ojzmfo5GetMfmQC2ZBoxMvpCGDz7LKIaHY3Je0YMYbd BCF9+ybvtCxXvzGzgpXkqATGDKK+CepI+tV5U2xtwnKHKnXqWW4+9wzL2uCrba9ZlxRw OQ1sDNemJUbqsUE3QS04EwcP+oqdbI4JXzuC8sf/JLUQ0CBIpgR+KYULaDyaqtyi1++0 n4I9O8oOQVynyjiJTQXroaAK5jSTionhH+b1EX6tQYvvgDWTxwYUIaL6t1F76SsrP8gd y0mz4EteG/7VBHHykCV2jvcEoRZ7+g7o2NPeOi9oDRzZNKu03vEP1NV2E60IIVQklaYj zCCQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=Lpgr/NMg; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w8-v6si7873720pll.795.2018.02.19.20.49.50; Mon, 19 Feb 2018 20:50:04 -0800 (PST) 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; dkim=pass header.i=@chromium.org header.s=google header.b=Lpgr/NMg; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751503AbeBTEpW (ORCPT + 99 others); Mon, 19 Feb 2018 23:45:22 -0500 Received: from mail-pg0-f66.google.com ([74.125.83.66]:43214 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751480AbeBTEpT (ORCPT ); Mon, 19 Feb 2018 23:45:19 -0500 Received: by mail-pg0-f66.google.com with SMTP id f6so6695519pgs.10 for ; Mon, 19 Feb 2018 20:45:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qKQRcz0Rc3iEqo8QsoQFYA5BRY782Da9lg+coMYknXU=; b=Lpgr/NMgbOe+1m9L8vA0pCW+nyJ/GVwQoppvhlqTI8KhLxsfnjGsuB2y1ku+bZ3ZLh ybVnQubaXkjEXRV0apFkvZPRpzSwp8aaoGTvTUOQ15z3Socta+IGnLMwPE1pY7kIkmkV 57b1l6E1FrO4FTdDox1KW8BfD1XjJlFC22y+Q= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=qKQRcz0Rc3iEqo8QsoQFYA5BRY782Da9lg+coMYknXU=; b=kkHmAdQoyEK9yDoqY7f/aEIqO5RPwLzBDgho1xVS4Im5Nw/rzPBtgLTpZ9w+StFYFC nHUFylZAGnEUyRHVvwd2CVB+QsJ8JkIRM4BTe9Ww2sEOJ908J7GVEtBpkWRGQlmWhIS3 8Aob+TzX/K7f32XRHsQztgbrGESSRNYHrTfCt97FzQW529gieyKFixdabw5ReDsGZLdX LoJmjMDHc5klI7nf0j/vpE84y9dDaWStDvwJx1EfDelzc9vsaGNLvCknPPu20TheF4vf saT1jTTArWMDQASVw0Jew40CR51qcvQlemEnTTUR6LgXzhVLh9txCThPqENQX+htnV5/ Bj5A== X-Gm-Message-State: APf1xPCHWd8pmy3wo+QPTVFUd4Sh5mKUaq4otnnnfd6cJIm/yKp57GCC Xh7oAD+X+iRacfzpTWIJ8F983A== X-Received: by 10.99.124.91 with SMTP id l27mr13786025pgn.298.1519101918753; Mon, 19 Feb 2018 20:45:18 -0800 (PST) Received: from acourbot.tok.corp.google.com ([2401:fa00:4:1002:a6cd:a898:e07b:a331]) by smtp.gmail.com with ESMTPSA id q9sm783397pgs.28.2018.02.19.20.45.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 19 Feb 2018 20:45:18 -0800 (PST) From: Alexandre Courbot To: Mauro Carvalho Chehab , Hans Verkuil , Laurent Pinchart , Pawel Osciak , Marek Szyprowski , Tomasz Figa , Sakari Ailus Cc: Gustavo Padovan , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Alexandre Courbot Subject: [RFCv4 13/21] media: videobuf2-v4l2: support for requests Date: Tue, 20 Feb 2018 13:44:17 +0900 Message-Id: <20180220044425.169493-14-acourbot@chromium.org> X-Mailer: git-send-email 2.16.1.291.g4437f3f132-goog In-Reply-To: <20180220044425.169493-1-acourbot@chromium.org> References: <20180220044425.169493-1-acourbot@chromium.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add a new vb2_qbuf_request() (a request-aware version of vb2_qbuf()) that request-aware drivers can call to queue a buffer into a request instead of directly into the vb2 queue if relevent. This function expects that drivers invoking it are using instances of v4l2_request_entity and v4l2_request_entity_data to describe their entity and entity data respectively. Also add the vb2_request_submit() helper function which drivers can invoke in order to queue all the buffers previously queued into a request into the regular vb2 queue. Signed-off-by: Alexandre Courbot --- .../media/common/videobuf2/videobuf2-v4l2.c | 129 +++++++++++++++++- include/media/videobuf2-v4l2.h | 59 ++++++++ 2 files changed, 187 insertions(+), 1 deletion(-) diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index 6d4d184aa68e..0627c3339572 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -28,8 +28,11 @@ #include #include #include +#include +#include #include +#include static int debug; module_param(debug, int, 0644); @@ -569,11 +572,131 @@ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) return -EBUSY; } + /* drivers supporting requests must call vb2_qbuf_request instead */ + if (b->request_fd > 0) { + dprintk(1, "invalid call to vb2_qbuf with request_fd set\n"); + return -EINVAL; + } + ret = vb2_queue_or_prepare_buf(q, b, "qbuf"); return ret ? ret : vb2_core_qbuf(q, b->index, b); } EXPORT_SYMBOL_GPL(vb2_qbuf); +#if IS_ENABLED(CONFIG_MEDIA_REQUEST_API) +int vb2_qbuf_request(struct vb2_queue *q, struct v4l2_buffer *b, + struct media_request_entity *entity) +{ + struct v4l2_request_entity_data *data; + struct v4l2_vb2_request_buffer *qb; + struct media_request *req; + struct vb2_buffer *vb; + int ret = 0; + + if (b->request_fd <= 0) + return vb2_qbuf(q, b); + + if (!q->allow_requests) + return -EINVAL; + + req = media_request_get_from_fd(b->request_fd); + if (!req) + return -EINVAL; + + data = to_v4l2_entity_data(media_request_get_entity_data(req, entity)); + if (IS_ERR(data)) { + ret = PTR_ERR(data); + goto out; + } + + mutex_lock(&req->lock); + + if (req->state != MEDIA_REQUEST_STATE_IDLE) { + ret = -EINVAL; + goto out; + } + + ret = vb2_queue_or_prepare_buf(q, b, "qbuf"); + if (ret) + goto out; + + vb = q->bufs[b->index]; + switch (vb->state) { + case VB2_BUF_STATE_DEQUEUED: + break; + case VB2_BUF_STATE_PREPARED: + break; + case VB2_BUF_STATE_PREPARING: + dprintk(1, "buffer still being prepared\n"); + ret = -EINVAL; + goto out; + default: + dprintk(1, "invalid buffer state %d\n", vb->state); + ret = -EINVAL; + goto out; + } + + /* do we already have a buffer for this request in the queue? */ + list_for_each_entry(qb, &data->queued_buffers, node) { + if (qb->queue == q) { + ret = -EBUSY; + goto out; + } + } + + qb = kzalloc(sizeof(*qb), GFP_KERNEL); + if (!qb) { + ret = -ENOMEM; + goto out; + } + + /* + * TODO should be prepare the buffer here if needed, to report errors + * early? + */ + qb->pre_req_state = vb->state; + qb->queue = q; + memcpy(&qb->v4l2_buf, b, sizeof(*b)); + vb->request = req; + vb->state = VB2_BUF_STATE_QUEUED; + list_add_tail(&qb->node, &data->queued_buffers); + +out: + mutex_unlock(&req->lock); + media_request_put(req); + + return ret; +} +EXPORT_SYMBOL_GPL(vb2_qbuf_request); + +int vb2_request_submit(struct v4l2_request_entity_data *data) +{ + struct v4l2_vb2_request_buffer *qb, *n; + + /* v4l2 requests require at least one buffer to reach the device */ + if (list_empty(&data->queued_buffers)) { + return -EINVAL; + } + + list_for_each_entry_safe(qb, n, &data->queued_buffers, node) { + struct vb2_queue *q = qb->queue; + struct vb2_buffer *vb = q->bufs[qb->v4l2_buf.index]; + int ret; + + list_del(&qb->node); + vb->state = qb->pre_req_state; + ret = vb2_core_qbuf(q, vb->index, &qb->v4l2_buf); + kfree(qb); + if (ret) + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(vb2_request_submit); + +#endif /* CONFIG_MEDIA_REQUEST_API */ + int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking) { int ret; @@ -776,10 +899,14 @@ EXPORT_SYMBOL_GPL(vb2_ioctl_querybuf); int vb2_ioctl_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) { struct video_device *vdev = video_devdata(file); + struct v4l2_fh *fh = NULL; + + if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags)) + fh = file->private_data; if (vb2_queue_is_busy(vdev, file)) return -EBUSY; - return vb2_qbuf(vdev->queue, p); + return vb2_qbuf_request(vdev->queue, p, fh ? fh->entity : NULL); } EXPORT_SYMBOL_GPL(vb2_ioctl_qbuf); diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h index 3d5e2d739f05..d4dfa266a0da 100644 --- a/include/media/videobuf2-v4l2.h +++ b/include/media/videobuf2-v4l2.h @@ -23,6 +23,12 @@ #error VB2_MAX_PLANES != VIDEO_MAX_PLANES #endif +struct media_entity; +struct v4l2_fh; +struct media_request; +struct media_request_entity; +struct v4l2_request_entity_data; + /** * struct vb2_v4l2_buffer - video buffer information for v4l2. * @@ -116,6 +122,59 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b); */ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b); +#if IS_ENABLED(CONFIG_MEDIA_REQUEST_API) + +/** + * vb2_qbuf_request() - Queue a buffer, with request support + * @q: pointer to &struct vb2_queue with videobuf2 queue. + * @b: buffer structure passed from userspace to + * &v4l2_ioctl_ops->vidioc_qbuf handler in driver + * @entity: request entity to queue for if requests are used. + * + * Should be called from &v4l2_ioctl_ops->vidioc_qbuf handler of a driver. + * + * If requests are not in use, calling this is equivalent to calling vb2_qbuf(). + * + * If the request_fd member of b is set, then the buffer represented by b is + * queued in the request instead of the vb2 queue. The buffer will be passed + * to the vb2 queue when the request is submitted. + * + * The return values from this function are intended to be directly returned + * from &v4l2_ioctl_ops->vidioc_qbuf handler in driver. + */ +int vb2_qbuf_request(struct vb2_queue *q, struct v4l2_buffer *b, + struct media_request_entity *entity); + +/** + * vb2_request_submit() - Queue all the buffers in a v4l2 request. + * @data: request entity data to queue buffers of + * + * This function should be called from the media_request_entity_ops::submit + * hook for instances of media_request_v4l2_entity_data. It will immediately + * queue all the request-bound buffers to their respective vb2 queues. + * + * Errors from vb2_core_qbuf() are returned if something happened. Also, since + * v4l2 request entities require at least one buffer for the request to trigger, + * this function will return -EINVAL if no buffer have been bound at all for + * this entity. + */ +int vb2_request_submit(struct v4l2_request_entity_data *data); + +#else /* CONFIG_MEDIA_REQUEST_API */ + +static inline int vb2_qbuf_request(struct vb2_queue *q, struct v4l2_buffer *b, + struct media_request_entity *entity) +{ + return vb2_qbuf(q, b); +} + +static inline int vb2_request_submit(struct v4l2_request_entity_data *data) +{ + return -ENOTSUPP; +} + +#endif /* CONFIG_MEDIA_REQUEST_API */ + /** * vb2_expbuf() - Export a buffer as a file descriptor * @q: pointer to &struct vb2_queue with videobuf2 queue. -- 2.16.1.291.g4437f3f132-goog