/*
 * RocketPort device driver for Linux
 *
 * Written by Theodore Ts'o, 1995, 1996, 1997, 1998, 1999, 2000.
 * 
 * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2003 by Comtrol, Inc.
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 * Kernel Synchronization:
 *
 * This driver has 2 kernel control paths - exception handlers (calls into the driver
 * from user mode) and the timer bottom half (tasklet).  This is a polled driver, interrupts
 * are not used.
 *
 * Critical data: 
 * -  rp_table[], accessed through passed "info" pointers, is a global (static) array of 
 *    serial port state information and the xmit_buf circular buffer.  Protected by 
 *    a per port spinlock.
 * -  xmit_flags[], an array of ints indexed by line (port) number, indicating that there
 *    is data to be transmitted.  Protected by atomic bit operations.
 * -  rp_num_ports, int indicating number of open ports, protected by atomic operations.
 * 
 * rp_write() and rp_write_char() functions use a per port semaphore to protect against
 * simultaneous access to the same port by more than one process.
 */

/****** Defines ******/
#define ROCKET_PARANOIA_CHECK
#define ROCKET_DISABLE_SIMUSAGE

#undef ROCKET_SOFT_FLOW
#undef ROCKET_DEBUG_OPEN
#undef ROCKET_DEBUG_INTR
#undef ROCKET_DEBUG_WRITE
#undef ROCKET_DEBUG_FLOW
#undef ROCKET_DEBUG_THROTTLE
#undef ROCKET_DEBUG_WAIT_UNTIL_SENT
#undef ROCKET_DEBUG_RECEIVE
#undef ROCKET_DEBUG_HANGUP
#undef REV_PCI_ORDER
#undef ROCKET_DEBUG_IO

#define POLL_PERIOD HZ/100	/*  Polling period .01 seconds (10ms) */

/****** Kernel includes ******/

#include <linux/module.h>
#include <linux/errno.h>
#include <linux/major.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
#include <linux/mutex.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/completion.h>
#include <linux/wait.h>
#include <linux/pci.h>
#include <linux/uaccess.h>
#include <asm/atomic.h>
#include <asm/unaligned.h>
#include <linux/bitops.h>
#include <linux/spinlock.h>
#include <linux/init.h>

/****** RocketPort includes ******/

#include "rocket_int.h"
#include "rocket.h"

#define ROCKET_VERSION "2.09"
#define ROCKET_DATE "12-June-2003"

/****** RocketPort Local Variables ******/

static void rp_do_poll(unsigned long dummy);

static struct tty_driver *rocket_driver;

static struct rocket_version driver_version = {	
	ROCKET_VERSION, ROCKET_DATE
};

static struct r_port *rp_table[MAX_RP_PORTS];	       /*  The main repository of serial port state information. */
static unsigned int xmit_flags[NUM_BOARDS];	       /*  Bit significant, indicates port had data to transmit. */
						       /*  eg.  Bit 0 indicates port 0 has xmit data, ...        */
static atomic_t rp_num_ports_open;	               /*  Number of serial ports open                           */
static DEFINE_TIMER(rocket_timer, rp_do_poll, 0, 0);

static unsigned long board1;	                       /* ISA addresses, retrieved from rocketport.conf          */
static unsigned long board2;
static unsigned long board3;
static unsigned long board4;
static unsigned long controller;
static int support_low_speed;
static unsigned long modem1;
static unsigned long modem2;
static unsigned long modem3;
static unsigned long modem4;
static unsigned long pc104_1[8];
static unsigned long pc104_2[8];
static unsigned long pc104_3[8];
static unsigned long pc104_4[8];
static unsigned long *pc104[4] = { pc104_1, pc104_2, pc104_3, pc104_4 };

static int rp_baud_base[NUM_BOARDS];	               /*  Board config info (Someday make a per-board structure)  */
static unsigned long rcktpt_io_addr[NUM_BOARDS];
static int rcktpt_type[NUM_BOARDS];
static int is_PCI[NUM_BOARDS];
static rocketModel_t rocketModel[NUM_BOARDS];
static int max_board;
static const struct tty_port_operations rocket_port_ops;

/*
 * The following arrays define the interrupt bits corresponding to each AIOP.
 * These bits are different between the ISA and regular PCI boards and the
 * Universal PCI boards.
 */

static Word_t aiop_intr_bits[AIOP_CTL_SIZE] = {
	AIOP_INTR_BIT_0,
	AIOP_INTR_BIT_1,
	AIOP_INTR_BIT_2,
	AIOP_INTR_BIT_3
};

static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = {
	UPCI_AIOP_INTR_BIT_0,
	UPCI_AIOP_INTR_BIT_1,
	UPCI_AIOP_INTR_BIT_2,
	UPCI_AIOP_INTR_BIT_3
};

static Byte_t RData[RDATASIZE] = {
	0x00, 0x09, 0xf6, 0x82,
	0x02, 0x09, 0x86, 0xfb,
	0x04, 0x09, 0x00, 0x0a,
	0x06, 0x09, 0x01, 0x0a,
	0x08, 0x09, 0x8a, 0x13,
	0x0a, 0x09, 0xc5, 0x11,
	0x0c, 0x09, 0x86, 0x85,
	0x0e, 0x09, 0x20, 0x0a,
	0x10, 0x09, 0x21, 0x0a,
	0x12, 0x09, 0x41, 0xff,
	0x14, 0x09, 0x82, 0x00,
	0x16, 0x09, 0x82, 0x7b,
	0x18, 0x09, 0x8a, 0x7d,
	0x1a, 0x09, 0x88, 0x81,
	0x1c, 0x09, 0x86, 0x7a,
	0x1e, 0x09, 0x84, 0x81,
	0x20, 0x09, 0x82, 0x7c,
	0x22, 0x09, 0x0a, 0x0a
};

static Byte_t RRegData[RREGDATASIZE] = {
	0x00, 0x09, 0xf6, 0x82,	/* 00: Stop Rx processor */
	0x08, 0x09, 0x8a, 0x13,	/* 04: Tx software flow control */
	0x0a, 0x09, 0xc5, 0x11,	/* 08: XON char */
	0x0c, 0x09, 0x86, 0x85,	/* 0c: XANY */
	0x12, 0x09, 0x41, 0xff,	/* 10: Rx mask char */
	0x14, 0x09, 0x82, 0x00,	/* 14: Compare/Ignore #0 */
	0x16, 0x09, 0x82, 0x7b,	/* 18: Compare #1 */
	0x18, 0x09, 0x8a, 0x7d,	/* 1c: Compare #2 */
	0x1a, 0x09, 0x88, 0x81,	/* 20: Interrupt #1 */
	0x1c, 0x09, 0x86, 0x7a,	/* 24: Ignore/Replace #1 */
	0x1e, 0x09, 0x84, 0x81,	/* 28: Interrupt #2 */
	0x20, 0x09, 0x82, 0x7c,	/* 2c: Ignore/Replace #2 */
	0x22, 0x09, 0x0a, 0x0a	/* 30: Rx FIFO Enable */
};

static CONTROLLER_T sController[CTL_SIZE] = {
	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
};

static Byte_t sBitMapClrTbl[8] = {
	0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
};

static Byte_t sBitMapSetTbl[8] = {
	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
};

static int sClockPrescale = 0x14;

/*
 *  Line number is the ttySIx number (x), the Minor number.  We 
 *  assign them sequentially, starting at zero.  The following 
 *  array keeps track of the line number assigned to a given board/aiop/channel.
 */
static unsigned char lineNumbers[MAX_RP_PORTS];
static unsigned long nextLineNumber;

/*****  RocketPort Static Prototypes   *********/
static int __init init_ISA(int i);
static void rp_wait_until_sent(struct tty_struct *tty, int timeout);
static void rp_flush_buffer(struct tty_struct *tty);
static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model);
static unsigned char GetLineNumber(int ctrl, int aiop, int ch);
static unsigned char SetLineNumber(int ctrl, int aiop, int ch);
static void rp_start(struct tty_struct *tty);
static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
		     int ChanNum);
static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
static void sFlushRxFIFO(CHANNEL_T * ChP);
static void sFlushTxFIFO(CHANNEL_T * ChP);
static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
static void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
			      ByteIO_t * AiopIOList, int AiopIOListSize,
			      WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
			      int PeriodicOnly, int altChanRingIndicator,
			      int UPCIRingInd);
static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
			   ByteIO_t * AiopIOList, int AiopIOListSize,
			   int IRQNum, Byte_t Frequency, int PeriodicOnly);
static int sReadAiopID(ByteIO_t io);
static int sReadAiopNumChan(WordIO_t io);

MODULE_AUTHOR("Theodore Ts'o");
MODULE_DESCRIPTION("Comtrol RocketPort driver");
module_param(board1, ulong, 0);
MODULE_PARM_DESC(board1, "I/O port for (ISA) board #1");
module_param(board2, ulong, 0);
MODULE_PARM_DESC(board2, "I/O port for (ISA) board #2");
module_param(board3, ulong, 0);
MODULE_PARM_DESC(board3, "I/O port for (ISA) board #3");
module_param(board4, ulong, 0);
MODULE_PARM_DESC(board4, "I/O port for (ISA) board #4");
module_param(controller, ulong, 0);
MODULE_PARM_DESC(controller, "I/O port for (ISA) rocketport controller");
module_param(support_low_speed, bool, 0);
MODULE_PARM_DESC(support_low_speed, "1 means support 50 baud, 0 means support 460400 baud");
module_param(modem1, ulong, 0);
MODULE_PARM_DESC(modem1, "1 means (ISA) board #1 is a RocketModem");
module_param(modem2, ulong, 0);
MODULE_PARM_DESC(modem2, "1 means (ISA) board #2 is a RocketModem");
module_param(modem3, ulong, 0);
MODULE_PARM_DESC(modem3, "1 means (ISA) board #3 is a RocketModem");
module_param(modem4, ulong, 0);
MODULE_PARM_DESC(modem4, "1 means (ISA) board #4 is a RocketModem");
module_param_array(pc104_1, ulong, NULL, 0);
MODULE_PARM_DESC(pc104_1, "set interface types for ISA(PC104) board #1 (e.g. pc104_1=232,232,485,485,...");
module_param_array(pc104_2, ulong, NULL, 0);
MODULE_PARM_DESC(pc104_2, "set interface types for ISA(PC104) board #2 (e.g. pc104_2=232,232,485,485,...");
module_param_array(pc104_3, ulong, NULL, 0);
MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc104_3=232,232,485,485,...");
module_param_array(pc104_4, ulong, NULL, 0);
MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,...");

static int rp_init(void);
static void rp_cleanup_module(void);

module_init(rp_init);
module_exit(rp_cleanup_module);


MODULE_LICENSE("Dual BSD/GPL");

/*************************************************************************/
/*                     Module code starts here                           */

static inline int rocket_paranoia_check(struct r_port *info,
					const char *routine)
{
#ifdef ROCKET_PARANOIA_CHECK
	if (!info)
		return 1;
	if (info->magic != RPORT_MAGIC) {
		printk(KERN_WARNING "Warning: bad magic number for rocketport "
				"struct in %s\n", routine);
		return 1;
	}
#endif
	return 0;
}


/*  Serial port receive data function.  Called (from timer poll) when an AIOPIC signals 
 *  that receive data is present on a serial port.  Pulls data from FIFO, moves it into the 
 *  tty layer.  
 */
static void rp_do_receive(struct r_port *info,
			  struct tty_struct *tty,
			  CHANNEL_t * cp, unsigned int ChanStatus)
{
	unsigned int CharNStat;
	int ToRecv, wRecv, space;
	unsigned char *cbuf;

	ToRecv = sGetRxCnt(cp);
#ifdef ROCKET_DEBUG_INTR
	printk(KERN_INFO "rp_do_receive(%d)...\n", ToRecv);
#endif
	if (ToRecv == 0)
		return;

	/*
	 * if status indicates there are errored characters in the
	 * FIFO, then enter status mode (a word in FIFO holds
	 * character and status).
	 */
	if (ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) {
		if (!(ChanStatus & STATMODE)) {
#ifdef ROCKET_DEBUG_RECEIVE
			printk(KERN_INFO "Entering STATMODE...\n");
#endif
			ChanStatus |= STATMODE;
			sEnRxStatusMode(cp);
		}
	}

	/* 
	 * if we previously entered status mode, then read down the
	 * FIFO one word at a time, pulling apart the character and
	 * the status.  Update error counters depending on status
	 */
	if (ChanStatus & STATMODE) {
#ifdef ROCKET_DEBUG_RECEIVE
		printk(KERN_INFO "Ignore %x, read %x...\n",
			info->ignore_status_mask, info->read_status_mask);
#endif
		while (ToRecv) {
			char flag;

			CharNStat = sInW(sGetTxRxDataIO(cp));
#ifdef ROCKET_DEBUG_RECEIVE
			printk(KERN_INFO "%x...\n", CharNStat);
#endif
			if (CharNStat & STMBREAKH)
				CharNStat &= ~(STMFRAMEH | STMPARITYH);
			if (CharNStat & info->ignore_status_mask) {
				ToRecv--;
				continue;
			}
			CharNStat &= info->read_status_mask;
			if (CharNStat & STMBREAKH)
				flag = TTY_BREAK;
			else if (CharNStat & STMPARITYH)
				flag = TTY_PARITY;
			else if (CharNStat & STMFRAMEH)
				flag = TTY_FRAME;
			else if (CharNStat & STMRCVROVRH)
				flag = TTY_OVERRUN;
			else
				flag = TTY_NORMAL;
			tty_insert_flip_char(tty, CharNStat & 0xff, flag);
			ToRecv--;
		}

		/*
		 * after we've emptied the FIFO in status mode, turn
		 * status mode back off
		 */
		if (sGetRxCnt(cp) == 0) {
#ifdef ROCKET_DEBUG_RECEIVE
			printk(KERN_INFO "Status mode off.\n");
#endif
			sDisRxStatusMode(cp);
		}
	} else {
		/*
		 * we aren't in status mode, so read down the FIFO two
		 * characters at time by doing repeated word IO
		 * transfer.
		 */
		space = tty_prepare_flip_string(tty, &cbuf, ToRecv);
		if (space < ToRecv) {
#ifdef ROCKET_DEBUG_RECEIVE
			printk(KERN_INFO "rp_do_receive:insufficient space ToRecv=%d space=%d\n", ToRecv, space);
#endif
			if (space <= 0)
				return;
			ToRecv = space;
		}
		wRecv = ToRecv >> 1;
		if (wRecv)
			sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv);
		if (ToRecv & 1)
			cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp));
	}
	/*  Push the data up to the tty layer */
	tty_flip_buffer_push(tty);
}

