On Wed, Aug 28, 2013 at 12:24 PM, Ming Lei <tom.leiming@xxxxxxxxx> wrote: > On Wed, 28 Aug 2013 12:02:03 +0800 > Ming Lei <ming.lei@xxxxxxxxxxxxx> 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html