linux/drivers/usb/host
Sarah Sharp 522989a27c xhci: Fix failed enqueue in the middle of isoch TD.
When an isochronous transfer is enqueued, xhci_queue_isoc_tx_prepare()
will ensure that there is enough room on the transfer rings for all of the
isochronous TDs for that URB.  However, when xhci_queue_isoc_tx() is
enqueueing individual isoc TDs, the prepare_transfer() function can fail
if the endpoint state has changed to disabled, error, or some other
unknown state.

With the current code, if Nth TD (not the first TD) fails, the ring is
left in a sorry state.  The partially enqueued TDs are left on the ring,
and the first TRB of the TD is not given back to the hardware.  The
enqueue pointer is left on the TRB after the last successfully enqueued
TD.  This means the ring is basically useless.  Any new transfers will be
enqueued after the failed TDs, which the hardware will never read because
the cycle bit indicates it does not own them.  The ring will fill up with
untransferred TDs, and the endpoint will be basically unusable.

The untransferred TDs will also remain on the TD list.  Since the td_list
is a FIFO, this basically means the ring handler will be waiting on TDs
that will never be completed (or worse, dereference memory that doesn't
exist any more).

Change the code to clean up the isochronous ring after a failed transfer.
If the first TD failed, simply return and allow the xhci_urb_enqueue
function to free the urb_priv.  If the Nth TD failed, first remove the TDs
from the td_list.  Then convert the TRBs that were enqueued into No-op
TRBs.  Make sure to flip the cycle bit on all enqueued TRBs (including any
link TRBs in the middle or between TDs), but leave the cycle bit of the
first TRB (which will show software-owned) intact.  Then move the ring
enqueue pointer back to the first TRB and make sure to change the
xhci_ring's cycle state to what is appropriate for that ring segment.

This ensures that the No-op TRBs will be overwritten by subsequent TDs,
and the hardware will not start executing random TRBs because the cycle
bit was left as hardware-owned.

This bug is unlikely to be hit, but it was something I noticed while
tracking down the watchdog timer issue.  I verified that the fix works by
injecting some errors on the 250th isochronous URB queued, although I
could not verify that the ring is in the correct state because uvcvideo
refused to talk to the device after the first usb_submit_urb() failed.
Ring debugging shows that the ring looks correct, however.

