Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp430429imu; Tue, 8 Jan 2019 23:39:56 -0800 (PST) X-Google-Smtp-Source: ALg8bN5JT8mghC54hZGedNVN8WZYyJPYdeVxKHkXnW9R3UZet9RAa4tTw/GRnHFY2nRvI+cnTpHo X-Received: by 2002:a17:902:780c:: with SMTP id p12mr4866256pll.197.1547019596602; Tue, 08 Jan 2019 23:39:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1547019596; cv=none; d=google.com; s=arc-20160816; b=EzxYgAfYltmdyhsqw6YdfOgdgN0z++XBkNDRmf7Pq2Iw6yhRynez7DN2UdnbYreB6/ E2KTWiNd/CMRg6aREI7bRMyFaBv7ferR9qHQawLMnT72yzfTd3xqUVo3ggCmQiZd+QIL DN/mRgw6YX0tuUaE8dNbwcFjMslmP/Ak3iCUCgrtQ9ZDvAlfJJofwIWU7dVgLenToAqE FAx2e8nv/Sr5CZKUcxTwPfR4G4CLd+TokbdEjyKAlL0dvn11IpovYT5OXuMjqlVLELRn 5S1YywWnB72/wRjvfeMmko7h4YbX2ulePEejB/DrwfqnqHX0lIn0GwUXi1J+ZgWgtd8/ +c7g== 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=ZKnINc3tH82MP7NfwH8QkxgzWOsO4jrshNlOL6UjxFw=; b=dRJQarC4Ds1m68z6yI3/nZ+zpU7lUIbCJD9DArTiqPTUjnQ5PzO18c7cmoD88MsMV8 VZ665bbR3ENZ5hPZUQGw/AzeGriqMvXO9VEPUTCTa3c61Mkh4fc+hd9dE+Qqt7lTZIXy YCrur57K8QuQsjLg6NjLuWLPHNgXoJGCq+ul0UvHOdSssnLdT3/8dToFV2PWP66MZ5ot GIlpXJRQpnfsapEkJiGjCD5vrmHFVjdYvl6fT0F50QdcxKE4aafWz1ilHJIA6BXG8tD8 YTAi1HWoPs2VrwYZDfMnTpE3C5jcvNqSaJIFlIsTa7zfbJwkLfQVyJbj4pMmqbcJSSrI Iyzg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass (test mode) header.i=@ideasonboard.com header.s=mail header.b="dWuYk/CE"; 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 ca19si5301304plb.238.2019.01.08.23.39.40; Tue, 08 Jan 2019 23:39:56 -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="dWuYk/CE"; 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 S1729843AbfAIHJ7 (ORCPT + 99 others); Wed, 9 Jan 2019 02:09:59 -0500 Received: from perceval.ideasonboard.com ([213.167.242.64]:50374 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729528AbfAIHJy (ORCPT ); Wed, 9 Jan 2019 02:09:54 -0500 Received: from localhost.localdomain (unknown [96.44.9.117]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6904458E; Wed, 9 Jan 2019 08:09:50 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1547017791; bh=ybMJEQV2MCdUaTe+2nKF1A6g8PZV6Po01rwD0CPnFXs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dWuYk/CEGmvRrDf9LuECwkuYEwY3ELla0MldCGfNvFxFiJWTnHTqETXeFq68mvkG4 C+eYhPNfA0FeUrNMNvWy26GcIN30h8ku3nEx/Kpb9yi7GWFc9tmnerdLmSHtoQZqnD MOho186KXdOM75GTXSpIqIHIpvfebl/Tksh83Wwg= 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 v5 2/6] usb: gadget: uvc: enqueue usb request in setup handler for control OUT Date: Wed, 9 Jan 2019 02:08:52 -0500 Message-Id: <20190109070856.27460-3-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190109070856.27460-1-paul.elder@ideasonboard.com> References: <20190109070856.27460-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 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 723ca91e4f2a..36de51ac30ed 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