From patchwork Thu Apr 26 10:17:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Pepper X-Patchwork-Id: 10365357 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9689860225 for ; Thu, 26 Apr 2018 10:28:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7E9A52909D for ; Thu, 26 Apr 2018 10:28:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7182F290A0; Thu, 26 Apr 2018 10:28:13 +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=-7.9 required=2.0 tests=BAYES_00, 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 CA62B2909D for ; Thu, 26 Apr 2018 10:28:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755102AbeDZK2L (ORCPT ); Thu, 26 Apr 2018 06:28:11 -0400 Received: from mail-out-3.itc.rwth-aachen.de ([134.130.5.48]:47390 "EHLO mail-out-3.itc.rwth-aachen.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754727AbeDZK2K (ORCPT ); Thu, 26 Apr 2018 06:28:10 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A2D9AwAKp+Fa/6EagoZbGgEBAQEBAgEBA?= =?us-ascii?q?QEIAQEBAYNDYYEiCphagXR1GpUGCxsRhEACgxAhNxUBAgEBAQEBAQJsHAyFIwY?= =?us-ascii?q?nUhAfMlcGDgWFDwSpFDODdIRlgkUJAYVjgiSBVD+BDyOCMweKdQKMDIt6CHVug?= =?us-ascii?q?36IXoE7hhMnhGSQEgICAgIJAhSBJTIigVIzGiSDEgmCFxcRiAWGA215HA+OagG?= =?us-ascii?q?BFwEB?= X-IPAS-Result: =?us-ascii?q?A2D9AwAKp+Fa/6EagoZbGgEBAQEBAgEBAQEIAQEBAYNDYYE?= =?us-ascii?q?iCphagXR1GpUGCxsRhEACgxAhNxUBAgEBAQEBAQJsHAyFIwYnUhAfMlcGDgWFD?= =?us-ascii?q?wSpFDODdIRlgkUJAYVjgiSBVD+BDyOCMweKdQKMDIt6CHVug36IXoE7hhMnhGS?= =?us-ascii?q?QEgICAgIJAhSBJTIigVIzGiSDEgmCFxcRiAWGA215HA+OagGBFwEB?= X-IronPort-AV: E=Sophos;i="5.49,330,1520895600"; d="scan'208";a="7264702" Received: from rwthex-s3-b.rwth-ad.de ([134.130.26.161]) by mail-in-3.itc.rwth-aachen.de with ESMTP; 26 Apr 2018 12:18:19 +0200 Received: from localhost.localdomain (37.201.181.173) by rwthex-s3-b.rwth-ad.de (2002:8682:1aa1::8682:1aa1) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1415.2; Thu, 26 Apr 2018 12:18:17 +0200 From: Joel Pepper To: Laurent Pinchart CC: Felipe Balbi , Greg Kroah-Hartman , , Paul Elder , Joel Pepper Subject: [PATCH v6 2/2] usb/gadget/uvc-configfs Fix host unable to negotiate framesizes other than first Date: Thu, 26 Apr 2018 12:17:54 +0200 X-Mailer: git-send-email 2.1.4 In-Reply-To: <1524737874-25218-1-git-send-email-joel.pepper@rwth-aachen.de> References: <3b77fb45-5ea3-4622-9473-538b4f80be1e@rwthex-s3-b.rwth-ad.de> <1524737874-25218-1-git-send-email-joel.pepper@rwth-aachen.de> MIME-Version: 1.0 X-Originating-IP: [37.201.181.173] X-ClientProxiedBy: rwthex-s3-a.rwth-ad.de (2002:8682:1aa0::8682:1aa0) To rwthex-s3-b.rwth-ad.de (2002:8682:1aa1::8682:1aa1) Message-ID: <9bcd4f01-dc7e-45c0-b9ca-5676c3e7f5ca@rwthex-s3-b.rwth-ad.de> 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 - Add bFrameIndex as a UVCG_FRAME_ATTR_RO for each frame size. - Automatically assign ascending bFrameIndex to each frame in a format. Before all "bFrameindex" attributes were set to "1" with no way to configure the gadget otherwise. This resulted in the host always negotiating for bFrameIndex 1 (i.e. the first framesize of the gadget). After the negotiation the host driver will set the user or application selected framesize, while the gadget is actually set to the first framesize. Now, when the containing format is linked into the streaming header, iterate over all child frame descriptors and assign ascending indices. The automatically assigned indices can be read from the new read only bFrameIndex configsfs attribute in each frame descriptor item. Signed-off-by: Joel Pepper --- v2: Add the new attribute to both MJPEG and uncompressed frame descriptors in Documentation/ABI, with note that it was added only in a later kernel version v3: Changed from simply allowing user to set the value for bFrameIndex to automatically assigning correct distinct frame indexes. Changed bFrameIndex from RW to RO v4: Actually include updated patch v5: bFrameIndex now returns -EBUSY if the parent fmt is not linked yet v6: Resubmit for next merge window; Documentation change updated to reflect that; Move version comments below tearline Documentation/ABI/testing/configfs-usb-gadget-uvc | 18 +++++++ drivers/usb/gadget/function/uvc_configfs.c | 64 +++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uvc b/Documentation/ABI/testing/configfs-usb-gadget-uvc index 1ba0d0f..86c9b2e 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uvc +++ b/Documentation/ABI/testing/configfs-usb-gadget-uvc @@ -194,6 +194,14 @@ Description: Specific MJPEG frame descriptors bmCapabilities - still image support, fixed frame-rate support +Date: May 2018 +KernelVersion: 4.18 + + bFrameIndex - unique id for this framedescriptor; + only defined after parent format is + linked into the streaming header; + read-only + What: /config/usb-gadget/gadget/functions/uvc.name/streaming/uncompressed Date: Dec 2014 KernelVersion: 4.0 @@ -241,6 +249,16 @@ Description: Specific uncompressed frame descriptors bmCapabilities - still image support, fixed frame-rate support +Date: May 2018 +KernelVersion: 4.18 + + bFrameIndex - unique id for this framedescriptor; + only defined after parent format is + linked into the streaming header; + read-only + + + What: /config/usb-gadget/gadget/functions/uvc.name/streaming/header Date: Dec 2014 KernelVersion: 4.0 diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c index 7a98f9f..37b4a14 100644 --- a/drivers/usb/gadget/function/uvc_configfs.c +++ b/drivers/usb/gadget/function/uvc_configfs.c @@ -32,6 +32,7 @@ static struct configfs_attribute prefix##attr_##cname = { \ } static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item); +static void __uvcg_fmt_set_indices(struct config_group *fmt); /* control/header/ */ DECLARE_UVC_HEADER_DESCRIPTOR(1); @@ -751,6 +752,8 @@ static int uvcg_streaming_header_allow_link(struct config_item *src, if (!target_fmt) goto out; + __uvcg_fmt_set_indices(to_config_group(target)); + format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL); if (!format_ptr) { ret = -ENOMEM; @@ -991,8 +994,46 @@ end: \ \ UVC_ATTR(uvcg_frame_, cname, aname); + +static ssize_t uvcg_frame_b_frame_index_show(struct config_item *item, + char *page) +{ + struct uvcg_frame *f = to_uvcg_frame(item); + struct uvcg_format *fmt; + struct f_uvc_opts *opts; + struct config_item *opts_item; + struct config_item *fmt_item; + struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex; + int result; + + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ + + fmt_item = f->item.ci_parent; + fmt = to_uvcg_format(fmt_item); + + if (!fmt->linked) { + result = -EBUSY; + goto out; + } + + opts_item = fmt_item->ci_parent->ci_parent->ci_parent; + opts = to_f_uvc_opts(opts_item); + + mutex_lock(&opts->lock); + result = sprintf(page, "%d\n", f->frame.b_frame_index); + mutex_unlock(&opts->lock); + +out: + mutex_unlock(su_mutex); + return result; +} + +UVC_ATTR_RO(uvcg_frame_, b_frame_index, bFrameIndex); + #define noop_conversion(x) (x) + + UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, noop_conversion, noop_conversion, 8); UVCG_FRAME_ATTR(w_width, wWidth, le16_to_cpu, cpu_to_le16, 16); @@ -1140,6 +1181,7 @@ UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval); static struct configfs_attribute *uvcg_frame_attrs[] = { &uvcg_frame_attr_bm_capabilities, + &uvcg_frame_attr_b_frame_index, &uvcg_frame_attr_w_width, &uvcg_frame_attr_w_height, &uvcg_frame_attr_dw_min_bit_rate, @@ -1217,6 +1259,28 @@ static void uvcg_frame_drop(struct config_group *group, struct config_item *item mutex_unlock(&opts->lock); } +static void __uvcg_fmt_set_indices(struct config_group *fmt) +{ + u8 i = 1; + struct list_head *entry; + struct config_item *ci; + struct uvcg_frame *frm; + + list_for_each(entry, &(fmt->cg_children)) { + + ci = container_of(entry, struct config_item, ci_entry); + + if (ci->ci_type != &uvcg_frame_type) + continue; + + frm = to_uvcg_frame(ci); + frm->frame.b_frame_index = i; + i++; + + } + +} + /* streaming/uncompressed/ */ struct uvcg_uncompressed { struct uvcg_format fmt;