resent for the list ... netscape remembered a bogus list address, Greg has the original.
- Dave David Brownell wrote: > In doing some more extensive testing of the urb queueing behavior, > I noticed that (a) IOC wasn't always being set for each urb, while > for now it needs to be set; (b) a qh patchup wasn't done quite > where it should be. This resolves those two issues, as well > as making it a bit less noisy to unlink lots of urbs at the once. > > Please merge to Linus' latest. Thanks in advance! > > - Dave > > > ------------------------------------------------------------------------ > > --- ./drivers/usb-dist/host/ehci-hcd.c Fri Sep 27 17:35:32 2002 > +++ ./drivers/usb/host/ehci-hcd.c Sat Sep 28 20:52:40 2002 > @@ -749,7 +754,7 @@ > default: > spin_lock_irqsave (&ehci->lock, flags); > if (ehci->reclaim) { > - dbg ("dq %p: reclaim = %p, %s", > + vdbg ("dq %p: reclaim = %p, %s", > qh, ehci->reclaim, RUN_CONTEXT); > if (qh == ehci->reclaim) { > /* unlinking qh for another queued urb? */ > --- ./drivers/usb-dist/host/ehci-q.c Fri Sep 27 17:35:32 2002 > +++ ./drivers/usb/host/ehci-q.c Sun Sep 29 08:47:47 2002 > @@ -255,23 +255,23 @@ > struct urb *urb = qtd->urb; > u32 token = 0; > > + /* hc's on-chip qh overlay cache can overwrite our idea of > + * next qtd ptrs, if we appended a qtd while the queue was > + * advancing. (because we don't use dummy qtds.) > + */ > + if (cpu_to_le32 (qtd->qtd_dma) == qh->hw_current > + && qtd->hw_next != qh->hw_qtd_next) { > + qh->hw_alt_next = qtd->hw_alt_next; > + qh->hw_qtd_next = qtd->hw_next; > + COUNT (ehci->stats.qpatch); > + } > + > /* clean up any state from previous QTD ...*/ > if (last) { > if (likely (last->urb != urb)) { > ehci_urb_done (ehci, last->urb); > count++; > } > - > - /* qh overlays can have HC's old cached copies of > - * next qtd ptrs, if an URB was queued afterwards. > - */ > - if (cpu_to_le32 (last->qtd_dma) == qh->hw_current > - && last->hw_next != qh->hw_qtd_next) { > - qh->hw_alt_next = last->hw_alt_next; > - qh->hw_qtd_next = last->hw_next; > - COUNT (ehci->stats.qpatch); > - } > - > ehci_qtd_free (ehci, last); > last = 0; > } > @@ -529,7 +529,8 @@ > } > > /* by default, enable interrupt on urb completion */ > - if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT))) > +// ... do it always, unless we switch over to dummy qtds > +// if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT))) > qtd->hw_token |= __constant_cpu_to_le32 (QTD_IOC); > return head; > > @@ -785,7 +786,6 @@ > /* append to tds already queued to this qh? */ > if (unlikely (!list_empty (&qh->qtd_list) && qtd)) { > struct ehci_qtd *last_qtd; > - int short_rx = 0; > u32 hw_next; > > /* update the last qtd's "next" pointer */ > @@ -800,23 +800,16 @@ > && (epnum & 0x10)) { > // only the last QTD for now > last_qtd->hw_alt_next = hw_next; > - short_rx = 1; > } > > - /* Adjust any old copies in qh overlay too. > - * Interrupt code must cope with case of HC having it > - * cached, and clobbering these updates. > - * ... complicates getting rid of extra interrupts! > - * (Or: use dummy td, so cache always stays valid.) > + /* qh_completions() may need to patch the qh overlay if > + * the hc was advancing this queue while we appended. > + * we know it can: last_qtd->hw_token has IOC set. > + * > + * or: use a dummy td (so the overlay gets the next td > + * only when we set its active bit); fewer irqs. > */ > - if (qh->hw_current == cpu_to_le32 (last_qtd->qtd_dma)) { > - wmb (); > - qh->hw_qtd_next = hw_next; > - if (short_rx) > - qh->hw_alt_next = hw_next > - | (qh->hw_alt_next & 0x1e); > - vdbg ("queue to qh %p, patch", qh); > - } > + wmb (); > > /* no URB queued */ > } else { ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel