This is a note to let you know that I've just added the patch titled xhci: Always set urb->status to zero for isoc endpoints.
to the 2.6.39-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: xhci-always-set-urb-status-to-zero-for-isoc-endpoints.patch and it can be found in the queue-2.6.39 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <sta...@kernel.org> know about it. >From b3df3f9c7df9a8d85e03e158d35487618a160901 Mon Sep 17 00:00:00 2001 From: Sarah Sharp <sarah.a.sh...@linux.intel.com> Date: Wed, 15 Jun 2011 19:57:46 -0700 Subject: xhci: Always set urb->status to zero for isoc endpoints. From: Sarah Sharp <sarah.a.sh...@linux.intel.com> 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.sh...@linux.intel.com> Cc: "Xu, Andiry" <andiry...@amd.com> Signed-off-by: Greg Kroah-Hartman <gre...@suse.de> --- drivers/usb/host/xhci-ring.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1768,9 +1768,6 @@ static int process_isoc_td(struct xhci_h } } - if ((idx == urb_priv->length - 1) && *status == -EINPROGRESS) - *status = 0; - return finish_td(xhci, td, event_trb, event, ep, status, false); } @@ -1788,8 +1785,7 @@ static int skip_isoc_td(struct xhci_hcd idx = urb_priv->td_cnt; frame = &td->urb->iso_frame_desc[idx]; - /* The transfer is partly done */ - *status = -EXDEV; + /* The transfer is partly done. */ frame->status = -EXDEV; /* calc actual length */ @@ -2139,6 +2135,11 @@ cleanup: "status = %d\n", urb, urb->actual_length, status); spin_unlock(&xhci->lock); + /* EHCI, UHCI, and OHCI always unconditionally set the + * urb->status of an isochronous endpoint to 0. + */ + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) + status = 0; usb_hcd_giveback_urb(bus_to_hcd(urb->dev->bus), urb, status); spin_lock(&xhci->lock); } Patches currently in stable-queue which might be from sarah.a.sh...@linux.intel.com are queue-2.6.39/usb-free-bandwidth-when-usb_disable_device-is-called.patch queue-2.6.39/xhci-always-set-urb-status-to-zero-for-isoc-endpoints.patch queue-2.6.39/xhci-add-reset-on-resume-quirk-for-asrock-p67-host.patch queue-2.6.39/xhci-reject-double-add-of-active-endpoints.patch _______________________________________________ stable mailing list stable@linux.kernel.org http://linux.kernel.org/mailman/listinfo/stable