On Tue, 24 Apr 2001, Johannes Erdfelt wrote:

> I would. The way UHCI works, Isochronous transfers are quite a bit
> different than all other transfers.

Right - idea was if there were something wrong with iso this might cause
some degradation for the remaining bulk bandwidth. But now seems to be
completely unrelated - see below.

> UHCI doesn't necessarily allow you to specify which packets are sent
> when, so the 17th data packet you saw is a result of the UHCI controller
> deciding that there was enough time to send another packet.

This was my feeling too. So I thought it might be helpful to find out,
what makes the HC to decide this way on some occasions when using usb-uhci
but apparently never with uhci.

> This sounds like uhci.c turned off full speed bandwidth reclamation as a
> result of a timeout of some sort. From your description, it sounds like
> it's a bug in my driver.
> 
> This would definately make sense given your example.

Unfortunately I don't have access to the test setup today. But looking at
the code I'm pretty sure that's the solution:

There is an IDLE_TIMEOUT = 50 msec used to disable FSBR. In some
contradiction to its name it is measured from the submission of the
urb, i.e. does not care whether we are really idle or not.
According to bit-time calculations from usbcore my 64kB=1024x64 transfer
would need about 51 msec for the data-packets. So we are really close to
the edge where a false positive idle timeout situation is detected and
FSBR gets disabled in the back of the running TD. In reality its not so
close, since the total 64kB transfer takes 64 frames/msec. This explains
why the problem never happens during the first 45kB or so.

Comparing uhci and usb-uhci shows, they use both the same 50msec
IDLE_TIMEOUT. However the implementation differs wrt when the timeout is
really checked: While uhci does this using an independent rh-timer, it is
done inside the hc-interrupt for usb-uhci. Besides some accidential
coincidence (since we are really at the edge of the timeout), this seems
to explain the different behavior.

Anyway, I believe any fixed-value timeout handled this way might cause
some trouble for both HCD's:

- device might be unable to supply data saturating the full bandwidth
  (simply lower source data rate or slower device whithout double
  buffering and DMA for example). So even much shorter transfers might
  require >50msec to complete. OTOH, much slower devices wouldn't suffer
  that much when loosing FSBR :-)
- other concurrent traffic (int/iso) might claim most of the bandwidth
  causing shorter bulk transfers to need really long time (1 packet per
  frame remaining means 64 msec for 4kB bulk transfer e.g.)
- I think neither USB nor UHCI specs impose any limit on the length of a
  bulk transfer so 64kB or more should be valid. Eventually somebody might
  manage to reserve 1MB continuous transfer buffer and starts 1MB
  transfers - which would need about 16 sec instead of 1 sec without FSBR.
- simply increasing the timeout to say 150 msec and defining transfers
  must be <=128MB (max. kmalloc-size) would not help in the first case and
  waste really much of PCI bandwith in case it's really idle.

What about making the timeout checker to monitor the transfer and let it
reset the timeout whenever some progress is detected? Would this be
possible with UHCI - i.e. is there something we may use as progress
indicator while the TD is still owned by the HC?

> If you're comfortable with C, you can find the full speed bandwidth
> reclamation code and play with it. You can remove the timeout code, or
> you can force it to use FSBR all of the time.

I believe what I've written above does explain what's going on. However
it's only deduced from reading the code - I'm going for a verification as
soon I've access to the hw.

Martin


_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
http://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to