summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2013-08-08 11:24:55 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-14 22:59:07 -0700
commitf004da5326d74b43d90ebf06699674378d4f0bb3 (patch)
tree8e9a6c5657223eeaf121bbefad2844bc5eca0929
parente88512e77c0a22fc860cfb1100920cb1ca3705d3 (diff)
ALSA: usb-audio: do not trust too-big wMaxPacketSize values
commit 57e6dae1087bbaa6b33d3dd8a8e90b63888939a3 upstream. 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@gmail.com> Tested-by: James Stone <jamesmstone@gmail.com> Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--sound/usb/endpoint.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 7a444b5501d9..659950e5b94f 100644
--- 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)