usb: gadget: u_audio: Fix high-speed max packet size
authorJohn Keeping <john@metanate.com>
Fri, 17 Jan 2020 10:40:22 +0000 (10:40 +0000)
committerFelipe Balbi <balbi@kernel.org>
Tue, 11 Feb 2020 06:45:45 +0000 (08:45 +0200)
Prior to commit eb9fecb9e69b ("usb: gadget: f_uac2: split out audio
core") the maximum packet size was calculated only from the high-speed
descriptor but now we use the largest of the full-speed and high-speed
descriptors.

This is correct, but the full-speed value is likely to be higher than
that for high-speed and this leads to submitting requests for OUT
transfers (received by the gadget) which are larger than the endpoint's
maximum packet size.  These are rightly rejected by the gadget core.

config_ep_by_speed() already sets up the correct maximum packet size for
the enumerated speed in the usb_ep structure, so we can simply use this
instead of the overall value that has been used to allocate buffers for
requests.

Note that the minimum period for ALSA is still set from the largest
value, and this is unavoidable because it's possible to open the audio
device before the gadget has been enumerated.

Tested-by: Pavel Hofman <pavel.hofman@ivitera.com>
Signed-off-by: John Keeping <john@metanate.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
drivers/usb/gadget/function/u_audio.c

index 6d956f1..e6d32c5 100644 (file)
@@ -361,7 +361,7 @@ int u_audio_start_capture(struct g_audio *audio_dev)
        ep = audio_dev->out_ep;
        prm = &uac->c_prm;
        config_ep_by_speed(gadget, &audio_dev->func, ep);
-       req_len = prm->max_psize;
+       req_len = ep->maxpacket;
 
        prm->ep_enabled = true;
        usb_ep_enable(ep);
@@ -379,7 +379,7 @@ int u_audio_start_capture(struct g_audio *audio_dev)
                        req->context = &prm->ureq[i];
                        req->length = req_len;
                        req->complete = u_audio_iso_complete;
-                       req->buf = prm->rbuf + i * prm->max_psize;
+                       req->buf = prm->rbuf + i * ep->maxpacket;
                }
 
                if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC))
@@ -430,9 +430,9 @@ int u_audio_start_playback(struct g_audio *audio_dev)
        uac->p_pktsize = min_t(unsigned int,
                                uac->p_framesize *
                                        (params->p_srate / uac->p_interval),
-                               prm->max_psize);
+                               ep->maxpacket);
 
-       if (uac->p_pktsize < prm->max_psize)
+       if (uac->p_pktsize < ep->maxpacket)
                uac->p_pktsize_residue = uac->p_framesize *
                        (params->p_srate % uac->p_interval);
        else
@@ -457,7 +457,7 @@ int u_audio_start_playback(struct g_audio *audio_dev)
                        req->context = &prm->ureq[i];
                        req->length = req_len;
                        req->complete = u_audio_iso_complete;
-                       req->buf = prm->rbuf + i * prm->max_psize;
+                       req->buf = prm->rbuf + i * ep->maxpacket;
                }
 
                if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC))