From patchwork Mon Dec 17 06:02:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 10732761 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 97AB7746 for ; Mon, 17 Dec 2018 06:03:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 87C2A29CB7 for ; Mon, 17 Dec 2018 06:03:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7C12E29CCF; Mon, 17 Dec 2018 06:03:24 +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 294BD29CB7 for ; Mon, 17 Dec 2018 06:03:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731475AbeLQGCx (ORCPT ); Mon, 17 Dec 2018 01:02:53 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:53884 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726363AbeLQGCw (ORCPT ); Mon, 17 Dec 2018 01:02:52 -0500 Received: from localhost.localdomain (unknown [96.44.9.229]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C2ADD578; Mon, 17 Dec 2018 07:02:48 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1545026570; bh=8li5/Y6DfNc5USeRDOrAPneDD1ZGZyUmdrOJP2B+RoM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jm9M9s8Ilw5BTic8bAaofzSg4uAsZbhDhIxMm0WWdVyuBmnVAn83i77L4QVuO7fAJ B0zhgBBJog+CSFMprETB3FynFCDJdDIr2bnLEopvEUr7J6sPBqwYPoB4jFO0iftogI opjKmtbpxj1I49GqeslQOydrWEvBPFCiDPQ8UGz8= From: Paul Elder To: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com Cc: Paul Elder , b-liu@ti.com, stern@rowland.harvard.edu, rogerq@ti.com, balbi@kernel.org, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/6] usb: uvc: include videodev2.h in g_uvc.h Date: Mon, 17 Dec 2018 01:02:11 -0500 Message-Id: <20181217060216.26368-2-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181217060216.26368-1-paul.elder@ideasonboard.com> References: <20181217060216.26368-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 --- No change from v1 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 Mon Dec 17 06:02:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 10732763 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 DC888746 for ; Mon, 17 Dec 2018 06:03:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CA63F29CB7 for ; Mon, 17 Dec 2018 06:03:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BCE3729CCF; Mon, 17 Dec 2018 06:03:30 +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 57E3829CB7 for ; Mon, 17 Dec 2018 06:03:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731495AbeLQGDY (ORCPT ); Mon, 17 Dec 2018 01:03:24 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:53890 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726323AbeLQGCx (ORCPT ); Mon, 17 Dec 2018 01:02:53 -0500 Received: from localhost.localdomain (unknown [96.44.9.229]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4AF89B64; Mon, 17 Dec 2018 07:02:50 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1545026571; bh=/9/TlpL0HgEKiDoc59BeQYVF5j1clAqim0IPOslwtQc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MnXBz5dUI6InXngwuTH0sIH+ituyT6UEt4bDK78SjPReLLQaG4UqY6eD5jeNcu5IB sVXk9JAXMLtKnE7dL2GAXuIwynDGDJBkrNrJBq/YkXVEl/HgCJI9OfCML8jLubAsaA bUc9eaIbWfhU664aAblDQPlc9aIo5FB3sYnENakc= From: Paul Elder To: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com Cc: Paul Elder , b-liu@ti.com, stern@rowland.harvard.edu, rogerq@ti.com, balbi@kernel.org, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/6] usb: gadget: uvc: enqueue usb request in setup handler for control OUT Date: Mon, 17 Dec 2018 01:02:12 -0500 Message-Id: <20181217060216.26368-3-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181217060216.26368-1-paul.elder@ideasonboard.com> References: <20181217060216.26368-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 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 --- No change from v1 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 3e07dcb885b7..772c99c297fc 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 7bfa43dbef9e..35353ffdf3b4 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 Mon Dec 17 06:02:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 10732759 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 C3D131399 for ; Mon, 17 Dec 2018 06:03:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B335629CB7 for ; Mon, 17 Dec 2018 06:03:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A751E29CCF; Mon, 17 Dec 2018 06:03:20 +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 458EF29CB7 for ; Mon, 17 Dec 2018 06:03:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731502AbeLQGCz (ORCPT ); Mon, 17 Dec 2018 01:02:55 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:53906 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731478AbeLQGCz (ORCPT ); Mon, 17 Dec 2018 01:02:55 -0500 Received: from localhost.localdomain (unknown [96.44.9.229]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C6F8AE48; Mon, 17 Dec 2018 07:02:51 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1545026573; bh=4tXR+uF+7/R95wTp2Ni92/O/j0WtRUdj/irsNJBOZac=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QkAoR53j1S4sHudfBdBklw6RG1GQSxn0wzYZyLbAeW7Plzfw2cWsswigU8PTqmPSO Wo4sowNPbawZVyH9DGDiWjkNfASROPN+c5V2rcITCOFBbfaFixB6vmmwCBtMekZawP qtr7l8W4hxpUAu9dsg1HZJ3E5j61VjOCS8A6Qg30= From: Paul Elder To: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com Cc: Paul Elder , b-liu@ti.com, stern@rowland.harvard.edu, rogerq@ti.com, balbi@kernel.org, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/6] usb: gadget: uvc: package setup and data for control OUT requests Date: Mon, 17 Dec 2018 01:02:13 -0500 Message-Id: <20181217060216.26368-4-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181217060216.26368-1-paul.elder@ideasonboard.com> References: <20181217060216.26368-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 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 --- No change from v1 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 772c99c297fc..d08957124e42 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 671020c8a836..1d89b1df4ba0 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 Mon Dec 17 06:02:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 10732757 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 C48091399 for ; Mon, 17 Dec 2018 06:03:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B32F329CCE for ; Mon, 17 Dec 2018 06:03:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A73EE29CB7; Mon, 17 Dec 2018 06:03:17 +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 2F1B729CB7 for ; Mon, 17 Dec 2018 06:03:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731571AbeLQGDL (ORCPT ); Mon, 17 Dec 2018 01:03:11 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:53890 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731495AbeLQGC4 (ORCPT ); Mon, 17 Dec 2018 01:02:56 -0500 Received: from localhost.localdomain (unknown [96.44.9.229]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4CCDC578; Mon, 17 Dec 2018 07:02:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1545026574; bh=n+f4q5XHTOoWjr3QnVUQ3VZNJ+w78Rl3ArG2h481Qn8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gbux4EPiXEba3BtUOXV/IRJVo0jMFElUG3zAZEBg+0vuwNffz4RHuy0sguwrzFGwb wcq+ThG9dY0wE0NNpvkg0yM4f/s1SzQFuV69ECmfE8XCUD7qqfUxvWtObBcOCq8XsM wX5fpzGu35aJutzWwJyWb31Z3/3C+agC7AfdTubw= From: Paul Elder To: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com Cc: Paul Elder , b-liu@ti.com, stern@rowland.harvard.edu, rogerq@ti.com, balbi@kernel.org, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 4/6] usb: gadget: add mechanism to specify an explicit status stage Date: Mon, 17 Dec 2018 01:02:14 -0500 Message-Id: <20181217060216.26368-5-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181217060216.26368-1-paul.elder@ideasonboard.com> References: <20181217060216.26368-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 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. A function driver that wants an explicit status stage should set the newly added explicit_status flag of the usb_request corresponding to the data stage. Later on the function driver can explicitly complete the status stage by enqueueing a usb_request also with the explicit_status flag set, and with the zero flag set to 1 for ACK, or 0 for STALL. To support both explicit and implicit status stages, a UDC driver must call the newly added usb_gadget_control_complete function right after calling usb_gadget_giveback_request. To support the explicit status stage, it might then check what stage the usb_request was queued in, or the explicit_status flag, and the zero flag for what status to send. Signed-off-by: Paul Elder v1 Reviewed-by: Laurent Pinchart --- Changes from v1: Complete change of API. Now we use a flag that should be set in the usb_request that is queued for the data stage to signal to the UDC that we want to delay the status stage (as opposed to setting a flag in the UDC itself, that persists across all requests). We now also provide a function for UDC drivers to very easily allow implicit status stages, to mitigate the need to convert all function drivers to this new API at once, and to make it easier for UDC drivers to convert. drivers/usb/gadget/udc/core.c | 33 +++++++++++++++++++++++++++++++++ include/linux/usb/gadget.h | 10 ++++++++++ 2 files changed, 43 insertions(+) diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index af88b48c1cea..e99481ef9147 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -894,6 +894,39 @@ EXPORT_SYMBOL_GPL(usb_gadget_giveback_request); /* ------------------------------------------------------------------------- */ +/** + * usb_gadget_control_complete - complete the status stage of a control + * request, or delay it + * Context: in_interrupt() + * + * @gadget: gadget whose control request's status stage should be completed + * @explicit_status: true to delay status stage, false to complete here + * + * This is called by device controller drivers after returning the completed + * request back to the gadget layer, to either complete or delay the status + * stage. + */ +void usb_gadget_control_complete(struct usb_gadget *gadget, + unsigned int explicit_status) +{ + struct usb_request *req; + + if (explicit_status) + return; + + /* Send an implicit status-stage request for ep0 */ + req = usb_ep_alloc_request(gadget->ep0, GFP_ATOMIC); + if (req) { + req->length = 0; + req->explicit_status = 0; + req->complete = usb_ep_free_request; + usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); + } +} +EXPORT_SYMBOL_GPL(usb_gadget_control_complete); + +/* ------------------------------------------------------------------------- */ + /** * gadget_find_ep_by_name - returns ep whose name is the same as sting passed * in second parameter or NULL if searched endpoint not found diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index e5cd84a0f84a..7a5283a224c7 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -73,6 +73,7 @@ struct usb_ep; * Note that for writes (IN transfers) some data bytes may still * reside in a device-side FIFO when the request is reported as * complete. + * @explicit_status: If true, delays the status stage * * These are allocated/freed through the endpoint they're used with. The * hardware's driver can add extra per-request data to the memory it returns, @@ -114,6 +115,8 @@ struct usb_request { int status; unsigned actual; + + unsigned explicit_status:1; }; /*-------------------------------------------------------------------------*/ @@ -850,6 +853,13 @@ extern void usb_gadget_giveback_request(struct usb_ep *ep, /*-------------------------------------------------------------------------*/ +/* utility to complete or delay status stage */ + +void usb_gadget_control_complete(struct usb_gadget *gadget, + unsigned int explicit_status); + +/*-------------------------------------------------------------------------*/ + /* utility to find endpoint by name */ extern struct usb_ep *gadget_find_ep_by_name(struct usb_gadget *g, From patchwork Mon Dec 17 06:02:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 10732755 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 D8405746 for ; Mon, 17 Dec 2018 06:03:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C8EC129CB7 for ; Mon, 17 Dec 2018 06:03:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BD43829CCF; Mon, 17 Dec 2018 06:03:11 +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 5D06129CB7 for ; Mon, 17 Dec 2018 06:03:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731536AbeLQGC7 (ORCPT ); Mon, 17 Dec 2018 01:02:59 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:53906 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731478AbeLQGC5 (ORCPT ); Mon, 17 Dec 2018 01:02:57 -0500 Received: from localhost.localdomain (unknown [96.44.9.229]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CDF51E4C; Mon, 17 Dec 2018 07:02:54 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1545026576; bh=1cO5OcvmM7RlA7UDmMxrJSgFT3YVDjBpi+db/Hv7iDU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HGWhB+TN985fN5UH32G7NAIE2MA2YRCFzRRxNNzo9U3WZfGyHGxp2Ui8IuUGcqgcc 4UuM0YbApEo8jHCDDR9ohhpRPkeb+Y6m+YznOPXMn48tQaeFmzIvvj2LuR+UfT+BQE LL2p9p5XJDpqh+KhCw0QJhlul6+aSuFu3YFxCs/Y= From: Paul Elder To: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com Cc: Paul Elder , b-liu@ti.com, stern@rowland.harvard.edu, rogerq@ti.com, balbi@kernel.org, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 5/6] usb: musb: gadget: implement optional explicit status stage Date: Mon, 17 Dec 2018 01:02:15 -0500 Message-Id: <20181217060216.26368-6-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181217060216.26368-1-paul.elder@ideasonboard.com> References: <20181217060216.26368-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 Implement the mechanism for optional explicit status stage for the MUSB driver. This allows a function driver to specify what to reply for the status stage. The functionality for an implicit status stage is retained. Signed-off-by: Paul Elder v1 Reviewed-by: Laurent Pinchart v1 Acked-by: Bin Liu --- Changes from v1: - obvious change to implement v2 mechanism laid out by 4/6 of this series (send_response, and musb_g_ep0_send_response function has been removed, call to usb_gadget_control_complete has been added) - ep0_send_response's ack argument has been changed from stall - last_packet flag in ep0_rxstate has been removed, since it is equal to req != NULL drivers/usb/musb/musb_gadget.c | 1 + drivers/usb/musb/musb_gadget_ep0.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index d3f33f449445..d83315dd22b2 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -145,6 +145,7 @@ __acquires(ep->musb->lock) trace_musb_req_gb(req); usb_gadget_giveback_request(&req->ep->end_point, &req->request); + usb_gadget_control_complete(&musb->g, request->explicit_status); spin_lock(&musb->lock); ep->busy = busy; } diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 91a5027b5c1f..b3da48f4c63c 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 ack) +{ + 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 + | (ack ? 0 : MUSB_CSR0_P_SENDSTALL); + + 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 */ @@ -504,10 +523,13 @@ static void ep0_rxstate(struct musb *musb) if (req) { musb->ackpend = csr; musb_g_ep0_giveback(musb, req); + if (req->explicit_status) + return; if (!musb->ackpend) return; musb->ackpend = 0; } + musb_ep_select(musb->mregs, 0); musb_writew(regs, MUSB_CSR0, csr); } @@ -939,6 +961,12 @@ musb_g_ep0_queue(struct usb_ep *e, struct usb_request *r, gfp_t gfp_flags) case MUSB_EP0_STAGE_ACKWAIT: /* zero-length data */ status = 0; break; + case MUSB_EP0_STAGE_STATUSIN: + if (r->explicit_status) + status = ep0_send_response(musb, r->zero); + else + status = ep0_send_response(musb, 1); + goto cleanup; default: musb_dbg(musb, "ep0 request queued in state %d", musb->ep0_state); From patchwork Mon Dec 17 06:02:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 10732753 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 ECBD9746 for ; Mon, 17 Dec 2018 06:03:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DB70129CB7 for ; Mon, 17 Dec 2018 06:03:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CBC5129CCF; Mon, 17 Dec 2018 06:03:09 +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 5D0A629CB7 for ; Mon, 17 Dec 2018 06:03:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731556AbeLQGDE (ORCPT ); Mon, 17 Dec 2018 01:03:04 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:53890 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731529AbeLQGC7 (ORCPT ); Mon, 17 Dec 2018 01:02:59 -0500 Received: from localhost.localdomain (unknown [96.44.9.229]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 538BCE5C; Mon, 17 Dec 2018 07:02:56 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1545026577; bh=IFKKX+mirCGTL05HfK0wK6Mbk0XG4VRYk0eeVau3ypM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cbVAYCHG1tkApVfObg+dV9Pnf9ngJgbQmTILsoFNg8bzdhteDKp0coQ5w5I6AOCXO sLPcuGGBuS6pnPg4VctdFoOvqgz86mRC2NCW5rR+NOx5p40DfBGDWwvqY0grAUGLXa xCPlwRUNVLQSh/EgskRwkCYofFBdDEA+ma9uPBvo= From: Paul Elder To: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com Cc: Paul Elder , b-liu@ti.com, stern@rowland.harvard.edu, rogerq@ti.com, balbi@kernel.org, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 6/6] usb: gadget: uvc: allow ioctl to send response in status stage Date: Mon, 17 Dec 2018 01:02:16 -0500 Message-Id: <20181217060216.26368-7-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181217060216.26368-1-paul.elder@ideasonboard.com> References: <20181217060216.26368-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 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 --- Changes from v1: - remove usb_ep_delay_status call from the old proposed API - changed portions of uvc_send_response to match v2 API - remove UDC warning that send_response is not implemented drivers/usb/gadget/function/f_uvc.c | 4 ++-- drivers/usb/gadget/function/uvc_v4l2.c | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index d08957124e42..91388bb647e0 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -209,14 +209,13 @@ 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)); + v4l2_event_queue(&uvc->vdev, &v4l2_event); } } @@ -251,6 +250,7 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) */ req->length = uvc->event_length; req->zero = 0; + req->explicit_status = 1; usb_ep_queue(f->config->cdev->gadget->ep0, req, GFP_KERNEL); } else { struct v4l2_event v4l2_event; diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index 35353ffdf3b4..f09aa92a1b01 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -37,10 +37,23 @@ 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) { + /* + * 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; + + req->zero = !data->length; + req->explicit_status = 1; + return usb_ep_queue(cdev->gadget->ep0, req, GFP_KERNEL); + } if (data->length < 0) return usb_ep_set_halt(cdev->gadget->ep0);