/*
 *  Serial port transmit data function.  Called from the timer polling loop as a 
 *  result of a bit set in xmit_flags[], indicating data (from the tty layer) is ready
 *  to be sent out the serial port.  Data is buffered in rp_table[line].xmit_buf, it is 
 *  moved to the port's xmit FIFO.  *info is critical data, protected by spinlocks.
 */
static void rp_do_transmit(struct r_port *info)
{
	int c;
	CHANNEL_t *cp = &info->channel;
	struct tty_struct *tty;
	unsigned long flags;

#ifdef ROCKET_DEBUG_INTR
	printk(KERN_DEBUG "%s\n", __func__);
#endif
	if (!info)
		return;
	tty = tty_port_tty_get(&info->port);

	if (tty == NULL) {
		printk(KERN_WARNING "rp: WARNING %s called with tty==NULL\n", __func__);
		clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
		return;
	}

	spin_lock_irqsave(&info->slock, flags);
	info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);

	/*  Loop sending data to FIFO until done or FIFO full */
	while (1) {
		if (tty->stopped || tty->hw_stopped)
			break;
		c = min(info->xmit_fifo_room, info->xmit_cnt);
		c = min(c, XMIT_BUF_SIZE - info->xmit_tail);
		if (c <= 0 || info->xmit_fifo_room <= 0)
			break;
		sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) (info->xmit_buf + info->xmit_tail), c / 2);
		if (c & 1)
			sOutB(sGetTxRxDataIO(cp), info->xmit_buf[info->xmit_tail + c - 1]);
		info->xmit_tail += c;
		info->xmit_tail &= XMIT_BUF_SIZE - 1;
		info->xmit_cnt -= c;
		info->xmit_fifo_room -= c;
#ifdef ROCKET_DEBUG_INTR
		printk(KERN_INFO "tx %d chars...\n", c);
#endif
	}

	if (info->xmit_cnt == 0)
		clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);

	if (info->xmit_cnt < WAKEUP_CHARS) {
		tty_wakeup(tty);
#ifdef ROCKETPORT_HAVE_POLL_WAIT
		wake_up_interruptible(&tty->poll_wait);
#endif
	}

	spin_unlock_irqrestore(&info->slock, flags);
	tty_kref_put(tty);

#ifdef ROCKET_DEBUG_INTR
	printk(KERN_DEBUG "(%d,%d,%d,%d)...\n", info->xmit_cnt, info->xmit_head,
	       info->xmit_tail, info->xmit_fifo_room);
#endif
}

/*
 *  Called when a serial port signals it has read data in it's RX FIFO.
 *  It checks what interrupts are pending and services them, including
 *  receiving serial data.  
 */
static void rp_handle_port(struct r_port *info)
{
	CHANNEL_t *cp;
	struct tty_struct *tty;
	unsigned int IntMask, ChanStatus;

	if (!info)
		return;

	if ((info->port.flags & ASYNC_INITIALIZED) == 0) {
		printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
				"info->flags & NOT_INIT\n");
		return;
	}
	tty = tty_port_tty_get(&info->port);
	if (!tty) {
		printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
				"tty==NULL\n");
		return;
	}
	cp = &info->channel;

	IntMask = sGetChanIntID(cp) & info->intmask;
#ifdef ROCKET_DEBUG_INTR
	printk(KERN_INFO "rp_interrupt %02x...\n", IntMask);
#endif
	ChanStatus = sGetChanStatus(cp);
	if (IntMask & RXF_TRIG) {	/* Rx FIFO trigger level */
		rp_do_receive(info, tty, cp, ChanStatus);
	}
	if (IntMask & DELTA_CD) {	/* CD change  */
#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_INTR) || defined(ROCKET_DEBUG_HANGUP))
		printk(KERN_INFO "ttyR%d CD now %s...\n", info->line,
		       (ChanStatus & CD_ACT) ? "on" : "off");
#endif
		if (!(ChanStatus & CD_ACT) && info->cd_status) {
#ifdef ROCKET_DEBUG_HANGUP
			printk(KERN_INFO "CD drop, calling hangup.\n");
#endif
			tty_hangup(tty);
		}
		info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0;
		wake_up_interruptible(&info->port.open_wait);
	}
#ifdef ROCKET_DEBUG_INTR
	if (IntMask & DELTA_CTS) {	/* CTS change */
		printk(KERN_INFO "CTS change...\n");
	}
	if (IntMask & DELTA_DSR) {	/* DSR change */
		printk(KERN_INFO "DSR change...\n");
	}
#endif
	tty_kref_put(tty);
}

/*
 *  The top level polling routine.  Repeats every 1/100 HZ (10ms).
 */
static void rp_do_poll(unsigned long dummy)
{
	CONTROLLER_t *ctlp;
	int ctrl, aiop, ch, line;
	unsigned int xmitmask, i;
	unsigned int CtlMask;
	unsigned char AiopMask;
	Word_t bit;

	/*  Walk through all the boards (ctrl's) */
	for (ctrl = 0; ctrl < max_board; ctrl++) {
		if (rcktpt_io_addr[ctrl] <= 0)
			continue;

		/*  Get a ptr to the board's control struct */
		ctlp = sCtlNumToCtlPtr(ctrl);

		/*  Get the interrupt status from the board */
#ifdef CONFIG_PCI
		if (ctlp->BusType == isPCI)
			CtlMask = sPCIGetControllerIntStatus(ctlp);
		else
#endif
			CtlMask = sGetControllerIntStatus(ctlp);

		/*  Check if any AIOP read bits are set */
		for (aiop = 0; CtlMask; aiop++) {
			bit = ctlp->AiopIntrBits[aiop];
			if (CtlMask & bit) {
				CtlMask &= ~bit;
				AiopMask = sGetAiopIntStatus(ctlp, aiop);

				/*  Check if any port read bits are set */
				for (ch = 0; AiopMask;  AiopMask >>= 1, ch++) {
					if (AiopMask & 1) {

						/*  Get the line number (/dev/ttyRx number). */
						/*  Read the data from the port. */
						line = GetLineNumber(ctrl, aiop, ch);
						rp_handle_port(rp_table[line]);
					}
				}
			}
		}

		xmitmask = xmit_flags[ctrl];

		/*
		 *  xmit_flags contains bit-significant flags, indicating there is data
		 *  to xmit on the port. Bit 0 is port 0 on this board, bit 1 is port 
		 *  1, ... (32 total possible).  The variable i has the aiop and ch 
		 *  numbers encoded in it (port 0-7 are aiop0, 8-15 are aiop1, etc).
		 */
		if (xmitmask) {
			for (i = 0; i < rocketModel[ctrl].numPorts; i++) {
				if (xmitmask & (1 << i)) {
					aiop = (i & 0x18) >> 3;
					ch = i & 0x07;
					line = GetLineNumber(ctrl, aiop, ch);
					rp_do_transmit(rp_table[line]);
				}
			}
		}
	}

	/*
	 * Reset the timer so we get called at the next clock tick (10ms).
	 */
	if (atomic_read(&rp_num_ports_open))
		mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
}

/*
 *  Initializes the r_port structure for a port, as well as enabling the port on 
 *  the board.  
 *  Inputs:  board, aiop, chan numbers
 */
static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
{
	unsigned rocketMode;
	struct r_port *info;
	int line;
	CONTROLLER_T *ctlp;

	/*  Get the next available line number */
	line = SetLineNumber(board, aiop, chan);

	ctlp = sCtlNumToCtlPtr(board);

	/*  Get a r_port struct for the port, fill it in and save it globally, indexed by line number */
	info = kzalloc(sizeof (struct r_port), GFP_KERNEL);
	if (!info) {
		printk(KERN_ERR "Couldn't allocate info struct for line #%d\n",
				line);
		return;
	}

	info->magic = RPORT_MAGIC;
	info->line = line;
	info->ctlp = ctlp;
	info->board = board;
	info->aiop = aiop;
	info->chan = chan;
	tty_port_init(&info->port);
	info->port.ops = &rocket_port_ops;
	init_completion(&info->close_wait);
	info->flags &= ~ROCKET_MODE_MASK;
	switch (pc104[board][line]) {
	case 422:
		info->flags |= ROCKET_MODE_RS422;
		break;
	case 485:
		info->flags |= ROCKET_MODE_RS485;
		break;
	case 232:
	default:
		info->flags |= ROCKET_MODE_RS232;
		break;
	}

	info->intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR;
	if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) {
		printk(KERN_ERR "RocketPort sInitChan(%d, %d, %d) failed!\n",
				board, aiop, chan);
		kfree(info);
		return;
	}

	rocketMode = info->flags & ROCKET_MODE_MASK;

	if ((info->flags & ROCKET_RTS_TOGGLE) || (rocketMode == ROCKET_MODE_RS485))
		sEnRTSToggle(&info->channel);
	else
		sDisRTSToggle(&info->channel);

	if (ctlp->boardType == ROCKET_TYPE_PC104) {
		switch (rocketMode) {
		case ROCKET_MODE_RS485:
			sSetInterfaceMode(&info->channel, InterfaceModeRS485);
			break;
		case ROCKET_MODE_RS422:
			sSetInterfaceMode(&info->channel, InterfaceModeRS422);
			break;
		case ROCKET_MODE_RS232:
		default:
			if (info->flags & ROCKET_RTS_TOGGLE)
				sSetInterfaceMode(&info->channel, InterfaceModeRS232T);
			else
				sSetInterfaceMode(&info->channel, InterfaceModeRS232);
			break;
		}
	}
	spin_lock_init(&info->slock);
	mutex_init(&info->write_mtx);
	rp_table[line] = info;
	tty_register_device(rocket_driver, line, pci_dev ? &pci_dev->dev :
			NULL);
}

/*
 *  Configures a rocketport port according to its termio settings.  Called from 
 *  user mode into the driver (exception handler).  *info CD manipulation is spinlock protected.
 */
static void configure_r_port(struct tty_struct *tty, struct r_port *info,
			     struct ktermios *old_termios)
{
	unsigned cflag;
	unsigned long flags;
	unsigned rocketMode;
	int bits, baud, divisor;
	CHANNEL_t *cp;
	struct ktermios *t = tty->termios;

	cp = &info->channel;
	cflag = t->c_cflag;

	/* Byte size and parity */
	if ((cflag & CSIZE) == CS8) {
		sSetData8(cp);
		bits = 10;
	} else {
		sSetData7(cp);
		bits = 9;
	}
	if (cflag & CSTOPB) {
		sSetStop2(cp);
		bits++;
	} else {
		sSetStop1(cp);
	}

	if (cflag & PARENB) {
		sEnParity(cp);
		bits++;
		if (cflag & PARODD) {
			sSetOddParity(cp);
		} else {
			sSetEvenParity(cp);
		}
	} else {
		sDisParity(cp);
	}

	/* baud rate */
	baud = tty_get_baud_rate(tty);
	if (!baud)
		baud = 9600;
	divisor = ((rp_baud_base[info->board] + (baud >> 1)) / baud) - 1;
	if ((divisor >= 8192 || divisor < 0) && old_termios) {
		baud = tty_termios_baud_rate(old_termios);
		if (!baud)
			baud = 9600;
		divisor = (rp_baud_base[info->board] / baud) - 1;
	}
	if (divisor >= 8192 || divisor < 0) {
		baud = 9600;
		divisor = (rp_baud_base[info->board] / baud) - 1;
	}
	info->cps = baud / bits;
	sSetBaud(cp, divisor);

	/* FIXME: Should really back compute a baud rate from the divisor */
	tty_encode_baud_rate(tty, baud, baud);

	if (cflag & CRTSCTS) {
		info->intmask |= DELTA_CTS;
		sEnCTSFlowCtl(cp);
	} else {
		info->intmask &= ~DELTA_CTS;
		sDisCTSFlowCtl(cp);
	}
	if (cflag & CLOCAL) {
		info->intmask &= ~DELTA_CD;
	} else {
		spin_lock_irqsave(&info->slock, flags);
		if (sGetChanStatus(cp) & CD_ACT)
			info->cd_status = 1;
		else
			info->cd_status = 0;
		info->intmask |= DELTA_CD;
		spin_unlock_irqrestore(&info->slock, flags);
	}

	/*
	 * Handle software flow control in the board
	 */
#ifdef ROCKET_SOFT_FLOW
	if (I_IXON(tty)) {
		sEnTxSoftFlowCtl(cp);
		if (I_IXANY(tty)) {
			sEnIXANY(cp);
		} else {
			sDisIXANY(cp);
		}
		sSetTxXONChar(cp, START_CHAR(tty));
		sSetTxXOFFChar(cp, STOP_CHAR(tty));
	} else {
		sDisTxSoftFlowCtl(cp);
		sDisIXANY(cp);
		sClrTxXOFF(cp);
	}
#endif

	/*
	 * Set up ignore/read mask words
	 */
	info->read_status_mask = STMRCVROVRH | 0xFF;
	if (I_INPCK(tty))
		info->read_status_mask |= STMFRAMEH | STMPARITYH;
	if (I_BRKINT(tty) || I_PARMRK(tty))
		info->read_status_mask |= STMBREAKH;

