Re: Changing the speed of the serial driver

tytso@mit.edu
Tue, 6 Jan 1998 17:42:49 -0500


From: Dag Brattli <dagb@cs.uit.no>
Date: 02 Jan 1998 16:48:09 +0100

To change the speed I have used the tty->driver.set_termios() function
which works quite well.

The problem is that the speed change seems to be immediate, which is a
problem to me. After negotiating the speed in the IrDA driver (
http://www.cs.uit.no/~dagb/irda/irda.html) I must change the speed after
sending an ack frame. Since the driver has no threads it is impossible for
me to just wait for the frame to be sent, so the last frame sent will be
sent partially in different speeds :-).

To avoid this I tried to change the speed after the write_wakeup() call,
but that only tells me that the serial driver can accept more data, not
that all the data has been sent. I now use a todo-timer and the
tty->driver.chars_in_buffer() to check if all data has been sent. This
works quit well, but I still get problems if I set the timer to short,
since I may get a situation where the serial driver has sent all its data,
but the fifo still contains data. I want to set the timer as short as
possible so the speed has changed before the next frame is received which
may be a problem, since the timing is critical.

Have I missed something? Is there a more "right" way to do this?

No, you haven't missed anything. If you need to wait until all of the
characters are sent, you're going to need to have a process context,
which means you'll have to start up a kernel thread. (Like kswapd,
etc.)

The good news is once you have a kernel thread, you can simply call
tty_wait_until_sent(), which for 2.1 kernels (assuming that the
low-level device driver has properly implemented the wait_until_sent()
method), handle the case of making sure the data has been flushed from
any transmit FIFO's and is completely clocked out of the UART.

By the way, you should note that 2.0 kernels don't have this feature,
which is a bug that can occasionally cause problems. (Not to mention
that it's not allowed by POSIX and is caught by the POSIX Compliance
Test Suite.) The PCTS is actually quite strict about the timing
requirements of exactly when certain POSIX routines return, and the 2.1
kernel has been fixed to meet these requirements.

- Ted