EHCI: use the isochronous scheduling threshold
authorAlan Stern <stern@rowland.harvard.edu>
Fri, 28 Sep 2012 20:01:34 +0000 (16:01 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 Oct 2012 15:57:43 +0000 (08:57 -0700)
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 <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci.h

index 6bf6c42481e8a6c645236ab27c170819c6f76024..61eac96441de58b8c6d93edbb95452d7a7f9aa04 100644 (file)
@@ -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);
 
index 2cb7d370c4eff93ee39509f739e9669ff2cd3a0a..d1407f8d42b1046b0012bcf52d73bc5cbc6c704e 100644 (file)
@@ -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;
index 7eb242f27c002a8a3537abfc5ec219dca5eef51e..b764cab2ab9ac65d78b88d6dc83ea986c4dde2c8 100644 (file)
@@ -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
index 0564a63f5eb3bee24d0b506bf2cd85a6399990a4..4ddf7c51616bc0e6e357bebd442ebb91199cc9d0 100644 (file)
@@ -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) */