	/*
	 * Characters to ignore
	 */
	info->ignore_status_mask = 0;
	if (I_IGNPAR(tty))
		info->ignore_status_mask |= STMFRAMEH | STMPARITYH;
	if (I_IGNBRK(tty)) {
		info->ignore_status_mask |= STMBREAKH;
		/*
		 * If we're ignoring parity and break indicators,
		 * ignore overruns too.  (For real raw support).
		 */
		if (I_IGNPAR(tty))
			info->ignore_status_mask |= STMRCVROVRH;
	}

	rocketMode = info->flags & ROCKET_MODE_MASK;

	if ((info->flags & ROCKET_RTS_TOGGLE)
	    || (rocketMode == ROCKET_MODE_RS485))
		sEnRTSToggle(cp);
	else
		sDisRTSToggle(cp);

	sSetRTS(&info->channel);

	if (cp->CtlP->boardType == ROCKET_TYPE_PC104) {
		switch (rocketMode) {
		case ROCKET_MODE_RS485:
			sSetInterfaceMode(cp, InterfaceModeRS485);
			break;
		case ROCKET_MODE_RS422:
			sSetInterfaceMode(cp, InterfaceModeRS422);
			break;
		case ROCKET_MODE_RS232:
		default:
			if (info->flags & ROCKET_RTS_TOGGLE)
				sSetInterfaceMode(cp, InterfaceModeRS232T);
			else
				sSetInterfaceMode(cp, InterfaceModeRS232);
			break;
		}
	}
}

static int carrier_raised(struct tty_port *port)
{
	struct r_port *info = container_of(port, struct r_port, port);
	return (sGetChanStatusLo(&info->channel) & CD_ACT) ? 1 : 0;
}

static void dtr_rts(struct tty_port *port, int on)
{
	struct r_port *info = container_of(port, struct r_port, port);
	if (on) {
		sSetDTR(&info->channel);
		sSetRTS(&info->channel);
	} else {
		sClrDTR(&info->channel);
		sClrRTS(&info->channel);
	}
}

/*
 *  Exception handler that opens a serial port.  Creates xmit_buf storage, fills in 
 *  port's r_port struct.  Initializes the port hardware.  
 */
static int rp_open(struct tty_struct *tty, struct file *filp)
{
	struct r_port *info;
	struct tty_port *port;
	int line = 0, retval;
	CHANNEL_t *cp;
	unsigned long page;

	line = tty->index;
	if (line < 0 || line >= MAX_RP_PORTS || ((info = rp_table[line]) == NULL))
		return -ENXIO;
	port = &info->port;
	
	page = __get_free_page(GFP_KERNEL);
	if (!page)
		return -ENOMEM;

	if (port->flags & ASYNC_CLOSING) {
		retval = wait_for_completion_interruptible(&info->close_wait);
		free_page(page);
		if (retval)
			return retval;
		return ((port->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
	}

	/*
	 * We must not sleep from here until the port is marked fully in use.
	 */
	if (info->xmit_buf)
		free_page(page);
	else
		info->xmit_buf = (unsigned char *) page;

	tty->driver_data = info;
	tty_port_tty_set(port, tty);

	if (port->count++ == 0) {
		atomic_inc(&rp_num_ports_open);

#ifdef ROCKET_DEBUG_OPEN
		printk(KERN_INFO "rocket mod++ = %d...\n",
				atomic_read(&rp_num_ports_open));
#endif
	}
#ifdef ROCKET_DEBUG_OPEN
	printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->port.count);
#endif

	/*
	 * Info->count is now 1; so it's safe to sleep now.
	 */
	if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
		cp = &info->channel;
		sSetRxTrigger(cp, TRIG_1);
		if (sGetChanStatus(cp) & CD_ACT)
			info->cd_status = 1;
		else
			info->cd_status = 0;
		sDisRxStatusMode(cp);
		sFlushRxFIFO(cp);
		sFlushTxFIFO(cp);

		sEnInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
		sSetRxTrigger(cp, TRIG_1);

		sGetChanStatus(cp);
		sDisRxStatusMode(cp);
		sClrTxXOFF(cp);

		sDisCTSFlowCtl(cp);
		sDisTxSoftFlowCtl(cp);

		sEnRxFIFO(cp);
		sEnTransmit(cp);

		set_bit(ASYNCB_INITIALIZED, &info->port.flags);

		/*
		 * Set up the tty->alt_speed kludge
		 */
		if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
			tty->alt_speed = 57600;
		if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
			tty->alt_speed = 115200;
		if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
			tty->alt_speed = 230400;
		if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
			tty->alt_speed = 460800;

		configure_r_port(tty, info, NULL);
		if (tty->termios->c_cflag & CBAUD) {
			sSetDTR(cp);
			sSetRTS(cp);
		}
	}
	/*  Starts (or resets) the maint polling loop */
	mod_timer(&rocket_timer, jiffies + POLL_PERIOD);

	retval = tty_port_block_til_ready(port, tty, filp);
	if (retval) {
#ifdef ROCKET_DEBUG_OPEN
		printk(KERN_INFO "rp_open returning after block_til_ready with %d\n", retval);
#endif
		return retval;
	}
	return 0;
}

/*
 *  Exception handler that closes a serial port. info->port.count is considered critical.
 */
static void rp_close(struct tty_struct *tty, struct file *filp)
{
	struct r_port *info = tty->driver_data;
	struct tty_port *port = &info->port;
	int timeout;
	CHANNEL_t *cp;
	
	if (rocket_paranoia_check(info, "rp_close"))
		return;

#ifdef ROCKET_DEBUG_OPEN
	printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->port.count);
#endif

	if (tty_port_close_start(port, tty, filp) == 0)
		return;

	cp = &info->channel;
	/*
	 * Before we drop DTR, make sure the UART transmitter
	 * has completely drained; this is especially
	 * important if there is a transmit FIFO!
	 */
	timeout = (sGetTxCnt(cp) + 1) * HZ / info->cps;
	if (timeout == 0)
		timeout = 1;
	rp_wait_until_sent(tty, timeout);
	clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);

	sDisTransmit(cp);
	sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
	sDisCTSFlowCtl(cp);
	sDisTxSoftFlowCtl(cp);
	sClrTxXOFF(cp);
	sFlushRxFIFO(cp);
	sFlushTxFIFO(cp);
	sClrRTS(cp);
	if (C_HUPCL(tty))
		sClrDTR(cp);

	rp_flush_buffer(tty);
		
	tty_ldisc_flush(tty);

	clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);

	/* We can't yet use tty_port_close_end as the buffer handling in this
	   driver is a bit different to the usual */

	if (port->blocked_open) {
		if (port->close_delay) {
			msleep_interruptible(jiffies_to_msecs(port->close_delay));
		}
		wake_up_interruptible(&port->open_wait);
	} else {
		if (info->xmit_buf) {
			free_page((unsigned long) info->xmit_buf);
			info->xmit_buf = NULL;
		}
	}
	info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE);
	tty->closing = 0;
	tty_port_tty_set(port, NULL);
	wake_up_interruptible(&port->close_wait);
	complete_all(&info->close_wait);
	atomic_dec(&rp_num_ports_open);

#ifdef ROCKET_DEBUG_OPEN
	printk(KERN_INFO "rocket mod-- = %d...\n",
			atomic_read(&rp_num_ports_open));
	printk(KERN_INFO "rp_close ttyR%d complete shutdown\n", info->line);
#endif

}

static void rp_set_termios(struct tty_struct *tty,
			   struct ktermios *old_termios)
{
	struct r_port *info = tty->driver_data;
	CHANNEL_t *cp;
	unsigned cflag;

	if (rocket_paranoia_check(info, "rp_set_termios"))
		return;

	cflag = tty->termios->c_cflag;

	/*
	 * This driver doesn't support CS5 or CS6
	 */
	if (((cflag & CSIZE) == CS5) || ((cflag & CSIZE) == CS6))
		tty->termios->c_cflag =
		    ((cflag & ~CSIZE) | (old_termios->c_cflag & CSIZE));
	/* Or CMSPAR */
	tty->termios->c_cflag &= ~CMSPAR;

	configure_r_port(tty, info, old_termios);

	cp = &info->channel;

	/* Handle transition to B0 status */
	if ((old_termios->c_cflag & CBAUD) && !(tty->termios->c_cflag & CBAUD)) {
		sClrDTR(cp);
		sClrRTS(cp);
	}

	/* Handle transition away from B0 status */
	if (!(old_termios->c_cflag & CBAUD) && (tty->termios->c_cflag & CBAUD)) {
		if (!tty->hw_stopped || !(tty->termios->c_cflag & CRTSCTS))
			sSetRTS(cp);
		sSetDTR(cp);
	}

	if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
		tty->hw_stopped = 0;
		rp_start(tty);
	}
}

static int rp_break(struct tty_struct *tty, int break_state)
{
	struct r_port *info = tty->driver_data;
	unsigned long flags;

	if (rocket_paranoia_check(info, "rp_break"))
		return -EINVAL;

	spin_lock_irqsave(&info->slock, flags);
	if (break_state == -1)
		sSendBreak(&info->channel);
	else
		sClrBreak(&info->channel);
	spin_unlock_irqrestore(&info->slock, flags);
	return 0;
}

/*
 * sGetChanRI used to be a macro in rocket_int.h. When the functionality for
 * the UPCI boards was added, it was decided to make this a function because
 * the macro was getting too complicated. All cases except the first one
 * (UPCIRingInd) are taken directly from the original macro.
 */
static int sGetChanRI(CHANNEL_T * ChP)
{
	CONTROLLER_t *CtlP = ChP->CtlP;
	int ChanNum = ChP->ChanNum;
	int RingInd = 0;

	if (CtlP->UPCIRingInd)
		RingInd = !(sInB(CtlP->UPCIRingInd) & sBitMapSetTbl[ChanNum]);
	else if (CtlP->AltChanRingIndicator)
		RingInd = sInB((ByteIO_t) (ChP->ChanStat + 8)) & DSR_ACT;
	else if (CtlP->boardType == ROCKET_TYPE_PC104)
		RingInd = !(sInB(CtlP->AiopIO[3]) & sBitMapSetTbl[ChanNum]);

	return RingInd;
}

/********************************************************************************************/
/*  Here are the routines used by rp_ioctl.  These are all called from exception handlers.  */

/*
 *  Returns the state of the serial modem control lines.  These next 2 functions 
 *  are the way kernel versions > 2.5 handle modem control lines rather than IOCTLs.
 */
static int rp_tiocmget(struct tty_struct *tty, struct file *file)
{
	struct r_port *info = tty->driver_data;
	unsigned int control, result, ChanStatus;

	ChanStatus = sGetChanStatusLo(&info->channel);
	control = info->channel.TxControl[3];
	result = ((control & SET_RTS) ? TIOCM_RTS : 0) | 
		((control & SET_DTR) ?  TIOCM_DTR : 0) |
		((ChanStatus & CD_ACT) ? TIOCM_CAR : 0) |
		(sGetChanRI(&info->channel) ? TIOCM_RNG : 0) |
		((ChanStatus & DSR_ACT) ? TIOCM_DSR : 0) |
		((ChanStatus & CTS_ACT) ? TIOCM_CTS : 0);

	return result;
}

/* 
 *  Sets the modem control lines
 */
static int rp_tiocmset(struct tty_struct *tty, struct file *file,
		    unsigned int set, unsigned int clear)
{
	struct r_port *info = tty->driver_data;

	if (set & TIOCM_RTS)
		info->channel.TxControl[3] |= SET_RTS;
	if (set & TIOCM_DTR)
		info->channel.TxControl[3] |= SET_DTR;
	if (clear & TIOCM_RTS)
		info->channel.TxControl[3] &= ~SET_RTS;
	if (clear & TIOCM_DTR)
		info->channel.TxControl[3] &= ~SET_DTR;

	out32(info->channel.IndexAddr, info->channel.TxControl);
	return 0;
}

static int get_config(struct r_port *info, struct rocket_config __user *retinfo)
{
	struct rocket_config tmp;

	if (!retinfo)
		return -EFAULT;
	memset(&tmp, 0, sizeof (tmp));
	tmp.line = info->line;
	tmp.flags = info->flags;
	tmp.close_delay = info->port.close_delay;
	tmp.closing_wait = info->port.closing_wait;
	tmp.port = rcktpt_io_addr[(info->line >> 5) & 3];

	if (copy_to_user(retinfo, &tmp, sizeof (*retinfo)))
		return -EFAULT;
	return 0;
}

static int set_config(struct tty_struct *tty, struct r_port *info,
					struct rocket_config __user *new_info)
{
	struct rocket_config new_serial;

	if (copy_from_user(&new_serial, new_info, sizeof (new_serial)))
		return -EFAULT;

	if (!capable(CAP_SYS_ADMIN))
	{
		if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK))
			return -EPERM;
		info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK));
		configure_r_port(tty, info, NULL);
		return 0;
	}

	info->flags = ((info->flags & ~ROCKET_FLAGS) | (new_serial.flags & ROCKET_FLAGS));
	info->port.close_delay = new_serial.close_delay;
	info->port.closing_wait = new_serial.closing_wait;

	if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
		tty->alt_speed = 57600;
	if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
		tty->alt_speed = 115200;
	if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
		tty->alt_speed = 230400;
	if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
		tty->alt_speed = 460800;

	configure_r_port(tty, info, NULL);
	return 0;
}

/*
 *  This function fills in a rocket_ports struct with information
 *  about what boards/ports are in the system.  This info is passed
 *  to user space.  See setrocket.c where the info is used to create
 *  the /dev/ttyRx ports.
 */
