Received: by 2002:a05:6a10:2785:0:0:0:0 with SMTP id ia5csp2673750pxb; Mon, 11 Jan 2021 16:49:06 -0800 (PST) X-Google-Smtp-Source: ABdhPJyDl5gUEM9IeqbwiMQVcJKPVpI//aQumysRfvq732CAs77pdYrHQt6lLJVnFqJ2r7BXuuTr X-Received: by 2002:a17:906:8693:: with SMTP id g19mr1448764ejx.111.1610412546293; Mon, 11 Jan 2021 16:49:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1610412546; cv=none; d=google.com; s=arc-20160816; b=dYdUahuPpTQ6Qkzk5BjUdX0jUhhrwkjlYuY0IKKZvUCLD6HK48wnWN9BHuqGuHsPdY NBIaJ8GftAIh1lrOCDJBZfvXyv1vO+PoQOHvvjvlJakCMejdke9+3Zf+gdfl4PtHwXO2 DDV6GCLdBLjJOIXCYwgcb/3mqQOpbtL3UxfebTnyw9O63zfS0ZjRK8LjvAbFn7uC3RUa UrSuNj421uW1BSk0BRCWZSNh88+t8eIGIbS+YDloJse5kBbq+EzIbgpk0uvEQ0a4vE05 9TAZeXAyW9tF90HTWRjumIJX1BkC4+I1nP95ohAY2/1f9o3CjftEBePUezvXbh/H3dI6 DgLA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=YFuotIOzbLVqJKmwefEOC6QSocYy271lTk0lCvYHTR0=; b=tpgk1eEtf2Q+M0M3lKPMJQDcZa1q8MUrF1t+jWH1dP+O4UC7X5WJfrJZ56S/B2eoEp PqR0Nukdi+A8cjNhDtT8cRYWhYKK5ZQ8M4/5sO/ONSkaovERCvlGdpmAfNSfn2KmBQIW rLSddBV01rdflnU2IVPlD3EuvmiAel8Rnruqxj+lGd6KJAge/ybY9BsixqUU2bad9Wlb la/FF4NGgFXN/LcWypZ5WSeLkmRHjb9Pozkh6RDHtoN26PqDfYFDSSJXqO1suJCLAtOV hcA/4lYUT4A7ajQc8STlE4dVSxZGMuyyAY3cc+nwIfDhteiHAGAtEnTvF2iy6F2LbSSX NX/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=AiavzTP8; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z1si387408eji.695.2021.01.11.16.48.42; Mon, 11 Jan 2021 16:49:06 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=AiavzTP8; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728076AbhAKNET (ORCPT + 99 others); Mon, 11 Jan 2021 08:04:19 -0500 Received: from mail.kernel.org ([198.145.29.99]:50798 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728173AbhAKNDy (ORCPT ); Mon, 11 Jan 2021 08:03:54 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 66DFB2251F; Mon, 11 Jan 2021 13:02:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1610370164; bh=69FRb86U0lkthIViw6BofrHtE23XAqp4RBNfmMOLtTs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AiavzTP89gbuE3Eou0+stsc1S3jAKajW5Wo4H6QG+PccIRh0zt7ZekJEn1gYgxrOV T96IrI8MrB7eSB7/Truwh2rYtllVhkP+Kk2+lkiKZxuoAu7KkCbtRnGch6J4ohwwFU I5s7JYs6JnOf2e85FXTRuxKmSCsu99b/uxuA7za4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jerome Brunet Subject: [PATCH 4.4 27/38] usb: gadget: f_uac2: reset wMaxPacketSize Date: Mon, 11 Jan 2021 14:00:59 +0100 Message-Id: <20210111130033.765431926@linuxfoundation.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210111130032.469630231@linuxfoundation.org> References: <20210111130032.469630231@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jerome Brunet commit 9389044f27081d6ec77730c36d5bf9a1288bcda2 upstream. 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 Cc: stable Link: https://lore.kernel.org/r/20201221173531.215169-2-jbrunet@baylibre.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_uac2.c | 69 +++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 14 deletions(-) --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -766,7 +766,7 @@ static struct usb_endpoint_descriptor fs .bEndpointAddress = USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, - .wMaxPacketSize = cpu_to_le16(1023), + /* .wMaxPacketSize = DYNAMIC */ .bInterval = 1, }; @@ -775,7 +775,7 @@ static struct usb_endpoint_descriptor hs .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, - .wMaxPacketSize = cpu_to_le16(1024), + /* .wMaxPacketSize = DYNAMIC */ .bInterval = 4, }; @@ -843,7 +843,7 @@ static struct usb_endpoint_descriptor fs .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, - .wMaxPacketSize = cpu_to_le16(1023), + /* .wMaxPacketSize = DYNAMIC */ .bInterval = 1, }; @@ -852,7 +852,7 @@ static struct usb_endpoint_descriptor hs .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, - .wMaxPacketSize = cpu_to_le16(1024), + /* .wMaxPacketSize = DYNAMIC */ .bInterval = 4, }; @@ -963,12 +963,28 @@ free_ep(struct uac2_rtd_params *prm, str "%s:%d Error!\n", __func__, __LINE__); } -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; @@ -980,10 +996,12 @@ static void set_ep_max_packet_size(const 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; } static int @@ -1082,10 +1100,33 @@ afunc_bind(struct usb_configuration *cfg uac2->c_prm.uac2 = uac2; /* 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; + } hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;