On Mon, May 29, 2000 at 09:48:11PM -0500, Peter E. Berger wrote:
> Hi Greg:
> 
> I've just been tracking down a problem in our Digi USB driver which
> may shed some light on yours.  In our case, on slower machines (e.g:
> <=300Mhz) with transfers at high baud rates (e.g: 115K), large (e.g:
> 400K byte) file transfers would sometimes hang the transfers with timeout
> errors.  We saw similar behavior with different file transfer protocols
> (e.g. zmodem and kermit), with non-protocol large text file dumps,
> with software and hardware flow control and when using usb or usb-uhci
> (I don't have an ohci machine).  On investigation it turned out that
> the transfers were always hung in the application level write on the
> main sending side (e.g: on the "sz" side in an sz -> rz transfer).
> I tracked down the data flow and found that in the failure cases,
> the line discipline was stuck sleeping and thus failing to send more
> characters to our driver write routine.  Even though we wake up the
> line discipline in the write callback routine (as you do in the Visor
> driver's generic_bulk_callback), it looks like there's a race condition
> where the wakeup can fail to come late enough, so the line discipline
> is left sleeping on the job (nice work if you can get it...).
> 
> Maybe this is the same problem you're seeing? 

This sounds like the problem that I have been seeing (and lots of other
people) with the Visor on OHCI seeming to just go to sleep in the middle
of a large transfer. When I slow the OHCI driver down by turning on all
of it's debugging, the problem goes away, which makes sense given what
you just described. 

Thanks!

Unfortunately I don't think this is the same problem on UHCI right now
(or the OHCI oops problem either.)

UHCI seems to have a problem with a transfer timing out (or so I'm
guessing). I think I/we need to figure this one out before I can even test
out what you see (or fix the oops on OHCI, then I could test it too.)

> A quick way to test this
> would be to grab a copy of the wakeup code from the bottom of your
> generic_bulk_callback() and paste it temporarily into a suitabl place
> in your open or ioctl code.  Then when you see a stuck transfer, see
> if the condition clears when you exercise the temporary wakeup code
> by, say, running stty on that port (e.g: stty -a -F /dev/ttyUSB0).
> That test worked for me.  Another test that worked here involved setting
> the wakeup code to run whenever a modem event occurs, though the wakeups
> generated by normal hardware handshaking were not sufficient -- I had
> to supplement them with extra manual modem events at a breakout box (not
> a solution of course, but it gave me confidence in my problem assessment).
> If either of these tests work for you, I'd say we've probably found the
> same problem.
> 
> I tried adding code to invoke the wakeup code whenever our device transmit
> buffer empties, but given the small size of the USB transfer packets and
> the low priority of the wakeup messages, I think this is a bad approach.
> I think a better approach will be to setup a task queue where we can
> schedule the line discipline wakeups when the buffers empty, but do
> the wakeups later.  Unless anyone has a better suggestion, I'll try
> that tomorrow.

Let me know of you try this and if it works for you. I don't really know
of any other place to put the wakeup in, and I don't think that calling
it too often is a real problem (unless anyone else can tell me
otherwise.)

Thanks for letting me know about this,

greg k-h
greg@(kroah|wirex).com

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to