Hi,
I can confirm the patch is definitely required. I compiled and booted a
vanilla 2.6.25 kernel (from kernel.org), and then compiled and installed
the latest uvcvideo driver (my webcam requires this module). The
problem was easily repeatable using Ekiga (the specific "-45" errors
showed up in dmesg within 60 seconds). Interestingly, I couldn't get
Skype to work at all in this configuration - it kept crashing every time
I pressed the "Test" button.
Then I applied Alan Stern's patch, and everything (Skype and Ekiga)
worked perfectly.
Lambros
On Mon, 2008-04-21 at 23:14 +0200, Laurent Pinchart wrote:
> Hi everybody,
>
> Alan Stern was kind enough to write a fix a few weeks ago for a video
> streaming issue that some of you encountered.
>
> In order to get the fix included in 2.6.26, David Brownell would like to know
> if the Linux UVC driver still suffers from the problem when used with 2.6.25
> *without* the patch.
>
> Could you please be kind enough to test 2.6.25 and report results ?
>
> Best regards,
>
> Laurent Pinchart
>
> ---------- Forwarded Message ----------
>
> Subject: Re: ehci-hcd issue with webcam / uvcvideo driver
> Date: Monday 21 April 2008
> From: Alan Stern <[EMAIL PROTECTED]>
> To: Laurent Pinchart <[EMAIL PROTECTED]>
>
> On Mon, 21 Apr 2008, Laurent Pinchart wrote:
>
> > > Below is an updated version of the patch. If you can, replace the
> > > earlier version with this one and give it some good stress testing.
> > > If everything works okay, I'll submit it for inclusion in the official
> > > kernel.
> >
> > I've received several reports from people who tested your patch with the
> > Linux UVC driver. They were all positive, the patch fixed their problem and
> > introduced no regression they noticed. Could the patch be scheduled for
> > 2.6.26 ?
>
> Dave had some questions, in particular, whether your testers still
> encounter problems when running 2.6.25 without the patch. It would be
> nice to know the answer, either way.
>
> (IMO the patch ought to be merged even if the problems are no longer
> present, because what it does is basically correct. There may be a
> detail or two I missed -- it always helps to have someone else review
> changes like this -- but on the whole the idea is right.)
>
> For reference, the current version of the patch is below.
>
> Alan Stern
>
>
> No Changelog comment yet... The ideas are:
>
> (1) Never return -EL2NSYNC if URB_ISO_ASAP is set -- there's
> no reason to do so. And ehci-hcd always assumes ISO_ASAP.
>
> (2) If the CPU is delayed by IRQ latency, advance to the next
> available schedule slot.
>
> (3) Return the correct status (-EXDEV) for Iso slots which were
> submitted too late to get used.
>
> (4) Don't check for liveness of Iso slots whose frames are already
> over.
>
>
> Index: usb-2.6/drivers/usb/host/ehci-sched.c
> ===================================================================
> --- usb-2.6.orig/drivers/usb/host/ehci-sched.c
> +++ usb-2.6/drivers/usb/host/ehci-sched.c
> @@ -1349,18 +1349,27 @@ iso_stream_schedule (
> /* when's the last uframe this urb could start? */
> max = now + mod;
>
> - /* typical case: reuse current schedule. stream is still active,
> - * and no gaps from host falling behind (irq delays etc)
> + /* Typical case: reuse current schedule, stream is still active.
> + * Hopefully there are no gaps from the host falling behind
> + * (irq delays etc), but if there are we'll take the next
> + * slot in the schedule, implicitly assuming URB_ISO_ASAP.
> */
> if (likely (!list_empty (&stream->td_list))) {
> start = stream->next_uframe;
> if (start < now)
> start += mod;
> - if (likely ((start + sched->span) < max))
> - goto ready;
> - /* else fell behind; someday, try to reschedule */
> - status = -EL2NSYNC;
> - goto fail;
> +
> + /* Fell behind (by up to twice the slop amount)? */
> + if (start >= max - 2 * 8 * SCHEDULE_SLOP)
> + start += stream->interval * DIV_ROUND_UP(
> + max - start, stream->interval) - mod;
> +
> + /* Tried to schedule too far into the future? */
> + if (unlikely((start + sched->span) >= max)) {
> + status = -EFBIG;
> + goto fail;
> + }
> + goto ready;
> }
>
> /* need to schedule; when's the next (u)frame we could start?
> @@ -1613,6 +1622,9 @@ itd_complete (
> } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) {
> desc->status = 0;
> desc->actual_length = EHCI_ITD_LENGTH (t);
> + } else {
> + /* URB was too late */
> + desc->status = -EXDEV;
> }
> }
>
> @@ -2095,7 +2107,7 @@ done:
> static void
> scan_periodic (struct ehci_hcd *ehci)
> {
> - unsigned frame, clock, now_uframe, mod;
> + unsigned now_uframe, frame, clock, clock_frame, mod;
> unsigned modified;
>
> mod = ehci->periodic_size << 3;
> @@ -2111,6 +2123,7 @@ scan_periodic (struct ehci_hcd *ehci)
> else
> clock = now_uframe + mod - 1;
> clock %= mod;
> + clock_frame = clock >> 3;
>
> for (;;) {
> union ehci_shadow q, *q_p;
> @@ -2157,22 +2170,26 @@ restart:
> case Q_TYPE_ITD:
> /* If this ITD is still active, leave it for
> * later processing ... check the next entry.
> + * No need to check for activity unless the
> + * frame is current.
> */
> - rmb ();
> - for (uf = 0; uf < 8 && live; uf++) {
> - if (0 == (q.itd->hw_transaction [uf]
> - & ITD_ACTIVE(ehci)))
> - continue;
> - incomplete = true;
> - q_p = &q.itd->itd_next;
> - hw_p = &q.itd->hw_next;
> - type = Q_NEXT_TYPE(ehci,
> + if (frame == clock_frame && live) {
> + rmb();
> + for (uf = 0; uf < 8; uf++) {
> + if (q.itd->hw_transaction[uf] &
> + ITD_ACTIVE(ehci))
> + break;
> + }
> + if (uf < 8) {
> + incomplete = true;
> + q_p = &q.itd->itd_next;
> + hw_p = &q.itd->hw_next;
> + type = Q_NEXT_TYPE(ehci,
> q.itd->hw_next);
> - q = *q_p;
> - break;
> + q = *q_p;
> + break;
> + }
> }
> - if (uf < 8 && live)
> - break;
>
> /* Take finished ITDs out of the schedule
> * and process them: recycle, maybe report
> @@ -2189,9 +2206,12 @@ restart:
> case Q_TYPE_SITD:
> /* If this SITD is still active, leave it for
> * later processing ... check the next entry.
> + * No need to check for activity unless the
> + * frame is current.
> */
> - if ((q.sitd->hw_results & SITD_ACTIVE(ehci))
> - && live) {
> + if (frame == clock_frame && live &&
> + (q.sitd->hw_results &
> + SITD_ACTIVE(ehci))) {
> incomplete = true;
> q_p = &q.sitd->sitd_next;
> hw_p = &q.sitd->hw_next;
> @@ -2260,6 +2280,7 @@ restart:
>
> /* rescan the rest of this frame, then ... */
> clock = now;
> + clock_frame = clock >> 3;
> } else {
> now_uframe++;
> now_uframe %= mod;
>
>
> -------------------------------------------------------
_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel