Bjorn Wesen wrote:
> [incredible cc-list trimmed]
>
> > We need an architecture similar to the net devices.
>
> agree
>
> > 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.
>
> I'd agree that the arch is very similar to net devices (network devices
> are in fact nothing else than a very specific form of serial devices :).
>
> BUT, by the same argument, the ol' circular buffer thingy needs to go as
> well.
>
> Example - our embedded CPU has full DMA to every I/O and the serial port
> can easily do 1.8 megabaud and has a 6 megabaud mode as well. Trying to
> get that to work with serial.c was a minor headache. Just because the PC
> still has shit-for-serial-ports should not be a limitation to scalability.
>
> My solution was to let the driver DMA directly into the tty flipbuf while
> the sends still has to be copied into a buffer.
>
> SOmething similar to the skb's would be preferable - so I can just take
> write blocks and chain them into the DMA hardware. Incoming data can go
> into "skb's" as well up to the tty.
>
> My point is just that if we're going to go through the horror of
> completely redesigning serial.c we might as well get rid of the "char by
> char" mentality, at least not so that it limits the _fast_ ports out
> there.
Agreed.
Part of my suggestion is that there may be more than one "I got input"
routines.
Some devices may not be able to provide more than one char at a
time. Think 8250.
ser_got_one_char (inb (port->base + DATA));
Others like CD1864 may be able to provide us with a number of valid
chars before we read them from the data register:
nvc = inb (port->base + NR_VALID_CHARS);
ser_got_chars_in_one_ioreg (port->base + DATA, nvc);
I also have a driver that would need:
nchars = readb (port->base + CHARS_IN_BUFFER)
ser_got_chars_in_iomem (port->base + BUFFER, nchars);
You'r suggesting that you'd like to do:
nchars = readl (port->base + CUR_DMA_POINTER) - port->cur_buf;
ser_got_chars_in_mem (port->cur_buf, nchars);
port->cur_buf = kmalloc (BUFSIZE);
writel (port->base + CUR_DMA_POINTER, virt_to_bus (port->cur_buf));
Now having something like skbuffs internally may make more sense if
you think about passing those buffers around. Point is: the driver
shouldn't need to know.
Roger.
-- ** 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