Commit 6b02af34 authored by John Keeping's avatar John Keeping Committed by Greg Kroah-Hartman

usb: gadget: f_uac2: fix packet size calculation

The packet size for USB audio must always be a multiple of the frame
size, otherwise we are transmitting a partial frame which omits some
channels (and these end up at the wrong offset in the next packet).
Furthermore, it breaks the residue handling such that we end up trying
to send a packet exceeding the maximum packet size for the endpoint.
Signed-off-by: default avatarJohn Keeping <john@metanate.com>
Signed-off-by: default avatarFelipe Balbi <balbi@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1e056efa
...@@ -407,7 +407,7 @@ int u_audio_start_playback(struct g_audio *audio_dev) ...@@ -407,7 +407,7 @@ int u_audio_start_playback(struct g_audio *audio_dev)
struct usb_ep *ep; struct usb_ep *ep;
struct uac_rtd_params *prm; struct uac_rtd_params *prm;
struct uac_params *params = &audio_dev->params; struct uac_params *params = &audio_dev->params;
unsigned int factor, rate; unsigned int factor;
const struct usb_endpoint_descriptor *ep_desc; const struct usb_endpoint_descriptor *ep_desc;
int req_len, i; int req_len, i;
...@@ -426,13 +426,15 @@ int u_audio_start_playback(struct g_audio *audio_dev) ...@@ -426,13 +426,15 @@ int u_audio_start_playback(struct g_audio *audio_dev)
/* pre-compute some values for iso_complete() */ /* pre-compute some values for iso_complete() */
uac->p_framesize = params->p_ssize * uac->p_framesize = params->p_ssize *
num_channels(params->p_chmask); num_channels(params->p_chmask);
rate = params->p_srate * uac->p_framesize;
uac->p_interval = factor / (1 << (ep_desc->bInterval - 1)); uac->p_interval = factor / (1 << (ep_desc->bInterval - 1));
uac->p_pktsize = min_t(unsigned int, rate / uac->p_interval, uac->p_pktsize = min_t(unsigned int,
uac->p_framesize *
(params->p_srate / uac->p_interval),
prm->max_psize); prm->max_psize);
if (uac->p_pktsize < prm->max_psize) if (uac->p_pktsize < prm->max_psize)
uac->p_pktsize_residue = rate % uac->p_interval; uac->p_pktsize_residue = uac->p_framesize *
(params->p_srate % uac->p_interval);
else else
uac->p_pktsize_residue = 0; uac->p_pktsize_residue = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment