diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 8 | ||||
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 21 |
2 files changed, 19 insertions, 10 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 2e704fa3cedf..34a928d3b7d2 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"; | |||
79 | #define EHCI_TUNE_RL_TT 0 | 79 | #define EHCI_TUNE_RL_TT 0 |
80 | #define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */ | 80 | #define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */ |
81 | #define EHCI_TUNE_MULT_TT 1 | 81 | #define EHCI_TUNE_MULT_TT 1 |
82 | #define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ | 82 | /* |
83 | * Some drivers think it's safe to schedule isochronous transfers more than | ||
84 | * 256 ms into the future (partly as a result of an old bug in the scheduling | ||
85 | * code). In an attempt to avoid trouble, we will use a minimum scheduling | ||
86 | * length of 512 frames instead of 256. | ||
87 | */ | ||
88 | #define EHCI_TUNE_FLS 1 /* (medium) 512-frame schedule */ | ||
83 | 89 | ||
84 | #define EHCI_IAA_MSECS 10 /* arbitrary */ | 90 | #define EHCI_IAA_MSECS 10 /* arbitrary */ |
85 | #define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ | 91 | #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 27dd841b9aa2..dd37350170bb 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -1395,28 +1395,31 @@ iso_stream_schedule ( | |||
1395 | struct ehci_iso_stream *stream | 1395 | struct ehci_iso_stream *stream |
1396 | ) | 1396 | ) |
1397 | { | 1397 | { |
1398 | u32 now, next, start, period; | 1398 | u32 now, next, start, period, span; |
1399 | int status; | 1399 | int status; |
1400 | unsigned mod = ehci->periodic_size << 3; | 1400 | unsigned mod = ehci->periodic_size << 3; |
1401 | struct ehci_iso_sched *sched = urb->hcpriv; | 1401 | struct ehci_iso_sched *sched = urb->hcpriv; |
1402 | 1402 | ||
1403 | if (sched->span > (mod - SCHEDULE_SLOP)) { | 1403 | period = urb->interval; |
1404 | span = sched->span; | ||
1405 | if (!stream->highspeed) { | ||
1406 | period <<= 3; | ||
1407 | span <<= 3; | ||
1408 | } | ||
1409 | |||
1410 | if (span > mod - SCHEDULE_SLOP) { | ||
1404 | ehci_dbg (ehci, "iso request %p too long\n", urb); | 1411 | ehci_dbg (ehci, "iso request %p too long\n", urb); |
1405 | status = -EFBIG; | 1412 | status = -EFBIG; |
1406 | goto fail; | 1413 | goto fail; |
1407 | } | 1414 | } |
1408 | 1415 | ||
1409 | if ((stream->depth + sched->span) > mod) { | 1416 | if (stream->depth + span > mod) { |
1410 | ehci_dbg (ehci, "request %p would overflow (%d+%d>%d)\n", | 1417 | ehci_dbg (ehci, "request %p would overflow (%d+%d>%d)\n", |
1411 | urb, stream->depth, sched->span, mod); | 1418 | urb, stream->depth, span, mod); |
1412 | status = -EFBIG; | 1419 | status = -EFBIG; |
1413 | goto fail; | 1420 | goto fail; |
1414 | } | 1421 | } |
1415 | 1422 | ||
1416 | period = urb->interval; | ||
1417 | if (!stream->highspeed) | ||
1418 | period <<= 3; | ||
1419 | |||
1420 | now = ehci_readl(ehci, &ehci->regs->frame_index) & (mod - 1); | 1423 | now = ehci_readl(ehci, &ehci->regs->frame_index) & (mod - 1); |
1421 | 1424 | ||
1422 | /* Typical case: reuse current schedule, stream is still active. | 1425 | /* Typical case: reuse current schedule, stream is still active. |
@@ -1445,7 +1448,7 @@ iso_stream_schedule ( | |||
1445 | period); | 1448 | period); |
1446 | 1449 | ||
1447 | /* Tried to schedule too far into the future? */ | 1450 | /* Tried to schedule too far into the future? */ |
1448 | if (unlikely(((start - now) & (mod - 1)) + sched->span | 1451 | if (unlikely(((start - now) & (mod - 1)) + span |
1449 | >= mod - 2 * SCHEDULE_SLOP)) { | 1452 | >= mod - 2 * SCHEDULE_SLOP)) { |
1450 | status = -EFBIG; | 1453 | status = -EFBIG; |
1451 | goto fail; | 1454 | goto fail; |