static int get_ports(struct r_port *info, struct rocket_ports __user *retports)
{
	struct rocket_ports tmp;
	int board;

	if (!retports)
		return -EFAULT;
	memset(&tmp, 0, sizeof (tmp));
	tmp.tty_major = rocket_driver->major;

	for (board = 0; board < 4; board++) {
		tmp.rocketModel[board].model = rocketModel[board].model;
		strcpy(tmp.rocketModel[board].modelString, rocketModel[board].modelString);
		tmp.rocketModel[board].numPorts = rocketModel[board].numPorts;
		tmp.rocketModel[board].loadrm2 = rocketModel[board].loadrm2;
		tmp.rocketModel[board].startingPortNumber = rocketModel[board].startingPortNumber;
	}
	if (copy_to_user(retports, &tmp, sizeof (*retports)))
		return -EFAULT;
	return 0;
}

static int reset_rm2(struct r_port *info, void __user *arg)
{
	int reset;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	if (copy_from_user(&reset, arg, sizeof (int)))
		return -EFAULT;
	if (reset)
		reset = 1;

	if (rcktpt_type[info->board] != ROCKET_TYPE_MODEMII &&
            rcktpt_type[info->board] != ROCKET_TYPE_MODEMIII)
		return -EINVAL;

	if (info->ctlp->BusType == isISA)
		sModemReset(info->ctlp, info->chan, reset);
	else
		sPCIModemReset(info->ctlp, info->chan, reset);

	return 0;
}

static int get_version(struct r_port *info, struct rocket_version __user *retvers)
{
	if (copy_to_user(retvers, &driver_version, sizeof (*retvers)))
		return -EFAULT;
	return 0;
}

/*  IOCTL call handler into the driver */
static int rp_ioctl(struct tty_struct *tty, struct file *file,
		    unsigned int cmd, unsigned long arg)
{
	struct r_port *info = tty->driver_data;
	void __user *argp = (void __user *)arg;
	int ret = 0;

	if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl"))
		return -ENXIO;

	lock_kernel();

	switch (cmd) {
	case RCKP_GET_STRUCT:
		if (copy_to_user(argp, info, sizeof (struct r_port)))
			ret = -EFAULT;
		break;
	case RCKP_GET_CONFIG:
		ret = get_config(info, argp);
		break;
	case RCKP_SET_CONFIG:
		ret = set_config(tty, info, argp);
		break;
	case RCKP_GET_PORTS:
		ret = get_ports(info, argp);
		break;
	case RCKP_RESET_RM2:
		ret = reset_rm2(info, argp);
		break;
	case RCKP_GET_VERSION:
		ret = get_version(info, argp);
		break;
	default:
		ret = -ENOIOCTLCMD;
	}
	unlock_kernel();
	return ret;
}

static void rp_send_xchar(struct tty_struct *tty, char ch)
{
	struct r_port *info = tty->driver_data;
	CHANNEL_t *cp;

	if (rocket_paranoia_check(info, "rp_send_xchar"))
		return;

	cp = &info->channel;
	if (sGetTxCnt(cp))
		sWriteTxPrioByte(cp, ch);
	else
		sWriteTxByte(sGetTxRxDataIO(cp), ch);
}

static void rp_throttle(struct tty_struct *tty)
{
	struct r_port *info = tty->driver_data;
	CHANNEL_t *cp;

#ifdef ROCKET_DEBUG_THROTTLE
	printk(KERN_INFO "throttle %s: %d....\n", tty->name,
	       tty->ldisc.chars_in_buffer(tty));
#endif

	if (rocket_paranoia_check(info, "rp_throttle"))
		return;

	cp = &info->channel;
	if (I_IXOFF(tty))
		rp_send_xchar(tty, STOP_CHAR(tty));

	sClrRTS(&info->channel);
}

static void rp_unthrottle(struct tty_struct *tty)
{
	struct r_port *info = tty->driver_data;
	CHANNEL_t *cp;
#ifdef ROCKET_DEBUG_THROTTLE
	printk(KERN_INFO "unthrottle %s: %d....\n", tty->name,
	       tty->ldisc.chars_in_buffer(tty));
#endif

	if (rocket_paranoia_check(info, "rp_throttle"))
		return;

	cp = &info->channel;
	if (I_IXOFF(tty))
		rp_send_xchar(tty, START_CHAR(tty));

	sSetRTS(&info->channel);
}

/*
 * ------------------------------------------------------------
 * rp_stop() and rp_start()
 *
 * This routines are called before setting or resetting tty->stopped.
 * They enable or disable transmitter interrupts, as necessary.
 * ------------------------------------------------------------
 */
static void rp_stop(struct tty_struct *tty)
{
	struct r_port *info = tty->driver_data;

#ifdef ROCKET_DEBUG_FLOW
	printk(KERN_INFO "stop %s: %d %d....\n", tty->name,
	       info->xmit_cnt, info->xmit_fifo_room);
#endif

	if (rocket_paranoia_check(info, "rp_stop"))
		return;

	if (sGetTxCnt(&info->channel))
		sDisTransmit(&info->channel);
}

static void rp_start(struct tty_struct *tty)
{
	struct r_port *info = tty->driver_data;

#ifdef ROCKET_DEBUG_FLOW
	printk(KERN_INFO "start %s: %d %d....\n", tty->name,
	       info->xmit_cnt, info->xmit_fifo_room);
#endif

	if (rocket_paranoia_check(info, "rp_stop"))
		return;

	sEnTransmit(&info->channel);
	set_bit((info->aiop * 8) + info->chan,
		(void *) &xmit_flags[info->board]);
}

/*
 * rp_wait_until_sent() --- wait until the transmitter is empty
 */
static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
{
	struct r_port *info = tty->driver_data;
	CHANNEL_t *cp;
	unsigned long orig_jiffies;
	int check_time, exit_time;
	int txcnt;

	if (rocket_paranoia_check(info, "rp_wait_until_sent"))
		return;

	cp = &info->channel;

	orig_jiffies = jiffies;
#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
	printk(KERN_INFO "In RP_wait_until_sent(%d) (jiff=%lu)...\n", timeout,
	       jiffies);
	printk(KERN_INFO "cps=%d...\n", info->cps);
#endif
	lock_kernel();
	while (1) {
		txcnt = sGetTxCnt(cp);
		if (!txcnt) {
			if (sGetChanStatusLo(cp) & TXSHRMT)
				break;
			check_time = (HZ / info->cps) / 5;
		} else {
			check_time = HZ * txcnt / info->cps;
		}
		if (timeout) {
			exit_time = orig_jiffies + timeout - jiffies;
			if (exit_time <= 0)
				break;
			if (exit_time < check_time)
				check_time = exit_time;
		}
		if (check_time == 0)
			check_time = 1;
#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
		printk(KERN_INFO "txcnt = %d (jiff=%lu,check=%d)...\n", txcnt,
				jiffies, check_time);
#endif
		msleep_interruptible(jiffies_to_msecs(check_time));
		if (signal_pending(current))
			break;
	}
	__set_current_state(TASK_RUNNING);
	unlock_kernel();
#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
	printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
#endif
}

/*
 * rp_hangup() --- called by tty_hangup() when a hangup is signaled.
 */
static void rp_hangup(struct tty_struct *tty)
{
	CHANNEL_t *cp;
	struct r_port *info = tty->driver_data;

	if (rocket_paranoia_check(info, "rp_hangup"))
		return;

#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_HANGUP))
	printk(KERN_INFO "rp_hangup of ttyR%d...\n", info->line);
#endif
	rp_flush_buffer(tty);
	if (info->port.flags & ASYNC_CLOSING)
		return;
	if (info->port.count)
		atomic_dec(&rp_num_ports_open);
	clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);

	tty_port_hangup(&info->port);

	cp = &info->channel;
	sDisRxFIFO(cp);
	sDisTransmit(cp);
	sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
	sDisCTSFlowCtl(cp);
	sDisTxSoftFlowCtl(cp);
	sClrTxXOFF(cp);
	info->port.flags &= ~ASYNC_INITIALIZED;

	wake_up_interruptible(&info->port.open_wait);
}

/*
 *  Exception handler - write char routine.  The RocketPort driver uses a
 *  double-buffering strategy, with the twist that if the in-memory CPU
 *  buffer is empty, and there's space in the transmit FIFO, the
 *  writing routines will write directly to transmit FIFO.
 *  Write buffer and counters protected by spinlocks
 */
static int rp_put_char(struct tty_struct *tty, unsigned char ch)
{
	struct r_port *info = tty->driver_data;
	CHANNEL_t *cp;
	unsigned long flags;

	if (rocket_paranoia_check(info, "rp_put_char"))
		return 0;

	/*
	 * Grab the port write mutex, locking out other processes that try to
	 * write to this port
	 */
	mutex_lock(&info->write_mtx);

#ifdef ROCKET_DEBUG_WRITE
	printk(KERN_INFO "rp_put_char %c...\n", ch);
#endif

	spin_lock_irqsave(&info->slock, flags);
	cp = &info->channel;

	if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room == 0)
		info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);

	if (tty->stopped || tty->hw_stopped || info->xmit_fifo_room == 0 || info->xmit_cnt != 0) {
		info->xmit_buf[info->xmit_head++] = ch;
		info->xmit_head &= XMIT_BUF_SIZE - 1;
		info->xmit_cnt++;
		set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
	} else {
		sOutB(sGetTxRxDataIO(cp), ch);
		info->xmit_fifo_room--;
	}
	spin_unlock_irqrestore(&info->slock, flags);
	mutex_unlock(&info->write_mtx);
	return 1;
}

/*
 *  Exception handler - write routine, called when user app writes to the device.
 *  A per port write mutex is used to protect from another process writing to
 *  this port at the same time.  This other process could be running on the other CPU
 *  or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out). 
 *  Spinlocks protect the info xmit members.
 */
static int rp_write(struct tty_struct *tty,
		    const unsigned char *buf, int count)
{
	struct r_port *info = tty->driver_data;
	CHANNEL_t *cp;
	const unsigned char *b;
	int c, retval = 0;
	unsigned long flags;

	if (count <= 0 || rocket_paranoia_check(info, "rp_write"))
		return 0;

	if (mutex_lock_interruptible(&info->write_mtx))
		return -ERESTARTSYS;

#ifdef ROCKET_DEBUG_WRITE
	printk(KERN_INFO "rp_write %d chars...\n", count);
#endif
	cp = &info->channel;

	if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room < count)
		info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);

        /*
	 *  If the write queue for the port is empty, and there is FIFO space, stuff bytes 
	 *  into FIFO.  Use the write queue for temp storage.
         */
	if (!tty->stopped && !tty->hw_stopped && info->xmit_cnt == 0 && info->xmit_fifo_room > 0) {
		c = min(count, info->xmit_fifo_room);
		b = buf;

		/*  Push data into FIFO, 2 bytes at a time */
		sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) b, c / 2);

		/*  If there is a byte remaining, write it */
		if (c & 1)
			sOutB(sGetTxRxDataIO(cp), b[c - 1]);

		retval += c;
		buf += c;
		count -= c;

		spin_lock_irqsave(&info->slock, flags);
		info->xmit_fifo_room -= c;
		spin_unlock_irqrestore(&info->slock, flags);
	}

	/* If count is zero, we wrote it all and are done */
	if (!count)
		goto end;

	/*  Write remaining data into the port's xmit_buf */
	while (1) {
		/* Hung up ? */
		if (!test_bit(ASYNCB_NORMAL_ACTIVE, &info->port.flags))
			goto end;
		c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
		c = min(c, XMIT_BUF_SIZE - info->xmit_head);
		if (c <= 0)
			break;

		b = buf;
		memcpy(info->xmit_buf + info->xmit_head, b, c);

		spin_lock_irqsave(&info->slock, flags);
		info->xmit_head =
		    (info->xmit_head + c) & (XMIT_BUF_SIZE - 1);
		info->xmit_cnt += c;
		spin_unlock_irqrestore(&info->slock, flags);

		buf += c;
		count -= c;
		retval += c;
	}

	if ((retval > 0) && !tty->stopped && !tty->hw_stopped)
		set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
	
end:
 	if (info->xmit_cnt < WAKEUP_CHARS) {
 		tty_wakeup(tty);
#ifdef ROCKETPORT_HAVE_POLL_WAIT
		wake_up_interruptible(&tty->poll_wait);
#endif
	}
	mutex_unlock(&info->write_mtx);
	return retval;
}

/*
 * Return the number of characters that can be sent.  We estimate
 * only using the in-memory transmit buffer only, and ignore the
 * potential space in the transmit FIFO.
 */
static int rp_write_room(struct tty_struct *tty)
{
	struct r_port *info = tty->driver_data;
	int ret;

	if (rocket_paranoia_check(info, "rp_write_room"))
		return 0;

	ret = XMIT_BUF_SIZE - info->xmit_cnt - 1;
	if (ret < 0)
		ret = 0;
#ifdef ROCKET_DEBUG_WRITE
	printk(KERN_INFO "rp_write_room returns %d...\n", ret);
#endif
	return ret;
}

/*
 * Return the number of characters in the buffer.  Again, this only
 * counts those characters in the in-memory transmit buffer.
 */
static int rp_chars_in_buffer(struct tty_struct *tty)
{
	struct r_port *info = tty->driver_data;
	CHANNEL_t *cp;

	if (rocket_paranoia_check(info, "rp_chars_in_buffer"))
		return 0;

	cp = &info->channel;

#ifdef ROCKET_DEBUG_WRITE
	printk(KERN_INFO "rp_chars_in_buffer returns %d...\n", info->xmit_cnt);
#endif
	return info->xmit_cnt;
}

/*
 *  Flushes the TX fifo for a port, deletes data in the xmit_buf stored in the
 *  r_port struct for the port.  Note that spinlock are used to protect info members,
 *  do not call this function if the spinlock is already held.
 */
