[alsa-devel] [PATCH] ALSA: usb-audio: do not trust too-big wMaxPacketSize values
Takashi Iwai
tiwai at suse.de
Thu Aug 8 11:37:51 CEST 2013
At Thu, 08 Aug 2013 11:24:55 +0200,
Clemens Ladisch wrote:
>
> The driver used to assume that the streaming endpoint's wMaxPacketSize
> value would be an indication of how much data the endpoint expects or
> sends, and compute the number of packets per URB using this value.
>
> However, the Focusrite Scarlett 2i4 declares a value of 1024 bytes,
> while only about 88 or 44 bytes are be actually used. This discrepancy
> would result in URBs with far too few packets, which would not work
> correctly on the EHCI driver.
>
> To get correct URBs, use wMaxPacketSize only as an upper limit on the
> packet size.
>
> Reported-by: James Stone <jamesmstone at gmail.com>
> Tested-by: James Stone <jamesmstone at gmail.com>
> Cc: <stable at vger.kernel.org> # 2.6.35+
> Signed-off-by: Clemens Ladisch <clemens at ladisch.de>
Thanks, applied.
Takashi
> ---
> sound/usb/endpoint.c | 13 ++++++-------
> 1 file changed, 6 insertions(+), 7 deletions(-)
>
> --- a/sound/usb/endpoint.c
> +++ b/sound/usb/endpoint.c
> @@ -591,17 +591,16 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep,
> ep->stride = frame_bits >> 3;
> ep->silence_value = pcm_format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0;
>
> - /* calculate max. frequency */
> - if (ep->maxpacksize) {
> + /* assume max. frequency is 25% higher than nominal */
> + ep->freqmax = ep->freqn + (ep->freqn >> 2);
> + maxsize = ((ep->freqmax + 0xffff) * (frame_bits >> 3))
> + >> (16 - ep->datainterval);
> + /* but wMaxPacketSize might reduce this */
> + if (ep->maxpacksize && ep->maxpacksize < maxsize) {
> /* whatever fits into a max. size packet */
> maxsize = ep->maxpacksize;
> ep->freqmax = (maxsize / (frame_bits >> 3))
> << (16 - ep->datainterval);
> - } else {
> - /* no max. packet size: just take 25% higher than nominal */
> - ep->freqmax = ep->freqn + (ep->freqn >> 2);
> - maxsize = ((ep->freqmax + 0xffff) * (frame_bits >> 3))
> - >> (16 - ep->datainterval);
> }
>
> if (ep->fill_max)
>
More information about the Alsa-devel
mailing list