This patch should be backported to kernels as old as 2.6.36.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: Andiry Xu <andiry.xu@amd.com>
Cc: stable@kernel.org
2011-08-09 14:49:05 -07:00
..
whci treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ehci-ath79.c Merge branch 'master' into for-next 2011-07-11 14:15:55 +02:00
ehci-atmel.c USB: EHCI: Support controllers with big endian capability regs 2011-05-03 11:43:21 -07:00
ehci-au1xxx.c USB: ehci-au1xxx: fix suspend callback 2011-05-06 18:16:39 -07:00
ehci-cns3xxx.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ehci-dbg.c USB: EHCI: Support controllers with big endian capability regs 2011-05-03 11:43:21 -07:00
ehci-fsl.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ehci-fsl.h USB: ehci-fsl: add MPC5121E specific suspend and resume 2011-05-02 16:59:36 -07:00
ehci-grlib.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ehci-hcd.c Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6 2011-07-25 23:08:32 -07:00
ehci-hub.c USB: EHCI: Fix test mode sequence 2011-08-08 12:34:47 -07:00
ehci-ixp4xx.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ehci-lpm.c USB: Mark EHCI LPM functions as __maybe_unused 2011-02-17 10:47:55 -08:00
ehci-mem.c USB: EHCI: AMD periodic frame list table quirk 2010-11-16 13:36:40 -08:00
ehci-msm.c ehci-msm : use ehci_setup 2011-07-08 14:51:29 -07:00
ehci-mxc.c usb/ehci-mxc: add missing inclusion of mach/hardware.h 2011-08-08 12:34:45 -07:00
ehci-octeon.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ehci-omap.c usb: host: ehci-omap: fix .remove and failure handling path of .probe(v1) 2011-08-01 22:06:48 +03:00
ehci-orion.c USB: EHCI: Support controllers with big endian capability regs 2011-05-03 11:43:21 -07:00
ehci-pci.c Intel xhci: Support EHCI/xHCI port switching. 2011-05-27 12:07:36 -07:00
ehci-pmcmsp.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ehci-ppc-of.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ehci-ps3.c USB: EHCI: Support controllers with big endian capability regs 2011-05-03 11:43:21 -07:00
ehci-q.c EHCI: fix direction handling for interrupt data toggles 2011-07-19 11:25:45 -07:00
ehci-s5p.c USB: ehci-s5p: add PM support 2011-06-06 16:32:36 -07:00
ehci-sched.c USB: EHCI: Allow users to override 80% max periodic bandwidth 2011-07-08 14:51:33 -07:00
ehci-sh.c USB: EHCI: Support controllers with big endian capability regs 2011-05-03 11:43:21 -07:00
ehci-spear.c USB: EHCI: Support controllers with big endian capability regs 2011-05-03 11:43:21 -07:00
ehci-sysfs.c USB: EHCI: Allow users to override 80% max periodic bandwidth 2011-07-08 14:51:33 -07:00
ehci-tegra.c USB: EHCI: Support controllers with big endian capability regs 2011-05-03 11:43:21 -07:00
ehci-vt8500.c USB: EHCI: Support controllers with big endian capability regs 2011-05-03 11:43:21 -07:00
ehci-w90x900.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ehci-xilinx-of.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ehci.h EHCI: fix direction handling for interrupt data toggles 2011-07-19 11:25:45 -07:00
fhci-dbg.c
fhci-hcd.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
fhci-hub.c
fhci-mem.c
fhci-q.c
fhci-sched.c fix comment/printk typos concerning "already" 2010-07-11 21:45:40 +02:00
fhci-tds.c Fix common misspellings 2011-03-31 11:26:23 -03:00
fhci.h Fix common misspellings 2011-03-31 11:26:23 -03:00
fsl-mph-dr-of.c USB: ehci-fsl: Fix 'have_sysif_regs' detection 2011-01-22 18:38:58 -08:00
hwa-hc.c USB: convert usb_hcd bitfields into atomic flags 2010-08-10 14:35:37 -07:00
imx21-dbg.c treewide: fix a few typos in comments 2011-05-10 10:16:21 +02:00
imx21-hcd.c Fix common misspellings 2011-03-31 11:26:23 -03:00
imx21-hcd.h USB: imx21-hcd accept arbitary transfer buffer alignement. 2010-10-22 10:22:03 -07:00
isp116x-hcd.c USB: remove remaining usages of hcd->state from usbcore and fix regression 2011-05-19 16:34:04 -07:00
isp116x.h Fix common misspellings 2011-03-31 11:26:23 -03:00
isp1362-hcd.c sanitize <linux/prefetch.h> usage 2011-05-20 12:50:29 -07:00
isp1362.h USB: host: Remove dead CONFIG_ARCH_KARO 2010-08-10 14:35:40 -07:00
isp1760-hcd.c usb/isp1760: Added missing call to usb_hcd_check_unlink_urb() during unlink 2011-08-08 12:34:48 -07:00
isp1760-hcd.h usb/isp1760: Improve urb queueing, get rid of BUG():s in normal code paths 2011-05-02 17:03:50 -07:00
isp1760-if.c dt/usb: Eliminate users of of_platform_{,un}register_driver 2011-02-28 13:22:45 -07:00
Kconfig USB: UHCI: Support big endian GRUSBHC HC 2011-05-19 16:45:32 -07:00
Makefile USB: Add EHCI and OHCH glue for OCTEON II SOCs. 2010-10-29 19:08:44 +01:00
octeon2-common.c usb: Configure octeon2 glue logic for proper uSOF cycle period. 2011-05-03 10:09:32 -07:00
ohci-at91.c
ohci-ath79.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ohci-au1xxx.c USB: ohci-au1xxx: fix warning "__BIG_ENDIAN" is not defined 2011-04-13 15:44:03 -07:00
ohci-cns3xxx.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ohci-da8xx.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ohci-dbg.c llseek: automatically add .llseek fop 2010-10-15 15:53:27 +02:00
ohci-ep93xx.c
ohci-hcd.c USB: change maintainership of ohci-hcd and ehci-hcd 2011-06-15 17:44:56 -07:00
ohci-hub.c USB 3.0 Hub Changes 2011-03-13 18:07:11 -07:00
ohci-jz4740.c USB: ohci-jz4740: Fix spelling in MODULE_ALIAS 2010-11-11 07:14:07 -08:00
ohci-mem.c
ohci-octeon.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ohci-omap.c
ohci-omap3.c usb: host: omap: ehci and ohci simplification 2011-03-01 17:02:49 +02:00
ohci-pci.c OHCI: fix regression caused by nVidia shutdown workaround 2011-05-17 11:20:23 -07:00
ohci-pnx4008.c i2c: Add support for custom probe function 2010-08-11 18:20:56 +02:00
ohci-pnx8550.c
ohci-ppc-of.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ohci-ppc-soc.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ohci-ps3.c
ohci-pxa27x.c drivers/usb/host/ohci-pxa27x.c: add missing clk_put 2011-06-07 09:07:47 -07:00
ohci-q.c USB host: Move AMD PLL quirk to pci-quirks.c 2011-03-01 16:01:45 -05:00
ohci-s3c2410.c USB: ohci-s3c2410: return proper error if clk_get fails 2011-05-06 18:16:40 -07:00
ohci-sa1111.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ohci-sh.c usb: update email address in ohci-sh and r8a66597-hcd 2011-07-08 14:57:12 -07:00
ohci-sm501.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ohci-spear.c USB host: Adding USB ehci & ohci support for spear platform 2010-11-16 13:53:29 -08:00
ohci-ssb.c Update my e-mail address 2011-07-07 15:18:01 +02:00
ohci-tmio.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
ohci.h Merge branch 'remove' of master.kernel.org:/home/rmk/linux-2.6-arm 2011-03-16 19:05:40 -07:00
oxu210hp-hcd.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
oxu210hp.h
pci-quirks.c usb/host/pci-quirks.c: correct annotation of `ehci_dmi_nohandoff_table' 2011-08-08 14:00:14 -07:00
pci-quirks.h Intel xhci: Support EHCI/xHCI port switching. 2011-05-27 12:07:36 -07:00
r8a66597-hcd.c Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6 2011-07-25 23:08:32 -07:00
r8a66597.h usb: r8a66597-hcd: add function for external controller 2011-07-08 14:57:11 -07:00
sl811-hcd.c Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6 2011-05-23 12:33:02 -07:00
sl811.h
sl811_cs.c pcmcia: Convert pcmcia_device_id declarations to const 2011-05-06 07:46:22 +02:00
u132-hcd.c usb: u132-hcd: Drop __TIME__ usage 2011-04-13 16:36:06 -07:00
uhci-debug.c USB: UHCI: Add support for big endian descriptors 2011-05-19 16:43:20 -07:00
uhci-grlib.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
uhci-hcd.c Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6 2011-05-23 12:33:02 -07:00
uhci-hcd.h USB: UHCI: Add support for big endian descriptors 2011-05-19 16:43:20 -07:00
uhci-hub.c USB: UHCI: Wrap I/O register accesses 2011-05-06 18:24:01 -07:00
uhci-pci.c USB: UHCI: Move PCI specific functions to uhci-pci.c 2011-05-06 18:24:00 -07:00
uhci-q.c USB: UHCI: Add support for big endian descriptors 2011-05-19 16:43:20 -07:00
xhci-dbg.c Merge 3.0-rc2 into usb-linus as it's needed by some USB patches 2011-06-14 06:51:23 -07:00
xhci-ext-caps.h xHCI: prolong host controller halt time limit 2011-03-13 18:07:09 -07:00
xhci-hub.c xHCI: report USB2 port in resuming as suspend 2011-08-09 14:44:50 -07:00
xhci-mem.c Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6 2011-07-25 23:08:32 -07:00
xhci-pci.c xhci: Add reset on resume quirk for asrock p67 host 2011-06-17 11:28:19 -07:00
xhci-ring.c xhci: Fix failed enqueue in the middle of isoch TD. 2011-08-09 14:49:05 -07:00
xhci.c xhci: Fix memory leak during failed enqueue. 2011-08-09 14:48:45 -07:00
xhci.h Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6 2011-07-25 23:08:32 -07:00