static void rp_flush_buffer(struct tty_struct *tty)
{
	struct r_port *info = tty->driver_data;
	CHANNEL_t *cp;
	unsigned long flags;

	if (rocket_paranoia_check(info, "rp_flush_buffer"))
		return;

	spin_lock_irqsave(&info->slock, flags);
	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
	spin_unlock_irqrestore(&info->slock, flags);

#ifdef ROCKETPORT_HAVE_POLL_WAIT
	wake_up_interruptible(&tty->poll_wait);
#endif
	tty_wakeup(tty);

	cp = &info->channel;
	sFlushTxFIFO(cp);
}

#ifdef CONFIG_PCI

static struct pci_device_id __devinitdata rocket_pci_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) },
	{ }
};
MODULE_DEVICE_TABLE(pci, rocket_pci_ids);

/*
 *  Called when a PCI card is found.  Retrieves and stores model information,
 *  init's aiopic and serial port hardware.
 *  Inputs:  i is the board number (0-n)
 */
static __init int register_PCI(int i, struct pci_dev *dev)
{
	int num_aiops, aiop, max_num_aiops, num_chan, chan;
	unsigned int aiopio[MAX_AIOPS_PER_BOARD];
	char *str, *board_type;
	CONTROLLER_t *ctlp;

	int fast_clock = 0;
	int altChanRingIndicator = 0;
	int ports_per_aiop = 8;
	WordIO_t ConfigIO = 0;
	ByteIO_t UPCIRingInd = 0;

	if (!dev || pci_enable_device(dev))
		return 0;

	rcktpt_io_addr[i] = pci_resource_start(dev, 0);

	rcktpt_type[i] = ROCKET_TYPE_NORMAL;
	rocketModel[i].loadrm2 = 0;
	rocketModel[i].startingPortNumber = nextLineNumber;

	/*  Depending on the model, set up some config variables */
	switch (dev->device) {
	case PCI_DEVICE_ID_RP4QUAD:
		str = "Quadcable";
		max_num_aiops = 1;
		ports_per_aiop = 4;
		rocketModel[i].model = MODEL_RP4QUAD;
		strcpy(rocketModel[i].modelString, "RocketPort 4 port w/quad cable");
		rocketModel[i].numPorts = 4;
		break;
	case PCI_DEVICE_ID_RP8OCTA:
		str = "Octacable";
		max_num_aiops = 1;
		rocketModel[i].model = MODEL_RP8OCTA;
		strcpy(rocketModel[i].modelString, "RocketPort 8 port w/octa cable");
		rocketModel[i].numPorts = 8;
		break;
	case PCI_DEVICE_ID_URP8OCTA:
		str = "Octacable";
		max_num_aiops = 1;
		rocketModel[i].model = MODEL_UPCI_RP8OCTA;
		strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/octa cable");
		rocketModel[i].numPorts = 8;
		break;
	case PCI_DEVICE_ID_RP8INTF:
		str = "8";
		max_num_aiops = 1;
		rocketModel[i].model = MODEL_RP8INTF;
		strcpy(rocketModel[i].modelString, "RocketPort 8 port w/external I/F");
		rocketModel[i].numPorts = 8;
		break;
	case PCI_DEVICE_ID_URP8INTF:
		str = "8";
		max_num_aiops = 1;
		rocketModel[i].model = MODEL_UPCI_RP8INTF;
		strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/external I/F");
		rocketModel[i].numPorts = 8;
		break;
	case PCI_DEVICE_ID_RP8J:
		str = "8J";
		max_num_aiops = 1;
		rocketModel[i].model = MODEL_RP8J;
		strcpy(rocketModel[i].modelString, "RocketPort 8 port w/RJ11 connectors");
		rocketModel[i].numPorts = 8;
		break;
	case PCI_DEVICE_ID_RP4J:
		str = "4J";
		max_num_aiops = 1;
		ports_per_aiop = 4;
		rocketModel[i].model = MODEL_RP4J;
		strcpy(rocketModel[i].modelString, "RocketPort 4 port w/RJ45 connectors");
		rocketModel[i].numPorts = 4;
		break;
	case PCI_DEVICE_ID_RP8SNI:
		str = "8 (DB78 Custom)";
		max_num_aiops = 1;
		rocketModel[i].model = MODEL_RP8SNI;
		strcpy(rocketModel[i].modelString, "RocketPort 8 port w/ custom DB78");
		rocketModel[i].numPorts = 8;
		break;
	case PCI_DEVICE_ID_RP16SNI:
		str = "16 (DB78 Custom)";
		max_num_aiops = 2;
		rocketModel[i].model = MODEL_RP16SNI;
		strcpy(rocketModel[i].modelString, "RocketPort 16 port w/ custom DB78");
		rocketModel[i].numPorts = 16;
		break;
	case PCI_DEVICE_ID_RP16INTF:
		str = "16";
		max_num_aiops = 2;
		rocketModel[i].model = MODEL_RP16INTF;
		strcpy(rocketModel[i].modelString, "RocketPort 16 port w/external I/F");
		rocketModel[i].numPorts = 16;
		break;
	case PCI_DEVICE_ID_URP16INTF:
		str = "16";
		max_num_aiops = 2;
		rocketModel[i].model = MODEL_UPCI_RP16INTF;
		strcpy(rocketModel[i].modelString, "RocketPort UPCI 16 port w/external I/F");
		rocketModel[i].numPorts = 16;
		break;
	case PCI_DEVICE_ID_CRP16INTF:
		str = "16";
		max_num_aiops = 2;
		rocketModel[i].model = MODEL_CPCI_RP16INTF;
		strcpy(rocketModel[i].modelString, "RocketPort Compact PCI 16 port w/external I/F");
		rocketModel[i].numPorts = 16;
		break;
	case PCI_DEVICE_ID_RP32INTF:
		str = "32";
		max_num_aiops = 4;
		rocketModel[i].model = MODEL_RP32INTF;
		strcpy(rocketModel[i].modelString, "RocketPort 32 port w/external I/F");
		rocketModel[i].numPorts = 32;
		break;
	case PCI_DEVICE_ID_URP32INTF:
		str = "32";
		max_num_aiops = 4;
		rocketModel[i].model = MODEL_UPCI_RP32INTF;
		strcpy(rocketModel[i].modelString, "RocketPort UPCI 32 port w/external I/F");
		rocketModel[i].numPorts = 32;
		break;
	case PCI_DEVICE_ID_RPP4:
		str = "Plus Quadcable";
		max_num_aiops = 1;
		ports_per_aiop = 4;
		altChanRingIndicator++;
		fast_clock++;
		rocketModel[i].model = MODEL_RPP4;
		strcpy(rocketModel[i].modelString, "RocketPort Plus 4 port");
		rocketModel[i].numPorts = 4;
		break;
	case PCI_DEVICE_ID_RPP8:
		str = "Plus Octacable";
		max_num_aiops = 2;
		ports_per_aiop = 4;
		altChanRingIndicator++;
		fast_clock++;
		rocketModel[i].model = MODEL_RPP8;
		strcpy(rocketModel[i].modelString, "RocketPort Plus 8 port");
		rocketModel[i].numPorts = 8;
		break;
	case PCI_DEVICE_ID_RP2_232:
		str = "Plus 2 (RS-232)";
		max_num_aiops = 1;
		ports_per_aiop = 2;
		altChanRingIndicator++;
		fast_clock++;
		rocketModel[i].model = MODEL_RP2_232;
		strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS232");
		rocketModel[i].numPorts = 2;
		break;
	case PCI_DEVICE_ID_RP2_422:
		str = "Plus 2 (RS-422)";
		max_num_aiops = 1;
		ports_per_aiop = 2;
		altChanRingIndicator++;
		fast_clock++;
		rocketModel[i].model = MODEL_RP2_422;
		strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS422");
		rocketModel[i].numPorts = 2;
		break;
	case PCI_DEVICE_ID_RP6M:

		max_num_aiops = 1;
		ports_per_aiop = 6;
		str = "6-port";

		/*  If revision is 1, the rocketmodem flash must be loaded.
		 *  If it is 2 it is a "socketed" version. */
		if (dev->revision == 1) {
			rcktpt_type[i] = ROCKET_TYPE_MODEMII;
			rocketModel[i].loadrm2 = 1;
		} else {
			rcktpt_type[i] = ROCKET_TYPE_MODEM;
		}

		rocketModel[i].model = MODEL_RP6M;
		strcpy(rocketModel[i].modelString, "RocketModem 6 port");
		rocketModel[i].numPorts = 6;
		break;
	case PCI_DEVICE_ID_RP4M:
		max_num_aiops = 1;
		ports_per_aiop = 4;
		str = "4-port";
		if (dev->revision == 1) {
			rcktpt_type[i] = ROCKET_TYPE_MODEMII;
			rocketModel[i].loadrm2 = 1;
		} else {
			rcktpt_type[i] = ROCKET_TYPE_MODEM;
		}

		rocketModel[i].model = MODEL_RP4M;
		strcpy(rocketModel[i].modelString, "RocketModem 4 port");
		rocketModel[i].numPorts = 4;
		break;
	default:
		str = "(unknown/unsupported)";
		max_num_aiops = 0;
		break;
	}

	/*
	 * Check for UPCI boards.
	 */

	switch (dev->device) {
	case PCI_DEVICE_ID_URP32INTF:
	case PCI_DEVICE_ID_URP8INTF:
	case PCI_DEVICE_ID_URP16INTF:
	case PCI_DEVICE_ID_CRP16INTF:
	case PCI_DEVICE_ID_URP8OCTA:
		rcktpt_io_addr[i] = pci_resource_start(dev, 2);
		ConfigIO = pci_resource_start(dev, 1);
		if (dev->device == PCI_DEVICE_ID_URP8OCTA) {
			UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;

			/*
			 * Check for octa or quad cable.
			 */
			if (!
			    (sInW(ConfigIO + _PCI_9030_GPIO_CTRL) &
			     PCI_GPIO_CTRL_8PORT)) {
				str = "Quadcable";
				ports_per_aiop = 4;
				rocketModel[i].numPorts = 4;
			}
		}
		break;
	case PCI_DEVICE_ID_UPCI_RM3_8PORT:
		str = "8 ports";
		max_num_aiops = 1;
		rocketModel[i].model = MODEL_UPCI_RM3_8PORT;
		strcpy(rocketModel[i].modelString, "RocketModem III 8 port");
		rocketModel[i].numPorts = 8;
		rcktpt_io_addr[i] = pci_resource_start(dev, 2);
		UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
		ConfigIO = pci_resource_start(dev, 1);
		rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
		break;
	case PCI_DEVICE_ID_UPCI_RM3_4PORT:
		str = "4 ports";
		max_num_aiops = 1;
		rocketModel[i].model = MODEL_UPCI_RM3_4PORT;
		strcpy(rocketModel[i].modelString, "RocketModem III 4 port");
		rocketModel[i].numPorts = 4;
		rcktpt_io_addr[i] = pci_resource_start(dev, 2);
		UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
		ConfigIO = pci_resource_start(dev, 1);
		rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
		break;
	default:
		break;
	}

	switch (rcktpt_type[i]) {
	case ROCKET_TYPE_MODEM:
		board_type = "RocketModem";
		break;
	case ROCKET_TYPE_MODEMII:
		board_type = "RocketModem II";
		break;
	case ROCKET_TYPE_MODEMIII:
		board_type = "RocketModem III";
		break;
	default:
		board_type = "RocketPort";
		break;
	}

	if (fast_clock) {
		sClockPrescale = 0x12;	/* mod 2 (divide by 3) */
		rp_baud_base[i] = 921600;
	} else {
		/*
		 * If support_low_speed is set, use the slow clock
		 * prescale, which supports 50 bps
		 */
		if (support_low_speed) {
			/* mod 9 (divide by 10) prescale */
			sClockPrescale = 0x19;
			rp_baud_base[i] = 230400;
		} else {
			/* mod 4 (devide by 5) prescale */
			sClockPrescale = 0x14;
			rp_baud_base[i] = 460800;
		}
	}

	for (aiop = 0; aiop < max_num_aiops; aiop++)
		aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x40);
	ctlp = sCtlNumToCtlPtr(i);
	num_aiops = sPCIInitController(ctlp, i, aiopio, max_num_aiops, ConfigIO, 0, FREQ_DIS, 0, altChanRingIndicator, UPCIRingInd);
	for (aiop = 0; aiop < max_num_aiops; aiop++)
		ctlp->AiopNumChan[aiop] = ports_per_aiop;

	dev_info(&dev->dev, "comtrol PCI controller #%d found at "
		"address %04lx, %d AIOP(s) (%s), creating ttyR%d - %ld\n",
		i, rcktpt_io_addr[i], num_aiops, rocketModel[i].modelString,
		rocketModel[i].startingPortNumber,
		rocketModel[i].startingPortNumber + rocketModel[i].numPorts-1);

	if (num_aiops <= 0) {
		rcktpt_io_addr[i] = 0;
		return (0);
	}
	is_PCI[i] = 1;

	/*  Reset the AIOPIC, init the serial ports */
	for (aiop = 0; aiop < num_aiops; aiop++) {
		sResetAiopByNum(ctlp, aiop);
		num_chan = ports_per_aiop;
		for (chan = 0; chan < num_chan; chan++)
			init_r_port(i, aiop, chan, dev);
	}

	/*  Rocket modems must be reset */
	if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) ||
	    (rcktpt_type[i] == ROCKET_TYPE_MODEMII) ||
	    (rcktpt_type[i] == ROCKET_TYPE_MODEMIII)) {
		num_chan = ports_per_aiop;
		for (chan = 0; chan < num_chan; chan++)
			sPCIModemReset(ctlp, chan, 1);
		msleep(500);
		for (chan = 0; chan < num_chan; chan++)
			sPCIModemReset(ctlp, chan, 0);
		msleep(500);
		rmSpeakerReset(ctlp, rocketModel[i].model);
	}
	return (1);
}

