/*
 * 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/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 <asm/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;

/*
 * 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;
	if (!info->port.tty) {
		printk(KERN_WARNING "rp: WARNING %s called with "
				"info->port.tty==NULL\n", __func__);
		clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
		return;
	}

	spin_lock_irqsave(&info->slock, flags);
	tty = info->port.tty;
	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);

#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->flags & ROCKET_INITIALIZED) == 0) {
		printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
				"info->flags & NOT_INIT\n");
		return;
	}
	if (!info->port.tty) {
		printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
				"info->port.tty==NULL\n");
		return;
	}
	cp = &info->channel;
	tty = info->port.tty;

	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
}

/*
 *  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;
	info->closing_wait = 3000;
	info->close_delay = 50;
	init_waitqueue_head(&info->port.open_wait);
	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 r_port *info,
			     struct ktermios *old_termios)
{
	unsigned cflag;
	unsigned long flags;
	unsigned rocketMode;
	int bits, baud, divisor;
	CHANNEL_t *cp;
	struct ktermios *t = info->port.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(info->port.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(info->port.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(info->port.tty)) {
		sEnTxSoftFlowCtl(cp);
		if (I_IXANY(info->port.tty)) {
			sEnIXANY(cp);
		} else {
			sDisIXANY(cp);
		}
		sSetTxXONChar(cp, START_CHAR(info->port.tty));
		sSetTxXOFFChar(cp, STOP_CHAR(info->port.tty));
	} else {
		sDisTxSoftFlowCtl(cp);
		sDisIXANY(cp);
		sClrTxXOFF(cp);
	}
#endif

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

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

/*  info->port.count is considered critical, protected by spinlocks.  */
static int block_til_ready(struct tty_struct *tty, struct file *filp,
			   struct r_port *info)
{
	DECLARE_WAITQUEUE(wait, current);
	int retval;
	int do_clocal = 0, extra_count = 0;
	unsigned long flags;

	/*
	 * If the device is in the middle of being closed, then block
	 * until it's done, and then try again.
	 */
	if (tty_hung_up_p(filp))
		return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
	if (info->flags & ROCKET_CLOSING) {
		if (wait_for_completion_interruptible(&info->close_wait))
			return -ERESTARTSYS;
		return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
	}

	/*
	 * If non-blocking mode is set, or the port is not enabled,
	 * then make the check up front and then exit.
	 */
	if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
		info->flags |= ROCKET_NORMAL_ACTIVE;
		return 0;
	}
	if (tty->termios->c_cflag & CLOCAL)
		do_clocal = 1;

	/*
	 * Block waiting for the carrier detect and the line to become free.  While we are in
	 * this loop, info->port.count is dropped by one, so that rp_close() knows when to free things.
         * We restore it upon exit, either normal or abnormal.
	 */
	retval = 0;
	add_wait_queue(&info->port.open_wait, &wait);
#ifdef ROCKET_DEBUG_OPEN
	printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, info->port.count);
#endif
	spin_lock_irqsave(&info->slock, flags);

#ifdef ROCKET_DISABLE_SIMUSAGE
	info->flags |= ROCKET_NORMAL_ACTIVE;
#else
	if (!tty_hung_up_p(filp)) {
		extra_count = 1;
		info->port.count--;
	}
#endif
	info->port.blocked_open++;

	spin_unlock_irqrestore(&info->slock, flags);

	while (1) {
		if (tty->termios->c_cflag & CBAUD) {
			sSetDTR(&info->channel);
			sSetRTS(&info->channel);
		}
		set_current_state(TASK_INTERRUPTIBLE);
		if (tty_hung_up_p(filp) || !(info->flags & ROCKET_INITIALIZED)) {
			if (info->flags & ROCKET_HUP_NOTIFY)
				retval = -EAGAIN;
			else
				retval = -ERESTARTSYS;
			break;
		}
		if (!(info->flags & ROCKET_CLOSING) && (do_clocal || (sGetChanStatusLo(&info->channel) & CD_ACT)))
			break;
		if (signal_pending(current)) {
			retval = -ERESTARTSYS;
			break;
		}
#ifdef ROCKET_DEBUG_OPEN
		printk(KERN_INFO "block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n",
		     info->line, info->port.count, info->flags);
#endif
		schedule();	/*  Don't hold spinlock here, will hang PC */
	}
	__set_current_state(TASK_RUNNING);
	remove_wait_queue(&info->port.open_wait, &wait);

	spin_lock_irqsave(&info->slock, flags);

	if (extra_count)
		info->port.count++;
	info->port.blocked_open--;

	spin_unlock_irqrestore(&info->slock, flags);

