16 Port Async Serial PCI-X Card on Linux
========================================
December 2008

----------------------------------------
Contents
----------------------------------------
1 Overview
2 The 8250 Driver
3 Obtain Kernel Source
4 Optional Device Recognition -- If desired you must do before next step
5 Configure Kernel Source
6 Compile the Kernel
7 Attach Driver to Device
8 Enable Shared Interrupts
9 Customer And Technical Support
10 Internet/Email Support


----------------------------------------
1 Overview
----------------------------------------
This document briefly describes the process necessary to install a PCI-X 16 port
asynchronous serial device in Linux and how to configure it for use.  The
following information corresponds to 2.6.x series kernels.  Some of the
information presented could be relevant in the 2.4.x series, but that is not
guaranteed.


----------------------------------------
2 The 8250 Driver
----------------------------------------
The Linux kernel has contained a driver compatible with 16850 UART (the one
used by the 16-port card) for quite some time.  However, the options used to
compile the kernel distributed with most flavors of Linux does not have some
of the necessary features enabled.  In order to use the Sealevel Systems
16 port card with Linux, you MUST recompile your kernel if the necessary
features are not enabled.

  Q: Does my kernel have the necessary features enabled?
  
  A: Find the .config file used to compile your kernel.  Various distributions
     often place it in the /boot directory under the name config-VERSION.  If
     the following variables are satisfied, you do not have to recompile.

                    #
                    # Serial drivers
                    #
                    CONFIG_SERIAL_8250=y
                    CONFIG_SERIAL_8250_CONSOLE=y
                    CONFIG_SERIAL_8250_PCI=y
                    CONFIG_SERIAL_8250_PNP=y
                    CONFIG_SERIAL_8250_NR_UARTS=16        # The MAXIMUM EVER
                    CONFIG_SERIAL_8250_RUNTIME_UARTS=16   # /dev/ttyS# to create
                    CONFIG_SERIAL_8250_EXTENDED=y         # SHARE_IRQ requires
                    CONFIG_SERIAL_8250_MANY_PORTS=y
                    CONFIG_SERIAL_8250_SHARE_IRQ=y        # MUST be ENABLED
                    
     NOTE:  The variable NR_UARTS must be the highest number of serial ports
     (total, not just Sealevel) you ever intend to have installed at the same
     time.  RUNTIME_UARTS can be set to whatever you like.  In fact you may also
     specify this value at boot time by passing the kernel the argument 
     8250.nr_uarts=# (<= CONFIG_SERIAL_8250_NR_UARTS=16).  This is done through
     your bootloader (most likely GRUB or LILO).  If you don't feel comfortable
     modifying your bootloader, set the RUNTIME_UARTS to the same as NR_UARTS.
 
If your kernel already has the necessary features enabled and you do not wish to
modify the kernel for automatic device recognition, proceed to section X: The 
setserial Command.

     
----------------------------------------
3 Obtain Kernel Source
----------------------------------------
If your kernel does not have the necessary features enabled, you MUST recompile
your kernel.  (The following steps are brief and focused on vanilla kernels
Consult the included documentation with your distribution's kernel source.)
The first step is to obtain a copy of your kernel's source.  This can be done
either through your distribution's maintainers, distribution package management,
or from www.kernel.org (vanilla - unmodified).


----------------------------------------
4 Optional Device Recognition
----------------------------------------
This section describes the changes to the 8250 driver source to automatically
recognize the Sealevel Systems device and attach the driver to it.  This step is
completely optional, you can still get the device to operate by using the
application setserial included with most distributions and freely available from
sourceforge.net/projects/setserial/

 1 Insertion is necessary in the file /usr/include/linux/pci_ids.h

	*Find "SEALEVEL".
	*Add a new definition to the end of the SEALEVEL section:
		#define PCI_DEVICE_ID_SEALEVEL_COMM16 0xE161
	*Save.
	
 1 Insertion is necessary in the file /usr/share/misc/pci.ids
	
	*Find "Sealevel".
	*Add a new device to the Sealevel section:
		E161  16 Port RS-232 Interface
	*Save.

 3 Insertions are necessary in the file /usr/src/linux/drivers/serial/8250_pci.c

	*Find "pbn_b1_8_115200".
	*Add a new after it like this:
		pbn_b1_8_115200,
		
		pbn_b1_16_460800,    // This is the new line
		
		pbn_b1_1_921600,
		... (etc)
		
	*Find "pbn_b1_8_115200".  (Again, this will take you to a struct entry)
	*Copy the entry that looks something like:
		[pbn_b1_8_115200] = {
			.flags          = FL_BASE1,
			.num_ports      = 8,
			.base_baud      = 115200,
			.uart_offset    = 8,
		},
	*And paste a new one below it, making these modifications:
		[pbn_b1_16_460800] = {
			.flags          = FL_BASE1,
			.num_ports      = 16,
			.base_baud      = 460800,
			.uart_offset    = 8,
		},
		
	*Find "SEALEVEL".
	*Copy one of the array entries that look something like:
		{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM8,
		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
		pbn_b2_8_115200 },
	*And paste a new one below it, making these modifications:
		{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM16,
		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
		pbn_b1_16_460800 },
	*Save.


----------------------------------------
5 Configure the Kernel
----------------------------------------
Run `make oldconfig` in the root of the source directory to copy as much of your
current configuration as possible (you will be prompted when necessary).  Now
run `make menuconfig` to make the necessary modifications for the serial driver
to work.  Remember to set the maximum and runtime variables according to YOUR 
needs.  You may, of course, build the 8250 driver as a module instead of built
into the kernel if you wish, but the default setting for most distributions is
built-in.

[Device Drivers] --> [Character Devices] --> [Serial Drivers] --> 

		<*> 8250/16550 and compatible serial support
		[*]   Console on 8250/16550 and compatible serial port
		(>=16)  Maximum number of 8250/16550 serial ports
		(>=16)  Number of 8250/16550 serial ports to register at runtime
		[*]   Extended 8250/16550 serial driver options
		[*]     Support more than 4 legacy serial ports
		[*]     Support for sharing serial interrupts


----------------------------------------
6 Compile the Kernel
----------------------------------------
Exit and save the configuration.  Now build the kernel and its modules.  Again,
consult your documentation.  The following steps are taken from vanilla source
2.6.21.  It is recommended you read through the following instructions before
attempting to follow them.  Note you may use GRUB instead of LILO, just use the
necessary steps to configure GRUB.  `man grub` for further information.

 - Do a "make" to create a compressed kernel image. It is also
   possible to do "make install" if you have lilo installed to suit the
   kernel makefiles, but you may want to check your particular lilo setup first.

   To do the actual install you have to be root, but none of the normal
   build should require that. Don't take the name of root in vain.

 - If you configured any of the parts of the kernel as `modules', you
   will also have to do "make modules_install".

 - Keep a backup kernel handy in case something goes wrong.  This is 
   especially true for the development releases, since each new release
   contains new code which has not been debugged.  Make sure you keep a
   backup of the modules corresponding to that kernel, as well.  If you
   are installing a new kernel with the same version number as your
   working kernel, make a backup of your modules directory before you
   do a "make modules_install".
   Alternatively, before compiling, use the kernel config option
   "LOCALVERSION" to append a unique suffix to the regular kernel version.
   LOCALVERSION can be set in the "General Setup" menu.

 - In order to boot your new kernel, you'll need to copy the kernel
   image (e.g. .../linux/arch/i386/boot/bzImage after compilation)
   to the place where your regular bootable kernel is found. 

 - Booting a kernel directly from a floppy without the assistance of a
   bootloader such as LILO, is no longer supported.

   If you boot Linux from the hard drive, chances are you use LILO which
   uses the kernel image as specified in the file /etc/lilo.conf.  The
   kernel image file is usually /vmlinuz, /boot/vmlinuz, /bzImage or
   /boot/bzImage.  To use the new kernel, save a copy of the old image
   and copy the new image over the old one.  Then, you MUST RERUN LILO
   to update the loading map!! If you don't, you won't be able to boot
   the new kernel image.

   Reinstalling LILO is usually a matter of running /sbin/lilo. 
   You may wish to edit /etc/lilo.conf to specify an entry for your
   old kernel image (say, /vmlinux.old) in case the new one does not
   work.  See the LILO docs for more information. 

   After reinstalling LILO, you should be all set.  Shutdown the system,
   reboot, and enjoy!

   If you ever need to change the default root device, video mode,
   ramdisk size, etc.  in the kernel image, use the 'rdev' program (or
   alternatively the LILO boot options when appropriate).  No need to
   recompile the kernel to change these parameters. 

 - Reboot with the new kernel and enjoy.  

     NOTE:  The number of devices initialized by the 8250 driver can either be
     set at boot (if it was built into the kernel) or at insertion (if compiled 
     as a module).  The boot parameter is 8250.nr_uarts=16.  Similarly to pass
     the module the parameter: `modprobe 8250 nr_uarts=16.
     (<= CONFIG_SERIAL_8250_NR_UARTS).


----------------------------------------
7 Attach Driver to Device
----------------------------------------
The following steps are not necessary if you chose to modify the 8250 sources
to automatically recognize the E161 as described in step 4.  You may proceed to
the next section.  If not, the setserial serial driver configuration application
can be used to easily attach the driver to the device.  An example script is
contained in the config directory of this package.

The setserial application is available with most distributions or through the
distribution's package management tools.  The latest version is also available
from sourceforge.net/projects/setserial/ .  Running the application in the
following manner will attempt to setup a serial UART at the specified I/O port.

	`setserial /dev/ttyS# port X irq Y autoconfigure baud_base 460800`
		(# is dependent on what dev file you wish to attach to,
		 X is the port address -- 8 ports per UART, and Y is the IRQ)
		 
To find out where exactly the OS has assigned your device memory locations and
IRQ run the lspci command.  To only show information about the E161 device, run
lspci with the -d switch like so, `lspci -d 135E:E161 -vv`.  The output should
indicate that region 0 is 512 bytes of memory and region 1 is 128 bytes of I/O.
The IRQ can also be found in the output.  These are the values necessary for the
setserial application.  The port address is expected in hex.  Note that
setserial will have to be run 16 times, incrementing the port by 8 each time.
The setsealevel script found in the config directory does this same thing if you
pass the port and irq arguments.  `/config/setsealevel X Y`.  Note that the
script assumes you wish the port device files to be /dev/ttyS[0-15], modify this
if necessary.

You will have to rerun the setserial commands each time you reboot.  You can use
the setserial configuration files found in /etc on most systems.  Consult the
setserial man pages for more information on automating the process.


----------------------------------------
8 Enable Shared Interrupts
----------------------------------------
The E161 uses a shared interrupt architecture to reduce the stress on the CPU
having to handle 16 interrupts from one device.  The shared interrupts must be
enabled for the device to function, however.  This is accomplished by enabling
bit 11 of the 32-bit register starting at byte 0x68 in the memory located at
BAR 0.  Source for a simple C application to accomplish this task is included
in this package.  The application requires the PCI-Utils-dev package version
2.2.4 or higher.  The intenable application will scan the pci bus for the E161.
All Sealevel Systems E161 devices will be enabled after running the application.
You can also choose to disable all E161 devices by passing the -d or --disable
switches to the intenable application (see `intenable --help` for more options).


----------------------------------------
9 Customer And Technical Support
----------------------------------------
For support relating to the Sealevel products, contact Sealevel at
(864)843-4343 M-F during normal business hours.


----------------------------------------
10 Internet/Email Support
----------------------------------------
Sealevel support personnel may be reached via the Internet by writing
support@sealevel.com.  Also visit the Sealevel web site (www.sealevel.com)
for information.