/*
 *  Probes for PCI cards, inits them if found
 *  Input:   board_found = number of ISA boards already found, or the
 *           starting board number
 *  Returns: Number of PCI boards found
 */
static int __init init_PCI(int boards_found)
{
	struct pci_dev *dev = NULL;
	int count = 0;

	/*  Work through the PCI device list, pulling out ours */
	while ((dev = pci_get_device(PCI_VENDOR_ID_RP, PCI_ANY_ID, dev))) {
		if (register_PCI(count + boards_found, dev))
			count++;
	}
	return (count);
}

#endif				/* CONFIG_PCI */

/*
 *  Probes for ISA cards
 *  Input:   i = the board number to look for
 *  Returns: 1 if board found, 0 else
 */
static int __init init_ISA(int i)
{
	int num_aiops, num_chan = 0, total_num_chan = 0;
	int aiop, chan;
	unsigned int aiopio[MAX_AIOPS_PER_BOARD];
	CONTROLLER_t *ctlp;
	char *type_string;

	/*  If io_addr is zero, no board configured */
	if (rcktpt_io_addr[i] == 0)
		return (0);

	/*  Reserve the IO region */
	if (!request_region(rcktpt_io_addr[i], 64, "Comtrol RocketPort")) {
		printk(KERN_ERR "Unable to reserve IO region for configured "
				"ISA RocketPort at address 0x%lx, board not "
				"installed...\n", rcktpt_io_addr[i]);
		rcktpt_io_addr[i] = 0;
		return (0);
	}

	ctlp = sCtlNumToCtlPtr(i);

	ctlp->boardType = rcktpt_type[i];

	switch (rcktpt_type[i]) {
	case ROCKET_TYPE_PC104:
		type_string = "(PC104)";
		break;
	case ROCKET_TYPE_MODEM:
		type_string = "(RocketModem)";
		break;
	case ROCKET_TYPE_MODEMII:
		type_string = "(RocketModem II)";
		break;
	default:
		type_string = "";
		break;
	}

	/*
	 * If support_low_speed is set, use the slow clock prescale,
	 * which supports 50 bps
	 */
	if (support_low_speed) {
		sClockPrescale = 0x19;	/* mod 9 (divide by 10) prescale */
		rp_baud_base[i] = 230400;
	} else {
		sClockPrescale = 0x14;	/* mod 4 (devide by 5) prescale */
		rp_baud_base[i] = 460800;
	}

	for (aiop = 0; aiop < MAX_AIOPS_PER_BOARD; aiop++)
		aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x400);

	num_aiops = sInitController(ctlp, i, controller + (i * 0x400), aiopio,  MAX_AIOPS_PER_BOARD, 0, FREQ_DIS, 0);

	if (ctlp->boardType == ROCKET_TYPE_PC104) {
		sEnAiop(ctlp, 2);	/* only one AIOPIC, but these */
		sEnAiop(ctlp, 3);	/* CSels used for other stuff */
	}

	/*  If something went wrong initing the AIOP's release the ISA IO memory */
	if (num_aiops <= 0) {
		release_region(rcktpt_io_addr[i], 64);
		rcktpt_io_addr[i] = 0;
		return (0);
	}
  
	rocketModel[i].startingPortNumber = nextLineNumber;

	for (aiop = 0; aiop < num_aiops; aiop++) {
		sResetAiopByNum(ctlp, aiop);
		sEnAiop(ctlp, aiop);
		num_chan = sGetAiopNumChan(ctlp, aiop);
		total_num_chan += num_chan;
		for (chan = 0; chan < num_chan; chan++)
			init_r_port(i, aiop, chan, NULL);
	}
	is_PCI[i] = 0;
	if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) || (rcktpt_type[i] == ROCKET_TYPE_MODEMII)) {
		num_chan = sGetAiopNumChan(ctlp, 0);
		total_num_chan = num_chan;
		for (chan = 0; chan < num_chan; chan++)
			sModemReset(ctlp, chan, 1);
		msleep(500);
		for (chan = 0; chan < num_chan; chan++)
			sModemReset(ctlp, chan, 0);
		msleep(500);
		strcpy(rocketModel[i].modelString, "RocketModem ISA");
	} else {
		strcpy(rocketModel[i].modelString, "RocketPort ISA");
	}
	rocketModel[i].numPorts = total_num_chan;
	rocketModel[i].model = MODEL_ISA;

	printk(KERN_INFO "RocketPort ISA card #%d found at 0x%lx - %d AIOPs %s\n", 
	       i, rcktpt_io_addr[i], num_aiops, type_string);

	printk(KERN_INFO "Installing %s, creating /dev/ttyR%d - %ld\n",
	       rocketModel[i].modelString,
	       rocketModel[i].startingPortNumber,
	       rocketModel[i].startingPortNumber +
	       rocketModel[i].numPorts - 1);

	return (1);
}

static const struct tty_operations rocket_ops = {
	.open = rp_open,
	.close = rp_close,
	.write = rp_write,
	.put_char = rp_put_char,
	.write_room = rp_write_room,
	.chars_in_buffer = rp_chars_in_buffer,
	.flush_buffer = rp_flush_buffer,
	.ioctl = rp_ioctl,
	.throttle = rp_throttle,
	.unthrottle = rp_unthrottle,
	.set_termios = rp_set_termios,
	.stop = rp_stop,
	.start = rp_start,
	.hangup = rp_hangup,
	.break_ctl = rp_break,
	.send_xchar = rp_send_xchar,
	.wait_until_sent = rp_wait_until_sent,
	.tiocmget = rp_tiocmget,
	.tiocmset = rp_tiocmset,
};

static const struct tty_port_operations rocket_port_ops = {
	.carrier_raised = carrier_raised,
	.dtr_rts = dtr_rts,
};

/*
 * The module "startup" routine; it's run when the module is loaded.
 */
static int __init rp_init(void)
{
	int ret = -ENOMEM, pci_boards_found, isa_boards_found, i;

	printk(KERN_INFO "RocketPort device driver module, version %s, %s\n",
	       ROCKET_VERSION, ROCKET_DATE);

	rocket_driver = alloc_tty_driver(MAX_RP_PORTS);
	if (!rocket_driver)
		goto err;

	/*
	 *  If board 1 is non-zero, there is at least one ISA configured.  If controller is 
	 *  zero, use the default controller IO address of board1 + 0x40.
	 */
	if (board1) {
		if (controller == 0)
			controller = board1 + 0x40;
	} else {
		controller = 0;  /*  Used as a flag, meaning no ISA boards */
	}

	/*  If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */
	if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) {
		printk(KERN_ERR "Unable to reserve IO region for first "
			"configured ISA RocketPort controller 0x%lx.  "
			"Driver exiting\n", controller);
		ret = -EBUSY;
		goto err_tty;
	}

	/*  Store ISA variable retrieved from command line or .conf file. */
	rcktpt_io_addr[0] = board1;
	rcktpt_io_addr[1] = board2;
	rcktpt_io_addr[2] = board3;
	rcktpt_io_addr[3] = board4;

	rcktpt_type[0] = modem1 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
	rcktpt_type[0] = pc104_1[0] ? ROCKET_TYPE_PC104 : rcktpt_type[0];
	rcktpt_type[1] = modem2 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
	rcktpt_type[1] = pc104_2[0] ? ROCKET_TYPE_PC104 : rcktpt_type[1];
	rcktpt_type[2] = modem3 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
	rcktpt_type[2] = pc104_3[0] ? ROCKET_TYPE_PC104 : rcktpt_type[2];
	rcktpt_type[3] = modem4 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
	rcktpt_type[3] = pc104_4[0] ? ROCKET_TYPE_PC104 : rcktpt_type[3];

	/*
	 * Set up the tty driver structure and then register this
	 * driver with the tty layer.
	 */

	rocket_driver->owner = THIS_MODULE;
	rocket_driver->flags = TTY_DRIVER_DYNAMIC_DEV;
	rocket_driver->name = "ttyR";
	rocket_driver->driver_name = "Comtrol RocketPort";
	rocket_driver->major = TTY_ROCKET_MAJOR;
	rocket_driver->minor_start = 0;
	rocket_driver->type = TTY_DRIVER_TYPE_SERIAL;
	rocket_driver->subtype = SERIAL_TYPE_NORMAL;
	rocket_driver->init_termios = tty_std_termios;
	rocket_driver->init_termios.c_cflag =
	    B9600 | CS8 | CREAD | HUPCL | CLOCAL;
	rocket_driver->init_termios.c_ispeed = 9600;
	rocket_driver->init_termios.c_ospeed = 9600;
#ifdef ROCKET_SOFT_FLOW
	rocket_driver->flags |= TTY_DRIVER_REAL_RAW;
#endif
	tty_set_operations(rocket_driver, &rocket_ops);

	ret = tty_register_driver(rocket_driver);
	if (ret < 0) {
		printk(KERN_ERR "Couldn't install tty RocketPort driver\n");
		goto err_tty;
	}

#ifdef ROCKET_DEBUG_OPEN
	printk(KERN_INFO "RocketPort driver is major %d\n", rocket_driver.major);
#endif

	/*
	 *  OK, let's probe each of the controllers looking for boards.  Any boards found
         *  will be initialized here.
	 */
	isa_boards_found = 0;
	pci_boards_found = 0;

	for (i = 0; i < NUM_BOARDS; i++) {
		if (init_ISA(i))
			isa_boards_found++;
	}

#ifdef CONFIG_PCI
	if (isa_boards_found < NUM_BOARDS)
		pci_boards_found = init_PCI(isa_boards_found);
#endif

	max_board = pci_boards_found + isa_boards_found;

	if (max_board == 0) {
		printk(KERN_ERR "No rocketport ports found; unloading driver\n");
		ret = -ENXIO;
		goto err_ttyu;
	}

	return 0;
err_ttyu:
	tty_unregister_driver(rocket_driver);
err_tty:
	put_tty_driver(rocket_driver);
err:
	return ret;
}


static void rp_cleanup_module(void)
{
	int retval;
	int i;

	del_timer_sync(&rocket_timer);

	retval = tty_unregister_driver(rocket_driver);
	if (retval)
		printk(KERN_ERR "Error %d while trying to unregister "
		       "rocketport driver\n", -retval);

	for (i = 0; i < MAX_RP_PORTS; i++)
		if (rp_table[i]) {
			tty_unregister_device(rocket_driver, i);
			kfree(rp_table[i]);
		}

	put_tty_driver(rocket_driver);

	for (i = 0; i < NUM_BOARDS; i++) {
		if (rcktpt_io_addr[i] <= 0 || is_PCI[i])
			continue;
		release_region(rcktpt_io_addr[i], 64);
	}
	if (controller)
		release_region(controller, 4);
}

/***************************************************************************
Function: sInitController
Purpose:  Initialization of controller global registers and controller
          structure.
Call:     sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize,
                          IRQNum,Frequency,PeriodicOnly)
          CONTROLLER_T *CtlP; Ptr to controller structure
          int CtlNum; Controller number
          ByteIO_t MudbacIO; Mudbac base I/O address.
          ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
             This list must be in the order the AIOPs will be found on the
             controller.  Once an AIOP in the list is not found, it is
             assumed that there are no more AIOPs on the controller.
          int AiopIOListSize; Number of addresses in AiopIOList
          int IRQNum; Interrupt Request number.  Can be any of the following:
                         0: Disable global interrupts
                         3: IRQ 3
                         4: IRQ 4
                         5: IRQ 5
                         9: IRQ 9
                         10: IRQ 10
                         11: IRQ 11
                         12: IRQ 12
                         15: IRQ 15
          Byte_t Frequency: A flag identifying the frequency
                   of the periodic interrupt, can be any one of the following:
                      FREQ_DIS - periodic interrupt disabled
                      FREQ_137HZ - 137 Hertz
                      FREQ_69HZ - 69 Hertz
                      FREQ_34HZ - 34 Hertz
                      FREQ_17HZ - 17 Hertz
                      FREQ_9HZ - 9 Hertz
                      FREQ_4HZ - 4 Hertz
                   If IRQNum is set to 0 the Frequency parameter is
                   overidden, it is forced to a value of FREQ_DIS.
          int PeriodicOnly: 1 if all interrupts except the periodic
                               interrupt are to be blocked.
                            0 is both the periodic interrupt and
                               other channel interrupts are allowed.
                            If IRQNum is set to 0 the PeriodicOnly parameter is
                               overidden, it is forced to a value of 0.
Return:   int: Number of AIOPs on the controller, or CTLID_NULL if controller
               initialization failed.

Comments:
          If periodic interrupts are to be disabled but AIOP interrupts
          are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.

          If interrupts are to be completely disabled set IRQNum to 0.

          Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
          invalid combination.

          This function performs initialization of global interrupt modes,
          but it does not actually enable global interrupts.  To enable
          and disable global interrupts use functions sEnGlobalInt() and
          sDisGlobalInt().  Enabling of global interrupts is normally not
          done until all other initializations are complete.

          Even if interrupts are globally enabled, they must also be
          individually enabled for each channel that is to generate
          interrupts.

Warnings: No range checking on any of the parameters is done.

          No context switches are allowed while executing this function.

          After this function all AIOPs on the controller are disabled,
          they can be enabled with sEnAiop().
*/
static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
			   ByteIO_t * AiopIOList, int AiopIOListSize,
			   int IRQNum, Byte_t Frequency, int PeriodicOnly)
{
	int i;
	ByteIO_t io;
	int done;

	CtlP->AiopIntrBits = aiop_intr_bits;
	CtlP->AltChanRingIndicator = 0;
	CtlP->CtlNum = CtlNum;
	CtlP->CtlID = CTLID_0001;	/* controller release 1 */
	CtlP->BusType = isISA;
	CtlP->MBaseIO = MudbacIO;
	CtlP->MReg1IO = MudbacIO + 1;
	CtlP->MReg2IO = MudbacIO + 2;
	CtlP->MReg3IO = MudbacIO + 3;
#if 1
	CtlP->MReg2 = 0;	/* interrupt disable */
	CtlP->MReg3 = 0;	/* no periodic interrupts */
#else
	if (sIRQMap[IRQNum] == 0) {	/* interrupts globally disabled */
		CtlP->MReg2 = 0;	/* interrupt disable */
		CtlP->MReg3 = 0;	/* no periodic interrupts */
	} else {
		CtlP->MReg2 = sIRQMap[IRQNum];	/* set IRQ number */
		CtlP->MReg3 = Frequency;	/* set frequency */
		if (PeriodicOnly) {	/* periodic interrupt only */
			CtlP->MReg3 |= PERIODIC_ONLY;
		}
	}
#endif
	sOutB(CtlP->MReg2IO, CtlP->MReg2);
	sOutB(CtlP->MReg3IO, CtlP->MReg3);
	sControllerEOI(CtlP);	/* clear EOI if warm init */
	/* Init AIOPs */
	CtlP->NumAiop = 0;
	for (i = done = 0; i < AiopIOListSize; i++) {
		io = AiopIOList[i];
		CtlP->AiopIO[i] = (WordIO_t) io;
		CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
		sOutB(CtlP->MReg2IO, CtlP->MReg2 | (i & 0x03));	/* AIOP index */
		sOutB(MudbacIO, (Byte_t) (io >> 6));	/* set up AIOP I/O in MUDBAC */
		if (done)
			continue;
		sEnAiop(CtlP, i);	/* enable the AIOP */
		CtlP->AiopID[i] = sReadAiopID(io);	/* read AIOP ID */
		if (CtlP->AiopID[i] == AIOPID_NULL)	/* if AIOP does not exist */
			done = 1;	/* done looking for AIOPs */
		else {
			CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io);	/* num channels in AIOP */
			sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE);	/* clock prescaler */
			sOutB(io + _INDX_DATA, sClockPrescale);
			CtlP->NumAiop++;	/* bump count of AIOPs */
		}
		sDisAiop(CtlP, i);	/* disable AIOP */
	}

	if (CtlP->NumAiop == 0)
		return (-1);
	else
		return (CtlP->NumAiop);
}