#ifdef ROCKET_DEBUG_OPEN
	printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n",
	       info->line, info->port.count);
#endif
	if (retval)
		return retval;
	info->flags |= ROCKET_NORMAL_ACTIVE;
	return 0;
}

/*
 *  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;
	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;

	page = __get_free_page(GFP_KERNEL);
	if (!page)
		return -ENOMEM;

	if (info->flags & ROCKET_CLOSING) {
		retval = wait_for_completion_interruptible(&info->close_wait);
		free_page(page);
		if (retval)
			return retval;
		return ((info->flags & ROCKET_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;
	info->port.tty = tty;

	if (info->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 ((info->flags & ROCKET_INITIALIZED) == 0) {
		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);

		info->flags |= ROCKET_INITIALIZED;

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

		configure_r_port(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 = block_til_ready(tty, filp, info);
	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 = (struct r_port *) tty->driver_data;
	unsigned long flags;
	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_hung_up_p(filp))
		return;
	spin_lock_irqsave(&info->slock, flags);

	if ((tty->count == 1) && (info->port.count != 1)) {
		/*
		 * Uh, oh.  tty->count is 1, which means that the tty
		 * structure will be freed.  Info->count should always
		 * be one in these conditions.  If it's greater than
		 * one, we've got real problems, since it means the
		 * serial port won't be shutdown.
		 */
		printk(KERN_WARNING "rp_close: bad serial port count; "
			"tty->count is 1, info->port.count is %d\n", info->port.count);
		info->port.count = 1;
	}
	if (--info->port.count < 0) {
		printk(KERN_WARNING "rp_close: bad serial port count for "
				"ttyR%d: %d\n", info->line, info->port.count);
		info->port.count = 0;
	}
	if (info->port.count) {
		spin_unlock_irqrestore(&info->slock, flags);
		return;
	}
	info->flags |= ROCKET_CLOSING;
	spin_unlock_irqrestore(&info->slock, flags);

	cp = &info->channel;

	/*
	 * Notify the line discpline to only process XON/XOFF characters
	 */
	tty->closing = 1;

	/*
	 * If transmission was throttled by the application request,
	 * just flush the xmit buffer.
	 */
	if (tty->flow_stopped)
		rp_flush_buffer(tty);

	/*
	 * Wait for the transmit buffer to clear
	 */
	if (info->closing_wait != ROCKET_CLOSING_WAIT_NONE)
		tty_wait_until_sent(tty, info->closing_wait);
	/*
	 * 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]);

	if (info->port.blocked_open) {
		if (info->close_delay) {
			msleep_interruptible(jiffies_to_msecs(info->close_delay));
		}
		wake_up_interruptible(&info->port.open_wait);
	} else {
		if (info->xmit_buf) {
			free_page((unsigned long) info->xmit_buf);
			info->xmit_buf = NULL;
		}
	}
	info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE);
	tty->closing = 0;
	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 = (struct r_port *) 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(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 void rp_break(struct tty_struct *tty, int break_state)
{
	struct r_port *info = (struct r_port *) tty->driver_data;
	unsigned long flags;

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

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

/*
 * 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 = (struct r_port *)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 = (struct r_port *)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->close_delay;
	tmp.closing_wait = info->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 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(info, NULL);
		return 0;
	}

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

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

	configure_r_port(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 = (struct r_port *) 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(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 = (struct r_port *) 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 = (struct r_port *) 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 = (struct r_port *) 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 = (struct r_port *) 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 = (struct r_port *) 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 = (struct r_port *) 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 = (struct r_port *) 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->flags & ROCKET_CLOSING)
		return;
	if (info->port.count)
		atomic_dec(&rp_num_ports_open);
	clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);

	info->port.count = 0;
	info->flags &= ~ROCKET_NORMAL_ACTIVE;
	info->port.tty = NULL;

	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->flags &= ~ROCKET_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 = (struct r_port *) 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 = (struct r_port *) 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) {
		if (!info->port.tty)		/* Seemingly obligatory check... */
			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 = (struct r_port *) 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 = (struct r_port *) 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 = (struct r_port *) 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,
};

/*
 * 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);
}
