This page describes my experiences writing a LinuxPPC device driver for the Keyspan SX serial card.
Back to Otto's LinuxPPC Goodies page.
The first stage of writing the device driver consisted of gathering information about the card I have, learning about Linux device drivers and an investigation on existing PCI serial card drivers.
PLX Technology, a company making PCI related devices. Here I could download the data sheet of the PLX9050 chip. This chip is a so called PCI bridge. Intended to attach slave devices to a PCI bus.
Exar, a company making various mixed signal IC's. Amongst there products is the ST16C654 four channel UART.
So it looked like the card has a fairly simple architecture: one chip containing a UART cabable of handling four serial ports, connected to the PCI bus via a chip that is designed to simplify access to hardware devices from the PCI bus. Furthermore, the UART is a member of the family of UARTs commonly found in PC's.
This information nicely corresponds with information I could find using Linux commands. See the next sections for more details.
Why not ask Keyspan for this information?
Good question. I think it is a nice challenge to try to reverse engineer the workings of the card. I looks like I have come a long way, without disassembling the existing MacOS driver. Maybe I will ask Keyspan for some confirmation on some issues at some point in time, however.
In the meantime I studied the Linux existing serial drivers to find out how they worked. I looked at the code in linux/drivers/char/serial.c and linux/drivers/macintosh/macserial.c. I found out that if I could make some glue to make the existing serial.c code talk to the UARTs on the SX card, I had a good chance of coming up with a working driver quickly. The serial.c code supports various UARTs from the same family as the ST16C654 directly. Sadly, there is no PCI support there. Other drivers, like cyclades.c do support PCI, but have a different architecture, so a direct port is not possible.
I also read an online document about the Linux kernel which also has a nice chapter about PCI. Sadly the "Linux Kernel Hackers' Guide" seems to be out of date on a lot ob subjects. I also browsed though the files in the linux/Documentation directory. The file linux/Documentation/kernel-docs.txt contains some references, but I found that a lot of them are outdated. The most comprehensive source of information is the book "Linux Device Drivers" by Alessandro Rubini. I think that understanding Linux device drivers was not too hard for me, since I learned a lot about Unix and device drivers in general during my study of Computer Science and subsequent jobs.
The PLX9050 is located on bus 1, device 3, function 0. It is a revison 1 chip and contains subsystem vendor id 11a9 and subsystem device id 5334. [what does medium devsel mean?] It uses interrupt request 24, and it has three memory regions and one I/O port region, which are all disabled.
Since all memory and I/O regions are disabled, the PLX9050 is not active in this state. It looks like the Mac Open Firmware booting process does not enable the card, and neither does the Linux PCI startup code. See below for configuration data from the card when running MacOS.
Connect Tech Inc. has a Linux driver for their BlueHeat card. It can be found here.
Next thing I tried was getting as much information about the card as possible. When running MacOS, that card is enabled, so I thought it was a good idea to look at the card when it is operating.
First, the addresses we saw using the lspci command come back here. So MacOS is using the same PCI address configuration as Linux.
This screen shows the local configuration registers from the PLX9050. The most interesting one is probably the command register, which shows that only memory access is enabled. I/O access is disabled. This information confirms the suspicion that the UARTs are accessed memory mapped, and not I/O mapped. This has big consequences since most UART drivers I have seen use I/O mapping. This explains why the drivers I tried could not contact the UART!
But of course Keyspan had some extra surpise. This one took me some time to find out: the UART registers are not mapped to a memory region of 7 consequtive bytes, but are mapped 0x80 bytes apart from each other. Reading from offset 0x00 to 0x7f just reads the same register! You can see data coming out of the UART in the bottom half of the screen dump nicely. The second block shows the value of the interrupt status register. The reason the first block of data changes in the middle is that while I was executing the dpm command, my modem was dumping its configuration at 300 baud to a terminal window. I happened to catch a part of one of the S register settings.
Here you can find the code of the very first working version of a device driver that does a probe for the SX card and its UARTs. This code works if you have a 2.2.10 source tree with this patch applied first. With other kernel versions it may also work, but I did not test that.
There are some design issues to resolve before I can proceed writing the real driver. I requested some assistence by sending out a mail to various mailing lsists. You can find the request here. If You have any comment to make, I'd like to hear.
Currently I am organizing some people to test the driver. The first step was set on Monday, Aug 9 1999. I send out a call to the linuxppc-dev and linuxppc-user mailing lists and the comp.os.linux.powerpc newsgroup. You can find the call here.
support for any PLX9050 based serial card with any of the serial.c UARTs?
What about other bridge chips?
Well, it looks like the future is here! The Keyspan SX driver evolved into a general purpose PCI serial driver. If you have a "dumb" PCI serial card and are running Linux 2.2.x on Intel, PowerPC, Alpha or any other system supporting PCI, chances are the driver will work for you. More information can be found here.