/***************************************************************************
Function: sPCIInitController
Purpose:  Initialization of controller global registers and controller
          structure.
Call:     sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize,
                          IRQNum,Frequency,PeriodicOnly)
          CONTROLLER_T *CtlP; Ptr to controller structure
          int CtlNum; Controller number
          ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
             This list must be in the order the AIOPs will be found on the
             controller.  Once an AIOP in the list is not found, it is
             assumed that there are no more AIOPs on the controller.
          int AiopIOListSize; Number of addresses in AiopIOList
          int IRQNum; Interrupt Request number.  Can be any of the following:
                         0: Disable global interrupts
                         3: IRQ 3
                         4: IRQ 4
                         5: IRQ 5
                         9: IRQ 9
                         10: IRQ 10
                         11: IRQ 11
                         12: IRQ 12
                         15: IRQ 15
          Byte_t Frequency: A flag identifying the frequency
                   of the periodic interrupt, can be any one of the following:
                      FREQ_DIS - periodic interrupt disabled
                      FREQ_137HZ - 137 Hertz
                      FREQ_69HZ - 69 Hertz
                      FREQ_34HZ - 34 Hertz
                      FREQ_17HZ - 17 Hertz
                      FREQ_9HZ - 9 Hertz
                      FREQ_4HZ - 4 Hertz
                   If IRQNum is set to 0 the Frequency parameter is
                   overidden, it is forced to a value of FREQ_DIS.
          int PeriodicOnly: 1 if all interrupts except the periodic
                               interrupt are to be blocked.
                            0 is both the periodic interrupt and
                               other channel interrupts are allowed.
                            If IRQNum is set to 0 the PeriodicOnly parameter is
                               overidden, it is forced to a value of 0.
Return:   int: Number of AIOPs on the controller, or CTLID_NULL if controller
               initialization failed.

Comments:
          If periodic interrupts are to be disabled but AIOP interrupts
          are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.

          If interrupts are to be completely disabled set IRQNum to 0.

          Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
          invalid combination.

          This function performs initialization of global interrupt modes,
          but it does not actually enable global interrupts.  To enable
          and disable global interrupts use functions sEnGlobalInt() and
          sDisGlobalInt().  Enabling of global interrupts is normally not
          done until all other initializations are complete.

          Even if interrupts are globally enabled, they must also be
          individually enabled for each channel that is to generate
          interrupts.

Warnings: No range checking on any of the parameters is done.

          No context switches are allowed while executing this function.

          After this function all AIOPs on the controller are disabled,
          they can be enabled with sEnAiop().
*/
static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
			      ByteIO_t * AiopIOList, int AiopIOListSize,
			      WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
			      int PeriodicOnly, int altChanRingIndicator,
			      int UPCIRingInd)
{
	int i;
	ByteIO_t io;

	CtlP->AltChanRingIndicator = altChanRingIndicator;
	CtlP->UPCIRingInd = UPCIRingInd;
	CtlP->CtlNum = CtlNum;
	CtlP->CtlID = CTLID_0001;	/* controller release 1 */
	CtlP->BusType = isPCI;	/* controller release 1 */

	if (ConfigIO) {
		CtlP->isUPCI = 1;
		CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL;
		CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL;
		CtlP->AiopIntrBits = upci_aiop_intr_bits;
	} else {
		CtlP->isUPCI = 0;
		CtlP->PCIIO =
		    (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC);
		CtlP->AiopIntrBits = aiop_intr_bits;
	}

	sPCIControllerEOI(CtlP);	/* clear EOI if warm init */
	/* Init AIOPs */
	CtlP->NumAiop = 0;
	for (i = 0; i < AiopIOListSize; i++) {
		io = AiopIOList[i];
		CtlP->AiopIO[i] = (WordIO_t) io;
		CtlP->AiopIntChanIO[i] = io + _INT_CHAN;

		CtlP->AiopID[i] = sReadAiopID(io);	/* read AIOP ID */
		if (CtlP->AiopID[i] == AIOPID_NULL)	/* if AIOP does not exist */
			break;	/* done looking for AIOPs */

		CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io);	/* num channels in AIOP */
		sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE);	/* clock prescaler */
		sOutB(io + _INDX_DATA, sClockPrescale);
		CtlP->NumAiop++;	/* bump count of AIOPs */
	}

	if (CtlP->NumAiop == 0)
		return (-1);
	else
		return (CtlP->NumAiop);
}

/***************************************************************************
Function: sReadAiopID
Purpose:  Read the AIOP idenfication number directly from an AIOP.
Call:     sReadAiopID(io)
          ByteIO_t io: AIOP base I/O address
Return:   int: Flag AIOPID_XXXX if a valid AIOP is found, where X
                 is replace by an identifying number.
          Flag AIOPID_NULL if no valid AIOP is found
Warnings: No context switches are allowed while executing this function.

*/
static int sReadAiopID(ByteIO_t io)
{
	Byte_t AiopID;		/* ID byte from AIOP */

	sOutB(io + _CMD_REG, RESET_ALL);	/* reset AIOP */
	sOutB(io + _CMD_REG, 0x0);
	AiopID = sInW(io + _CHN_STAT0) & 0x07;
	if (AiopID == 0x06)
		return (1);
	else			/* AIOP does not exist */
		return (-1);
}

/***************************************************************************
Function: sReadAiopNumChan
Purpose:  Read the number of channels available in an AIOP directly from
          an AIOP.
Call:     sReadAiopNumChan(io)
          WordIO_t io: AIOP base I/O address
Return:   int: The number of channels available
Comments: The number of channels is determined by write/reads from identical
          offsets within the SRAM address spaces for channels 0 and 4.
          If the channel 4 space is mirrored to channel 0 it is a 4 channel
          AIOP, otherwise it is an 8 channel.
Warnings: No context switches are allowed while executing this function.
*/
static int sReadAiopNumChan(WordIO_t io)
{
	Word_t x;
	static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 };

	/* write to chan 0 SRAM */
	out32((DWordIO_t) io + _INDX_ADDR, R);
	sOutW(io + _INDX_ADDR, 0);	/* read from SRAM, chan 0 */
	x = sInW(io + _INDX_DATA);
	sOutW(io + _INDX_ADDR, 0x4000);	/* read from SRAM, chan 4 */
	if (x != sInW(io + _INDX_DATA))	/* if different must be 8 chan */
		return (8);
	else
		return (4);
}

/***************************************************************************
Function: sInitChan
Purpose:  Initialization of a channel and channel structure
Call:     sInitChan(CtlP,ChP,AiopNum,ChanNum)
          CONTROLLER_T *CtlP; Ptr to controller structure
          CHANNEL_T *ChP; Ptr to channel structure
          int AiopNum; AIOP number within controller
          int ChanNum; Channel number within AIOP
Return:   int: 1 if initialization succeeded, 0 if it fails because channel
               number exceeds number of channels available in AIOP.
Comments: This function must be called before a channel can be used.
Warnings: No range checking on any of the parameters is done.

          No context switches are allowed while executing this function.
*/
static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
		     int ChanNum)
{
	int i;
	WordIO_t AiopIO;
	WordIO_t ChIOOff;
	Byte_t *ChR;
	Word_t ChOff;
	static Byte_t R[4];
	int brd9600;

	if (ChanNum >= CtlP->AiopNumChan[AiopNum])
		return 0;	/* exceeds num chans in AIOP */

	/* Channel, AIOP, and controller identifiers */
	ChP->CtlP = CtlP;
	ChP->ChanID = CtlP->AiopID[AiopNum];
	ChP->AiopNum = AiopNum;
	ChP->ChanNum = ChanNum;

	/* Global direct addresses */
	AiopIO = CtlP->AiopIO[AiopNum];
	ChP->Cmd = (ByteIO_t) AiopIO + _CMD_REG;
	ChP->IntChan = (ByteIO_t) AiopIO + _INT_CHAN;
	ChP->IntMask = (ByteIO_t) AiopIO + _INT_MASK;
	ChP->IndexAddr = (DWordIO_t) AiopIO + _INDX_ADDR;
	ChP->IndexData = AiopIO + _INDX_DATA;

	/* Channel direct addresses */
	ChIOOff = AiopIO + ChP->ChanNum * 2;
	ChP->TxRxData = ChIOOff + _TD0;
	ChP->ChanStat = ChIOOff + _CHN_STAT0;
	ChP->TxRxCount = ChIOOff + _FIFO_CNT0;
	ChP->IntID = (ByteIO_t) AiopIO + ChP->ChanNum + _INT_ID0;

	/* Initialize the channel from the RData array */
	for (i = 0; i < RDATASIZE; i += 4) {
		R[0] = RData[i];
		R[1] = RData[i + 1] + 0x10 * ChanNum;
		R[2] = RData[i + 2];
		R[3] = RData[i + 3];
		out32(ChP->IndexAddr, R);
	}

	ChR = ChP->R;
	for (i = 0; i < RREGDATASIZE; i += 4) {
		ChR[i] = RRegData[i];
		ChR[i + 1] = RRegData[i + 1] + 0x10 * ChanNum;
		ChR[i + 2] = RRegData[i + 2];
		ChR[i + 3] = RRegData[i + 3];
	}

	/* Indexed registers */
	ChOff = (Word_t) ChanNum *0x1000;

	if (sClockPrescale == 0x14)
		brd9600 = 47;
	else
		brd9600 = 23;

	ChP->BaudDiv[0] = (Byte_t) (ChOff + _BAUD);
	ChP->BaudDiv[1] = (Byte_t) ((ChOff + _BAUD) >> 8);
	ChP->BaudDiv[2] = (Byte_t) brd9600;
	ChP->BaudDiv[3] = (Byte_t) (brd9600 >> 8);
	out32(ChP->IndexAddr, ChP->BaudDiv);

	ChP->TxControl[0] = (Byte_t) (ChOff + _TX_CTRL);
	ChP->TxControl[1] = (Byte_t) ((ChOff + _TX_CTRL) >> 8);
	ChP->TxControl[2] = 0;
	ChP->TxControl[3] = 0;
	out32(ChP->IndexAddr, ChP->TxControl);

	ChP->RxControl[0] = (Byte_t) (ChOff + _RX_CTRL);
	ChP->RxControl[1] = (Byte_t) ((ChOff + _RX_CTRL) >> 8);
	ChP->RxControl[2] = 0;
	ChP->RxControl[3] = 0;
	out32(ChP->IndexAddr, ChP->RxControl);

	ChP->TxEnables[0] = (Byte_t) (ChOff + _TX_ENBLS);
	ChP->TxEnables[1] = (Byte_t) ((ChOff + _TX_ENBLS) >> 8);
	ChP->TxEnables[2] = 0;
	ChP->TxEnables[3] = 0;
	out32(ChP->IndexAddr, ChP->TxEnables);

	ChP->TxCompare[0] = (Byte_t) (ChOff + _TXCMP1);
	ChP->TxCompare[1] = (Byte_t) ((ChOff + _TXCMP1) >> 8);
	ChP->TxCompare[2] = 0;
	ChP->TxCompare[3] = 0;
	out32(ChP->IndexAddr, ChP->TxCompare);

	ChP->TxReplace1[0] = (Byte_t) (ChOff + _TXREP1B1);
	ChP->TxReplace1[1] = (Byte_t) ((ChOff + _TXREP1B1) >> 8);
	ChP->TxReplace1[2] = 0;
	ChP->TxReplace1[3] = 0;
	out32(ChP->IndexAddr, ChP->TxReplace1);

	ChP->TxReplace2[0] = (Byte_t) (ChOff + _TXREP2);
	ChP->TxReplace2[1] = (Byte_t) ((ChOff + _TXREP2) >> 8);
	ChP->TxReplace2[2] = 0;
	ChP->TxReplace2[3] = 0;
	out32(ChP->IndexAddr, ChP->TxReplace2);

	ChP->TxFIFOPtrs = ChOff + _TXF_OUTP;
	ChP->TxFIFO = ChOff + _TX_FIFO;

	sOutB(ChP->Cmd, (Byte_t) ChanNum | RESTXFCNT);	/* apply reset Tx FIFO count */
	sOutB(ChP->Cmd, (Byte_t) ChanNum);	/* remove reset Tx FIFO count */
	sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs);	/* clear Tx in/out ptrs */
	sOutW(ChP->IndexData, 0);
	ChP->RxFIFOPtrs = ChOff + _RXF_OUTP;
	ChP->RxFIFO = ChOff + _RX_FIFO;

	sOutB(ChP->Cmd, (Byte_t) ChanNum | RESRXFCNT);	/* apply reset Rx FIFO count */
	sOutB(ChP->Cmd, (Byte_t) ChanNum);	/* remove reset Rx FIFO count */
	sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs);	/* clear Rx out ptr */
	sOutW(ChP->IndexData, 0);
	sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2);	/* clear Rx in ptr */
	sOutW(ChP->IndexData, 0);
	ChP->TxPrioCnt = ChOff + _TXP_CNT;
	sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioCnt);
	sOutB(ChP->IndexData, 0);
	ChP->TxPrioPtr = ChOff + _TXP_PNTR;
	sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioPtr);
	sOutB(ChP->IndexData, 0);
	ChP->TxPrioBuf = ChOff + _TXP_BUF;
	sEnRxProcessor(ChP);	/* start the Rx processor */

	return 1;
}

