• Sarah Sharp's avatar
    xhci: Intel Panther Point BEI quirk. · 80fab3b2
    Sarah Sharp authored
    When a device with an isochronous endpoint is behind a hub plugged into
    the Intel Panther Point xHCI host controller, and the driver submits
    multiple frames per URB, the xHCI driver will set the Block Event
    Interrupt (BEI) flag on all but the last TD for the URB.  This causes
    the host controller to place an event on the event ring, but not send an
    interrupt.  When the last TD for the URB completes, BEI is cleared, and
    we get an interrupt for the whole URB.
    
    However, under a Panther Point xHCI host controller, if the parent hub
    is unplugged when one or more events from transfers with BEI set are on
    the event ring, a port status change event is placed on the event ring,
    but no interrupt is generated.  This means URBs stop completing, and the
    USB device disconnect is not noticed.  Something like a USB headset will
    cause mplayer to hang when the device is disconnected.
    
    If another transfer is sent (such as running `sudo lsusb -v`), the next
    transfer event seems to "unstick" the event ring, the xHCI driver gets
    an interrupt, and the disconnect is reported to the USB core.
    
    The fix is not to use the BEI flag under the Panther Point xHCI host.
    This will impact power consumption and system responsiveness, because
    the xHCI driver will receive an interrupt for every frame in all
    isochronous URBs instead of once per URB.
    
    Intel chipset developers confirm that this bug will be hit if the BEI
    flag is used on any endpoint, not just ones that are behind a hub.
    
    This patch should be backported to kernels as old as 3.0, that contain
    the commit 69e848c2 "Intel xhci: Support
    EHCI/xHCI port switching."
    Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
    Cc: stable@vger.kernel.org
    80fab3b2
xhci-ring.c 121 KB