Installing and Programming RocketPort Universal PCI Serial Controller

Installation

  1. Copy the diagnostic disk from the Comtrol CD to a floppy
     dd if=1800056F.i of=/dev/fd0 
    and boot from the floppy.
  2. Attach the loopback plug onto the first octopus-type plug, labeled 'P0' when instructed by the diagnostic software. Repeat to test the other ports.
  3. Power-cycle the computer after testing the rocket port card, as testing screws up the PC hardware.
  4. Unpack a 2.4 kernel source in /usr/src and make a link in /usr/src, e.g.
     ln -s /usr/src/linux-2.4.21 /usr/src/linux 
    The rocket port software expects the source to be in /usr/src.
  5. Compile a 2.4 kernel. The driver will not compile in later kernels. Enable Rocket port, multiple ports support, and kernel modules. Don't set rocketport to 'module' yet or modules_install will not work.
    #
    # Character devices
    #
    CONFIG_VT=y
    CONFIG_VT_CONSOLE=y
    CONFIG_SERIAL=y
    CONFIG_SERIAL_CONSOLE=y
    CONFIG_SERIAL_EXTENDED=y
    CONFIG_SERIAL_MANY_PORTS=y
    CONFIG_SERIAL_SHARE_IRQ=y
    CONFIG_SERIAL_MULTIPORT=y
    CONFIG_SERIAL_NONSTANDARD=y
    CONFIG_ROCKETPORT=y
    CONFIG_UNIX98_PTYS=y
    CONFIG_UNIX98_PTY_COUNT=256 
  6. Here's the procedure for compiling the old 2.4 kernels, in case you've forgotten it:
    make dep
    make xconfig
    make
    make bzImage
    cd arch/i386/boot
    cp bzImage /boot/bzImage2421
    cd -
    make modules_install 
  7. Edit /etc/lilo.conf to make the new kernel the default.
  8. /sbin/lilo
  9. Reboot into new kernel. Now the rocket port software should compile.
  10. Obtain rocket port driver (1800024H.tgz) from CD or the Comtrol website.
  11. Untar the driver in /usr/src. It will create a directory named "comtrol".
  12. Compile the driver
    cd comtrol
    make clean
    make 
    make install 
    Although this is not supposed to be necessary, I copied the object file (rocketport.o) into the linux source tree:
     cp /usr/src/comtrol/*rocket*  /usr/src/linux/drivers/char/ 
    The "make install" command should put a startup script named "rocket" in /etc/rc.d. Make sure there's a link in rc3.d
    ls -l /etc/rc.d/rc?.d/*rocket*
    lrwxrwxrwx   1 root  root /etc/rc.d/rc0.d/K20rocket -> ../rocket
    lrwxrwxrwx   1 root  root /etc/rc.d/rc1.d/K20rocket -> ../rocket
    lrwxrwxrwx   1 root  root /etc/rc.d/rc2.d/S83rocket -> ../rocket
    lrwxrwxrwx   1 root  root /etc/rc.d/rc3.d/S83rocket -> ../rocket
    lrwxrwxrwx   1 root  root /etc/rc.d/rc5.d/S83rocket -> ../rocket
    lrwxrwxrwx   1 root  root /etc/rc.d/rc6.d/K20rocket -> ../rocket
  13. Reconfigure, rebuild, and reinstall the kernel, making rocket port a module this time. (You can also compile it into the kernel; but the card still must be initialized by /etc/rc.d/rocket).
  14. When it boots up, dmesg should say
    RocketPort device driver module, 
    version 2.11, 12-Aug-2003
    Comtrol PCI controller #0 ID 0x805 found 
    in bus:slot:fn 00:0d.0 at address c800,\
      1 AIOP(s) (RocketPort UPCI 8 port w/octa 
      cable)
    Installing RocketPort UPCI 8 port w/octa 
    cable, creating /dev/ttyR0 - 7

As dmesg says, the eight additional serial ports are named /dev/ttyR0 to /dev/ttyR7.

Programming the RocketPort uPCI card

Programming this card is similar to programming an ordinary serial port. The only difference is that the ioctl command to obtain the port address ( TIOCGSERIAL ) doesn't work, and the serial port must be hard-coded. The address (usually either 0xc800 or 0xcc00) can be found by typing

  cat proc/ioports 

For example, here is part of a program to initialize the two standard ports and one rocketport port.

  int main(void)
  {
      int fd[MAX_PORTS];
      initialize_app_globals();
      ////  Open any additional ports here
      if(PORTS>=1) fd[0] = open_port(SERIAL_PORT_0);
      if(PORTS>=2) fd[1] = open_port(SERIAL_PORT_1);
      if(PORTS>=3) fd[2] = open_port(SERIAL_PORT_2);
      sleep(5);
      initialize_curses();
      clear_screen();
      monitor(fd);
      endwin();                    // reset terminal
      ////  Close any additional ports here
      if(PORTS>=3) close(fd[2]);
      if(PORTS>=2) close(fd[1]);
      if(PORTS>=1) close(fd[0]);
      exit(EXIT_SUCCESS);
  }  


  int open_port(const char *port_name)
  {
    int fd;
    int port = 0x2e8;
    static struct serial_struct ss;
    static struct termios newtio;

    printf("Trying to open serial port %s ...\n", port_name);

    //// Open port
    if((fd = open(port_name, O_RDWR | O_NOCTTY | O_NDELAY )) < 0)
    {   printf("Cant open serial port %s\n", port_name);
        exit(1);
    }
    printf("Serial port %s opened\n", port_name);
    printf("Trying to find port address for %s ...\n", port_name);

    //// Find out what port and get permission to write to it
    if(ioctl(fd, TIOCGSERIAL, &ss)) 
    {   printf("ioctl(TIOCSERGSTRUCT) failed: -- trying c800\n");
        ss.port = 0xc800;
    }

    //// Should be 3f8 for cua0, 2f8 for cua1, 
    //// 3e8 for cua2, 0x2e8 for cua3
    port=ss.port;  
    printf("%s port %x\n" ,port_name, port);

    //// Enable asynchronous I/O
    if(fcntl(fd, F_SETFL, FNDELAY)) printf("fcntl didnt work\n");;
    printf("Opened port %s, fd = %d\n", port_name, fd);
    //// Obtain current port settings 
    tcgetattr(fd, &newtio); 

    //// Set new port settings 
    newtio.c_cflag |= (CLOCAL | CREAD);
    newtio.c_cflag &= ~PARENB;
    newtio.c_cflag &= ~CSTOPB;
    newtio.c_cflag &= ~CSIZE;
    newtio.c_cflag |= CS8;
    newtio.c_cflag &= ~CRTSCTS;

    newtio.c_lflag &= ~(ICANON | ECHO | ISIG);
    newtio.c_cc[VMIN]=1;
    newtio.c_cc[VTIME]=0;   // Tenths of seconds before timeout

    tcflush(fd, TCIFLUSH);
    tcsetattr(fd, TCSANOW, &newtio);

    //// Set baud rate
    cfsetispeed(&newtio, BAUDRATE);
    cfsetospeed(&newtio, BAUDRATE);
    tcflush(fd, TCIFLUSH);
    tcsetattr(fd, TCSANOW, &newtio);
    return fd;
  }

You also need the usual include files. Here's part of the relevant part of the include file for the above program.

  const int PORTS    = 3;

  //// Add any additional ports here
  const char SERIAL_PORT_0[64] = "/dev/ttyS0";
  const char SERIAL_PORT_1[64] = "/dev/ttyS1";
  const char SERIAL_PORT_2[64] = "/dev/ttyR0";
  const char SERIAL_PORT_3[64] = "/dev/ttyR1";
  const int MAX_PORTS = 10;

  //--------Include files--------------//
  #include <stdio.h>
  #include <string.h>
  #include <strings.h>        // For index() in Solaris
  #include <math.h>
  #include <stdlib.h>
  #include <stdarg.h>
  #include <ctype.h>
  #include <errno.h>
  #include <time.h>
  #include <sys/time.h>
  #include <sys/times.h>
  #include <signal.h>         // Needed for semaphores & ipc
  #include <sys/types.h>
  #include <sys/socket.h>
  #include <sys/wait.h>
  #include <curses.h>

  #ifndef __u32
  #define __u32 unsigned int
  #endif

  // These are needed for serial I/O
  #include <fcntl.h>
  #include <termios.h>
  #include <unistd.h>
  #include <sys/ioctl.h>
  #include <sys/syslog.h>     // For syslog
  #include <linux/serial.h>

Back