/***************************************************************************
Function: sStopRxProcessor
Purpose:  Stop the receive processor from processing a channel.
Call:     sStopRxProcessor(ChP)
          CHANNEL_T *ChP; Ptr to channel structure

Comments: The receive processor can be started again with sStartRxProcessor().
          This function causes the receive processor to skip over the
          stopped channel.  It does not stop it from processing other channels.

Warnings: No context switches are allowed while executing this function.

          Do not leave the receive processor stopped for more than one
          character time.

          After calling this function a delay of 4 uS is required to ensure
          that the receive processor is no longer processing this channel.
*/
static void sStopRxProcessor(CHANNEL_T * ChP)
{
	Byte_t R[4];

	R[0] = ChP->R[0];
	R[1] = ChP->R[1];
	R[2] = 0x0a;
	R[3] = ChP->R[3];
	out32(ChP->IndexAddr, R);
}

/***************************************************************************
Function: sFlushRxFIFO
Purpose:  Flush the Rx FIFO
Call:     sFlushRxFIFO(ChP)
          CHANNEL_T *ChP; Ptr to channel structure
Return:   void
Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
          while it is being flushed the receive processor is stopped
          and the transmitter is disabled.  After these operations a
          4 uS delay is done before clearing the pointers to allow
          the receive processor to stop.  These items are handled inside
          this function.
Warnings: No context switches are allowed while executing this function.
*/
static void sFlushRxFIFO(CHANNEL_T * ChP)
{
	int i;
	Byte_t Ch;		/* channel number within AIOP */
	int RxFIFOEnabled;	/* 1 if Rx FIFO enabled */

	if (sGetRxCnt(ChP) == 0)	/* Rx FIFO empty */
		return;		/* don't need to flush */

	RxFIFOEnabled = 0;
	if (ChP->R[0x32] == 0x08) {	/* Rx FIFO is enabled */
		RxFIFOEnabled = 1;
		sDisRxFIFO(ChP);	/* disable it */
		for (i = 0; i < 2000 / 200; i++)	/* delay 2 uS to allow proc to disable FIFO */
			sInB(ChP->IntChan);	/* depends on bus i/o timing */
	}
	sGetChanStatus(ChP);	/* clear any pending Rx errors in chan stat */
	Ch = (Byte_t) sGetChanNum(ChP);
	sOutB(ChP->Cmd, Ch | RESRXFCNT);	/* apply reset Rx FIFO count */
	sOutB(ChP->Cmd, Ch);	/* remove reset Rx FIFO count */
	sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs);	/* clear Rx out ptr */
	sOutW(ChP->IndexData, 0);
	sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2);	/* clear Rx in ptr */
	sOutW(ChP->IndexData, 0);
	if (RxFIFOEnabled)
		sEnRxFIFO(ChP);	/* enable Rx FIFO */
}

/***************************************************************************
Function: sFlushTxFIFO
Purpose:  Flush the Tx FIFO
Call:     sFlushTxFIFO(ChP)
          CHANNEL_T *ChP; Ptr to channel structure
Return:   void
Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
          while it is being flushed the receive processor is stopped
          and the transmitter is disabled.  After these operations a
          4 uS delay is done before clearing the pointers to allow
          the receive processor to stop.  These items are handled inside
          this function.
Warnings: No context switches are allowed while executing this function.
*/
static void sFlushTxFIFO(CHANNEL_T * ChP)
{
	int i;
	Byte_t Ch;		/* channel number within AIOP */
	int TxEnabled;		/* 1 if transmitter enabled */

	if (sGetTxCnt(ChP) == 0)	/* Tx FIFO empty */
		return;		/* don't need to flush */

	TxEnabled = 0;
	if (ChP->TxControl[3] & TX_ENABLE) {
		TxEnabled = 1;
		sDisTransmit(ChP);	/* disable transmitter */
	}
	sStopRxProcessor(ChP);	/* stop Rx processor */
	for (i = 0; i < 4000 / 200; i++)	/* delay 4 uS to allow proc to stop */
		sInB(ChP->IntChan);	/* depends on bus i/o timing */
	Ch = (Byte_t) sGetChanNum(ChP);
	sOutB(ChP->Cmd, Ch | RESTXFCNT);	/* apply reset Tx FIFO count */
	sOutB(ChP->Cmd, Ch);	/* remove reset Tx FIFO count */
	sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs);	/* clear Tx in/out ptrs */
	sOutW(ChP->IndexData, 0);
	if (TxEnabled)
		sEnTransmit(ChP);	/* enable transmitter */
	sStartRxProcessor(ChP);	/* restart Rx processor */
}

/***************************************************************************
Function: sWriteTxPrioByte
Purpose:  Write a byte of priority transmit data to a channel
Call:     sWriteTxPrioByte(ChP,Data)
          CHANNEL_T *ChP; Ptr to channel structure
          Byte_t Data; The transmit data byte

Return:   int: 1 if the bytes is successfully written, otherwise 0.

Comments: The priority byte is transmitted before any data in the Tx FIFO.

Warnings: No context switches are allowed while executing this function.
*/
static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
{
	Byte_t DWBuf[4];	/* buffer for double word writes */
	Word_t *WordPtr;	/* must be far because Win SS != DS */
	register DWordIO_t IndexAddr;

	if (sGetTxCnt(ChP) > 1) {	/* write it to Tx priority buffer */
		IndexAddr = ChP->IndexAddr;
		sOutW((WordIO_t) IndexAddr, ChP->TxPrioCnt);	/* get priority buffer status */
		if (sInB((ByteIO_t) ChP->IndexData) & PRI_PEND)	/* priority buffer busy */
			return (0);	/* nothing sent */

		WordPtr = (Word_t *) (&DWBuf[0]);
		*WordPtr = ChP->TxPrioBuf;	/* data byte address */

		DWBuf[2] = Data;	/* data byte value */
		out32(IndexAddr, DWBuf);	/* write it out */

		*WordPtr = ChP->TxPrioCnt;	/* Tx priority count address */

		DWBuf[2] = PRI_PEND + 1;	/* indicate 1 byte pending */
		DWBuf[3] = 0;	/* priority buffer pointer */
		out32(IndexAddr, DWBuf);	/* write it out */
	} else {		/* write it to Tx FIFO */

		sWriteTxByte(sGetTxRxDataIO(ChP), Data);
	}
	return (1);		/* 1 byte sent */
}

/***************************************************************************
Function: sEnInterrupts
Purpose:  Enable one or more interrupts for a channel
Call:     sEnInterrupts(ChP,Flags)
          CHANNEL_T *ChP; Ptr to channel structure
          Word_t Flags: Interrupt enable flags, can be any combination
             of the following flags:
                TXINT_EN:   Interrupt on Tx FIFO empty
                RXINT_EN:   Interrupt on Rx FIFO at trigger level (see
                            sSetRxTrigger())
                SRCINT_EN:  Interrupt on SRC (Special Rx Condition)
                MCINT_EN:   Interrupt on modem input change
                CHANINT_EN: Allow channel interrupt signal to the AIOP's
                            Interrupt Channel Register.
Return:   void
Comments: If an interrupt enable flag is set in Flags, that interrupt will be
          enabled.  If an interrupt enable flag is not set in Flags, that
          interrupt will not be changed.  Interrupts can be disabled with
          function sDisInterrupts().

          This function sets the appropriate bit for the channel in the AIOP's
          Interrupt Mask Register if the CHANINT_EN flag is set.  This allows
          this channel's bit to be set in the AIOP's Interrupt Channel Register.

          Interrupts must also be globally enabled before channel interrupts
          will be passed on to the host.  This is done with function
          sEnGlobalInt().

          In some cases it may be desirable to disable interrupts globally but
          enable channel interrupts.  This would allow the global interrupt
          status register to be used to determine which AIOPs need service.
*/
static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
{
	Byte_t Mask;		/* Interrupt Mask Register */

	ChP->RxControl[2] |=
	    ((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));

	out32(ChP->IndexAddr, ChP->RxControl);

	ChP->TxControl[2] |= ((Byte_t) Flags & TXINT_EN);

	out32(ChP->IndexAddr, ChP->TxControl);

	if (Flags & CHANINT_EN) {
		Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum];
		sOutB(ChP->IntMask, Mask);
	}
}

/***************************************************************************
Function: sDisInterrupts
Purpose:  Disable one or more interrupts for a channel
Call:     sDisInterrupts(ChP,Flags)
          CHANNEL_T *ChP; Ptr to channel structure
          Word_t Flags: Interrupt flags, can be any combination
             of the following flags:
                TXINT_EN:   Interrupt on Tx FIFO empty
                RXINT_EN:   Interrupt on Rx FIFO at trigger level (see
                            sSetRxTrigger())
                SRCINT_EN:  Interrupt on SRC (Special Rx Condition)
                MCINT_EN:   Interrupt on modem input change
                CHANINT_EN: Disable channel interrupt signal to the
                            AIOP's Interrupt Channel Register.
Return:   void
Comments: If an interrupt flag is set in Flags, that interrupt will be
          disabled.  If an interrupt flag is not set in Flags, that
          interrupt will not be changed.  Interrupts can be enabled with
          function sEnInterrupts().

          This function clears the appropriate bit for the channel in the AIOP's
          Interrupt Mask Register if the CHANINT_EN flag is set.  This blocks
          this channel's bit from being set in the AIOP's Interrupt Channel
          Register.
*/
static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
{
	Byte_t Mask;		/* Interrupt Mask Register */

	ChP->RxControl[2] &=
	    ~((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
	out32(ChP->IndexAddr, ChP->RxControl);
	ChP->TxControl[2] &= ~((Byte_t) Flags & TXINT_EN);
	out32(ChP->IndexAddr, ChP->TxControl);

	if (Flags & CHANINT_EN) {
		Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum];
		sOutB(ChP->IntMask, Mask);
	}
}

static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
{
	sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum);
}

/*
 *  Not an official SSCI function, but how to reset RocketModems.
 *  ISA bus version
 */
static void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
{
	ByteIO_t addr;
	Byte_t val;

	addr = CtlP->AiopIO[0] + 0x400;
	val = sInB(CtlP->MReg3IO);
	/* if AIOP[1] is not enabled, enable it */
	if ((val & 2) == 0) {
		val = sInB(CtlP->MReg2IO);
		sOutB(CtlP->MReg2IO, (val & 0xfc) | (1 & 0x03));
		sOutB(CtlP->MBaseIO, (unsigned char) (addr >> 6));
	}

	sEnAiop(CtlP, 1);
	if (!on)
		addr += 8;
	sOutB(addr + chan, 0);	/* apply or remove reset */
	sDisAiop(CtlP, 1);
}

/*
 *  Not an official SSCI function, but how to reset RocketModems.
 *  PCI bus version
 */
static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
{
	ByteIO_t addr;

	addr = CtlP->AiopIO[0] + 0x40;	/* 2nd AIOP */
	if (!on)
		addr += 8;
	sOutB(addr + chan, 0);	/* apply or remove reset */
}

/*  Resets the speaker controller on RocketModem II and III devices */
static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model)
{
	ByteIO_t addr;

	/* RocketModem II speaker control is at the 8th port location of offset 0x40 */
	if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) {
		addr = CtlP->AiopIO[0] + 0x4F;
		sOutB(addr, 0);
	}

	/* RocketModem III speaker control is at the 1st port location of offset 0x80 */
	if ((model == MODEL_UPCI_RM3_8PORT)
	    || (model == MODEL_UPCI_RM3_4PORT)) {
		addr = CtlP->AiopIO[0] + 0x88;
		sOutB(addr, 0);
	}
}

/*  Returns the line number given the controller (board), aiop and channel number */
static unsigned char GetLineNumber(int ctrl, int aiop, int ch)
{
	return lineNumbers[(ctrl << 5) | (aiop << 3) | ch];
}

/*
 *  Stores the line number associated with a given controller (board), aiop
 *  and channel number.  
 *  Returns:  The line number assigned 
 */
static unsigned char SetLineNumber(int ctrl, int aiop, int ch)
{
	lineNumbers[(ctrl << 5) | (aiop << 3) | ch] = nextLineNumber++;
	return (nextLineNumber - 1);
}
