From 98cae42d82fe9c9e2b5dacdf391edaa007e147e5 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 28 Sep 2012 16:01:34 -0400 Subject: [PATCH] EHCI: use the isochronous scheduling threshold This patch (as1609) changes the way ehci-hcd uses the "Isochronous Scheduling Threshold" in its calculations. Until now the code has ignored the threshold except for certain Intel PCI-based controllers. This violates the EHCI spec. The new code takes the threshold into account always, removing the need for the fs_i_thresh quirk flag. In addition it implements the "full frame cache" setting more efficiently, moving forward only as far as the next frame boundary instead of always moving forward 8 microframes. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 2 +- drivers/usb/host/ehci-pci.c | 1 - drivers/usb/host/ehci-sched.c | 12 ++++-------- drivers/usb/host/ehci.h | 1 - 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 6bf6c42481e8..61eac96441de 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -503,7 +503,7 @@ static int ehci_init(struct usb_hcd *hcd) /* controllers may cache some of the periodic schedule ... */ if (HCC_ISOC_CACHE(hcc_params)) // full frame cache - ehci->i_thresh = 2 + 8; + ehci->i_thresh = 0; else // N microframes cached ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 2cb7d370c4ef..d1407f8d42b1 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -103,7 +103,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) } break; case PCI_VENDOR_ID_INTEL: - ehci->fs_i_thresh = 1; if (pdev->device == PCI_DEVICE_ID_INTEL_CE4100_USB) hcd->has_tt = 1; break; diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 7eb242f27c00..b764cab2ab9a 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1391,15 +1391,11 @@ iso_stream_schedule ( */ if (likely (!list_empty (&stream->td_list))) { - /* For high speed devices, allow scheduling within the - * isochronous scheduling threshold. For full speed devices - * and Intel PCI-based controllers, don't (work around for - * Intel ICH9 bug). - */ - if (!stream->highspeed && ehci->fs_i_thresh) - next = now + ehci->i_thresh; + /* Take the isochronous scheduling threshold into account */ + if (ehci->i_thresh) + next = now + ehci->i_thresh; /* uframe cache */ else - next = now; + next = (now + 2 + 7) & ~0x07; /* full frame cache */ /* * Use ehci->last_iso_frame as the base. There can't be any diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 0564a63f5eb3..4ddf7c51616b 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -193,7 +193,6 @@ struct ehci_hcd { /* one per controller */ unsigned has_amcc_usb23:1; unsigned need_io_watchdog:1; unsigned amd_pll_fix:1; - unsigned fs_i_thresh:1; /* Intel iso scheduling */ unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ unsigned has_synopsys_hc_bug:1; /* Synopsys HC */ unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */