From patchwork Wed Oct 10 02:48:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 10633871 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2112F112B for ; Wed, 10 Oct 2018 02:50:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 10568294DF for ; Wed, 10 Oct 2018 02:50:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 04B8529AAE; Wed, 10 Oct 2018 02:50:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A7D09294DF for ; Wed, 10 Oct 2018 02:50:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727351AbeJJKJU (ORCPT ); Wed, 10 Oct 2018 06:09:20 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:44274 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726721AbeJJKJT (ORCPT ); Wed, 10 Oct 2018 06:09:19 -0400 Received: from garnet.amanokami.net (unknown [96.44.9.229]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 54CE21BF9; Wed, 10 Oct 2018 04:49:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1539139760; bh=OCP1C/Jq1hJ1n1s1Bpzhzc8kEnIB9upcUwlguoJnu3w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dijQyiF4D7tGEr3qQGXJNFCCh1CjbLr4KKAVdt7OmLvARLU74Wd/WHiTn9wqRqx9n q3+W+a57HFy8ndYGKIN7rO+7qFE0tnbXt727trreEDoDhaBJ2IgpQOcBddIA5r+LOD cNZEKaZc3GbpPtXpAZPjqj7OTfxsE1o4upKN5a9I= From: Paul Elder To: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com Cc: Paul Elder , b-liu@ti.com, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, balbi@kernel.org, stern@rowland.harvard.edu, rogerq@ti.com Subject: [PATCH 1/6] usb: uvc: include videodev2.h in g_uvc.h Date: Tue, 9 Oct 2018 22:48:58 -0400 Message-Id: <20181010024903.1633-2-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181010024903.1633-1-paul.elder@ideasonboard.com> References: <20181010024903.1633-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP V4L2_EVENT_PRIVATE_START is used in g_uvc.h but is defined in videodev2.h, which is not included and causes a compiler warning: linux/usb/g_uvc.h:15:28: error: ‘V4L2_EVENT_PRIVATE_START’ undeclared here (not in a function) #define UVC_EVENT_FIRST (V4L2_EVENT_PRIVATE_START + 0) Include videodev2.h in g_uvc.h. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart --- include/uapi/linux/usb/g_uvc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/usb/g_uvc.h b/include/uapi/linux/usb/g_uvc.h index 3c9ee3020cbb..6698c3263ae8 100644 --- a/include/uapi/linux/usb/g_uvc.h +++ b/include/uapi/linux/usb/g_uvc.h @@ -11,6 +11,7 @@ #include #include #include +#include #define UVC_EVENT_FIRST (V4L2_EVENT_PRIVATE_START + 0) #define UVC_EVENT_CONNECT (V4L2_EVENT_PRIVATE_START + 0) From patchwork Wed Oct 10 02:48:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 10633869 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3869C933 for ; Wed, 10 Oct 2018 02:49:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2658A294DF for ; Wed, 10 Oct 2018 02:49:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1A30B29B94; Wed, 10 Oct 2018 02:49:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A9EA5294DF for ; Wed, 10 Oct 2018 02:49:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727396AbeJJKJV (ORCPT ); Wed, 10 Oct 2018 06:09:21 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:44280 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726701AbeJJKJV (ORCPT ); Wed, 10 Oct 2018 06:09:21 -0400 Received: from garnet.amanokami.net (unknown [96.44.9.229]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D35CF1BFA; Wed, 10 Oct 2018 04:49:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1539139762; bh=2uMXRpN7ZfS0oDUuPn6ctdCkiFckaZQyBU511QaXG8I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PslQessQqG1rDn6xLKRkwx+xolhTdjTKyNyg/6ngqfnkNWiIgOstm8PhJJT6svZPx jLvV6SUYxr8k9qyydfY9mCdC1PzoZrYS/cF+qaYN0oAlIoBY2xA4SvJD1/5MVTw6o1 bKevTCXs4RsGIxw8iJMK3r+IqeezasTF05TaM4yo= From: Paul Elder To: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com Cc: Paul Elder , b-liu@ti.com, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, balbi@kernel.org, stern@rowland.harvard.edu, rogerq@ti.com Subject: [PATCH 2/6] usb: gadget: uvc: enqueue usb request in setup handler for control OUT Date: Tue, 9 Oct 2018 22:48:59 -0400 Message-Id: <20181010024903.1633-3-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181010024903.1633-1-paul.elder@ideasonboard.com> References: <20181010024903.1633-1-paul.elder@ideasonboard.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently, for uvc class-specific control IN and OUT requests, in the setup handler a UVC_EVENT_SETUP with the setup control is enqueued to userspace. In response to this, the uvc function driver expects userspace to call ioctl UVCIOC_SEND_RESPONSE containing uvc request data. In the case of control IN this is fine, but for control OUT it causes a problem. Since the host sends data immediately after the setup stage completes, it is possible that the empty uvc request data is not enqueued in time for the UDC driver to put the data stage data into (this causes some UDC drivers, such as MUSB, to reply with a STALL). This problem is remedied by having the setup handler enqueue the empty uvc request data, instead of waiting for userspace to do it. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart --- drivers/usb/gadget/function/f_uvc.c | 25 +++++++++++++++++++------ drivers/usb/gadget/function/uvc_v4l2.c | 7 +++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index dc12d868f9e8..8452de3dfccc 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -223,8 +223,6 @@ static int uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) { struct uvc_device *uvc = to_uvc(f); - struct v4l2_event v4l2_event; - struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; if ((ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) { uvcg_info(f, "invalid request type\n"); @@ -241,10 +239,25 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) uvc->event_setup_out = !(ctrl->bRequestType & USB_DIR_IN); uvc->event_length = le16_to_cpu(ctrl->wLength); - memset(&v4l2_event, 0, sizeof(v4l2_event)); - v4l2_event.type = UVC_EVENT_SETUP; - memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req)); - v4l2_event_queue(&uvc->vdev, &v4l2_event); + if (uvc->event_setup_out) { + struct usb_request *req = uvc->control_req; + + /* + * Enqueue the request immediately for control OUT as the + * host will start the data stage straight away. + */ + req->length = uvc->event_length; + req->zero = 0; + usb_ep_queue(f->config->cdev->gadget->ep0, req, GFP_KERNEL); + } else { + struct v4l2_event v4l2_event; + struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; + + memset(&v4l2_event, 0, sizeof(v4l2_event)); + v4l2_event.type = UVC_EVENT_SETUP; + memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req)); + v4l2_event_queue(&uvc->vdev, &v4l2_event); + } return 0; } diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index 038482ff40e8..2e2251bdef03 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -35,6 +35,13 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data) struct usb_composite_dev *cdev = uvc->func.config->cdev; struct usb_request *req = uvc->control_req; + /* + * For control OUT transfers the request has been enqueued synchronously + * by the setup handler, there's nothing to be done here. + */ + if (uvc->event_setup_out) + return 0; + if (data->length < 0) return usb_ep_set_halt(cdev->gadget->ep0); From patchwork Wed Oct 10 02:49:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 10633861 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 815DA679F for ; Wed, 10 Oct 2018 02:49:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6EA2129B94 for ; Wed, 10 Oct 2018 02:49:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 62D6E29CD0; Wed, 10 Oct 2018 02:49:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0A3E729C92 for ; Wed, 10 Oct 2018 02:49:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727467AbeJJKJX (ORCPT ); Wed, 10 Oct 2018 06:09:23 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:44288 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726721AbeJJKJW (ORCPT ); Wed, 10 Oct 2018 06:09:22 -0400 Received: from garnet.amanokami.net (unknown [96.44.9.229]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 594EC1BFB; Wed, 10 Oct 2018 04:49:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1539139763; bh=uhDEMQX5iuVB9gQ5c64F1HPfKJu6/dksbXh7SVKnWAs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ofUgNoNbs3ETaNZUo1FSHkhbEx+XF+ew81wurIx17EADBrqClkEU7ZTsERv6pbCa1 oC1CoKjEFDzTj0egzdLGsGP+TqZF7lZOODXGgMHmSZZk8mJObXWfm5eH3JqZzDm9MA A/8ZpLMSKJn1lFwOdqvr3EM7G35sd1hFHhxcSox0= From: Paul Elder To: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com Cc: Paul Elder , b-liu@ti.com, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, balbi@kernel.org, stern@rowland.harvard.edu, rogerq@ti.com Subject: [PATCH 3/6] usb: gadget: uvc: package setup and data for control OUT requests Date: Tue, 9 Oct 2018 22:49:00 -0400 Message-Id: <20181010024903.1633-4-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181010024903.1633-1-paul.elder@ideasonboard.com> References: <20181010024903.1633-1-paul.elder@ideasonboard.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Since "usb: gadget: uvc: enqueue uvc_request_data in setup handler for control OUT requests" it is no longer necessary for userspace to call ioctl UVCIOC_SEND_RESPONSE in response to receiving a UVC_EVENT_SETUP from the uvc function driver for a control OUT request. This change means that for control OUT userspace will receive a UVC_EVENT_SETUP and not do anything with it. This is a waste of a pair of context switches, so we put the setup and data stage data into a single UVC_EVENT_DATA to give to userspace. Previously struct uvc_request_data had 60 bytes allocated for data, and since uvc data at most is 34 bytes in UVC 1.1 and 48 bytes in UVC 1.5, we can afford to cut out 8 bytes to store the setup control. Since the setup control is discarded after the handling of the setup stage, it must be saved in struct uvc_device during the setup handler in order for the data stage handler to be able to read it and send it to userspace. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart --- drivers/usb/gadget/function/f_uvc.c | 3 +++ drivers/usb/gadget/function/uvc.h | 1 + include/uapi/linux/usb/g_uvc.h | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 8452de3dfccc..9df3eac440ea 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -215,6 +215,8 @@ uvc_function_ep0_complete(struct usb_ep *ep, struct usb_request *req) v4l2_event.type = UVC_EVENT_DATA; uvc_event->data.length = req->actual; memcpy(&uvc_event->data.data, req->buf, req->actual); + memcpy(&uvc_event->data.setup, &uvc->control_setup, + sizeof(uvc_event->data.setup)); v4l2_event_queue(&uvc->vdev, &v4l2_event); } } @@ -238,6 +240,7 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) */ uvc->event_setup_out = !(ctrl->bRequestType & USB_DIR_IN); uvc->event_length = le16_to_cpu(ctrl->wLength); + memcpy(&uvc->control_setup, ctrl, sizeof(uvc->control_setup)); if (uvc->event_setup_out) { struct usb_request *req = uvc->control_req; diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index 5e75c0e93cc4..03d83eab2b90 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -163,6 +163,7 @@ struct uvc_device { unsigned int control_intf; struct usb_ep *control_ep; struct usb_request *control_req; + struct usb_ctrlrequest control_setup; void *control_buf; unsigned int streaming_intf; diff --git a/include/uapi/linux/usb/g_uvc.h b/include/uapi/linux/usb/g_uvc.h index 6698c3263ae8..10fbb4382925 100644 --- a/include/uapi/linux/usb/g_uvc.h +++ b/include/uapi/linux/usb/g_uvc.h @@ -24,7 +24,8 @@ struct uvc_request_data { __s32 length; - __u8 data[60]; + struct usb_ctrlrequest setup; + __u8 data[52]; }; struct uvc_event { From patchwork Wed Oct 10 02:49:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 10633867 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6DDDF933 for ; Wed, 10 Oct 2018 02:49:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5D462294DF for ; Wed, 10 Oct 2018 02:49:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 517FF29B94; Wed, 10 Oct 2018 02:49:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D9466294DF for ; Wed, 10 Oct 2018 02:49:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727469AbeJJKJX (ORCPT ); Wed, 10 Oct 2018 06:09:23 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:44280 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726701AbeJJKJX (ORCPT ); Wed, 10 Oct 2018 06:09:23 -0400 Received: from garnet.amanokami.net (unknown [96.44.9.229]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D7A991C1D; Wed, 10 Oct 2018 04:49:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1539139765; bh=IFgcyVHcjFLgyNIfLwBnAtX8aNSKPm6W8hUPJslYMg4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CS7ZTfnsisL/GtZiY/WXTTXdnJX+0vNngeq6fZgmhH6KB4J2Lh423XGe4/W2tF52W xeA6dhTro/ZJhDWNuvrySUTSH42ymJtayo3EsDzoGYoFvw7mOWMp1ruRJOTfqUCOTd JEka7AdGphTE3aYAT/4g1Yt8+GMDlw8YmKqICVM0= From: Paul Elder To: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com Cc: Paul Elder , b-liu@ti.com, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, balbi@kernel.org, stern@rowland.harvard.edu, rogerq@ti.com Subject: [PATCH 4/6] usb: gadget: add functions to signal udc driver to delay status stage Date: Tue, 9 Oct 2018 22:49:01 -0400 Message-Id: <20181010024903.1633-5-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181010024903.1633-1-paul.elder@ideasonboard.com> References: <20181010024903.1633-1-paul.elder@ideasonboard.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP A usb gadget function driver may or may not want to delay the status stage of a control OUT request. An instance it might want to is to asynchronously validate the data of a class-specific request. Add a function usb_ep_delay_status to allow function drivers to choose to delay the status stage in the request completion handler. The UDC should then check the usb_ep->delayed_status flag and act accordingly to delay the status stage. Also add a function usb_ep_send_response as a wrapper for usb_ep->ops->send_response, whose prototype is added as well. This function should be called by function drivers to tell the UDC what to reply in the status stage that it has requested to be delayed. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart --- drivers/usb/gadget/udc/core.c | 35 +++++++++++++++++++++++++++++++++++ include/linux/usb/gadget.h | 11 +++++++++++ 2 files changed, 46 insertions(+) diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index af88b48c1cea..1ec5ce6b43cd 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -443,6 +443,41 @@ void usb_ep_fifo_flush(struct usb_ep *ep) } EXPORT_SYMBOL_GPL(usb_ep_fifo_flush); +/** + * usb_ep_ep_delay_status - set delay_status flag + * @ep: the endpoint whose delay_status flag is being set + * + * This function instructs the UDC to delay the status stage of a control + * request. It can only be called from the request completion handler of a + * control request. + */ +void usb_ep_delay_status(struct usb_ep *ep) +{ + ep->delayed_status = true; +} +EXPORT_SYMBOL_GPL(usb_ep_delay_status); + +/** + * usb_ep_send_response - reply to control OUT request + * @ep: the endpoint to send reply + * @stall: true for STALL, false for ACK + * + * Instruct the UDC to complete the status stage of a control request that was + * previously delayed with a call to usb_ep_delay_status(). + */ +int usb_ep_send_response(struct usb_ep *ep, bool stall) +{ + if (!ep->ops->send_response) + return -ENOSYS; + + if (!ep->delayed_status) + return -EINVAL; + + ep->delayed_status = false; + return ep->ops->send_response(ep, stall); +} +EXPORT_SYMBOL_GPL(usb_ep_send_response); + /* ------------------------------------------------------------------------- */ /** diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index e5cd84a0f84a..d39c221d4b68 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -144,6 +144,8 @@ struct usb_ep_ops { int (*fifo_status) (struct usb_ep *ep); void (*fifo_flush) (struct usb_ep *ep); + + int (*send_response) (struct usb_ep *ep, bool stall); }; /** @@ -209,6 +211,8 @@ struct usb_ep_caps { * enabled and remains valid until the endpoint is disabled. * @comp_desc: In case of SuperSpeed support, this is the endpoint companion * descriptor that is used to configure the endpoint + * @delayed_status: True if status stage is being delayed. Valid only for + * control endpoints. * * the bus controller driver lists all the general purpose endpoints in * gadget->ep_list. the control endpoint (gadget->ep0) is not in that list, @@ -232,6 +236,7 @@ struct usb_ep { u8 address; const struct usb_endpoint_descriptor *desc; const struct usb_ss_ep_comp_descriptor *comp_desc; + bool delayed_status; }; /*-------------------------------------------------------------------------*/ @@ -249,6 +254,8 @@ int usb_ep_clear_halt(struct usb_ep *ep); int usb_ep_set_wedge(struct usb_ep *ep); int usb_ep_fifo_status(struct usb_ep *ep); void usb_ep_fifo_flush(struct usb_ep *ep); +void usb_ep_delay_status(struct usb_ep *ep); +int usb_ep_send_response(struct usb_ep *ep, bool stall); #else static inline void usb_ep_set_maxpacket_limit(struct usb_ep *ep, unsigned maxpacket_limit) @@ -278,6 +285,10 @@ static inline int usb_ep_fifo_status(struct usb_ep *ep) { return 0; } static inline void usb_ep_fifo_flush(struct usb_ep *ep) { } +static inline void usb_ep_delay_status(struct usb_ep *ep) +{ } +static inline int usb_ep_send_response(struct usb_ep *ep, bool stall) +{ } #endif /* USB_GADGET */ /*-------------------------------------------------------------------------*/ From patchwork Wed Oct 10 02:49:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 10633865 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D9C8C112B for ; Wed, 10 Oct 2018 02:49:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C9B47294DF for ; Wed, 10 Oct 2018 02:49:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BDC8129AAE; Wed, 10 Oct 2018 02:49:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 074BE29CBA for ; Wed, 10 Oct 2018 02:49:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727526AbeJJKJ0 (ORCPT ); Wed, 10 Oct 2018 06:09:26 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:44310 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726701AbeJJKJZ (ORCPT ); Wed, 10 Oct 2018 06:09:25 -0400 Received: from garnet.amanokami.net (unknown [96.44.9.229]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6547D1C3D; Wed, 10 Oct 2018 04:49:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1539139766; bh=LQaoT+rmlpkEpS2F515HIOIpAYO4V9yxI7kW1uHehsk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Lsq9lUfEgwo4coUIsp3ownL4+06BUij/gk556FxV34cGDNqj0IVRf0KjUL4QdchBT gLvQEbBFq3Gg/4M2LYy6vpbypu4o80hnMDhhV1jO8ZmYzV5AfA/rT1sE9iOq5ANXWT m1uVb3qGcYpJo5rJMJbiNmcMlYb3VE33ie9qEZic= From: Paul Elder To: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com Cc: Paul Elder , b-liu@ti.com, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, balbi@kernel.org, stern@rowland.harvard.edu, rogerq@ti.com Subject: [PATCH 5/6] usb: musb: gadget: implement send_response Date: Tue, 9 Oct 2018 22:49:02 -0400 Message-Id: <20181010024903.1633-6-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181010024903.1633-1-paul.elder@ideasonboard.com> References: <20181010024903.1633-1-paul.elder@ideasonboard.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch implements a mechanism to signal the MUSB driver to reply to a control OUT request with STALL or ACK. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart Acked-by: Bin Liu --- drivers/usb/musb/musb_gadget_ep0.c | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 91a5027b5c1f..f0ed1f7472a3 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c @@ -458,6 +458,25 @@ __acquires(musb->lock) return handled; } +static int ep0_send_response(struct musb *musb, bool stall) +{ + void __iomem *regs = musb->control_ep->regs; + u16 ackpend; + + if (musb->ep0_state != MUSB_EP0_STAGE_RX && + musb->ep0_state != MUSB_EP0_STAGE_STATUSIN) + return -EINVAL; + + ackpend = MUSB_CSR0_P_DATAEND + | MUSB_CSR0_P_SVDRXPKTRDY + | (stall ? MUSB_CSR0_P_SENDSTALL : 0); + + musb_ep_select(musb->mregs, 0); + musb_writew(regs, MUSB_CSR0, ackpend); + + return 0; +} + /* we have an ep0out data packet * Context: caller holds controller lock */ @@ -466,10 +485,13 @@ static void ep0_rxstate(struct musb *musb) void __iomem *regs = musb->control_ep->regs; struct musb_request *request; struct usb_request *req; + struct usb_ep *ep; u16 count, csr; + bool last_packet = false; request = next_ep0_request(musb); req = &request->request; + ep = &request->ep->end_point; /* read packet and ack; or stall because of gadget driver bug: * should have provided the rx buffer before setup() returned. @@ -492,6 +514,7 @@ static void ep0_rxstate(struct musb *musb) if (count < 64 || req->actual == req->length) { musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; csr |= MUSB_CSR0_P_DATAEND; + last_packet = true; } else req = NULL; } else @@ -508,6 +531,10 @@ static void ep0_rxstate(struct musb *musb) return; musb->ackpend = 0; } + + if (last_packet && ep->delayed_status) + return; + musb_ep_select(musb->mregs, 0); musb_writew(regs, MUSB_CSR0, csr); } @@ -991,6 +1018,19 @@ static int musb_g_ep0_dequeue(struct usb_ep *ep, struct usb_request *req) return -EINVAL; } +static int musb_g_ep0_send_response(struct usb_ep *e, bool stall) +{ + struct musb_ep *ep = to_musb_ep(e); + struct musb *musb = ep->musb; + unsigned long flags; + int ret; + + spin_lock_irqsave(&musb->lock, flags); + ret = ep0_send_response(musb, stall); + spin_unlock_irqrestore(&musb->lock, flags); + return ret; +} + static int musb_g_ep0_halt(struct usb_ep *e, int value) { struct musb_ep *ep; @@ -1059,4 +1099,5 @@ const struct usb_ep_ops musb_g_ep0_ops = { .queue = musb_g_ep0_queue, .dequeue = musb_g_ep0_dequeue, .set_halt = musb_g_ep0_halt, + .send_response = musb_g_ep0_send_response, }; From patchwork Wed Oct 10 02:49:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 10633863 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 96A7C69B1 for ; Wed, 10 Oct 2018 02:49:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8743329B94 for ; Wed, 10 Oct 2018 02:49:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 78C5129C9C; Wed, 10 Oct 2018 02:49:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DBDB929C9C for ; Wed, 10 Oct 2018 02:49:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727563AbeJJKJ1 (ORCPT ); Wed, 10 Oct 2018 06:09:27 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:44324 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726883AbeJJKJ1 (ORCPT ); Wed, 10 Oct 2018 06:09:27 -0400 Received: from garnet.amanokami.net (unknown [96.44.9.229]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E18EC1C3E; Wed, 10 Oct 2018 04:49:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1539139768; bh=JsxG7EJNzKYcwR9A4HHtrXqKQFblkhWA0v2DVZGe17w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FYnB8GPy1A+sLVazaXsMmQEU51x3iMWh8W9AxMGitLf+3WJQ8SzRx/dEc1V73muM1 bl8MnhTk4rAjS8J8rcs3K9kJtyRV1+AonqWaCLBISKDGrWFzv51bt8Y6Lg8HkZ9n14 KpAZMEfiBx52kx/PGQR92GXFK3sd6kx3tBo82NP4= From: Paul Elder To: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com Cc: Paul Elder , b-liu@ti.com, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, balbi@kernel.org, stern@rowland.harvard.edu, rogerq@ti.com Subject: [PATCH 6/6] usb: gadget: uvc: allow ioctl to send response in status stage Date: Tue, 9 Oct 2018 22:49:03 -0400 Message-Id: <20181010024903.1633-7-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181010024903.1633-1-paul.elder@ideasonboard.com> References: <20181010024903.1633-1-paul.elder@ideasonboard.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We now have a mechanism to signal the UDC driver to reply to a control OUT request with STALL or ACK, and we have packaged the setup stage data and the data stage data of a control OUT request into a single UVC_EVENT_DATA for userspace to consume. The ioctl UVCIOC_SEND_RESPONSE in the case of a control OUT request sends a response to the data stage, and so the ioctl now notifies the UDC driver to reply with STALL or ACK. In the case of a control IN request, the ioctl sends the UVC data as before. Also tell the UDC to delay the status stage for this to work. Signed-off-by: Paul Elder --- drivers/usb/gadget/function/f_uvc.c | 5 +++-- drivers/usb/gadget/function/uvc_v4l2.c | 20 +++++++++++++++++--- drivers/usb/gadget/udc/core.c | 5 +++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 9df3eac440ea..ff89a76a7417 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -209,14 +209,15 @@ uvc_function_ep0_complete(struct usb_ep *ep, struct usb_request *req) struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; if (uvc->event_setup_out) { - uvc->event_setup_out = 0; - memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_DATA; uvc_event->data.length = req->actual; memcpy(&uvc_event->data.data, req->buf, req->actual); memcpy(&uvc_event->data.setup, &uvc->control_setup, sizeof(uvc_event->data.setup)); + + usb_ep_delay_status(ep); + v4l2_event_queue(&uvc->vdev, &v4l2_event); } } diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index 2e2251bdef03..caa6412c0bda 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -37,10 +37,24 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data) /* * For control OUT transfers the request has been enqueued synchronously - * by the setup handler, there's nothing to be done here. + * by the setup handler, we just need to tell the UDC whether to ACK or + * STALL the control transfer. */ - if (uvc->event_setup_out) - return 0; + if (uvc->event_setup_out) { + struct usb_ep *ep = cdev->gadget->ep0; + bool stall = data->length < 0; + + /* + * The length field carries the control request status. + * Negative values signal a STALL and zero values an ACK. + * Positive values are not valid as there is no data to send + * back in the status stage. + */ + if (data->length > 0) + return -EINVAL; + + return usb_ep_send_response(ep, stall); + } if (data->length < 0) return usb_ep_set_halt(cdev->gadget->ep0); diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 1ec5ce6b43cd..0f62a3f1aa29 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1369,6 +1369,11 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri dev_dbg(&udc->dev, "registering UDC driver [%s]\n", driver->function); + if (!udc->gadget->ep0->ops->send_response) { + dev_warn(&udc->dev, "UDC doesn't implement send_response\n"); + dev_warn(&udc->dev, "Proper operation can't be guaranteed\n"); + } + udc->driver = driver; udc->dev.driver = &driver->driver; udc->gadget->dev.driver = &driver->driver;