Re: [PATCH v2 2/5] usb: gadget: f_uac2: reset wMaxPacketSize

2021-01-07 Thread Felipe Balbi

Jerome Brunet  writes:
> 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 

-- 
balbi


signature.asc
Description: PGP signature


[PATCH v2 2/5] usb: gadget: f_uac2: reset wMaxPacketSize

2021-01-06 Thread Jerome Brunet
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 
---
 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, _epin_desc, 1000, true);
-   set_ep_max_packet_size(uac2_opts, _epout_desc, 1000, false);
-   set_ep_max_packet_size(uac2_opts, _epin_desc, 8000, true);
-   set_ep_max_packet_size(uac2_opts, _epout_desc, 8000, false);
+   ret = set_ep_max_packet_size(uac2_opts, _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, _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, _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, _epout_desc, USB_SPEED_HIGH,
+