Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Nov 1997 17:28:47 +1100
From:      Bruce Evans <bde@zeta.org.au>
To:        bde@zeta.org.au, mouth@ibm.net
Cc:        hackers@freebsd.org
Subject:   Re: Status of 650 UART support
Message-ID:  <199711240628.RAA01234@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>I applied the patch to 2.2.5 sio.c -- the first hunk failed but the
>rest succeeded. =20
>
>Just curious, what is vcom all about?  In any case, after starting to

It's about fixing an old bogus/slow interface.

>>/*
>> * Loop until there is no activity on any port.  This is necessary
>> * to get an interrupt edge more than to avoid another interrupt.
>> * If the IRQ signal is just an OR of the IRQ signals from several
>> * devices, then the edge from one may be lost because another is
>> * on.
>> */
>
>I believe this is untrue.  If so, that may call certain aspects of
>siointr into question. =20

This is true :-).

>On an ISA bus, several devices cannot OR their IRQ lines at all,
>unless you are willing to heat up a soldering iron, or purchase a
>multiport card with hardware logic for IRQ sharing.  Otherwise,  the
>totem pole output of any one device holding its line low will sink the
>output of all others to ground and you will never see an interrupt
>from any of the ORed devices.

This is also true :-).  The code being discussed is for multiport cards
with (simple) hardware logic for IRQ sharing.  Not-so-simple hardware
might have a way to force an edge, but siointr() is for the general
case so it can't have support for or dependencies on this.

The code is configured by option COM_MULTIPORT and is not used by default.
Unfortunately, if you want to use just one multiport card then you
have to configure COM_MULTIPORT and the code gets used for all ports,
slowing down the non-multiport cards unnecessarily.  Part of the patch
is about fixing this (this part is very incomplete).

>Incidentally, there is some code in sioprobe which floats the IRQ
>output of all UARTs, attempting to find all which may be "sharing" an
>IRQ in the COM1/COM3 manner.  I would change that and force users to
>set up their COM ports correctly (at least for UNIX).  ;-)

It actually attempts to float them all to begin with, then drives one.
Sharing is only detected indirectly as probe failures.  The usual
misconfiguration is COM1/COM3 on irq4 and COM2/COM4 on irq3, but
with the FreeBSD config not changed from the default of COM3 on irq5
and COM4 on irq9, so that the static conflict checking doesn't help.
Another misconfiguration is COM3 or COM4 not in the FreeBSD config, but
present and driving an irq that is shared with the COM1 or COM2 irq.
For some reason ;-), most users don't understand the "test N failed"
messages for these errors.  I don't want to throw away the checking
completely because users that misconfigure the COM3-4 irqs need it
most.  If the floating stuff could be trusted then we could determine
the actual irq and print a better error message "probe failed due
to irq misconfiguration (configured as 5, seems to be 4; use `?' if
you want auto-configuration of 4)".

>I changed my own copy of sioprobe to drive the IRQ output, letting
>each UART pull its line to ground during sioprobe.  I had to do that
>because I built a homebrewed OR gate for all the serial cards in one
>of my test machines, and I forgot to use a pull down resistor on each
>input and there wasn't enough room left on my proto board to add them
>after I was finished.   It was much quicker to change that one line of
>code in sioprobe than throw out my custom design and start all over.

You mean all at the start?  It's not very nice to drive sio1-N in
the probe for sio0.  The unhacked version just floats sio0-N and
then drives the the device being probed, leaving it driven after a
successful probe so that with correct configurations precisely sio0-M
will be driven when sio(M+1) is probed.  Even this much cross-device
handling caused problems with S3 cards.  The problems were worked
around by disabling sio2-3 in GENERIC.  This prevents all accesses
to the sio2-3 registers (which may actually be video registers).
Unfortunately, this breaks the floating stuff if sio2-3 are present.
Users should enable them if they exist so that they don't interfere
with sio0-1.  Incorrect irq configuration should then just result in
sio2-3 not being found.

>Anyway, I want to purse this issue of whether looping in siointr is
>"necessary to get an interrupt edge,"  because it has a direct impact
>on how siointr might be improved with UART burst mode input.

It's certainly necessary for simple OR gates.  The IRQ outputs of the
UARTs are independent so there is no guarantee that a falling edge on one
will make it to the output of the OR gate.  More complicated h/w could
watch all the inputs and arrange for a falling edge on the final output
if there is a falling edge on any input.  I think this would be a good
kludge for generic boards that have to work with slightly broken drivers,
but it wouldn't be best - it would cause more interrupts than necessary
(probably not many more).

It's the scan for an active port that is wasteful.  The best way to
handle it would be to have a single register (32 bits if necessary :-)
that gives the status of all UART irq outputs outputs on the board.
I think most multiport boards have 8-bit register(s) for this.
FreeBSD doesn't support them because there is no standard and I don't
have any multiport boards :-).  More complicated h/w could have other
interesting UART outputs and programmable priorities for the active
interrupts supported... (the driver can't handle scheduling very well
since it would have to do too much i/o to decide which fifo needs
servicing most urgently, etc).

>I wrote a code fragment in Turbo C which implements a highly optimized
>framework (not a finished product) for UART receiver burst mode if you
>want to see it.  It also handles the case of FIFO timeout where you
>need to read characters in the usual way, one at a time. I tested it
>in a small terminal program and it works well.

Not really.  I think I know what to do, butnot how to integrate it.

>I would like to integrate it with sio.c, but I'm never satisfied with
>my C code until I've eliminated all goto statements.  Extracting the
>many from sio.c might take a long time, and I don't know if I'm ready
>to jump into that snakepit.

There's only 3 in the standard version and they're just to get out
of error cases :-).  The gotos in the patch are mostly because I
didn't want to integrate it properly until it was working.  I expect
future versions will have multiple variants of the interrupt handler
(a separate one for the multiport case, etc).  I don't know how to
manage this right - siointr1 is too big to have 10 copies of.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711240628.RAA01234>