Revision c2d7b49f42f50d7fc5cbfd195b785a128723fdf4 authored by Andiry Xu on 19 September 2011, 23:05:12 UTC, committed by Linus Torvalds on 20 September 2011, 00:15:47 UTC
When a xHC host is unable to handle isochronous transfer in the
interval, it reports a Missed Service Error event and skips some tds.

Currently xhci driver handles MSE event in the following ways:

1. When encounter a MSE event, set ep->skip flag, update event ring
   dequeue pointer and return.

2. When encounter the next event on this ep, the driver will run the
   do-while loop, fetch td from ep's td_list to find the td
   corresponding to this event.  All tds missed are marked as short
   transfer(-EXDEV).

The do-while loop will end in two ways:

1. If the td pointed by the event trb is found;

2. If the ep ring's td_list is empty.

However, if a buggy HW reports some unpredicted event (for example, an
overrun event following a MSE event while the ep ring is actually not
empty), the driver will never find the td, and it will loop until the
td_list is empty.

Unfortunately, the spinlock is dropped when give back a urb in the
do-while loop.  During the spinlock released period, the class driver
may still submit urbs and add tds to the td_list.  This may cause
disaster, since the td_list will never be empty and the loop never ends,
and the system hangs.

To fix this, count the number of TDs on the ep ring before skipping TDs,
and quit the loop when skipped that number of tds.  This guarantees the
do-while loop will end after certain number of cycles, and driver will
not be trapped in an infinite loop.

Signed-off-by: Andiry Xu <andiry.xu@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 44f4c3e
Raw File
.gitignore
#
# NOTE! Don't add files that are generated in specific
# subdirectories here. Add them in the ".gitignore" file
# in that subdirectory instead.
#
# NOTE! Please use 'git ls-files -i --exclude-standard'
# command after changing this file, to see if there are
# any tracked files which get ignored after the change.
#
# Normal rules
#
.*
*.o
*.o.*
*.a
*.s
*.ko
*.so
*.so.dbg
*.mod.c
*.i
*.lst
*.symtypes
*.order
modules.builtin
*.elf
*.bin
*.gz
*.bz2
*.lzma
*.xz
*.lzo
*.patch
*.gcno

#
# Top-level generic files
#
/tags
/TAGS
/linux
/vmlinux
/vmlinuz
/System.map
/Module.markers
/Module.symvers

#
# Debian directory (make deb-pkg)
#
/debian/

#
# git files that we don't want to ignore even it they are dot-files
#
!.gitignore
!.mailmap

#
# Generated include files
#
include/config
include/linux/version.h
include/generated
arch/*/include/generated

# stgit generated dirs
patches-*

# quilt's files
patches
series

# cscope files
cscope.*
ncscope.*

# gnu global files
GPATH
GRTAGS
GSYMS
GTAGS

*.orig
*~
\#*#
back to top