[alsa-devel] [PATCH] ALSA: usb-audio: do not trust too-big wMaxPacketSize values

Eldad Zack eldad at fogrefinery.com
Thu Aug 8 20:07:58 CEST 2013



On Thu, 8 Aug 2013, 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.

Works good on here too (M-Audio C400) - and maxsize does gets smaller
for 48/44.1KHz.

> 
> 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>
> ---
>  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)
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 


More information about the Alsa-devel mailing list