summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/ehci-hcd.c8
-rw-r--r--drivers/usb/host/ehci-sched.c21
2 files changed, 19 insertions, 10 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 2e704fa3ced..34a928d3b7d 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -79,7 +79,13 @@ static const char hcd_name [] = "ehci_hcd";
#define EHCI_TUNE_RL_TT 0
#define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */
#define EHCI_TUNE_MULT_TT 1
-#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */
+/*
+ * Some drivers think it's safe to schedule isochronous transfers more than
+ * 256 ms into the future (partly as a result of an old bug in the scheduling
+ * code). In an attempt to avoid trouble, we will use a minimum scheduling
+ * length of 512 frames instead of 256.
+ */
+#define EHCI_TUNE_FLS 1 /* (medium) 512-frame schedule */
#define EHCI_IAA_MSECS 10 /* arbitrary */
#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 27dd841b9aa..dd37350170b 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1395,28 +1395,31 @@ iso_stream_schedule (
struct ehci_iso_stream *stream
)
{
- u32 now, next, start, period;
+ u32 now, next, start, period, span;
int status;
unsigned mod = ehci->periodic_size << 3;
struct ehci_iso_sched *sched = urb->hcpriv;
- if (sched->span > (mod - SCHEDULE_SLOP)) {
+ period = urb->interval;
+ span = sched->span;
+ if (!stream->highspeed) {
+ period <<= 3;
+ span <<= 3;
+ }
+
+ if (span > mod - SCHEDULE_SLOP) {
ehci_dbg (ehci, "iso request %p too long\n", urb);
status = -EFBIG;
goto fail;
}
- if ((stream->depth + sched->span) > mod) {
+ if (stream->depth + span > mod) {
ehci_dbg (ehci, "request %p would overflow (%d+%d>%d)\n",
- urb, stream->depth, sched->span, mod);
+ urb, stream->depth, span, mod);
status = -EFBIG;
goto fail;
}
- period = urb->interval;
- if (!stream->highspeed)
- period <<= 3;
-
now = ehci_readl(ehci, &ehci->regs->frame_index) & (mod - 1);
/* Typical case: reuse current schedule, stream is still active.
@@ -1445,7 +1448,7 @@ iso_stream_schedule (
period);
/* Tried to schedule too far into the future? */
- if (unlikely(((start - now) & (mod - 1)) + sched->span
+ if (unlikely(((start - now) & (mod - 1)) + span
>= mod - 2 * SCHEDULE_SLOP)) {
status = -EFBIG;
goto fail;