OSDN Git Service

xhci: Always set urb->status to zero for isoc endpoints.
authorSarah Sharp <sarah.a.sharp@linux.intel.com>
Thu, 16 Jun 2011 02:57:46 +0000 (19:57 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Sat, 9 Jul 2011 06:15:08 +0000 (23:15 -0700)
commit0c6f67c9e49dd99d92eeed74c2f58fa096f9e0b1
treea9e8417cce0328d0339294aeaa0d8b260f5309eb
parent35c8e70897c718597b9ef10214771dc46de548f4
xhci: Always set urb->status to zero for isoc endpoints.

commit b3df3f9c7df9a8d85e03e158d35487618a160901 upstream.

When the xHCI driver encounters a Missed Service Interval event for an
isochronous endpoint ring, it means the host controller skipped over
one or more isochronous TDs.  For TD that is skipped, skip_isoc_td() is
called.  This sets the frame descriptor status to -EXDEV, and also sets
the value stored in the int pointed to by status to -EXDEV.

If the isochronous TD happens to be the last TD in an URB,
handle_tx_event() will use the status variable to give back the URB to
the USB core.  That means drivers will see urb->status as -EXDEV.

It turns out that EHCI, UHCI, and OHCI always set urb->status to zero for
an isochronous urb, regardless of what the frame status is.  See
itd_complete() in ehci-sched.c:

                } else {
                        /* URB was too late */
                        desc->status = -EXDEV;
                }
        }

        /* handle completion now? */
        if (likely ((urb_index + 1) != urb->number_of_packets))
                goto done;

        /* ASSERT: it's really the last itd for this urb
        list_for_each_entry (itd, &stream->td_list, itd_list)
                BUG_ON (itd->urb == urb);
         */

        /* give urb back to the driver; completion often (re)submits */
        dev = urb->dev;
        ehci_urb_done(ehci, urb, 0);

ehci_urb_done() completes the URB with the status of the third argument, which
is always zero in this case.

It turns out that many USB webcam drivers, such as uvcvideo, cannot
handle urb->status set to a non-zero value.  They will not resubmit
their isochronous URBs in that case, and userspace will see a frozen
video.

Change the xHCI driver to be consistent with the EHCI and UHCI driver,
and always set urb->status to 0 for isochronous URBs.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/host/xhci-ring.c