mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
USB: EHCI: accept very late isochronous URBs
Since commits4005ad4390
(EHCI: implement new semantics for URB_ISO_ASAP) andc75c5ab575
(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 commit4005ad4390
. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Tested-by: Maksim Boyko <maksboyko@yandex.ru> CC: Clemens Ladisch <clemens@ladisch.de> CC: <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
d4e4ab86bc
commit
24f531371d
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user