From patchwork Wed Jan 6 13:36:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Brunet X-Patchwork-Id: 12001645 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0CDF5C433E0 for ; Wed, 6 Jan 2021 13:38:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D384D23124 for ; Wed, 6 Jan 2021 13:38:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727002AbhAFNi2 (ORCPT ); Wed, 6 Jan 2021 08:38:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48928 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726698AbhAFNi2 (ORCPT ); Wed, 6 Jan 2021 08:38:28 -0500 Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 453C9C06135A for ; Wed, 6 Jan 2021 05:37:09 -0800 (PST) Received: by mail-ed1-x529.google.com with SMTP id j16so4468188edr.0 for ; Wed, 06 Jan 2021 05:37:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UTSIWNrCdfFZGrfLRZuDMagz0Cnd73ZK/iAZinL3Hdk=; b=z4y0UhlLkVRbZwM3AYQ8WT/PFQO5q/ewfILqGNVWDDSMNZ3Dr694H0d6AwNfgq+ISL FdSNQMMAd0pT0ZKv3rBEBj9s5p1d/TBNyPHUpQe0Z73m+HSZJAq86rGi4NbhDsMJmlBf xt32C+2TcJPryWI7lUZBIucFO8LIuFBGBQGsRDRpm4I5kF5Z1qFOC1XFeoC/PO5SHU3E 6M321HF23UdseRxzEJYX3DeJdDCy44rJgNUdxHrubStKupfWATezQ04igbAJekVSFdy5 4kwsTwcjTEWkozYqZZGv4hV3qMn5BMZyqBq8+5kIEKRWq90/NIyqM91iN5MC+ZvFokk/ CCbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UTSIWNrCdfFZGrfLRZuDMagz0Cnd73ZK/iAZinL3Hdk=; b=t6iy7sfNQYia/8jLcLsrtkgibPQ6Yxemu1o+Ezop9aC76bUYo9mTH2qcQv8AdRIovK nuczzFdfz7OMks5TRNr1TEFusclwMZJ5VOYPTMFto78dXRWVEPPt7RgCj+mRHj+aGOUb 3PXqnOr7ANR/dR78pmtQZERbaPAkMBTud8WSN5gVoYW+BPGK0S3hXsNRUntxeSXgZaeV Bs467WxIK2nxDYdMPRj3niUtBS7hFKC5SyKqZoTAMPTXUABvm8Fyqj69PsKuzsy1DL3V 76Dokrd6A+MW5asCwcoH7G/tS6kJPd9hiS3ITynplcPMITbUyu9vy4dioG446C6SnDei X3+Q== X-Gm-Message-State: AOAM532QexAkjOCkx6M87Bu0G6ahNUzGf0g0B+epoMSGIiUSM1/BdqFp 6M+r1kwO6VLFuV704fAo7D0cBA== X-Google-Smtp-Source: ABdhPJxTST/UKEVGGXaHxa8sUjQ9TOJ57dlm4hVgN3wyZhrouwJGt0HYUWmDq8U+NVaEhXraKxMb6w== X-Received: by 2002:a50:bac4:: with SMTP id x62mr3927427ede.59.1609940228024; Wed, 06 Jan 2021 05:37:08 -0800 (PST) Received: from localhost.localdomain (82-65-169-74.subs.proxad.net. [82.65.169.74]) by smtp.googlemail.com with ESMTPSA id n20sm1259275ejo.83.2021.01.06.05.37.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Jan 2021 05:37:07 -0800 (PST) From: Jerome Brunet To: Felipe Balbi , Greg Kroah-Hartman Cc: Jerome Brunet , Ruslan Bilovol , Jack Pham , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/5] usb: gadget: f_uac2: reset wMaxPacketSize Date: Wed, 6 Jan 2021 14:36:49 +0100 Message-Id: <20210106133652.512178-3-jbrunet@baylibre.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210106133652.512178-1-jbrunet@baylibre.com> References: <20210106133652.512178-1-jbrunet@baylibre.com> MIME-Version: 1.0 X-Patchwork-Bot: notify Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org With commit 913e4a90b6f9 ("usb: gadget: f_uac2: finalize wMaxPacketSize according to bandwidth") wMaxPacketSize is computed dynamically but the value is never reset. Because of this, the actual maximum packet size can only decrease each time the audio gadget is instantiated. Reset the endpoint maximum packet size and mark wMaxPacketSize as dynamic to solve the problem. Fixes: 913e4a90b6f9 ("usb: gadget: f_uac2: finalize wMaxPacketSize according to bandwidth") Signed-off-by: Jerome Brunet Acked-by: Felipe Balbi --- drivers/usb/gadget/function/f_uac2.c | 69 ++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 3633df6d7610..5d960b6603b6 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -271,7 +271,7 @@ static struct usb_endpoint_descriptor fs_epout_desc = { .bEndpointAddress = USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, - .wMaxPacketSize = cpu_to_le16(1023), + /* .wMaxPacketSize = DYNAMIC */ .bInterval = 1, }; @@ -280,7 +280,7 @@ static struct usb_endpoint_descriptor hs_epout_desc = { .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, - .wMaxPacketSize = cpu_to_le16(1024), + /* .wMaxPacketSize = DYNAMIC */ .bInterval = 4, }; @@ -348,7 +348,7 @@ static struct usb_endpoint_descriptor fs_epin_desc = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, - .wMaxPacketSize = cpu_to_le16(1023), + /* .wMaxPacketSize = DYNAMIC */ .bInterval = 1, }; @@ -357,7 +357,7 @@ static struct usb_endpoint_descriptor hs_epin_desc = { .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, - .wMaxPacketSize = cpu_to_le16(1024), + /* .wMaxPacketSize = DYNAMIC */ .bInterval = 4, }; @@ -444,12 +444,28 @@ struct cntrl_range_lay3 { __le32 dRES; } __packed; -static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, +static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, struct usb_endpoint_descriptor *ep_desc, - unsigned int factor, bool is_playback) + enum usb_device_speed speed, bool is_playback) { int chmask, srate, ssize; - u16 max_packet_size; + u16 max_size_bw, max_size_ep; + unsigned int factor; + + switch (speed) { + case USB_SPEED_FULL: + max_size_ep = 1023; + factor = 1000; + break; + + case USB_SPEED_HIGH: + max_size_ep = 1024; + factor = 8000; + break; + + default: + return -EINVAL; + } if (is_playback) { chmask = uac2_opts->p_chmask; @@ -461,10 +477,12 @@ static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, ssize = uac2_opts->c_ssize; } - max_packet_size = num_channels(chmask) * ssize * + max_size_bw = num_channels(chmask) * ssize * DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); - ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_packet_size, - le16_to_cpu(ep_desc->wMaxPacketSize))); + ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, + max_size_ep)); + + return 0; } /* Use macro to overcome line length limitation */ @@ -670,10 +688,33 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) } /* Calculate wMaxPacketSize according to audio bandwidth */ - set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true); - set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false); - set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true); - set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false); + ret = set_ep_max_packet_size(uac2_opts, &fs_epin_desc, USB_SPEED_FULL, + true); + if (ret < 0) { + dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); + return ret; + } + + ret = set_ep_max_packet_size(uac2_opts, &fs_epout_desc, USB_SPEED_FULL, + false); + if (ret < 0) { + dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); + return ret; + } + + ret = set_ep_max_packet_size(uac2_opts, &hs_epin_desc, USB_SPEED_HIGH, + true); + if (ret < 0) { + dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); + return ret; + } + + ret = set_ep_max_packet_size(uac2_opts, &hs_epout_desc, USB_SPEED_HIGH, + false); + if (ret < 0) { + dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); + return ret; + } if (EPOUT_EN(uac2_opts)) { agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc);