Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 174910
b: refs/heads/master
c: dccd574
h: refs/heads/master
v: v3
  • Loading branch information
Sarah Sharp authored and Greg Kroah-Hartman committed Dec 11, 2009
1 parent 774142c commit 49e38ca
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 12 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d7e055f1975cac560427c924d2bff4b5d41fe442
refs/heads/master: dccd574cccad950d9ed9bc192eae4089c6044d9d
2 changes: 1 addition & 1 deletion trunk/drivers/usb/host/ehci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ static int ehci_init(struct usb_hcd *hcd)
/* controllers may cache some of the periodic schedule ... */
hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
if (HCC_ISOC_CACHE(hcc_params)) // full frame cache
ehci->i_thresh = 8;
ehci->i_thresh = 2 + 8;
else // N microframes cached
ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params);

Expand Down
30 changes: 20 additions & 10 deletions trunk/drivers/usb/host/ehci-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -1394,10 +1394,11 @@ iso_stream_schedule (
struct ehci_iso_stream *stream
)
{
u32 now, start, max, period;
u32 now, next, start, period;
int status;
unsigned mod = ehci->periodic_size << 3;
struct ehci_iso_sched *sched = urb->hcpriv;
struct pci_dev *pdev;

if (sched->span > (mod - SCHEDULE_SLOP)) {
ehci_dbg (ehci, "iso request %p too long\n", urb);
Expand All @@ -1418,26 +1419,35 @@ iso_stream_schedule (

now = ehci_readl(ehci, &ehci->regs->frame_index) % mod;

/* when's the last uframe this urb could start? */
max = now + mod;

/* Typical case: reuse current schedule, stream is still active.
* Hopefully there are no gaps from the host falling behind
* (irq delays etc), but if there are we'll take the next
* slot in the schedule, implicitly assuming URB_ISO_ASAP.
*/
if (likely (!list_empty (&stream->td_list))) {
pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
start = stream->next_uframe;
if (start < now)
start += mod;

/* For high speed devices, allow scheduling within the
* isochronous scheduling threshold. For full speed devices,
* don't. (Work around for Intel ICH9 bug.)
*/
if (!stream->highspeed &&
pdev->vendor == PCI_VENDOR_ID_INTEL)
next = now + ehci->i_thresh;
else
next = now;

/* Fell behind (by up to twice the slop amount)? */
if (start >= max - 2 * SCHEDULE_SLOP)
if (((start - next) & (mod - 1)) >=
mod - 2 * SCHEDULE_SLOP)
start += period * DIV_ROUND_UP(
max - start, period) - mod;
(next - start) & (mod - 1),
period);

/* Tried to schedule too far into the future? */
if (unlikely((start + sched->span) >= max)) {
if (unlikely(((start - now) & (mod - 1)) + sched->span
>= mod - 2 * SCHEDULE_SLOP)) {
status = -EFBIG;
goto fail;
}
Expand Down Expand Up @@ -1482,7 +1492,7 @@ iso_stream_schedule (
/* no room in the schedule */
ehci_dbg (ehci, "iso %ssched full %p (now %d max %d)\n",
list_empty (&stream->td_list) ? "" : "re",
urb, now, max);
urb, now, now + mod);
status = -ENOSPC;

fail:
Expand Down

0 comments on commit 49e38ca

Please sign in to comment.