Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp5924569imu; Sun, 20 Jan 2019 23:33:08 -0800 (PST) X-Google-Smtp-Source: ALg8bN5mtZ4HkRKBQ14lxPLkImUx6X2YEPv6nkFBATxqDRuCS5KHaKXJ3lr/nYFMMYhkuRYVuFSh X-Received: by 2002:a63:334a:: with SMTP id z71mr27361217pgz.400.1548055988803; Sun, 20 Jan 2019 23:33:08 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548055988; cv=none; d=google.com; s=arc-20160816; b=plc622vFby3ALUvAE157ne07DG8q8tGMyqS0rAdqzUho3NIn8sV7mFVLe2JJDl8/Ho rClyaVhNS61eClGKYTIi0J6RWHa+pVnYxuyLVK0PCBS9ZXBzyp2ZvB0GYf6cPX9Ym2mW NBKtLuGuxB+btjVum1C/nG616jdPqEYHQIGhfHYCQDrnjgZLvG8724qvOLRggRlhfRwi BNpZ6uLrpgwuxtkggy20Rg8xzppW0yjRYC856aTY0XWnYfwTeWloYeG3lofZ+qq7siKM kMDaBDAujzfi7xWmXXwlqVhWpuBaVChK+kfGI2Ix/Uvr3tABbdqkXdUWGTPwHSwYC6pQ bW0w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=A2/fuLW2swoQuYAcbxwg8c57rK1+enasqyzgfPxmP/Q=; b=T/y+yKUEFZEeDcGncJjyUdIBWXyHW7fZgXoeiHqlNsgSVfSJtE1MzHpxTeifk88stV mpicxSm1kP/h2Ok301VW3TZuFcGZP1vtP8t5Kg206bDebC7/qi1EqXoeEuWBEUBgbGkt D9yJg/ycHOatNugwECB9XFfOlRx1A/bbEd3qIs7zY+sYPB0I9ZO1Kc5IksmWqwH+oPk0 3C/sEWiFDJkUMuiZNnCS4eiSuNh7yntPINWz4GrSRFDrVH0x1vnrdjaA7HVwSDqyzpsO i4+vbMZclvJDrM938fH6lU2dcp7wTW7xyFzueYDGQsXmUL4QlS3dbj58biSHf2yb5cUU OntA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass (test mode) header.i=@ideasonboard.com header.s=mail header.b="k/vfs1A5"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p3si11506481plr.376.2019.01.20.23.32.53; Sun, 20 Jan 2019 23:33:08 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass (test mode) header.i=@ideasonboard.com header.s=mail header.b="k/vfs1A5"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728570AbfAUHbg (ORCPT + 99 others); Mon, 21 Jan 2019 02:31:36 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:45900 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727597AbfAUHbd (ORCPT ); Mon, 21 Jan 2019 02:31:33 -0500 Received: from localhost.localdomain (unknown [96.44.9.117]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 01A2FE46; Sun, 20 Jan 2019 20:41:57 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1548013319; bh=e3y5eq3pWQILXCkoJ1/Ruo8CBZq3bYdfhPm3gOvlNPE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=k/vfs1A5usErhwm01SEEc8p7IXTAS6stFZIeSq1PRRgdsJSi9HObCd4L8EgNAqlcx QJO8965/nbkKM3pFtg9SXnilaBxz0aS9HfCzgv+OcLxArZrLrAtA+DTqAuV5Ea87uN AalHkmrsA08HxuguSentExVSeqfbdzxpRhSW3cac= 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 v6 2/6] usb: gadget: uvc: enqueue usb request in setup handler for control OUT Date: Sun, 20 Jan 2019 14:41:32 -0500 Message-Id: <20190120194136.21870-3-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190120194136.21870-1-paul.elder@ideasonboard.com> References: <20190120194136.21870-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 v5 No change from v4 No change from v3 No change from v2 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 4134117b5f81..f571623cc6e4 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 7816ea9886e1..ac48f49d9f10 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); -- 2.20.1