From: <R.E...@Bi...> - 2000-08-22 13:48:07
|
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...@Bi... ** 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 ******** |