On Thu, May 09, 2002, David Brownell <[EMAIL PROTECTED]> wrote:
> > Unfortunately, if you use UHCI like it was designed, you get poor USB
> > performance or you get poor system performance.
> >
> > So we have some hacks which play some nasty tricks with FSBR to solve
> > the problem. To implement this, we need to fiddle with the IOC bit while
> > the HC is processing the schedule.
> 
> I start to see what you're getting at.  Would you elaborate
> a bit?  I think I'd be more enlightened if you (and/or code
> comments) highlighted the cases where these tricks are
> being applied. 
> The tricky cases would seem to be when td->status is
> tweaked for "live" TDs ... but it's not clear which those
> cases are.  Or why "usb-uhci" can do FSBR without
> relying on I/O-atomic IOC bit-set ... is it just a potential risk
> of going an extra time around the FSBR ring?

Take the example of an ethernet dongle. It places an URB in the schedule
waiting for some traffic. On an idle system, it'll get added to the
schedule, but continuously NAK'd and it'll just waste PCI cycles doing
FSBR.

Take a look at rh_int_timer_do. It gets called as part of the root hub's
polling timer. This piece of code determines if the transfer has stalled
and if we should disable FSBR for that transfer:

                /* Check if the FSBR timed out */
                if (up->fsbr && !up->fsbr_timeout && time_after_eq(jiffies, 
up->fsbrtime + IDLE_TIMEOUT))
                        uhci_fsbr_timeout(uhci, u);

uhci_fsbr_timeout has some code which sets the IOC bit on the first
active TD:

                if (td->status & TD_CTRL_ACTIVE) {
                        set_bit(TD_CTRL_IOC_BIT, &td->status);
                        break;
                }

We do that so we can reenable FSBR when the transfer starts doing
something. Like when a large packet comes in, so it'll finish quicker.
Instead of waiting some 23 frames to finish one transfer, it can finish
in 2 frames (1 for the non FSBR frame, and another for the rest of the
TD's). Once we see it making headway again (in uhci_result_interrupt,
which is also uhci_result_bulk):

                if (urbp->fsbr_timeout && (td->status & TD_CTRL_IOC) &&
                    !(td->status & TD_CTRL_ACTIVE)) {
                        uhci_inc_fsbr(urb->dev->bus->hcpriv, urb);
                        urbp->fsbr_timeout = 0;
                        urbp->fsbrtime = jiffies;
                        clear_bit(TD_CTRL_IOC_BIT, &td->status);
                }

Clearing the IOC bit here isn't really necessary. The TD is retired, but
I do it for completeness sake.

The real race is in uhci_fsbr_timeout. If the transfer starts moving
again, then we will have read td->status, set the IOC bit and wrote it
back out again while the HC clears the ACTIVE bit behind our backs.

usb-uhci gets away without needing clear_bit or set_bit because it
doesn't even bother turning on FSBR again for URB's that were once
considered "stalled" (it went past the idle timeout). It lost it's right
to bandwidth when it didn't finish immediately.

This isn't horrible though. Just less than optimal. Enabling and
disabling FSBR at all is more of a performance gain than the extra
steps I went through.

It's also needed for bulk queuing right now in uhci.c, but I can workaround
the lack of it. It's not absolutely necessary, just needed the way that
it's coded right now.

> p.s. FWIW the UHCI "td->status" strongly resembles
>     the EHCI "qtd->hw_token".  But the async schedule
>     (for control/bulk) is always a ring ... some aspects
>     of that were clearly borrowed/improved from UHCI.
>     (And others from OHCI ... like TDs that support I/O
>     for multiple pages!  :)

Take the best of UHCI and the best of OHCI. It's a good thing they had
some experience to work off of.

JE


_______________________________________________________________

Have big pipes? SourceForge.net is looking for download mirrors. We supply
the hardware. You get the recognition. Email Us: [EMAIL PROTECTED]
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to