From 4a77405f60f97b5b0c3da55fa738b461e246d5fe Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 7 Aug 2013 10:58:05 -0400 Subject: [PATCH] USB: EHCI: accept very late isochronous URBs Since commits d5932453344f (EHCI: implement new semantics for URB_ISO_ASAP) and 98f8d5e26b84 (ALSA: USB: adjust for changed 3.8 USB API) became widely distributed, people have been experiencing problems with audio transfers. The slightest underrun causes complete failure, requiring the audio stream to be restarted. It turns out that the current isochronous API doesn't handle underruns in the best way. The ALSA developers would much rather have transfers that are submitted too late be accepted and complete in the normal fashion, rather than being refused outright. This patch implements the requested approach. When an isochronous URB submission is so late that all its scheduled slots have already expired, a debugging message will be printed in the log and the URB will be accepted as usual. Assuming it was submitted by a completion handler (which is normally the case), it will complete shortly thereafter with all the usb_iso_packet_descriptor status fields marked -EXDEV. This fixes (for ehci-hcd) https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1191603 It should be applied to all kernels that include commit d5932453344f. Signed-off-by: Alan Stern Tested-by: Maksim Boyko CC: Clemens Ladisch CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sched.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index f80d0330d548d..8e3c878f38cf5 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1391,21 +1391,20 @@ iso_stream_schedule ( /* Behind the scheduling threshold? */ if (unlikely(start < next)) { + unsigned now2 = (now - base) & (mod - 1); /* USB_ISO_ASAP: Round up to the first available slot */ if (urb->transfer_flags & URB_ISO_ASAP) start += (next - start + period - 1) & -period; /* - * Not ASAP: Use the next slot in the stream. If - * the entire URB falls before the threshold, fail. + * Not ASAP: Use the next slot in the stream, + * no matter what. */ - else if (start + span - period < next) { - ehci_dbg(ehci, "iso urb late %p (%u+%u < %u)\n", + else if (start + span - period < now2) { + ehci_dbg(ehci, "iso underrun %p (%u+%u < %u)\n", urb, start + base, - span - period, next + base); - status = -EXDEV; - goto fail; + span - period, now2 + base); } } -- 2.39.5