We have been developing a driver for a USB serial box, using
the Keyspan code and the generic serial drivers as examples.
Thanks for this great work!
In the process, we found a problem with our driver and it is also
a problem with the Keyspan driver. There is a related problem
in the generic serial driver. This is in 2.3.99-pre6.
The keyspan_pda_write function sleeps if usb->status is -EINPROGRESS.
However, keyspan_pda_write can be called on interrupt time from the
n_tty.c line discipline code and then sleep causes a panic.
To see the problem connect the Keyspan to an external terminal. Run
"cat < /dev/ttyUSB0". On the external terminal type "hello" and
press RETURN. You will see the hello and a carriage return
echo to the external terminal, but no linefeed will be echoed. The
system running the Keyspan driver will panic when RETURN is sent from
the external terminal.
Note if you change stty settings so that CARRIAGE RETURN/LINEFEED
is not echoed there will not be a panic.
When keyspan_pda_rx_interrupt gets the RETURN from the external
terminal it calls tty_flip_buffer_push which queues up flush_to_ldisc.
When this is run (on interrupt time) it calls tty->driver.put_char
twice to echo CARRIAGE RETURN and LINEFEED. put_char calls
keyspan_pda_write. The CARRIAGE RETURN gets through, but when
keyspan_pda_write is called again to write the LINEFEED, urb->status
is -EINPROGRESS and so it sleeps. Panic.
The generic serial driver simply returns 0 when it sees -EINPROGRESS;
this means, in this situation, that the put_char for the LINEFEED will
simply fail and no LINEFEED will be echoed.
It seems to me that the best possible solution is to have a write
buffer in the driver and hope there is room to stuff characters in
the buffer when -EINPROGRESS is set and in_interrupt() is true.
However, this could still fail when the buffer is full.
Scheduling the write for later might write data out of order.
Any suggestions for other ways around this problem?
Thanks,
Al Borchers Peter Berger
[EMAIL PROTECTED] [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]