aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hcd.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-10-27 13:55:05 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 14:55:18 -0500
commitdccd574cccad950d9ed9bc192eae4089c6044d9d (patch)
treecd4a5c599c5a50c84dee8074e25e939dae71a276 /drivers/usb/host/ehci-hcd.c
parentd7e055f1975cac560427c924d2bff4b5d41fe442 (diff)
USB: ehci: Respect IST when scheduling new split iTDs.
The EHCI specification says that an EHCI host controller may cache part of the isochronous schedule. The EHCI controller must advertise how much it caches in the schedule through the HCCPARAMS register isochronous scheduling threshold (IST) bits. In theory, adding new iTDs within the IST should be harmless. The HW will follow the old cached linked list and miss the new iTD. SW will notice HW missed the iTD and return 0 for the transfer length. However, Intel ICH9 chipsets (and some later chipsets) have issues when SW attempts to schedule a split transaction within the IST. All transfers will cease being sent out that port, and the drivers will see isochronous packets complete with a length of zero. Start of frames may or may not also disappear, causing the device to go into auto-suspend. This "bus stall" will continue until a control or bulk transfer is queued to a device under that roothub. Most drivers will never cause this behavior, because they use multiple URBs with multiple packets to keep the bus busy. If you limit the number of URBs to one, you may be able to hit this bug. Make sure the EHCI driver does not schedule full-speed transfers within the IST under an Intel chipset. Make sure that when we fall behind the current microframe plus IST, we schedule the new transfer at the next periodic interval after the IST. Don't change the scheduling for new transfers, since the schedule slop will always be greater than the IST. Allow high speed isochronous transfers to be scheduled within the IST, since this doesn't trigger the Intel chipset bug. Make sure that if the host caches the full frame, the EHCI driver's internal isochronous threshold (ehci->i_thresh) is set to 8 microframes + 2 microframes wiggle room. This is similar to what is done in the case where the host caches less than the full frame. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: David Brownell <dbrownell@users.sourceforge.net> Cc: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r--drivers/usb/host/ehci-hcd.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 4ed2c931daeb..546ad8814008 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -549,7 +549,7 @@ static int ehci_init(struct usb_hcd *hcd)
549 /* controllers may cache some of the periodic schedule ... */ 549 /* controllers may cache some of the periodic schedule ... */
550 hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); 550 hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
551 if (HCC_ISOC_CACHE(hcc_params)) // full frame cache 551 if (HCC_ISOC_CACHE(hcc_params)) // full frame cache
552 ehci->i_thresh = 8; 552 ehci->i_thresh = 2 + 8;
553 else // N microframes cached 553 else // N microframes cached
554 ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); 554 ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params);
555 555