android_kernel_xiaomi_sm8350/drivers
Sarah Sharp 678539cfaa USB: xhci: Handle URB cancel, complete and resubmit race.
In the old code, there was a race condition between the stop endpoint
command and the URB submission process.  When the stop endpoint command is
handled by the event handler, the endpoint ring is assumed to be stopped.
When a stop endpoint command is queued, URB submissions are to not ring
the doorbell.  The old code would check the number of pending URBs to be
canceled, and would not ring the doorbell if it was non-zero.

However, the following race condition could occur with the old code:

1. Cancel an URB, add it to the list of URBs to be canceled, queue the stop
   endpoint command, and increment ep->cancels_pending to 1.
2. The URB finishes on the HW, and an event is enqueued to the event ring
   (at the same time as 1).
3. The stop endpoint command finishes, and the endpoint is halted.  An
   event is queued to the event ring.
4. The event handler sees the finished URB, notices it was to be
   canceled, decrements ep->cancels_pending to 0, and removes it from the to
   be canceled list.
5. The event handler drops the lock and gives back the URB.  The
   completion handler requeues the URB (or a different driver enqueues a new
   URB).  This causes the endpoint's doorbell to be rung, since
   ep->cancels_pending == 0.  The endpoint is now running.
6. A second URB is canceled, and it's added to the canceled list.
   Since ep->cancels_pending == 0, a new stop endpoint command is queued, and
   ep->cancels_pending is incremented to 1.
7. The event handler then sees the completed stop endpoint command.  The
   handler assumes the endpoint is stopped, but it isn't.  It attempts to
   move the dequeue pointer or change TDs to cancel the second URB, while the
   hardware is actively accessing the endpoint ring.

To eliminate this race condition, a new endpoint state bit is introduced,
EP_HALT_PENDING.  When this bit is set, a stop endpoint command has been
queued, and the command handler has not begun to process the URB
cancellation list yet.  The endpoint doorbell should not be rung when this
is set.  Set this when a stop endpoint command is queued, clear it when
the handler for that command runs, and check if it's set before ringing a
doorbell.  ep->cancels_pending is eliminated, because it is no longer
used.

Make sure to ring the doorbell for an endpoint when the stop endpoint
command handler runs, even if the canceled URB list is empty.  All
canceled URBs could have completed and new URBs could have been enqueued
without the doorbell being rung before the command was handled.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-12-11 11:55:17 -08:00
..
accessibility
acpi Merge branch 'acpica' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6 2009-12-09 19:57:06 -08:00
amba
ata Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
atm Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
auxdisplay
base Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
block Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
bluetooth Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
cdrom Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6 2009-12-09 19:03:16 -08:00
char Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input 2009-12-09 19:52:01 -08:00
clocksource
connector
cpufreq
cpuidle
crypto Merge branch 'for-next' into for-linus 2009-12-07 18:36:35 +01:00
dca
dio m68k: don't export static inline functions 2009-12-06 11:18:28 +01:00
dma Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
edac
eisa
firewire Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
firmware
gpio
gpu Merge branch 'acpica' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6 2009-12-09 19:57:06 -08:00
hid Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input 2009-12-09 19:52:01 -08:00
hwmon Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging 2009-12-09 19:53:11 -08:00
i2c Merge branch 'acpica' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6 2009-12-09 19:57:06 -08:00
ide Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-next-2.6 2009-12-09 19:45:38 -08:00
idle
ieee1394 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
ieee802154
infiniband Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
input Merge branch 'xen/fbdev' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen 2009-12-10 09:34:40 -08:00
isdn Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
leds Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6 2009-12-08 08:15:29 -08:00
lguest
macintosh Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
mca
md Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
media V4L/DVB (13592): max2165: 32bit build patch 2009-12-10 12:45:18 -02:00
memstick
message Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
mfd Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input 2009-12-09 19:52:01 -08:00
misc Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
mmc Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
mtd Merge git://git.infradead.org/ubifs-2.6 2009-12-10 09:31:45 -08:00
net Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
nubus
of
oprofile
parisc Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
parport Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k 2009-12-08 08:13:35 -08:00
pci Merge branch 'acpica' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6 2009-12-09 19:57:06 -08:00
pcmcia Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6 2009-12-08 08:15:29 -08:00
platform Merge branch 'acpica' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6 2009-12-09 19:57:06 -08:00
pnp
power
pps
ps3
rapidio
regulator
rtc Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
s390 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
sbus
scsi Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
serial Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
sfi
sh
sn
spi Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
ssb Merge branch 'master' of /home/davem/src/GIT/linux-2.6/ 2009-12-05 15:22:26 -08:00
staging Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6 2009-12-09 19:50:49 -08:00
tc
telephony Merge branch 'for-next' into for-linus 2009-12-07 18:36:35 +01:00
thermal
uio
usb USB: xhci: Handle URB cancel, complete and resubmit race. 2009-12-11 11:55:17 -08:00
uwb
video Merge branch 'xen/fbdev' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen 2009-12-10 09:34:40 -08:00
virtio
vlynq
w1
watchdog Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-12-09 19:43:33 -08:00
xen Merge branch 'bugfix' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen 2009-12-10 09:35:02 -08:00
zorro m68k: don't export static inline functions 2009-12-06 11:18:28 +01:00
Kconfig
Makefile