Subject: BOCA - ioAT66 driver for NetBSD-1.3 (long)
To: None <tech-kern@NetBSD.ORG>
From: Lucio de Re <lucio@proxima.alt.za>
List: tech-kern
Date: 01/07/1998 17:30:46
BOCA make a very poorly documented unintelligent serial card, they call
the ioAT66, with six 16550-look-alike UARTS.
I have modified the existing BOCA driver for this particular card, and,
within certain restrictions into which I will delve below, it seems to
work correctly.
Is there any interest out there for this particular driver? I managed
to streamline some of the existing code, possibly not to any great
degree, and it may be worth retrofitting the changes to the other
multiport card drivers... Let me know, anyone.
Now for some of the issues that were raised, probably through too
little understanding on my part of how device drivers and the CONFIG
utility are meant to interact:
1. Each individual UART on the ioAT66 can be configured to one of two
I/O ports and one of two interrupt request levels, the first interrupt
level is fixed and unique (on the adapter) for that port, while the
alternative is one of two choices, and the choice is the same for all
ports. This second IRQ is, in other words, shared by all ports that
have been set to share it.
2. To complicate the issue, one of the fixed IRQs is "4", which also
happens to be one of the two choices (the other is "5") for the shared
interrupt. This allows some very peculiar configurations.
3. In addition, there is a STATUS register that reports which port
currently requires interrupt servicing. I have not checked this, but I
am pretty certain that this notification is independent of the
selection of a shared or individually specified interrupt level. The
adapter manual lies rather forcefully about the polarity of the
indication: a one bit, despite BOCA's protestations, represents an
actively interrupting UART and the two unused bits are permanently zero.
4. The first four UARTs may be set to the conventional COM1 through
COM4 ports, although the choice of IRQ10 and IRQ11 is less traditional.
The next two ports have more unconventional addresses and fixed IRQs.
I only noticed recently that one can use the shared IRQ for any one
UART and that by choosing the shared IRQ to be "5" one gets yet one
more configuration option. I was baffled by the fact that in a
previous configuration, I could not successfully use the fourth port,
but of course it clashed with IRQ 11 which is used, I think, by the PCI
bus/SCSI controller combination. I presume I can configure port 4 to
use the shared IRQ and set the latter to "5" and I will have all 6
ports available.
Now, all this being said, I could not determine how to write the driver
so that, between the actual adapter settings and the contents of the
CONFIG file, it would be possible to use each port, irrespective of how
it was configured. The potential pitfalls are:
(a) The device driver has no mechanism to discriminate between standard
COM ports and those on the adapter it services. If the driver attempts
to service COM1 and it is not an adapter port, it will fail to do so
because the interrupt indicator flag in the STATUS register for that
port will not be set. Unless the NetBSD kernel chains interrupt
handlers so that the correct handler is called on such a failure, the
standard UART ports will become unusable. And this presupposes that
the conventional handler was configured correctly, earlier -
another possibility is to include the standard ports in the ioAT66
driver, trigger interrupts at probe time, determine which cause the
STATUS register to report and which don't and attach two slightly
different interrupt handlers to the two different groups.
(b) Only with such convoluted probing is it possible to determine the
actual adapter configuration, and here is the point: I chose to make
certain assumptions about the configuration of the adapter, so as to
minimise the likelihood of misconfigurations. The first assumption is
that conventional ports are paired with (nearly) conventional IRQs:
COM1 and COM2 are taken to be standard, COM3 and COM4 nearly so, and
COM5 and COM6 merely extrapolate on this. The alternate ports are all
taken to use the chosen shared IRQ and aren't even considered for
probing if the IRQ specification in the configuration is left out. The
alternative port is tested first, making it possible for other drivers
to manage the conventional ports if they are excluded on the adapter.
(c) Any number of adapter configuration can trash this scheme, for
example, to match a current configuration, the third port would have to
be set up as 0x248/5 instead of 0x2E8/5, the latter would be forced to
0x2E8/11 and clash.
(d) The only alternative would be to find some means of describing in
the CONFIG file, the properties of individual slaves, not so much their
I/O address, where the choices are limited and mutually exclusive, but
the rather the selected IRQ (god forbid that this should then be wrong
:-(
(e) Another useful specification might, in this case, be whether we
want to incorporate the standard ports - we can handle them, as long as
we don't expect the STATUS register to give us any indication about
them - or, equally important, whether we should ignore them even if we
happen to detect them.
In summary, there are two options: a more complex mechanism to describe
adapters (I guess that's where PnP was meant to help) or the ability to
perform rather complex tests, including triggering and intercepting
interrupts, at adapter probing time. I think the former option
stretches into dangerous territory, while the latter could provide
additional robustness to other drivers. I'm not comfortable with
exploring this avenue, but with sufficient encouragment and support, I
may embark on it.
In the meantime, it has been fun to get this far, it would be a pleasure
to be able to contribute where so far I have only been a spectator.
--
Lucio de Re (lucio@proxima.alt.za)
Disclaimer: I'm working at getting my opinions to agree with me.