Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2283588imu; Sun, 16 Dec 2018 22:06:21 -0800 (PST) X-Google-Smtp-Source: AFSGD/UYI5rrYC/drOTPv9K/xWSk9aR9ZIeZYPVWfCOt2Y2sa/RmyXf/UjRjikjFzMzkU/eIH3Ch X-Received: by 2002:a63:594d:: with SMTP id j13mr11047053pgm.210.1545026781646; Sun, 16 Dec 2018 22:06:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545026781; cv=none; d=google.com; s=arc-20160816; b=OySAXoRfiDjuIO00by165JLYFOu8pAnRcTH7joSGovEpFPq9ttKYWdU3w7EV3zyIu5 Vw5xoO/8Mjeh5UCiz4QMlPhMwV1uWqZHi5HLeVG4PSp2UkE/43+VyVHr3sII09oE2zvq 31E5/2VH6pq6DlHPB3+TWjUqyPU6Nq3uwtFxSV0v/LM5eVTPNsLGgsnc08OxHzmsds1O TU/+/Q72NdXWK2ae71NEtMhLIhAvFaHD5JOuhkpqQDmJVq59FpDVogUhv/G7iMmtjmQr h5xMAM46B9Ua4/n9EeFcZ32pYq5DfqopSM5N1ot+QJGOpahbYNcrz+r+Z4bN9s6KfwrV NwHw== 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=ER/iI+jgQScfnPZTeq6mqHeZ2icDoLvZQKIzTUGQgD8=; b=BlpDQLKLuqpOn+EQcpgUqZLj4WNsy28APhcBo94PWgglEH6DqJIDwPPnhdwhKU0fP2 A/TcqGt9v17rXifKQVRC8eP2eaUO3aT3uOHW9RPRpptxi9pKGS7HsdlpOmy/FYDW2sTH m+a0A0eCY2bLaQ7HefaeBl4w8XTcBse3pW8C9vTYhAdkTJEAUDQ5nANn4vhsfp6iIEG5 8bUXVN0BW1CJey/w1RtDuqDFf+zKSkY4nO9xGX7/SJ/oIbHocyXdxiYwTG+Wc/HEZL9f WhcAOdDgBgPaTwQqKv2x3IKiixIt5LofoTBtXHHK/f1EYAQb1dAKF7yZWPluzTkhnMzN xmPg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass (test mode) header.i=@ideasonboard.com header.s=mail header.b=MnXBz5dU; 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 t10si10014380plh.307.2018.12.16.22.06.05; Sun, 16 Dec 2018 22:06:21 -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=MnXBz5dU; 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 S1731599AbeLQGDZ (ORCPT + 99 others); Mon, 17 Dec 2018 01:03:25 -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 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 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); -- 2.19.2