Messages in this thread |  | | Subject | Re: [PATCH] Re: Move of input drivers, some word needed from you | Date | Tue, 22 Aug 2000 14:16:51 +0200 (MEST) | From | (Rogier Wolff) |
| |
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/
|  |