On Wed, Aug 28, 2013 at 12:24 PM, Ming Lei <tom.leim...@gmail.com> wrote:
> On Wed, 28 Aug 2013 12:02:03 +0800
> Ming Lei <ming....@canonical.com> wrote:
>
>> Actually the problem only happened when underrun without
>> URB_ISO_ASAP.
>>
>> I have another fix which uses rebase trick and is simper(less change), could
>> you comment on the attachment patch?
>
> Sorry, please ignore last attachment patch, and comment on the below one:
>
> diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
> index 83be03f..4a3ddc9 100644
> --- a/drivers/usb/host/ehci-sched.c
> +++ b/drivers/usb/host/ehci-sched.c
> @@ -1370,6 +1370,21 @@ sitd_slot_ok (
>         return 1;
>  }
>
> +/* rebase in case of underun without ISO_ASAP together */
> +static void iso_stream_rebase(struct ehci_hcd *ehci,
> +       struct ehci_iso_stream  *stream, u32 mod)
> +{
> +       u32 i;
> +
> +       if (ehci->last_base == -1)
> +               return;
> +
> +       for (i = ehci->last_base; i != ehci->last_iso_frame;
> +                       i = (i + 1) & (mod - 1))
> +               if ((stream->next_uframe & (mod - 1)) == i)
> +                       ehci->last_iso_frame = i;
> +}

mod should switch to ehci->periodic_size, and stream->next_uframe
should convert to frame.

Also if the URB has been completed('now' is behind 'start + span'), the URB
need to complete immediately, or rescan after linking simply.

I will prepare for another one later.

> +
>  /*
>   * This scheduler plans almost as far into the future as it has actual
>   * periodic schedule slots.  (Affected by TUNE_FLS, which defaults to
> @@ -1409,7 +1424,9 @@ iso_stream_schedule (
>          * (irq delays etc).  If there are, the behavior depends on
>          * whether URB_ISO_ASAP is set.
>          */
> -       if (likely (!list_empty (&stream->td_list))) {
> +       if (likely (!list_empty (&stream->td_list) ||
> +                               hcd_complete_in_progress(
> +                               ehci_to_hcd(ehci), urb))) {
>
>                 /* Take the isochronous scheduling threshold into account */
>                 if (ehci->i_thresh)
> @@ -1417,6 +1434,10 @@ iso_stream_schedule (
>                 else
>                         next = (now + 2 + 7) & ~0x07;   /* full frame cache */
>
> +               if (list_empty(&stream->td_list) &&
> +                               !(urb->transfer_flags & URB_ISO_ASAP))
> +                       iso_stream_rebase(ehci, stream, mod);
> +
>                 /*
>                  * Use ehci->last_iso_frame as the base.  There can't be any
>                  * TDs scheduled for earlier than that.
> @@ -1517,6 +1538,7 @@ iso_stream_schedule (
>         /* Make sure scan_isoc() sees these */
>         if (ehci->isoc_count == 0)
>                 ehci->last_iso_frame = now >> 3;
> +       ehci->last_base = -1;
>         return 0;
>
>   fail:
> @@ -2255,6 +2277,9 @@ static void scan_isoc(struct ehci_hcd *ehci)
>         }
>         ehci->now_frame = now_frame;
>
> +       if (ehci->last_base == -1)
> +               ehci->last_base = ehci->last_iso_frame;
> +
>         frame = ehci->last_iso_frame;
>         for (;;) {
>                 union ehci_shadow       q, *q_p;
>
>

Thanks,
--
Ming Lei
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to