Re: [PATCH] Re: Move of input drivers, some word needed from you

From: Rogier Wolff (R.E.Wolff@BitWizard.nl)
Date: Tue Aug 22 2000 - 07:16:51 EST


David Woodhouse wrote:
>
> torvalds@transmeta.com said:
> > A lot of serial.c is actually completely hardware-independent, and
> > serial.c in many ways is already "two drivers", in that it both knows
> > how to handle the low-level hardware AND it knows how to handle the
> > higher-level issues. And I don't think it would be bad to split it up
> > some more.
>
> The problem is that if you start to decouple the chipset driver from the
> code which knows how to access the chip, you end up with lots of horrible
> indirect function calls in the inner loops. This isn't really going to help
> improve performance - and the serial driver has one of the biggest problems
> w.r.t latency already.
>
> I figure I can get away with it for the MTD code (see the interaction
> between the CFI chipset code and the 'map' modules) because flash is
> generally slow as hell anyway, but for serial it's just not that feasible.
>
> We have the same problem when readb() becomes something other than a
> #define or inline function.
>
> One possibility for serial might be to reuse the generic chipset code in
> source form rather than object form - i.e. define serial_readb() et al.
> functions for your particular board/bus/mapping and then
> #include <generic_16550.c>. That's quite ugly though.

It is not quite that bad.

We need an architecture similar to the net devices.

tty layer just need a few callbacks.

The tty layer needs to set termios, and write characters. tty layer
should copy these into the circular buffer without leaving that to the
individual driver. (*) Usually the interrupt routine will just empty
the circular buffer.

The serial driver needs to report "here is another char". That might
be an inline function.

The serial driver also should be able to report "here is a bunch of
chars in IO memory". There are a few more possibilities.

Initial implementation of the improved tty layer may implement that
the trivial way, but it can be enormously optimized almost trivially
too.

Now, currently, most of the recieve handling is postponed to the
bottom half. I question the usefulness of this optimization. It
certainly adds latency. What is it that needs to be done on reception
of a few chars? Copy the data to userspace, and hit the waitq of the
process that's waiting for data. If you want to prevent the races, use
a kernel-space circular buffer, and do the processing (copy to
userspace) in the context of the wokenup process.

Similarly, a line discipline like "ppp" will just scan the chars for
the end-of-packet char while copying the data to the reception skbuf.
It's not as if this is highly time-consuming: we already have to copy
the data somewhere, so that part is "unavoidable". And the possibly
more expensive part is the "packet recieved". We already call that
from the interrupt routine many more times per second for the 100mbps
ethernet cards.

Oh, with DCD and stuff, we also need a callback for "modem signals
changed". What to do with that (i.e. unblock someone in open, or
hangup the users shell) should be the tty layer's choice. Not
something that is done in the hardware driver.

A driver would implement:

        open /* Just the bare "tell the hardware we're now
                  interested in various things like CD. */
        close /* nobody interested anymore. Disable interrupts
                  for this device. */
        get_modemsignals /* report the modem signals */
        set_modemsignals /* Set the modem signals */

        tx_buffer_nonempty /* Call to use when tx buffer becomes
                                nonempty */
        change_termios /* termios changed. returns termios settings NOT
                        implemented in the hardware. */

and performs callbacks from the interrupt routine for:
        - reception of characters
        - modem status change

Getting a callback for a modem status change (e.g. CD dropped) while
that is currently ignored is not a problem. This doesn't happen that
often.

tx_buffer_nonempty will, on some chips (e.g. 16550 and compatible)
just enable tx buffer empty interrupts. On others it may have to push
a buffer full of data onto the card (for example, sx doesn't interrupt
for tx_empty unless the buffer was previously filled).

The standard open routine will all the open routine followed by
set_modemsignals to set rts/dtr. Next, get_modemsignals is called to
check for DCD.

This certainly CANNOT happen for 2.4, and it's a lot of work to get to
the level that we currently have with the current structuring.

generic_serial is a step in the right direction, but it certainly
isn't the best way to do things.

                                Roger.

(*) Just like filesystem or device drivers change file->ops to point
to their own "ops" structure, that is what a "super intelligent"
serial driver would do if it didn't want the automatic "write copies
into circular buffer". Or we could have a write routine anyway, which
most drivers wouldn't implement as they wanted the fallback
copy-to-circular buffer....

-- 
** R.E.Wolff@BitWizard.nl ** http://www.BitWizard.nl/ ** +31-15-2137555 **
*-- BitWizard writes Linux device drivers for any device you may have! --*
*       Common sense is the collection of                                *
******  prejudices acquired by age eighteen.   -- Albert Einstein ********
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Aug 23 2000 - 21:00:06 EST