From patchwork Mon Jan 8 12:00:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 185925 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:37c1:b0:101:2151:f287 with SMTP id y1csp969466dyq; Mon, 8 Jan 2024 04:01:51 -0800 (PST) X-Google-Smtp-Source: AGHT+IGWK+6p714DOAmj+jyr8G19cvXrITnU6V8+QHnSIZ71JWlFWogrQfOMUD51yuaiSnyr29is X-Received: by 2002:a17:906:225c:b0:a26:e35a:de3d with SMTP id 28-20020a170906225c00b00a26e35ade3dmr3758299ejr.23.1704715311449; Mon, 08 Jan 2024 04:01:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704715311; cv=none; d=google.com; s=arc-20160816; b=mwjqA8jpPKl6Q02lGhu1oMPPxaCPzLtj8A2PRg5sbptpntWjZPV5QXk7U0XxJAme2P OlWfn1DWmPdDJ2VoPCBdjKkk9pCwdNFXIB93YKDkz5MtNk4/fF6830MlnQYsTvfM3+bS Ge9QESDtubw/KtzecbrLontJFqmLjFGwjH92qbA8ohk97B6aYFPa7On/rNBdfpRtF+dw Bu7mOBXarQBSa0vLRz1oRvtrW3+1H222rV69BNQrWo4MWt+ODNB2yDtVyOwcYPjyVglu F6fj9QgLlagr4X7hbLlrLKHLbubWzKokBsWbkNk/OjK9gOYDnDUbynVHnzhJz1iiH7je e4rQ== ARC-Message-Signature: i=1; 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 :date:subject:cc:to:from:dkim-signature; bh=SqXbfp61fzBHWNEqVrElLd46cr7HG/1wYVIvKKSn5jY=; fh=uCl+pDf5A/h9/EhC2a7e6oA3XsaNDDsC5zMoVf40Kzc=; b=BEcgfRS4MIH0Usfa0MHnMAdBQM7m7t+SDqNc+JtWpe38HX8inIap6d0AJEJrcyZPkK h3Qdw/jTqfoJIgoLaHEu/EAMUT2hjStCIWcq3Y5zFh9reT4fTSSrwjnshHUZxqGuZ/IR ab50h4SlFEWxSwnuEkU31kNRzWTLPKA3+17FHbwehmHRZUSev93T4bRs41Xn20KZa5f/ k+80ZzSZSBVJNiqh5lPqG+WTe/9rA/2TI2Gt1FZE+QwLt2p35J9kdMNTU4EIZ3y3vqnR TpgW/mpTu0C6rq+rEHHXIKx8gtZguIh5pBmmeNle5/qhHXl4b/ffhhk+FekGQUfrAxbH /Fdw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b="EJknILA/"; spf=pass (google.com: domain of linux-kernel+bounces-19461-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-19461-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id c10-20020a170906154a00b00a0fe0ed680esi2985606ejd.178.2024.01.08.04.01.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jan 2024 04:01:51 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-19461-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b="EJknILA/"; spf=pass (google.com: domain of linux-kernel+bounces-19461-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-19461-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net 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 am.mirrors.kernel.org (Postfix) with ESMTPS id 13B9D1F22961 for ; Mon, 8 Jan 2024 12:01:51 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 23DA429423; Mon, 8 Jan 2024 12:01:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=crapouillou.net header.i=@crapouillou.net header.b="EJknILA/" X-Original-To: linux-kernel@vger.kernel.org Received: from aposti.net (aposti.net [89.234.176.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E52F424B44; Mon, 8 Jan 2024 12:01:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=crapouillou.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=crapouillou.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1704715263; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SqXbfp61fzBHWNEqVrElLd46cr7HG/1wYVIvKKSn5jY=; b=EJknILA/HcKeDAL+7bQrURFIu+gP9lVq+/v4qUkcgDZvksaoRrwtu5A38lq0FNq3QBtxEV ompQuhN94wCW3HbKR7KvZuWRG9E0cifTT1ZcaZPQIyVvV3DELCVMJqbc3VobOa9OzmVcFB MNsdzO4yEXjkqXxXizWm6M6a92ciaLg= From: Paul Cercueil To: Greg Kroah-Hartman , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Jonathan Corbet Cc: Jonathan Cameron , =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Andrzej Pietrasiewicz , linux-usb@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Paul Cercueil Subject: [PATCH v3 1/4] usb: gadget: Support already-mapped DMA SGs Date: Mon, 8 Jan 2024 13:00:53 +0100 Message-ID: <20240108120056.22165-2-paul@crapouillou.net> In-Reply-To: <20240108120056.22165-1-paul@crapouillou.net> References: <20240108120056.22165-1-paul@crapouillou.net> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam: Yes X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787523562280824338 X-GMAIL-MSGID: 1787523562280824338 Add a new 'sg_was_mapped' field to the struct usb_request. This field can be used to indicate that the scatterlist associated to the USB transfer has already been mapped into the DMA space, and it does not have to be done internally. Signed-off-by: Paul Cercueil --- drivers/usb/gadget/udc/core.c | 7 ++++++- include/linux/usb/gadget.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index d59f94464b87..9d4150124fdb 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -903,6 +903,11 @@ int usb_gadget_map_request_by_dev(struct device *dev, if (req->length == 0) return 0; + if (req->sg_was_mapped) { + req->num_mapped_sgs = req->num_sgs; + return 0; + } + if (req->num_sgs) { int mapped; @@ -948,7 +953,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_map_request); void usb_gadget_unmap_request_by_dev(struct device *dev, struct usb_request *req, int is_in) { - if (req->length == 0) + if (req->length == 0 || req->sg_was_mapped) return; if (req->num_mapped_sgs) { diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index a771ccc038ac..c529e4e06997 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -52,6 +52,7 @@ struct usb_ep; * @short_not_ok: When reading data, makes short packets be * treated as errors (queue stops advancing till cleanup). * @dma_mapped: Indicates if request has been mapped to DMA (internal) + * @sg_was_mapped: Set if the scatterlist has been mapped before the request * @complete: Function called when request completes, so this request and * its buffer may be re-used. The function will always be called with * interrupts disabled, and it must not sleep. @@ -111,6 +112,7 @@ struct usb_request { unsigned zero:1; unsigned short_not_ok:1; unsigned dma_mapped:1; + unsigned sg_was_mapped:1; void (*complete)(struct usb_ep *ep, struct usb_request *req); From patchwork Mon Jan 8 12:00:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 185926 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:37c1:b0:101:2151:f287 with SMTP id y1csp969673dyq; Mon, 8 Jan 2024 04:02:10 -0800 (PST) X-Google-Smtp-Source: AGHT+IGu097Vfjj4Nyd2Og5+hv2tADusQs2Te317cO8LzSFnPOkNYtChZmNa7/y97voKz6pXpY74 X-Received: by 2002:ac8:7e8f:0:b0:429:9d51:c5ef with SMTP id w15-20020ac87e8f000000b004299d51c5efmr402206qtj.17.1704715329877; Mon, 08 Jan 2024 04:02:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704715329; cv=none; d=google.com; s=arc-20160816; b=o0fMMVH3Tqel/0rmxU/OHSoxSQIvaN3q4wN9bBnq56xXSdLs6Xv0HldmSDyPcuI7MA RBNH20MmsFufRpDh1QJP/1pSSsDH5GxjRkQmsWCQX+iSTqSo6E/ojOoPg3FAXvZJ865g 63ZXZ2HfIiL37WDY7xkCWLUVnnSUtKoaW+7L/korGitw4yMSyHCwkjeRDct+SUKz4Iox qNz5wh52XLmwea9PbG21Y2En3NM850HDTuZ42SrhlhwqT25E3sFBrzTvFhnGBTohUdML KcHAC6DnQkjpg+hIxjrHHXlT+K+AYhdQyHKuXoz4JSYcNEVMeVrvwBXEHOVNYSmgz8kG qEEQ== ARC-Message-Signature: i=1; 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 :date:subject:cc:to:from:dkim-signature; bh=PFENih9XWAd70944xbCOau+9oHw/D103WR9u3LQvnx8=; fh=uCl+pDf5A/h9/EhC2a7e6oA3XsaNDDsC5zMoVf40Kzc=; b=baoeQe+9fUas23k4fTcSTyeUUbv42EIALED4RiVvD++cZoe4vGvsU2SOQplY7Z3VKB hUN1gx00byU4hSSGCK3eMo7sN4HX/EJm5JFRr5Qjkm6XdcZRF+8CUEEMEnso+5+7bgyW DXbsVvt+aAiprlJQnLvzZd4ZZ6qDiGjkxScfkuEtCbWdt8q85q8BBDDi/veEIfGlFs0E paoed1tX9+t8gUVx/G7dfWvdpLPaPT3cu7SveJsn0XlNoBQ9CfVWLV965KO5c3F/7KiG G3yJp2rAMAcH1iThH/wEmS1ZvKWjZhIiJxJnjYCBTrlOnzeGoDMQ2Ai+q2jMQ5hnTJwg vc0w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=QEsdJscw; spf=pass (google.com: domain of linux-kernel+bounces-19462-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-19462-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id u21-20020a05622a199500b00425e75fa13csi2148192qtc.90.2024.01.08.04.02.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jan 2024 04:02:09 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-19462-ouuuleilei=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=@crapouillou.net header.s=mail header.b=QEsdJscw; spf=pass (google.com: domain of linux-kernel+bounces-19462-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-19462-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net 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 A83C21C221A4 for ; Mon, 8 Jan 2024 12:02:09 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9D2DD2D796; Mon, 8 Jan 2024 12:01:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=crapouillou.net header.i=@crapouillou.net header.b="QEsdJscw" X-Original-To: linux-kernel@vger.kernel.org Received: from aposti.net (aposti.net [89.234.176.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 894982C688; Mon, 8 Jan 2024 12:01:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=crapouillou.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=crapouillou.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1704715264; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PFENih9XWAd70944xbCOau+9oHw/D103WR9u3LQvnx8=; b=QEsdJscwiJEspTAoEHRDNK7VnoGgpp0UGaBRfdN8yjy64rkHYjOZYbhcPEnI8nVS88oAIb lUCdoJ6bnksYqtGmP1DgMA+2SYnNjnqO8RVCclnVrpFxfZU3wLhxd+Ijyl27rmZApxI4Jl n0GqzBZqFruQrC9jLKU5sAfjRLjmBxo= From: Paul Cercueil To: Greg Kroah-Hartman , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Jonathan Corbet Cc: Jonathan Cameron , =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Andrzej Pietrasiewicz , linux-usb@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Paul Cercueil Subject: [PATCH v3 2/4] usb: gadget: functionfs: Factorize wait-for-endpoint code Date: Mon, 8 Jan 2024 13:00:54 +0100 Message-ID: <20240108120056.22165-3-paul@crapouillou.net> In-Reply-To: <20240108120056.22165-1-paul@crapouillou.net> References: <20240108120056.22165-1-paul@crapouillou.net> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam: Yes X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787523581837122225 X-GMAIL-MSGID: 1787523581837122225 This exact same code was duplicated in two different places. Signed-off-by: Paul Cercueil --- drivers/usb/gadget/function/f_fs.c | 48 +++++++++++++++++------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 6bff6cb93789..ed2a6d5fcef7 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -934,31 +934,44 @@ static ssize_t __ffs_epfile_read_data(struct ffs_epfile *epfile, return ret; } -static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) +static struct ffs_ep *ffs_epfile_wait_ep(struct file *file) { struct ffs_epfile *epfile = file->private_data; - struct usb_request *req; struct ffs_ep *ep; - char *data = NULL; - ssize_t ret, data_len = -EINVAL; - int halt; - - /* Are we still active? */ - if (WARN_ON(epfile->ffs->state != FFS_ACTIVE)) - return -ENODEV; + int ret; /* Wait for endpoint to be enabled */ ep = epfile->ep; if (!ep) { if (file->f_flags & O_NONBLOCK) - return -EAGAIN; + return ERR_PTR(-EAGAIN); ret = wait_event_interruptible( epfile->ffs->wait, (ep = epfile->ep)); if (ret) - return -EINTR; + return ERR_PTR(-EINTR); } + return ep; +} + +static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) +{ + struct ffs_epfile *epfile = file->private_data; + struct usb_request *req; + struct ffs_ep *ep; + char *data = NULL; + ssize_t ret, data_len = -EINVAL; + int halt; + + /* Are we still active? */ + if (WARN_ON(epfile->ffs->state != FFS_ACTIVE)) + return -ENODEV; + + ep = ffs_epfile_wait_ep(file); + if (IS_ERR(ep)) + return PTR_ERR(ep); + /* Do we halt? */ halt = (!io_data->read == !epfile->in); if (halt && epfile->isoc) @@ -1280,16 +1293,9 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, return -ENODEV; /* Wait for endpoint to be enabled */ - ep = epfile->ep; - if (!ep) { - if (file->f_flags & O_NONBLOCK) - return -EAGAIN; - - ret = wait_event_interruptible( - epfile->ffs->wait, (ep = epfile->ep)); - if (ret) - return -EINTR; - } + ep = ffs_epfile_wait_ep(file); + if (IS_ERR(ep)) + return PTR_ERR(ep); spin_lock_irq(&epfile->ffs->eps_lock); From patchwork Mon Jan 8 12:00:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 185927 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:37c1:b0:101:2151:f287 with SMTP id y1csp969957dyq; Mon, 8 Jan 2024 04:02:34 -0800 (PST) X-Google-Smtp-Source: AGHT+IEMTAu9JIxi0j5UwXsibatwg5eipqnzSUZsMqxR+Hi87mW1BP9hkvVhfqmc77ZG1zDBbiPb X-Received: by 2002:a05:6a20:8e25:b0:199:7bc4:e4e5 with SMTP id y37-20020a056a208e2500b001997bc4e4e5mr1159271pzj.62.1704715354493; Mon, 08 Jan 2024 04:02:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704715354; cv=none; d=google.com; s=arc-20160816; b=I065qeUL+6VVTkMdAc0yuiKpzkL6CeyQ8oPRZ65ynGqaZxbgeRgwPb0M/Xhx73M2hh mdyZNYz3Bnhk9UqNLKdZ2SC7zoLWagSq9yxu6Q8CHk0rDJRe7vhIlJRh7aYCWe7g+THg 489FoM9vgMKDLodguM9SJ/LrPrhwzoHOsGQz2j+X2smMdbfcpkY93K/VGa+dqVXVOYLS K/Qb8aKc6DlkxRZ1u07KdiPct+JY4UX3PwpCVo6uuCaZcXGRGP7V3kT2PUe3enY2Taq8 IeZu04APf3qxEigKDaFZrvbY2dVYK+yxghg7yex2zlhIH71R2+ydWZw//WNTUjD1xbEn kRjg== ARC-Message-Signature: i=1; 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 :date:subject:cc:to:from:dkim-signature; bh=Q9mxfSAcx42gMCZXbFFy0yc92feIycZ5XionnrPVZkg=; fh=uCl+pDf5A/h9/EhC2a7e6oA3XsaNDDsC5zMoVf40Kzc=; b=LHM1oB0fNbPMW5q8QoNtRLzQvruiXa33+n1luygfCsIn0cuvOTNuPlpHHDjaSAB5wZ +L7lKQrNjMgmLdZNEQ41fnniufWNMDTqiZ8zX5JTrXCfnD0CrAQyHVvFOgxGnnijTDwS VQFqGePY7J62zVhW1/3yBSU1xT94mLRBugByq/g0YxERG740rs2+QW+sn/bt4HvhbBSq t/VMa6/ry3tHd0YRXo5Bwm4GhmO5DPZm609o9ULbP0GG0BdbZ8mqioCUzNoPWmdm+lQO 1qL4AlZyVJCTfjkxnXvW6JYEd8OD/a/owQ9/OeWeCyRj/u9nlr9dLotjrzTFlmBK7cRl 3NKA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=w1oTp+Rb; spf=pass (google.com: domain of linux-kernel+bounces-19463-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-19463-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id r25-20020a63a019000000b005c67e7f7917si5810322pge.409.2024.01.08.04.02.34 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jan 2024 04:02:34 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-19463-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=w1oTp+Rb; spf=pass (google.com: domain of linux-kernel+bounces-19463-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-19463-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net 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 sv.mirrors.kernel.org (Postfix) with ESMTPS id BE86C2830B0 for ; Mon, 8 Jan 2024 12:02:30 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 35A7E2E826; Mon, 8 Jan 2024 12:01:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=crapouillou.net header.i=@crapouillou.net header.b="w1oTp+Rb" X-Original-To: linux-kernel@vger.kernel.org Received: from aposti.net (aposti.net [89.234.176.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 92B532E62C; Mon, 8 Jan 2024 12:01:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=crapouillou.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=crapouillou.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1704715265; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Q9mxfSAcx42gMCZXbFFy0yc92feIycZ5XionnrPVZkg=; b=w1oTp+Rb5o+UbMrCLAIZKzHOinU2vw9EdbWtVvCVr3YimLcdLB9XX1WlVDApSJIl/8fDk/ z/Zf5OvB23u53F90KaTxgLmhmKlX+AKpGteBcTiyP62ERBks0rFQvcmCOvb0BPBG4mmjEP bPTauxIh7EtegXwOf5yPuGPRi5TB7xk= From: Paul Cercueil To: Greg Kroah-Hartman , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Jonathan Corbet Cc: Jonathan Cameron , =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Andrzej Pietrasiewicz , linux-usb@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Paul Cercueil Subject: [PATCH v3 3/4] usb: gadget: functionfs: Add DMABUF import interface Date: Mon, 8 Jan 2024 13:00:55 +0100 Message-ID: <20240108120056.22165-4-paul@crapouillou.net> In-Reply-To: <20240108120056.22165-1-paul@crapouillou.net> References: <20240108120056.22165-1-paul@crapouillou.net> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam: Yes X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787523607227090239 X-GMAIL-MSGID: 1787523607227090239 This patch introduces three new ioctls. They all should be called on a data endpoint (ie. not ep0). They are: - FUNCTIONFS_DMABUF_ATTACH, which takes the file descriptor of a DMABUF object to attach to the endpoint. - FUNCTIONFS_DMABUF_DETACH, which takes the file descriptor of the DMABUF to detach from the endpoint. Note that closing the endpoint's file descriptor will automatically detach all attached DMABUFs. - FUNCTIONFS_DMABUF_TRANSFER, which requests a data transfer from / to the given DMABUF. Its argument is a structure that packs the DMABUF's file descriptor, the size in bytes to transfer (which should generally be set to the size of the DMABUF), and a 'flags' field which is unused for now. Before this ioctl can be used, the related DMABUF must be attached with FUNCTIONFS_DMABUF_ATTACH. These three ioctls enable the FunctionFS code to transfer data between the USB stack and a DMABUF object, which can be provided by a driver from a completely different subsystem, in a zero-copy fashion. Signed-off-by: Paul Cercueil Acked-by: Daniel Vetter --- v2: - Make ffs_dma_resv_lock() static - Add MODULE_IMPORT_NS(DMA_BUF); - The attach/detach functions are now performed without locking the eps_lock spinlock. The transfer function starts with the spinlock unlocked, then locks it before allocating and queueing the USB transfer. v3: - Inline to_ffs_dma_fence() which was called only once. - Simplify ffs_dma_resv_lock() - Add comment explaining why we unref twice in ffs_dmabuf_detach() - Document uapi struct usb_ffs_dmabuf_transfer_req and IOCTLs --- drivers/usb/gadget/function/f_fs.c | 417 ++++++++++++++++++++++++++++ include/uapi/linux/usb/functionfs.h | 41 +++ 2 files changed, 458 insertions(+) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index ed2a6d5fcef7..9df1f5abb0d4 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -15,6 +15,9 @@ /* #define VERBOSE_DEBUG */ #include +#include +#include +#include #include #include #include @@ -43,6 +46,8 @@ #define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */ +MODULE_IMPORT_NS(DMA_BUF); + /* Reference counter handling */ static void ffs_data_get(struct ffs_data *ffs); static void ffs_data_put(struct ffs_data *ffs); @@ -124,6 +129,21 @@ struct ffs_ep { u8 num; }; +struct ffs_dmabuf_priv { + struct list_head entry; + struct kref ref; + struct dma_buf_attachment *attach; + spinlock_t lock; + u64 context; +}; + +struct ffs_dma_fence { + struct dma_fence base; + struct ffs_dmabuf_priv *priv; + struct sg_table *sgt; + enum dma_data_direction dir; +}; + struct ffs_epfile { /* Protects ep->ep and ep->req. */ struct mutex mutex; @@ -197,6 +217,8 @@ struct ffs_epfile { unsigned char isoc; /* P: ffs->eps_lock */ unsigned char _pad; + + struct list_head dmabufs; }; struct ffs_buffer { @@ -1271,10 +1293,44 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to) return res; } +static void ffs_dmabuf_release(struct kref *ref) +{ + struct ffs_dmabuf_priv *priv = container_of(ref, struct ffs_dmabuf_priv, ref); + struct dma_buf_attachment *attach = priv->attach; + struct dma_buf *dmabuf = attach->dmabuf; + + pr_debug("FFS DMABUF release\n"); + dma_buf_detach(attach->dmabuf, attach); + dma_buf_put(dmabuf); + + list_del(&priv->entry); + kfree(priv); +} + +static void ffs_dmabuf_get(struct dma_buf_attachment *attach) +{ + struct ffs_dmabuf_priv *priv = attach->importer_priv; + + kref_get(&priv->ref); +} + +static void ffs_dmabuf_put(struct dma_buf_attachment *attach) +{ + struct ffs_dmabuf_priv *priv = attach->importer_priv; + + kref_put(&priv->ref, ffs_dmabuf_release); +} + static int ffs_epfile_release(struct inode *inode, struct file *file) { struct ffs_epfile *epfile = inode->i_private; + struct ffs_dmabuf_priv *priv, *tmp; + + /* Close all attached DMABUFs */ + list_for_each_entry_safe(priv, tmp, &epfile->dmabufs, entry) { + ffs_dmabuf_put(priv->attach); + } __ffs_epfile_read_buffer_free(epfile); ffs_data_closed(epfile->ffs); @@ -1282,6 +1338,328 @@ ffs_epfile_release(struct inode *inode, struct file *file) return 0; } +static void ffs_dmabuf_signal_done(struct ffs_dma_fence *dma_fence, int ret) +{ + struct ffs_dmabuf_priv *priv = dma_fence->priv; + struct dma_fence *fence = &dma_fence->base; + + dma_fence_get(fence); + fence->error = ret; + dma_fence_signal(fence); + + dma_buf_unmap_attachment(priv->attach, dma_fence->sgt, dma_fence->dir); + dma_fence_put(fence); + ffs_dmabuf_put(priv->attach); +} + +static void ffs_epfile_dmabuf_io_complete(struct usb_ep *ep, + struct usb_request *req) +{ + pr_debug("FFS: DMABUF transfer complete, status=%d\n", req->status); + ffs_dmabuf_signal_done(req->context, req->status); + usb_ep_free_request(ep, req); +} + +static const char *ffs_dmabuf_get_driver_name(struct dma_fence *fence) +{ + return "functionfs"; +} + +static const char *ffs_dmabuf_get_timeline_name(struct dma_fence *fence) +{ + return ""; +} + +static void ffs_dmabuf_fence_release(struct dma_fence *fence) +{ + struct ffs_dma_fence *dma_fence = + container_of(fence, struct ffs_dma_fence, base); + + kfree(dma_fence); +} + +static const struct dma_fence_ops ffs_dmabuf_fence_ops = { + .get_driver_name = ffs_dmabuf_get_driver_name, + .get_timeline_name = ffs_dmabuf_get_timeline_name, + .release = ffs_dmabuf_fence_release, +}; + +static int ffs_dma_resv_lock(struct dma_buf *dmabuf, bool nonblock) +{ + int ret; + + ret = dma_resv_lock_interruptible(dmabuf->resv, NULL); + if (ret) { + if (ret != -EDEADLK) + return ret; + if (nonblock) + return -EBUSY; + + ret = dma_resv_lock_slow_interruptible(dmabuf->resv, NULL); + } + + return ret; +} + +static struct dma_buf_attachment * +ffs_dmabuf_find_attachment(struct device *dev, struct dma_buf *dmabuf, + bool nonblock) +{ + struct dma_buf_attachment *elm, *attach = NULL; + int ret; + + ret = ffs_dma_resv_lock(dmabuf, nonblock); + if (ret) + return ERR_PTR(ret); + + list_for_each_entry(elm, &dmabuf->attachments, node) { + if (elm->dev == dev) { + attach = elm; + break; + } + } + + if (attach) + ffs_dmabuf_get(elm); + + dma_resv_unlock(dmabuf->resv); + + return attach ?: ERR_PTR(-EPERM); +} + +static int ffs_dmabuf_attach(struct file *file, int fd) +{ + struct ffs_epfile *epfile = file->private_data; + struct usb_gadget *gadget = epfile->ffs->gadget; + struct dma_buf_attachment *attach; + struct ffs_dmabuf_priv *priv; + struct dma_buf *dmabuf; + int err; + + if (!gadget || !gadget->sg_supported) + return -EPERM; + + dmabuf = dma_buf_get(fd); + if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); + + attach = dma_buf_attach(dmabuf, gadget->dev.parent); + if (IS_ERR(attach)) { + err = PTR_ERR(attach); + goto err_dmabuf_put; + } + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + err = -ENOMEM; + goto err_dmabuf_detach; + } + + attach->importer_priv = priv; + + priv->attach = attach; + spin_lock_init(&priv->lock); + kref_init(&priv->ref); + priv->context = dma_fence_context_alloc(1); + + list_add(&priv->entry, &epfile->dmabufs); + + return 0; + +err_dmabuf_detach: + dma_buf_detach(dmabuf, attach); +err_dmabuf_put: + dma_buf_put(dmabuf); + + return err; +} + +static int ffs_dmabuf_detach(struct file *file, int fd) +{ + struct ffs_epfile *epfile = file->private_data; + struct usb_gadget *gadget = epfile->ffs->gadget; + bool nonblock = file->f_flags & O_NONBLOCK; + struct dma_buf_attachment *attach; + struct dma_buf *dmabuf; + int ret = 0; + + dmabuf = dma_buf_get(fd); + if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); + + attach = ffs_dmabuf_find_attachment(gadget->dev.parent, + dmabuf, nonblock); + if (IS_ERR(attach)) { + ret = PTR_ERR(attach); + goto out_dmabuf_put; + } + + /* + * Unref twice to release the reference obtained with + * ffs_dmabuf_find_attachment() above, and the one obtained in + * ffs_dmabuf_attach(). + */ + ffs_dmabuf_put(attach); + ffs_dmabuf_put(attach); + +out_dmabuf_put: + dma_buf_put(dmabuf); + return ret; +} + +static int ffs_dmabuf_transfer(struct file *file, + const struct usb_ffs_dmabuf_transfer_req *req) +{ + bool dma_to_ram, nonblock = file->f_flags & O_NONBLOCK; + struct ffs_epfile *epfile = file->private_data; + struct usb_gadget *gadget = epfile->ffs->gadget; + struct dma_buf_attachment *attach; + struct ffs_dmabuf_priv *priv; + enum dma_data_direction dir; + struct ffs_dma_fence *fence; + struct usb_request *usb_req; + struct sg_table *sg_table; + struct dma_buf *dmabuf; + struct ffs_ep *ep; + int ret; + + if (req->flags & ~USB_FFS_DMABUF_TRANSFER_MASK) + return -EINVAL; + + dmabuf = dma_buf_get(req->fd); + if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); + + if (req->length > dmabuf->size || req->length == 0) { + ret = -EINVAL; + goto err_dmabuf_put; + } + + attach = ffs_dmabuf_find_attachment(gadget->dev.parent, + dmabuf, nonblock); + if (IS_ERR(attach)) { + ret = PTR_ERR(attach); + goto err_dmabuf_put; + } + + priv = attach->importer_priv; + + if (epfile->in) + dir = DMA_FROM_DEVICE; + else + dir = DMA_TO_DEVICE; + + sg_table = dma_buf_map_attachment(attach, dir); + if (IS_ERR(sg_table)) { + ret = PTR_ERR(sg_table); + goto err_attachment_put; + } + + ep = ffs_epfile_wait_ep(file); + if (IS_ERR(ep)) { + ret = PTR_ERR(ep); + goto err_unmap_attachment; + } + + ret = ffs_dma_resv_lock(dmabuf, nonblock); + if (ret) + goto err_unmap_attachment; + + /* Make sure we don't have writers */ + if (!dma_resv_test_signaled(dmabuf->resv, DMA_RESV_USAGE_WRITE)) { + pr_debug("FFS WRITE fence is not signaled\n"); + ret = -EBUSY; + goto err_resv_unlock; + } + + dma_to_ram = dir == DMA_FROM_DEVICE; + + /* If we're writing to the DMABUF, make sure we don't have readers */ + if (dma_to_ram && + !dma_resv_test_signaled(dmabuf->resv, DMA_RESV_USAGE_READ)) { + pr_debug("FFS READ fence is not signaled\n"); + ret = -EBUSY; + goto err_resv_unlock; + } + + ret = dma_resv_reserve_fences(dmabuf->resv, 1); + if (ret) + goto err_resv_unlock; + + fence = kmalloc(sizeof(*fence), GFP_KERNEL); + if (!fence) { + ret = -ENOMEM; + goto err_resv_unlock; + } + + fence->sgt = sg_table; + fence->dir = dir; + fence->priv = priv; + + dma_fence_init(&fence->base, &ffs_dmabuf_fence_ops, + &priv->lock, priv->context, 0); + + spin_lock_irq(&epfile->ffs->eps_lock); + + /* In the meantime, endpoint got disabled or changed. */ + if (epfile->ep != ep) { + ret = -ESHUTDOWN; + goto err_fence_put; + } + + usb_req = usb_ep_alloc_request(ep->ep, GFP_ATOMIC); + if (!usb_req) { + ret = -ENOMEM; + goto err_fence_put; + } + + dma_resv_add_fence(dmabuf->resv, &fence->base, + dma_resv_usage_rw(dma_to_ram)); + dma_resv_unlock(dmabuf->resv); + + /* Now that the dma_fence is in place, queue the transfer. */ + + usb_req->length = req->length; + usb_req->buf = NULL; + usb_req->sg = sg_table->sgl; + usb_req->num_sgs = sg_nents_for_len(sg_table->sgl, req->length); + usb_req->sg_was_mapped = true; + usb_req->context = fence; + usb_req->complete = ffs_epfile_dmabuf_io_complete; + + ret = usb_ep_queue(ep->ep, usb_req, GFP_ATOMIC); + if (ret) { + usb_ep_free_request(ep->ep, usb_req); + + spin_unlock_irq(&epfile->ffs->eps_lock); + + pr_warn("FFS: Failed to queue DMABUF: %d\n", ret); + ffs_dmabuf_signal_done(fence, ret); + goto out_dma_buf_put; + } + + spin_unlock_irq(&epfile->ffs->eps_lock); + +out_dma_buf_put: + dma_buf_put(dmabuf); + + return ret; + +err_fence_put: + spin_unlock_irq(&epfile->ffs->eps_lock); + dma_fence_put(&fence->base); +err_resv_unlock: + dma_resv_unlock(dmabuf->resv); +err_unmap_attachment: + dma_buf_unmap_attachment(attach, sg_table, dir); +err_attachment_put: + ffs_dmabuf_put(attach); +err_dmabuf_put: + dma_buf_put(dmabuf); + + return ret; +} + static long ffs_epfile_ioctl(struct file *file, unsigned code, unsigned long value) { @@ -1292,6 +1670,44 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, if (WARN_ON(epfile->ffs->state != FFS_ACTIVE)) return -ENODEV; + switch (code) { + case FUNCTIONFS_DMABUF_ATTACH: + { + int fd; + + if (copy_from_user(&fd, (void __user *)value, sizeof(fd))) { + ret = -EFAULT; + break; + } + + return ffs_dmabuf_attach(file, fd); + } + case FUNCTIONFS_DMABUF_DETACH: + { + int fd; + + if (copy_from_user(&fd, (void __user *)value, sizeof(fd))) { + ret = -EFAULT; + break; + } + + return ffs_dmabuf_detach(file, fd); + } + case FUNCTIONFS_DMABUF_TRANSFER: + { + struct usb_ffs_dmabuf_transfer_req req; + + if (copy_from_user(&req, (void __user *)value, sizeof(req))) { + ret = -EFAULT; + break; + } + + return ffs_dmabuf_transfer(file, &req); + } + default: + break; + } + /* Wait for endpoint to be enabled */ ep = ffs_epfile_wait_ep(file); if (IS_ERR(ep)) @@ -1869,6 +2285,7 @@ static int ffs_epfiles_create(struct ffs_data *ffs) for (i = 1; i <= count; ++i, ++epfile) { epfile->ffs = ffs; mutex_init(&epfile->mutex); + INIT_LIST_HEAD(&epfile->dmabufs); if (ffs->user_flags & FUNCTIONFS_VIRTUAL_ADDR) sprintf(epfile->name, "ep%02x", ffs->eps_addrmap[i]); else diff --git a/include/uapi/linux/usb/functionfs.h b/include/uapi/linux/usb/functionfs.h index 078098e73fd3..9f88de9c3d66 100644 --- a/include/uapi/linux/usb/functionfs.h +++ b/include/uapi/linux/usb/functionfs.h @@ -86,6 +86,22 @@ struct usb_ext_prop_desc { __le16 wPropertyNameLength; } __attribute__((packed)); +/* Flags for usb_ffs_dmabuf_transfer_req->flags (none for now) */ +#define USB_FFS_DMABUF_TRANSFER_MASK 0x0 + +/** + * struct usb_ffs_dmabuf_transfer_req - Transfer request for a DMABUF object + * @fd: file descriptor of the DMABUF object + * @flags: one or more USB_FFS_DMABUF_TRANSFER_* flags + * @length: number of bytes used in this DMABUF for the data transfer. + * Should generally be set to the DMABUF's size. + */ +struct usb_ffs_dmabuf_transfer_req { + int fd; + __u32 flags; + __u64 length; +} __attribute__((packed)); + #ifndef __KERNEL__ /* @@ -290,6 +306,31 @@ struct usb_functionfs_event { #define FUNCTIONFS_ENDPOINT_DESC _IOR('g', 130, \ struct usb_endpoint_descriptor) +/* + * Attach the DMABUF object, identified by its file descriptor, to the + * data endpoint. Returns zero on success, and a negative errno value + * on error. + */ +#define FUNCTIONFS_DMABUF_ATTACH _IOW('g', 131, int) + +/* + * Detach the given DMABUF object, identified by its file descriptor, + * from the data endpoint. Returns zero on success, and a negative + * errno value on error. Note that closing the endpoint's file + * descriptor will automatically detach all attached DMABUFs. + */ +#define FUNCTIONFS_DMABUF_DETACH _IOW('g', 132, int) + +/* + * Enqueue the previously attached DMABUF to the transfer queue. + * The argument is a structure that packs the DMABUF's file descriptor, + * the size in bytes to transfer (which should generally correspond to + * the size of the DMABUF), and a 'flags' field which is unused + * for now. Returns zero on success, and a negative errno value on + * error. + */ +#define FUNCTIONFS_DMABUF_TRANSFER _IOW('g', 133, \ + struct usb_ffs_dmabuf_transfer_req) #endif /* _UAPI__LINUX_FUNCTIONFS_H__ */ From patchwork Mon Jan 8 12:00:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 185928 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:37c1:b0:101:2151:f287 with SMTP id y1csp970197dyq; Mon, 8 Jan 2024 04:02:55 -0800 (PST) X-Google-Smtp-Source: AGHT+IE6IK1poDGnY4z86Hj2WmJRwvPsg+UlJ7a9GIZp0lW8DsVotkEylVRM1UVFHebQuEDjWkGt X-Received: by 2002:a17:90a:bf83:b0:28d:651:2631 with SMTP id d3-20020a17090abf8300b0028d06512631mr1534256pjs.88.1704715375630; Mon, 08 Jan 2024 04:02:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704715375; cv=none; d=google.com; s=arc-20160816; b=z65AWgsiOcqVl3hdmzlNIUoT4lpoABq9Bq5+OsnitjKRonjtxPqXcUPBb+ifGeDqgI qThNtTxiGRUGcxIpDK/faSUfFUAeBHgebii0rovA87oOheWT5vwIGdJmPVW/n7cxLlKz JrIdDs68TvEcUYVYrkPaustuhq273c1UP5Dqq/X0cusHGGP/RhC3medDg0lWDRUcOX43 XkDENDxWgPe+MISPNa/fzjEgjTxpwkNa2bfhhG+Ah+gJPMu30pPxsMCCbW/IrWbuNVFp hfHy5+Y80Om77q8cfcrZlZCzfwmBFDBbmZmvJ6p1xeNFMxbTgxzFbNsQrKZeVWWNaAAU CFbg== ARC-Message-Signature: i=1; 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 :date:subject:cc:to:from:dkim-signature; bh=zL3Tp6j0FI2WH0LNy5N+K5/yV+yjLiDhRH8Apc3kyR0=; fh=uCl+pDf5A/h9/EhC2a7e6oA3XsaNDDsC5zMoVf40Kzc=; b=grHB5RNd1VH8k6CjblLE17K12K3knU1vzHOc6aJvSJhPiIoEWeOTIWTaG/bV6M/1GS z8gpVTpdUUlu5Atjw5VKImKD0GYZgmIF+swDavQXnptSGQmMtIkSz7BWiALILefbdH/E xQPF+vPmICjx1q/20Nr7YAzDFA/ME/Mm05puvAklyME+gH1qGShrylffC0dXBUqLRWhE ZX4Fqpv+UKGXdXdYYidh8HosZvONsI2Cn8uI/jOlWSqDJ3UXMlQXoj7TblMpcwik5tZ7 AIY5PY3+OixYjbWJxMYhvyw4dwZSCHR3S558oDDTJ4QLJ+QemPk+WVJikMeKG+NuZ11J IhDQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=cgWfNFnB; spf=pass (google.com: domain of linux-kernel+bounces-19464-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-19464-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id p11-20020a17090b010b00b0028d38c793e4si3443856pjz.36.2024.01.08.04.02.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jan 2024 04:02:55 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-19464-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@crapouillou.net header.s=mail header.b=cgWfNFnB; spf=pass (google.com: domain of linux-kernel+bounces-19464-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-19464-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net 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 sv.mirrors.kernel.org (Postfix) with ESMTPS id B04932836E3 for ; Mon, 8 Jan 2024 12:02:50 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 98B4C358A4; Mon, 8 Jan 2024 12:01:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=crapouillou.net header.i=@crapouillou.net header.b="cgWfNFnB" X-Original-To: linux-kernel@vger.kernel.org Received: from aposti.net (aposti.net [89.234.176.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9B59B29412; Mon, 8 Jan 2024 12:01:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=crapouillou.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=crapouillou.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1704715266; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zL3Tp6j0FI2WH0LNy5N+K5/yV+yjLiDhRH8Apc3kyR0=; b=cgWfNFnBlx8XcxRkz6PLY+lsRV8zjLvwNCEb+L6VVnv8ksJAaPibrjKhNtF2TaQWErgXH7 Y9cBoaxDQIPQTzwMdqXvjv+LRDIlmk+keUTPfMvZiGpAlwBPhtwUQ3ucK2+vQTwRu7HRpY TyoFiLpGf5rG8lSa0r3vZX5fMmkmdB0= From: Paul Cercueil To: Greg Kroah-Hartman , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Jonathan Corbet Cc: Jonathan Cameron , =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Andrzej Pietrasiewicz , linux-usb@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Paul Cercueil Subject: [PATCH v3 4/4] Documentation: usb: Document FunctionFS DMABUF API Date: Mon, 8 Jan 2024 13:00:56 +0100 Message-ID: <20240108120056.22165-5-paul@crapouillou.net> In-Reply-To: <20240108120056.22165-1-paul@crapouillou.net> References: <20240108120056.22165-1-paul@crapouillou.net> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam: Yes X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787523629955236910 X-GMAIL-MSGID: 1787523629955236910 Add documentation for the three ioctls used to attach or detach externally-created DMABUFs, and to request transfers from/to previously attached DMABUFs. Signed-off-by: Paul Cercueil --- v3: New patch --- Documentation/usb/functionfs.rst | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Documentation/usb/functionfs.rst b/Documentation/usb/functionfs.rst index a3054bea38f3..d05a775bc45b 100644 --- a/Documentation/usb/functionfs.rst +++ b/Documentation/usb/functionfs.rst @@ -2,6 +2,9 @@ How FunctionFS works ==================== +Overview +======== + From kernel point of view it is just a composite function with some unique behaviour. It may be added to an USB configuration only after the user space driver has registered by writing descriptors and @@ -66,3 +69,36 @@ have been written to their ep0's. Conversely, the gadget is unregistered after the first USB function closes its endpoints. + +DMABUF interface +================ + +FunctionFS additionally supports a DMABUF based interface, where the +userspace can attach DMABUF objects (externally created) to an endpoint, +and subsequently use them for data transfers. + +A userspace application can then use this interface to share DMABUF +objects between several interfaces, allowing it to transfer data in a +zero-copy fashion, for instance between IIO and the USB stack. + +As part of this interface, three new IOCTLs have been added. These three +IOCTLs have to be performed on a data endpoint (ie. not ep0). They are: + + ``FUNCTIONFS_DMABUF_ATTACH(int)`` + Attach the DMABUF object, identified by its file descriptor, to the + data endpoint. Returns zero on success, and a negative errno value + on error. + + ``FUNCTIONFS_DMABUF_DETACH(int)`` + Detach the given DMABUF object, identified by its file descriptor, + from the data endpoint. Returns zero on success, and a negative + errno value on error. Note that closing the endpoint's file + descriptor will automatically detach all attached DMABUFs. + + ``FUNCTIONFS_DMABUF_TRANSFER(struct usb_ffs_dmabuf_transfer_req *)`` + Enqueue the previously attached DMABUF to the transfer queue. + The argument is a structure that packs the DMABUF's file descriptor, + the size in bytes to transfer (which should generally correspond to + the size of the DMABUF), and a 'flags' field which is unused + for now. Returns zero on success, and a negative errno value on + error.