Re: serial.c (race?)

Rogier Wolff (R.E.Wolff@BitWizard.nl)
Mon, 18 Oct 1999 08:08:17 +0200 (MEST)


tytso@mit.edu wrote:
> Date: Sat, 16 Oct 1999 09:18:38 +0200 (MEST)
> From: R.E.Wolff@BitWizard.nl (Rogier Wolff)
>
> The transmit routine is kind of brain-dead. It waits for the FIFO to
> drain completely, and then shoves complete FIFO depth of data into the
> transmitter. This means that when the system has an IRQ latency larger
> than a byte transmit time, (I.e. when you actually need the input
> FIFO), then you will generate gaps in the output stream.
>
> All UART's don't have a way of determining how much space is in the FIFO
^^^^^^^^^^^^ Not true. Most.

The 16PCI954 at least has readable fifo levels.

> (except when it's empty), and most UART's don't have a way of sending an
> interrupt except when the FIFO completely drained. Some newer UART's,
> such as the 16650, do have a way of sending an interrupt before the FIFO
> is completely drained, but I haven't wanted to make the interrupt
> service routine far more complicated to support the various different
> UART's, especially since it would mean adding a number of extra branches
> and I/O port reads (which would be a disaster over the 8MHz ISA bus ---
> the ISA bus must DIE!).

As we have a rs_single etc etc. we could do something similar with the
"transmit" routine.

.... [info->type.uart_type] -> transmit_func (info)

and then have

ox16c954_transmit (... info)
{
bytes_to_send = uart->xmit_fifo_size - serial_icr_read (info, UART_TFL);
...
}

normal_transmit (... inf)
{
if (! read (... status) & FIFO_EMPTY) return;
bytes_to_send = uart->xmit_fifo_size;
....
}

Alternatively:

....transmit (...info)
{

if (....uart.type == UART_954)
bytes_to_send = uart->xmit_fifo_size - serial_icr_read (info, UART_TFL);
else {
if (! read (... status) & FIFO_EMPTY) return;
bytes_to_send = uart->xmit_fifo_size;
}
....

}

The ISA bus accesses are FAR too slow to do more than absolutely
neccesary. But memory accesses, although expensive compared to CPU
processing is cheap enough. If we call a different routine or switch
to different code depending on an often accessed flag in a cache line
that is already often accessed, the cost will be pretty low.

> Furthermore, unless you have some really brain-damaged drivers in your
> system, in practice it's really not an issue anyway.

I don't agree.

> (If you really
> care about performance for some real-time data acquisition system, for
> example, what the heck are you doing with a non-DMA IDE controller? :-)

David Woodhouse was involved in a project where he needed guarantees
about being able to send a sequence of bytes without any "idle" bits.
(i.e. after the stop bit always a start bit). With a 16 byte fifo, you
can use e.g. half the fifo to make that guarantee a lot easier. The
way it is implemented right now means we have to meet the
realtime-one-character interrupt latency. I feel a lot better if the
system achieves the interrupt in one character-time all of the time
but then the software is implemented to require only "within 8
character-times". That'd be nice.

Roger.

-- 
** R.E.Wolff@BitWizard.nl ** http://www.BitWizard.nl/ ** +31-15-2137555 **
*-- BitWizard writes Linux device drivers for any device you may have! --*
------ Microsoft SELLS you Windows, Linux GIVES you the whole house ------

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/