diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
new file mode 100644
index 0000000..82c5f30
--- /dev/null
+++ b/drivers/char/ip2/i2lib.c
@@ -0,0 +1,2219 @@
+/*******************************************************************************
+*
+*   (c) 1999 by Computone Corporation
+*
+********************************************************************************
+*
+*
+*   PACKAGE:     Linux tty Device Driver for IntelliPort family of multiport
+*                serial I/O controllers.
+*
+*   DESCRIPTION: High-level interface code for the device driver. Uses the
+*                Extremely Low Level Interface Support (i2ellis.c). Provides an
+*                interface to the standard loadware, to support drivers or
+*                application code. (This is included source code, not a separate
+*                compilation module.)
+*
+*******************************************************************************/
+//------------------------------------------------------------------------------
+// Note on Strategy:
+// Once the board has been initialized, it will interrupt us when:
+// 1) It has something in the fifo for us to read (incoming data, flow control
+// packets, or whatever).
+// 2) It has stripped whatever we have sent last time in the FIFO (and
+// consequently is ready for more).
+//
+// Note also that the buffer sizes declared in i2lib.h are VERY SMALL. This
+// worsens performance considerably, but is done so that a great many channels
+// might use only a little memory.
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Revision History:
+//
+// 0.00 -  4/16/91 --- First Draft
+// 0.01 -  4/29/91 --- 1st beta release
+// 0.02 -  6/14/91 --- Changes to allow small model compilation
+// 0.03 -  6/17/91 MAG Break reporting protected from interrupts routines with
+//                     in-line asm added for moving data to/from ring buffers,
+//                     replacing a variety of methods used previously.
+// 0.04 -  6/21/91 MAG Initial flow-control packets not queued until
+//                     i2_enable_interrupts time. Former versions would enqueue
+//                     them at i2_init_channel time, before we knew how many
+//                     channels were supposed to exist!
+// 0.05 - 10/12/91 MAG Major changes: works through the ellis.c routines now;
+//                     supports new 16-bit protocol and expandable boards.
+//      - 10/24/91 MAG Most changes in place and stable.
+// 0.06 -  2/20/92 MAG Format of CMD_HOTACK corrected: the command takes no
+//                     argument.
+// 0.07 -- 3/11/92 MAG Support added to store special packet types at interrupt
+//                     level (mostly responses to specific commands.)
+// 0.08 -- 3/30/92 MAG Support added for STAT_MODEM packet
+// 0.09 -- 6/24/93 MAG i2Link... needed to update number of boards BEFORE
+//                     turning on the interrupt.
+// 0.10 -- 6/25/93 MAG To avoid gruesome death from a bad board, we sanity check
+//                     some incoming.
+//
+// 1.1  - 12/25/96 AKM Linux version.
+//      - 10/09/98 DMC Revised Linux version.
+//------------------------------------------------------------------------------
+
+//************
+//* Includes *
+//************
+
+#include <linux/sched.h>
+#include "i2lib.h"
+
+
+//***********************
+//* Function Prototypes *
+//***********************
+static void i2QueueNeeds(i2eBordStrPtr, i2ChanStrPtr, int);
+static i2ChanStrPtr i2DeQueueNeeds(i2eBordStrPtr, int );
+static void i2StripFifo(i2eBordStrPtr);
+static void i2StuffFifoBypass(i2eBordStrPtr);
+static void i2StuffFifoFlow(i2eBordStrPtr);
+static void i2StuffFifoInline(i2eBordStrPtr);
+static int i2RetryFlushOutput(i2ChanStrPtr);
+
+// Not a documented part of the library routines (careful...) but the Diagnostic
+// i2diag.c finds them useful to help the throughput in certain limited
+// single-threaded operations.
+static void iiSendPendingMail(i2eBordStrPtr);
+static void serviceOutgoingFifo(i2eBordStrPtr);
+
+// Functions defined in ip2.c as part of interrupt handling
+static void do_input(void *);
+static void do_status(void *);
+
+//***************
+//* Debug  Data *
+//***************
+#ifdef DEBUG_FIFO
+
+unsigned char DBGBuf[0x4000];
+unsigned short I = 0;
+
+static void
+WriteDBGBuf(char *s, unsigned char *src, unsigned short n ) 
+{
+	char *p = src;
+
+	// XXX: We need a spin lock here if we ever use this again
+
+	while (*s) {	// copy label
+		DBGBuf[I] = *s++;
+		I = I++ & 0x3fff;
+	}
+	while (n--) {	// copy data
+		DBGBuf[I] = *p++;
+		I = I++ & 0x3fff;
+	}
+}
+
+static void
+fatality(i2eBordStrPtr pB )
+{
+	int i;
+
+	for (i=0;i<sizeof(DBGBuf);i++) {
+		if ((i%16) == 0)
+			printk("\n%4x:",i);
+		printk("%02x ",DBGBuf[i]);
+	}
+	printk("\n");
+	for (i=0;i<sizeof(DBGBuf);i++) {
+		if ((i%16) == 0)
+			printk("\n%4x:",i);
+		if (DBGBuf[i] >= ' ' && DBGBuf[i] <= '~') {
+			printk(" %c ",DBGBuf[i]);
+		} else {
+			printk(" . ");
+		}
+	}
+	printk("\n");
+	printk("Last index %x\n",I);
+}
+#endif /* DEBUG_FIFO */
+
+//********
+//* Code *
+//********
+
+static inline int
+i2Validate ( i2ChanStrPtr pCh )
+{
+	//ip2trace(pCh->port_index, ITRC_VERIFY,ITRC_ENTER,2,pCh->validity,
+	//	(CHANNEL_MAGIC | CHANNEL_SUPPORT));
+	return ((pCh->validity & (CHANNEL_MAGIC_BITS | CHANNEL_SUPPORT)) 
+			  == (CHANNEL_MAGIC | CHANNEL_SUPPORT));
+}
+
+//******************************************************************************
+// Function:   iiSendPendingMail(pB)
+// Parameters: Pointer to a board structure
+// Returns:    Nothing
+//
+// Description:
+// If any outgoing mail bits are set and there is outgoing mailbox is empty,
+// send the mail and clear the bits.
+//******************************************************************************
+static inline void
+iiSendPendingMail(i2eBordStrPtr pB)
+{
+	if (pB->i2eOutMailWaiting && (!pB->i2eWaitingForEmptyFifo) )
+	{
+		if (iiTrySendMail(pB, pB->i2eOutMailWaiting))
+		{
+			/* If we were already waiting for fifo to empty,
+			 * or just sent MB_OUT_STUFFED, then we are
+			 * still waiting for it to empty, until we should
+			 * receive an MB_IN_STRIPPED from the board.
+			 */
+			pB->i2eWaitingForEmptyFifo |=
+				(pB->i2eOutMailWaiting & MB_OUT_STUFFED);
+			pB->i2eOutMailWaiting = 0;
+			pB->SendPendingRetry = 0;
+		} else {
+/*		The only time we hit this area is when "iiTrySendMail" has
+		failed.  That only occurs when the outbound mailbox is
+		still busy with the last message.  We take a short breather
+		to let the board catch up with itself and then try again.
+		16 Retries is the limit - then we got a borked board.
+			/\/\|=mhw=|\/\/				*/
+
+			if( ++pB->SendPendingRetry < 16 ) {
+
+				init_timer( &(pB->SendPendingTimer) );
+				pB->SendPendingTimer.expires  = jiffies + 1;
+				pB->SendPendingTimer.function = (void*)(unsigned long)iiSendPendingMail;
+				pB->SendPendingTimer.data     = (unsigned long)pB;
+				add_timer( &(pB->SendPendingTimer) );
+			} else {
+				printk( KERN_ERR "IP2: iiSendPendingMail unable to queue outbound mail\n" );
+			}
+		}
+	}
+}
+
+//******************************************************************************
+// Function:   i2InitChannels(pB, nChannels, pCh)
+// Parameters: Pointer to Ellis Board structure
+//             Number of channels to initialize
+//             Pointer to first element in an array of channel structures
+// Returns:    Success or failure
+//
+// Description:
+//
+// This function patches pointers, back-pointers, and initializes all the
+// elements in the channel structure array.
+//
+// This should be run after the board structure is initialized, through having
+// loaded the standard loadware (otherwise it complains).
+//
+// In any case, it must be done before any serious work begins initializing the
+// irq's or sending commands...
+//
+//******************************************************************************
+static int
+i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh)
+{
+	int index, stuffIndex;
+	i2ChanStrPtr *ppCh;
+	
+	if (pB->i2eValid != I2E_MAGIC) {
+		COMPLETE(pB, I2EE_BADMAGIC);
+	}
+	if (pB->i2eState != II_STATE_STDLOADED) {
+		COMPLETE(pB, I2EE_BADSTATE);
+	}
+
+	LOCK_INIT(&pB->read_fifo_spinlock);
+	LOCK_INIT(&pB->write_fifo_spinlock);
+	LOCK_INIT(&pB->Dbuf_spinlock);
+	LOCK_INIT(&pB->Bbuf_spinlock);
+	LOCK_INIT(&pB->Fbuf_spinlock);
+	
+	// NO LOCK needed yet - this is init
+
+	pB->i2eChannelPtr = pCh;
+	pB->i2eChannelCnt = nChannels;
+
+	pB->i2Fbuf_strip = pB->i2Fbuf_stuff = 0;
+	pB->i2Dbuf_strip = pB->i2Dbuf_stuff = 0;
+	pB->i2Bbuf_strip = pB->i2Bbuf_stuff = 0;
+
+	pB->SendPendingRetry = 0;
+
+	memset ( pCh, 0, sizeof (i2ChanStr) * nChannels );
+
+	for (index = stuffIndex = 0, ppCh = (i2ChanStrPtr *)(pB->i2Fbuf);
+		  nChannels && index < ABS_MOST_PORTS;
+		  index++)
+	{
+		if ( !(pB->i2eChannelMap[index >> 4] & (1 << (index & 0xf)) ) ) {
+			continue;
+		}
+		LOCK_INIT(&pCh->Ibuf_spinlock);
+		LOCK_INIT(&pCh->Obuf_spinlock);
+		LOCK_INIT(&pCh->Cbuf_spinlock);
+		LOCK_INIT(&pCh->Pbuf_spinlock);
+		// NO LOCK needed yet - this is init
+		// Set up validity flag according to support level
+		if (pB->i2eGoodMap[index >> 4] & (1 << (index & 0xf)) ) {
+			pCh->validity = CHANNEL_MAGIC | CHANNEL_SUPPORT;
+		} else {
+			pCh->validity = CHANNEL_MAGIC;
+		}
+		pCh->pMyBord = pB;      /* Back-pointer */
+
+		// Prepare an outgoing flow-control packet to send as soon as the chance
+		// occurs.
+		if ( pCh->validity & CHANNEL_SUPPORT ) {
+			pCh->infl.hd.i2sChannel = index;
+			pCh->infl.hd.i2sCount = 5;
+			pCh->infl.hd.i2sType = PTYPE_BYPASS;
+			pCh->infl.fcmd = 37;
+			pCh->infl.asof = 0;
+			pCh->infl.room = IBUF_SIZE - 1;
+
+			pCh->whenSendFlow = (IBUF_SIZE/5)*4; // when 80% full
+
+		// The following is similar to calling i2QueueNeeds, except that this
+		// is done in longhand, since we are setting up initial conditions on
+		// many channels at once.
+			pCh->channelNeeds = NEED_FLOW;  // Since starting from scratch
+			pCh->sinceLastFlow = 0;         // No bytes received since last flow
+											// control packet was queued
+			stuffIndex++;
+			*ppCh++ = pCh;      // List this channel as needing
+								// initial flow control packet sent
+		}
+
+		// Don't allow anything to be sent until the status packets come in from
+		// the board.
+
+		pCh->outfl.asof = 0;
+		pCh->outfl.room = 0;
+
+		// Initialize all the ring buffers
+
+		pCh->Ibuf_stuff = pCh->Ibuf_strip = 0;
+		pCh->Obuf_stuff = pCh->Obuf_strip = 0;
+		pCh->Cbuf_stuff = pCh->Cbuf_strip = 0;
+
+		memset( &pCh->icount, 0, sizeof (struct async_icount) );
+		pCh->hotKeyIn       = HOT_CLEAR;
+		pCh->channelOptions = 0;
+		pCh->bookMarks      = 0;
+		init_waitqueue_head(&pCh->pBookmarkWait);
+
+		init_waitqueue_head(&pCh->open_wait);
+		init_waitqueue_head(&pCh->close_wait);
+		init_waitqueue_head(&pCh->delta_msr_wait);
+
+		// Set base and divisor so default custom rate is 9600
+		pCh->BaudBase    = 921600;	// MAX for ST654, changed after we get
+		pCh->BaudDivisor = 96;		// the boxids (UART types) later
+
+		pCh->dataSetIn   = 0;
+		pCh->dataSetOut  = 0;
+
+		pCh->wopen       = 0;
+		pCh->throttled   = 0;
+
+		pCh->speed       = CBR_9600;
+
+		pCh->flags    = 0;
+
+		pCh->ClosingDelay     = 5*HZ/10;
+		pCh->ClosingWaitTime  = 30*HZ;
+
+		// Initialize task queue objects
+		INIT_WORK(&pCh->tqueue_input, do_input, pCh);
+		INIT_WORK(&pCh->tqueue_status, do_status, pCh);
+
+#ifdef IP2DEBUG_TRACE
+		pCh->trace = ip2trace;
+#endif
+
+		++pCh;
+     	--nChannels;
+	}
+	// No need to check for wrap here; this is initialization.
+	pB->i2Fbuf_stuff = stuffIndex;
+	COMPLETE(pB, I2EE_GOOD);
+
+}
+
+//******************************************************************************
+// Function:   i2DeQueueNeeds(pB, type)
+// Parameters: Pointer to a board structure
+//             type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW
+// Returns:   
+//             Pointer to a channel structure
+//
+// Description: Returns pointer struct of next channel that needs service of
+//  the type specified. Otherwise returns a NULL reference.
+//
+//******************************************************************************
+static i2ChanStrPtr 
+i2DeQueueNeeds(i2eBordStrPtr pB, int type)
+{
+	unsigned short queueIndex;
+	unsigned long flags;
+
+	i2ChanStrPtr pCh = NULL;
+
+	switch(type) {
+
+	case  NEED_INLINE:
+
+		WRITE_LOCK_IRQSAVE(&pB->Dbuf_spinlock,flags);
+		if ( pB->i2Dbuf_stuff != pB->i2Dbuf_strip)
+		{
+			queueIndex = pB->i2Dbuf_strip;
+			pCh = pB->i2Dbuf[queueIndex];
+			queueIndex++;
+			if (queueIndex >= CH_QUEUE_SIZE) {
+				queueIndex = 0;
+			}
+			pB->i2Dbuf_strip = queueIndex;
+			pCh->channelNeeds &= ~NEED_INLINE;
+		}
+		WRITE_UNLOCK_IRQRESTORE(&pB->Dbuf_spinlock,flags); 
+		break;
+
+	case NEED_BYPASS:
+
+		WRITE_LOCK_IRQSAVE(&pB->Bbuf_spinlock,flags);
+		if (pB->i2Bbuf_stuff != pB->i2Bbuf_strip)
+		{
+			queueIndex = pB->i2Bbuf_strip;
+			pCh = pB->i2Bbuf[queueIndex];
+			queueIndex++;
+			if (queueIndex >= CH_QUEUE_SIZE) {
+				queueIndex = 0;
+			}
+			pB->i2Bbuf_strip = queueIndex;
+			pCh->channelNeeds &= ~NEED_BYPASS;
+		}
+		WRITE_UNLOCK_IRQRESTORE(&pB->Bbuf_spinlock,flags); 
+		break;
+	
+	case NEED_FLOW:
+
+		WRITE_LOCK_IRQSAVE(&pB->Fbuf_spinlock,flags);
+		if (pB->i2Fbuf_stuff != pB->i2Fbuf_strip)
+		{
+			queueIndex = pB->i2Fbuf_strip;
+			pCh = pB->i2Fbuf[queueIndex];
+			queueIndex++;
+			if (queueIndex >= CH_QUEUE_SIZE) {
+				queueIndex = 0;
+			}
+			pB->i2Fbuf_strip = queueIndex;
+			pCh->channelNeeds &= ~NEED_FLOW;
+		}
+		WRITE_UNLOCK_IRQRESTORE(&pB->Fbuf_spinlock,flags); 
+		break;
+	default:
+		printk(KERN_ERR "i2DeQueueNeeds called with bad type:%x\n",type);
+		break;
+	}
+	return pCh;
+}
+
+//******************************************************************************
+// Function:   i2QueueNeeds(pB, pCh, type)
+// Parameters: Pointer to a board structure
+//             Pointer to a channel structure
+//             type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW
+// Returns:    Nothing
+//
+// Description:
+// For each type of need selected, if the given channel is not already in the
+// queue, adds it, and sets the flag indicating it is in the queue.
+//******************************************************************************
+static void
+i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type)
+{
+	unsigned short queueIndex;
+	unsigned long flags;
+
+	// We turn off all the interrupts during this brief process, since the
+	// interrupt-level code might want to put things on the queue as well.
+
+	switch (type) {
+
+	case NEED_INLINE:
+
+		WRITE_LOCK_IRQSAVE(&pB->Dbuf_spinlock,flags);
+		if ( !(pCh->channelNeeds & NEED_INLINE) )
+		{
+			pCh->channelNeeds |= NEED_INLINE;
+			queueIndex = pB->i2Dbuf_stuff;
+			pB->i2Dbuf[queueIndex++] = pCh;
+			if (queueIndex >= CH_QUEUE_SIZE)
+				queueIndex = 0;
+			pB->i2Dbuf_stuff = queueIndex;
+		}
+		WRITE_UNLOCK_IRQRESTORE(&pB->Dbuf_spinlock,flags); 
+		break;
+
+	case NEED_BYPASS:
+
+		WRITE_LOCK_IRQSAVE(&pB->Bbuf_spinlock,flags);
+		if ((type & NEED_BYPASS) && !(pCh->channelNeeds & NEED_BYPASS))
+		{
+			pCh->channelNeeds |= NEED_BYPASS;
+			queueIndex = pB->i2Bbuf_stuff;
+			pB->i2Bbuf[queueIndex++] = pCh;
+			if (queueIndex >= CH_QUEUE_SIZE)
+				queueIndex = 0;
+			pB->i2Bbuf_stuff = queueIndex;
+		} 
+		WRITE_UNLOCK_IRQRESTORE(&pB->Bbuf_spinlock,flags); 
+		break;
+
+	case NEED_FLOW:
+
+		WRITE_LOCK_IRQSAVE(&pB->Fbuf_spinlock,flags);
+		if ((type & NEED_FLOW) && !(pCh->channelNeeds & NEED_FLOW))
+		{
+			pCh->channelNeeds |= NEED_FLOW;
+			queueIndex = pB->i2Fbuf_stuff;
+			pB->i2Fbuf[queueIndex++] = pCh;
+			if (queueIndex >= CH_QUEUE_SIZE)
+				queueIndex = 0;
+			pB->i2Fbuf_stuff = queueIndex;
+		}
+		WRITE_UNLOCK_IRQRESTORE(&pB->Fbuf_spinlock,flags); 
+		break;
+
+	case NEED_CREDIT:
+		pCh->channelNeeds |= NEED_CREDIT;
+		break;
+	default:
+		printk(KERN_ERR "i2QueueNeeds called with bad type:%x\n",type);
+		break;
+	}
+	return;
+}
+
+//******************************************************************************
+// Function:   i2QueueCommands(type, pCh, timeout, nCommands, pCs,...)
+// Parameters: type - PTYPE_BYPASS or PTYPE_INLINE
+//             pointer to the channel structure
+//             maximum period to wait
+//             number of commands (n)
+//             n commands
+// Returns:    Number of commands sent, or -1 for error
+//
+// get board lock before calling
+//
+// Description:
+// Queues up some commands to be sent to a channel. To send possibly several
+// bypass or inline commands to the given channel. The timeout parameter
+// indicates how many HUNDREDTHS OF SECONDS to wait until there is room:
+// 0 = return immediately if no room, -ive  = wait forever, +ive = number of
+// 1/100 seconds to wait. Return values:
+// -1 Some kind of nasty error: bad channel structure or invalid arguments.
+//  0 No room to send all the commands
+// (+)   Number of commands sent
+//******************************************************************************
+static int
+i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands,
+					 cmdSyntaxPtr pCs0,...)
+{
+	int totalsize = 0;
+	int blocksize;
+	int lastended;
+	cmdSyntaxPtr *ppCs;
+	cmdSyntaxPtr pCs;
+	int count;
+	int flag;
+	i2eBordStrPtr pB;
+
+	unsigned short maxBlock;
+	unsigned short maxBuff;
+	short bufroom;
+	unsigned short stuffIndex;
+	unsigned char *pBuf;
+	unsigned char *pInsert;
+	unsigned char *pDest, *pSource;
+	unsigned short channel;
+	int cnt;
+	unsigned long flags = 0;
+	rwlock_t *lock_var_p = NULL;
+
+	// Make sure the channel exists, otherwise do nothing
+	if ( !i2Validate ( pCh ) ) {
+		return -1;
+	}
+
+	ip2trace (CHANN, ITRC_QUEUE, ITRC_ENTER, 0 );
+
+	pB = pCh->pMyBord;
+
+	// Board must also exist, and THE INTERRUPT COMMAND ALREADY SENT
+	if (pB->i2eValid != I2E_MAGIC || pB->i2eUsingIrq == IRQ_UNDEFINED) {
+		return -2;
+	}
+	// If the board has gone fatal, return bad, and also hit the trap routine if
+	// it exists.
+	if (pB->i2eFatal) {
+		if ( pB->i2eFatalTrap ) {
+			(*(pB)->i2eFatalTrap)(pB);
+		}
+		return -3;
+	}
+	// Set up some variables, Which buffers are we using?  How big are they?
+	switch(type)
+	{
+	case PTYPE_INLINE:
+		flag = INL;
+		maxBlock = MAX_OBUF_BLOCK;
+		maxBuff = OBUF_SIZE;
+		pBuf = pCh->Obuf;
+		break;
+	case PTYPE_BYPASS:
+		flag = BYP;
+		maxBlock = MAX_CBUF_BLOCK;
+		maxBuff = CBUF_SIZE;
+		pBuf = pCh->Cbuf;
+		break;
+	default:
+		return -4;
+	}
+	// Determine the total size required for all the commands
+	totalsize = blocksize = sizeof(i2CmdHeader);
+	lastended = 0;
+	ppCs = &pCs0;
+	for ( count = nCommands; count; count--, ppCs++)
+	{
+		pCs = *ppCs;
+		cnt = pCs->length;
+		// Will a new block be needed for this one? 
+		// Two possible reasons: too
+		// big or previous command has to be at the end of a packet.
+		if ((blocksize + cnt > maxBlock) || lastended) {
+			blocksize = sizeof(i2CmdHeader);
+			totalsize += sizeof(i2CmdHeader);
+		}
+		totalsize += cnt;
+		blocksize += cnt;
+
+		// If this command had to end a block, then we will make sure to
+		// account for it should there be any more blocks.
+		lastended = pCs->flags & END;
+	}
+	for (;;) {
+		// Make sure any pending flush commands go out before we add more data.
+		if ( !( pCh->flush_flags && i2RetryFlushOutput( pCh ) ) ) {
+			// How much room (this time through) ?
+			switch(type) {
+			case PTYPE_INLINE:
+				lock_var_p = &pCh->Obuf_spinlock;
+				WRITE_LOCK_IRQSAVE(lock_var_p,flags);
+				stuffIndex = pCh->Obuf_stuff;
+				bufroom = pCh->Obuf_strip - stuffIndex;
+				break;
+			case PTYPE_BYPASS:
+				lock_var_p = &pCh->Cbuf_spinlock;
+				WRITE_LOCK_IRQSAVE(lock_var_p,flags);
+				stuffIndex = pCh->Cbuf_stuff;
+				bufroom = pCh->Cbuf_strip - stuffIndex;
+				break;
+			default:
+				return -5;
+			}
+			if (--bufroom < 0) {
+				bufroom += maxBuff;
+			}
+
+			ip2trace (CHANN, ITRC_QUEUE, 2, 1, bufroom );
+
+			// Check for overflow
+			if (totalsize <= bufroom) {
+				// Normal Expected path - We still hold LOCK
+				break; /* from for()- Enough room: goto proceed */
+			}
+		}
+
+		ip2trace (CHANN, ITRC_QUEUE, 3, 1, totalsize );
+
+		// Prepare to wait for buffers to empty
+		WRITE_UNLOCK_IRQRESTORE(lock_var_p,flags); 
+		serviceOutgoingFifo(pB);	// Dump what we got
+
+		if (timeout == 0) {
+			return 0;   // Tired of waiting
+		}
+		if (timeout > 0)
+			timeout--;   // So negative values == forever
+		
+		if (!in_interrupt()) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(1);	// short nap 
+		} else {
+			// we cannot sched/sleep in interrrupt silly
+			return 0;   
+		}
+		if (signal_pending(current)) {
+			return 0;   // Wake up! Time to die!!!
+		}
+
+		ip2trace (CHANN, ITRC_QUEUE, 4, 0 );
+
+	}	// end of for(;;)
+
+	// At this point we have room and the lock - stick them in.
+	channel = pCh->infl.hd.i2sChannel;
+	pInsert = &pBuf[stuffIndex];     // Pointer to start of packet
+	pDest = CMD_OF(pInsert);         // Pointer to start of command
+
+	// When we start counting, the block is the size of the header
+	for (blocksize = sizeof(i2CmdHeader), count = nCommands,
+			lastended = 0, ppCs = &pCs0;
+		count;
+		count--, ppCs++)
+	{
+		pCs = *ppCs;         // Points to command protocol structure
+
+		// If this is a bookmark request command, post the fact that a bookmark
+		// request is pending. NOTE THIS TRICK ONLY WORKS BECAUSE CMD_BMARK_REQ
+		// has no parameters!  The more general solution would be to reference
+		// pCs->cmd[0].
+		if (pCs == CMD_BMARK_REQ) {
+			pCh->bookMarks++;
+
+			ip2trace (CHANN, ITRC_DRAIN, 30, 1, pCh->bookMarks );
+
+		}
+		cnt = pCs->length;
+
+		// If this command would put us over the maximum block size or 
+		// if the last command had to be at the end of a block, we end
+		// the existing block here and start a new one.
+		if ((blocksize + cnt > maxBlock) || lastended) {
+
+			ip2trace (CHANN, ITRC_QUEUE, 5, 0 );
+
+			PTYPE_OF(pInsert) = type;
+			CHANNEL_OF(pInsert) = channel;
+			// count here does not include the header
+			CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader);
+			stuffIndex += blocksize;
+			if(stuffIndex >= maxBuff) {
+				stuffIndex = 0;
+				pInsert = pBuf;
+			}
+			pInsert = &pBuf[stuffIndex];  // Pointer to start of next pkt
+			pDest = CMD_OF(pInsert);
+			blocksize = sizeof(i2CmdHeader);
+		}
+		// Now we know there is room for this one in the current block
+
+		blocksize += cnt;       // Total bytes in this command
+		pSource = pCs->cmd;     // Copy the command into the buffer
+		while (cnt--) {
+			*pDest++ = *pSource++;
+		}
+		// If this command had to end a block, then we will make sure to account
+		// for it should there be any more blocks.
+		lastended = pCs->flags & END;
+	}	// end for
+	// Clean up the final block by writing header, etc
+
+	PTYPE_OF(pInsert) = type;
+	CHANNEL_OF(pInsert) = channel;
+	// count here does not include the header
+	CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader);
+	stuffIndex += blocksize;
+	if(stuffIndex >= maxBuff) {
+		stuffIndex = 0;
+		pInsert = pBuf;
+	}
+	// Updates the index, and post the need for service. When adding these to
+	// the queue of channels, we turn off the interrupt while doing so,
+	// because at interrupt level we might want to push a channel back to the
+	// end of the queue.
+	switch(type)
+	{
+	case PTYPE_INLINE:
+		pCh->Obuf_stuff = stuffIndex;  // Store buffer pointer
+		WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags); 
+
+		pB->debugInlineQueued++;
+		// Add the channel pointer to list of channels needing service (first
+		// come...), if it's not already there.
+		i2QueueNeeds(pB, pCh, NEED_INLINE);
+		break;
+
+	case PTYPE_BYPASS:
+		pCh->Cbuf_stuff = stuffIndex;  // Store buffer pointer
+		WRITE_UNLOCK_IRQRESTORE(&pCh->Cbuf_spinlock,flags); 
+
+		pB->debugBypassQueued++;
+		// Add the channel pointer to list of channels needing service (first
+		// come...), if it's not already there.
+		i2QueueNeeds(pB, pCh, NEED_BYPASS);
+		break;
+	}
+
+	ip2trace (CHANN, ITRC_QUEUE, ITRC_RETURN, 1, nCommands );
+
+	return nCommands; // Good status: number of commands sent
+}
+
+//******************************************************************************
+// Function:   i2GetStatus(pCh,resetBits)
+// Parameters: Pointer to a channel structure
+//             Bit map of status bits to clear
+// Returns:    Bit map of current status bits
+//
+// Description:
+// Returns the state of data set signals, and whether a break has been received,
+// (see i2lib.h for bit-mapped result). resetBits is a bit-map of any status
+// bits to be cleared: I2_BRK, I2_PAR, I2_FRA, I2_OVR,... These are cleared
+// AFTER the condition is passed. If pCh does not point to a valid channel,
+// returns -1 (which would be impossible otherwise.
+//******************************************************************************
+static int
+i2GetStatus(i2ChanStrPtr pCh, int resetBits)
+{
+	unsigned short status;
+	i2eBordStrPtr pB;
+
+	ip2trace (CHANN, ITRC_STATUS, ITRC_ENTER, 2, pCh->dataSetIn, resetBits );
+
+	// Make sure the channel exists, otherwise do nothing */
+	if ( !i2Validate ( pCh ) )
+		return -1;
+
+	pB = pCh->pMyBord;
+
+	status = pCh->dataSetIn;
+
+	// Clear any specified error bits: but note that only actual error bits can
+	// be cleared, regardless of the value passed.
+	if (resetBits)
+	{
+		pCh->dataSetIn &= ~(resetBits & (I2_BRK | I2_PAR | I2_FRA | I2_OVR));
+		pCh->dataSetIn &= ~(I2_DDCD | I2_DCTS | I2_DDSR | I2_DRI);
+	}
+
+	ip2trace (CHANN, ITRC_STATUS, ITRC_RETURN, 1, pCh->dataSetIn );
+
+	return status;
+}
+
+//******************************************************************************
+// Function:   i2Input(pChpDest,count)
+// Parameters: Pointer to a channel structure
+//             Pointer to data buffer
+//             Number of bytes to read
+// Returns:    Number of bytes read, or -1 for error
+//
+// Description:
+// Strips data from the input buffer and writes it to pDest. If there is a
+// collosal blunder, (invalid structure pointers or the like), returns -1.
+// Otherwise, returns the number of bytes read.
+//******************************************************************************
+static int
+i2Input(i2ChanStrPtr pCh)
+{
+	int amountToMove;
+	unsigned short stripIndex;
+	int count;
+	unsigned long flags = 0;
+
+	ip2trace (CHANN, ITRC_INPUT, ITRC_ENTER, 0);
+
+	// Ensure channel structure seems real
+	if ( !i2Validate( pCh ) ) {
+		count = -1;
+		goto i2Input_exit;
+	}
+	WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
+
+	// initialize some accelerators and private copies
+	stripIndex = pCh->Ibuf_strip;
+
+	count = pCh->Ibuf_stuff - stripIndex;
+
+	// If buffer is empty or requested data count was 0, (trivial case) return
+	// without any further thought.
+	if ( count == 0 ) {
+		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
+		goto i2Input_exit;
+	}
+	// Adjust for buffer wrap
+	if ( count < 0 ) {
+		count += IBUF_SIZE;
+	}
+	// Don't give more than can be taken by the line discipline
+	amountToMove = pCh->pTTY->ldisc.receive_room( pCh->pTTY );
+	if (count > amountToMove) {
+		count = amountToMove;
+	}
+	// How much could we copy without a wrap?
+	amountToMove = IBUF_SIZE - stripIndex;
+
+	if (amountToMove > count) {
+		amountToMove = count;
+	}
+	// Move the first block
+	pCh->pTTY->ldisc.receive_buf( pCh->pTTY, 
+		 &(pCh->Ibuf[stripIndex]), NULL, amountToMove );
+	// If we needed to wrap, do the second data move
+	if (count > amountToMove) {
+		pCh->pTTY->ldisc.receive_buf( pCh->pTTY, 
+		 pCh->Ibuf, NULL, count - amountToMove );
+	}
+	// Bump and wrap the stripIndex all at once by the amount of data read. This
+	// method is good regardless of whether the data was in one or two pieces.
+	stripIndex += count;
+	if (stripIndex >= IBUF_SIZE) {
+		stripIndex -= IBUF_SIZE;
+	}
+	pCh->Ibuf_strip = stripIndex;
+
+	// Update our flow control information and possibly queue ourselves to send
+	// it, depending on how much data has been stripped since the last time a
+	// packet was sent.
+	pCh->infl.asof += count;
+
+	if ((pCh->sinceLastFlow += count) >= pCh->whenSendFlow) {
+		pCh->sinceLastFlow -= pCh->whenSendFlow;
+		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
+		i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW);
+	} else {
+		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
+	}
+
+i2Input_exit:
+
+	ip2trace (CHANN, ITRC_INPUT, ITRC_RETURN, 1, count);
+
+	return count;
+}
+
+//******************************************************************************
+// Function:   i2InputFlush(pCh)
+// Parameters: Pointer to a channel structure
+// Returns:    Number of bytes stripped, or -1 for error
+//
+// Description:
+// Strips any data from the input buffer. If there is a collosal blunder,
+// (invalid structure pointers or the like), returns -1. Otherwise, returns the
+// number of bytes stripped.
+//******************************************************************************
+static int
+i2InputFlush(i2ChanStrPtr pCh)
+{
+	int count;
+	unsigned long flags;
+
+	// Ensure channel structure seems real
+	if ( !i2Validate ( pCh ) )
+		return -1;
+
+	ip2trace (CHANN, ITRC_INPUT, 10, 0);
+
+	WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
+	count = pCh->Ibuf_stuff - pCh->Ibuf_strip;
+
+	// Adjust for buffer wrap
+	if (count < 0) {
+		count += IBUF_SIZE;
+	}
+
+	// Expedient way to zero out the buffer
+	pCh->Ibuf_strip = pCh->Ibuf_stuff;
+
+
+	// Update our flow control information and possibly queue ourselves to send
+	// it, depending on how much data has been stripped since the last time a
+	// packet was sent.
+
+	pCh->infl.asof += count;
+
+	if ( (pCh->sinceLastFlow += count) >= pCh->whenSendFlow )
+	{
+		pCh->sinceLastFlow -= pCh->whenSendFlow;
+		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
+		i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW);
+	} else {
+		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
+	}
+
+	ip2trace (CHANN, ITRC_INPUT, 19, 1, count);
+
+	return count;
+}
+
+//******************************************************************************
+// Function:   i2InputAvailable(pCh)
+// Parameters: Pointer to a channel structure
+// Returns:    Number of bytes available, or -1 for error
+//
+// Description:
+// If there is a collosal blunder, (invalid structure pointers or the like),
+// returns -1. Otherwise, returns the number of bytes stripped. Otherwise,
+// returns the number of bytes available in the buffer.
+//******************************************************************************
+#if 0
+static int
+i2InputAvailable(i2ChanStrPtr pCh)
+{
+	int count;
+
+	// Ensure channel structure seems real
+	if ( !i2Validate ( pCh ) ) return -1;
+
+
+	// initialize some accelerators and private copies
+	READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
+	count = pCh->Ibuf_stuff - pCh->Ibuf_strip;
+	READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
+
+	// Adjust for buffer wrap
+	if (count < 0)
+	{
+		count += IBUF_SIZE;
+	}
+
+	return count;
+}
+#endif 
+
+//******************************************************************************
+// Function:   i2Output(pCh, pSource, count)
+// Parameters: Pointer to channel structure
+//             Pointer to source data
+//             Number of bytes to send
+// Returns:    Number of bytes sent, or -1 for error
+//
+// Description:
+// Queues the data at pSource to be sent as data packets to the board. If there
+// is a collosal blunder, (invalid structure pointers or the like), returns -1.
+// Otherwise, returns the number of bytes written. What if there is not enough
+// room for all the data? If pCh->channelOptions & CO_NBLOCK_WRITE is set, then
+// we transfer as many characters as we can now, then return. If this bit is
+// clear (default), routine will spin along until all the data is buffered.
+// Should this occur, the 1-ms delay routine is called while waiting to avoid
+// applications that one cannot break out of.
+//******************************************************************************
+static int
+i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user )
+{
+	i2eBordStrPtr pB;
+	unsigned char *pInsert;
+	int amountToMove;
+	int countOriginal = count;
+	unsigned short channel;
+	unsigned short stuffIndex;
+	unsigned long flags;
+	int rc = 0;
+
+	int bailout = 10;
+
+	ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, user );
+
+	// Ensure channel structure seems real
+	if ( !i2Validate ( pCh ) ) 
+		return -1;
+
+	// initialize some accelerators and private copies
+	pB = pCh->pMyBord;
+	channel = pCh->infl.hd.i2sChannel;
+
+	// If the board has gone fatal, return bad, and also hit the trap routine if
+	// it exists.
+	if (pB->i2eFatal) {
+		if (pB->i2eFatalTrap) {
+			(*(pB)->i2eFatalTrap)(pB);
+		}
+		return -1;
+	}
+	// Proceed as though we would do everything
+	while ( count > 0 ) {
+
+		// How much room in output buffer is there?
+		READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
+		amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1;
+		READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
+		if (amountToMove < 0) {
+			amountToMove += OBUF_SIZE;
+		}
+		// Subtract off the headers size and see how much room there is for real
+		// data. If this is negative, we will discover later.
+		amountToMove -= sizeof (i2DataHeader);
+
+		// Don't move more (now) than can go in a single packet
+		if ( amountToMove > (int)(MAX_OBUF_BLOCK - sizeof(i2DataHeader)) ) {
+			amountToMove = MAX_OBUF_BLOCK - sizeof(i2DataHeader);
+		}
+		// Don't move more than the count we were given
+		if (amountToMove > count) {
+			amountToMove = count;
+		}
+		// Now we know how much we must move: NB because the ring buffers have
+		// an overflow area at the end, we needn't worry about wrapping in the
+		// middle of a packet.
+
+// Small WINDOW here with no LOCK but I can't call Flush with LOCK
+// We would be flushing (or ending flush) anyway
+
+		ip2trace (CHANN, ITRC_OUTPUT, 10, 1, amountToMove );
+
+		if ( !(pCh->flush_flags && i2RetryFlushOutput(pCh) ) 
+				&& amountToMove > 0 )
+		{
+			WRITE_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
+			stuffIndex = pCh->Obuf_stuff;
+      
+			// Had room to move some data: don't know whether the block size,
+			// buffer space, or what was the limiting factor...
+			pInsert = &(pCh->Obuf[stuffIndex]);
+
+			// Set up the header
+			CHANNEL_OF(pInsert)     = channel;
+			PTYPE_OF(pInsert)       = PTYPE_DATA;
+			TAG_OF(pInsert)         = 0;
+			ID_OF(pInsert)          = ID_ORDINARY_DATA;
+			DATA_COUNT_OF(pInsert)  = amountToMove;
+
+			// Move the data
+			if ( user ) {
+				rc = copy_from_user((char*)(DATA_OF(pInsert)), pSource,
+						amountToMove );
+			} else {
+				memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove );
+			}
+			// Adjust pointers and indices
+			pSource					+= amountToMove;
+			pCh->Obuf_char_count	+= amountToMove;
+			stuffIndex 				+= amountToMove + sizeof(i2DataHeader);
+			count 					-= amountToMove;
+
+			if (stuffIndex >= OBUF_SIZE) {
+				stuffIndex = 0;
+			}
+			pCh->Obuf_stuff = stuffIndex;
+
+			WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
+
+			ip2trace (CHANN, ITRC_OUTPUT, 13, 1, stuffIndex );
+
+		} else {
+
+			// Cannot move data
+			// becuz we need to stuff a flush 
+			// or amount to move is <= 0
+
+			ip2trace(CHANN, ITRC_OUTPUT, 14, 3,
+				amountToMove,  pB->i2eFifoRemains,
+				pB->i2eWaitingForEmptyFifo );
+
+			// Put this channel back on queue
+			// this ultimatly gets more data or wakes write output
+			i2QueueNeeds(pB, pCh, NEED_INLINE);
+
+			if ( pB->i2eWaitingForEmptyFifo ) {
+
+				ip2trace (CHANN, ITRC_OUTPUT, 16, 0 );
+
+				// or schedule
+				if (!in_interrupt()) {
+
+					ip2trace (CHANN, ITRC_OUTPUT, 61, 0 );
+
+					current->state = TASK_INTERRUPTIBLE;
+					schedule_timeout(2);
+					if (signal_pending(current)) {
+						break;
+					}
+					continue;
+				} else {
+
+					ip2trace (CHANN, ITRC_OUTPUT, 62, 0 );
+
+					// let interrupt in = WAS restore_flags()
+					// We hold no lock nor is irq off anymore???
+					
+					break;
+				}
+				break;   // from while(count)
+			}
+			else if ( pB->i2eFifoRemains < 32 && !pB->i2eTxMailEmpty ( pB ) )
+			{
+				ip2trace (CHANN, ITRC_OUTPUT, 19, 2,
+					pB->i2eFifoRemains,
+					pB->i2eTxMailEmpty );
+
+				break;   // from while(count)
+			} else if ( pCh->channelNeeds & NEED_CREDIT ) {
+
+				ip2trace (CHANN, ITRC_OUTPUT, 22, 0 );
+
+				break;   // from while(count)
+			} else if ( --bailout) {
+
+				// Try to throw more things (maybe not us) in the fifo if we're
+				// not already waiting for it.
+	
+				ip2trace (CHANN, ITRC_OUTPUT, 20, 0 );
+
+				serviceOutgoingFifo(pB);
+				//break;  CONTINUE;
+			} else {
+				ip2trace (CHANN, ITRC_OUTPUT, 21, 3,
+					pB->i2eFifoRemains,
+					pB->i2eOutMailWaiting,
+					pB->i2eWaitingForEmptyFifo );
+
+				break;   // from while(count)
+			}
+		}
+	} // End of while(count)
+
+	i2QueueNeeds(pB, pCh, NEED_INLINE);
+
+	// We drop through either when the count expires, or when there is some
+	// count left, but there was a non-blocking write.
+	if (countOriginal > count) {
+
+		ip2trace (CHANN, ITRC_OUTPUT, 17, 2, countOriginal, count );
+
+		serviceOutgoingFifo( pB );
+	}
+
+	ip2trace (CHANN, ITRC_OUTPUT, ITRC_RETURN, 2, countOriginal, count );
+
+	return countOriginal - count;
+}
+
+//******************************************************************************
+// Function:   i2FlushOutput(pCh)
+// Parameters: Pointer to a channel structure
+// Returns:    Nothing
+//
+// Description:
+// Sends bypass command to start flushing (waiting possibly forever until there
+// is room), then sends inline command to stop flushing output, (again waiting
+// possibly forever).
+//******************************************************************************
+static inline void
+i2FlushOutput(i2ChanStrPtr pCh)
+{
+
+	ip2trace (CHANN, ITRC_FLUSH, 1, 1, pCh->flush_flags );
+
+	if (pCh->flush_flags)
+		return;
+
+	if ( 1 != i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) {
+		pCh->flush_flags = STARTFL_FLAG;		// Failed - flag for later
+
+		ip2trace (CHANN, ITRC_FLUSH, 2, 0 );
+
+	} else if ( 1 != i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL) ) {
+		pCh->flush_flags = STOPFL_FLAG;		// Failed - flag for later
+
+		ip2trace (CHANN, ITRC_FLUSH, 3, 0 );
+	}
+}
+
+static int 
+i2RetryFlushOutput(i2ChanStrPtr pCh)
+{
+	int old_flags = pCh->flush_flags;
+
+	ip2trace (CHANN, ITRC_FLUSH, 14, 1, old_flags );
+
+	pCh->flush_flags = 0;	// Clear flag so we can avoid recursion
+									// and queue the commands
+
+	if ( old_flags & STARTFL_FLAG ) {
+		if ( 1 == i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) {
+			old_flags = STOPFL_FLAG;	//Success - send stop flush
+		} else {
+			old_flags = STARTFL_FLAG;	//Failure - Flag for retry later
+		}
+
+		ip2trace (CHANN, ITRC_FLUSH, 15, 1, old_flags );
+
+	}
+	if ( old_flags & STOPFL_FLAG ) {
+		if (1 == i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL)) {
+			old_flags = 0;	// Success - clear flags
+		}
+
+		ip2trace (CHANN, ITRC_FLUSH, 16, 1, old_flags );
+	}
+	pCh->flush_flags = old_flags;
+
+	ip2trace (CHANN, ITRC_FLUSH, 17, 1, old_flags );
+
+	return old_flags;
+}
+
+//******************************************************************************
+// Function:   i2DrainOutput(pCh,timeout)
+// Parameters: Pointer to a channel structure
+//             Maximum period to wait
+// Returns:    ?
+//
+// Description:
+// Uses the bookmark request command to ask the board to send a bookmark back as
+// soon as all the data is completely sent.
+//******************************************************************************
+static void
+i2DrainWakeup(i2ChanStrPtr pCh)
+{
+	ip2trace (CHANN, ITRC_DRAIN, 10, 1, pCh->BookmarkTimer.expires );
+
+	pCh->BookmarkTimer.expires = 0;
+	wake_up_interruptible( &pCh->pBookmarkWait );
+}
+
+static void
+i2DrainOutput(i2ChanStrPtr pCh, int timeout)
+{
+	wait_queue_t wait;
+	i2eBordStrPtr pB;
+
+	ip2trace (CHANN, ITRC_DRAIN, ITRC_ENTER, 1, pCh->BookmarkTimer.expires);
+
+	pB = pCh->pMyBord;
+	// If the board has gone fatal, return bad, 
+	// and also hit the trap routine if it exists.
+	if (pB->i2eFatal) {
+		if (pB->i2eFatalTrap) {
+			(*(pB)->i2eFatalTrap)(pB);
+		}
+		return;
+	}
+	if ((timeout > 0) && (pCh->BookmarkTimer.expires == 0 )) {
+		// One per customer (channel)
+		init_timer( &(pCh->BookmarkTimer) );
+		pCh->BookmarkTimer.expires  = jiffies + timeout;
+		pCh->BookmarkTimer.function = (void*)(unsigned long)i2DrainWakeup;
+		pCh->BookmarkTimer.data     = (unsigned long)pCh;
+
+		ip2trace (CHANN, ITRC_DRAIN, 1, 1, pCh->BookmarkTimer.expires );
+
+		add_timer( &(pCh->BookmarkTimer) );
+	}
+	
+	i2QueueCommands( PTYPE_INLINE, pCh, -1, 1, CMD_BMARK_REQ );
+
+	init_waitqueue_entry(&wait, current);
+	add_wait_queue(&(pCh->pBookmarkWait), &wait);
+	set_current_state( TASK_INTERRUPTIBLE );
+
+	serviceOutgoingFifo( pB );
+	
+	schedule();	// Now we take our interruptible sleep on
+
+	// Clean up the queue
+	set_current_state( TASK_RUNNING );
+	remove_wait_queue(&(pCh->pBookmarkWait), &wait);
+
+	// if expires == 0 then timer poped, then do not need to del_timer
+	if ((timeout > 0) && pCh->BookmarkTimer.expires && 
+	                     time_before(jiffies, pCh->BookmarkTimer.expires)) {
+		del_timer( &(pCh->BookmarkTimer) );
+		pCh->BookmarkTimer.expires = 0;
+
+		ip2trace (CHANN, ITRC_DRAIN, 3, 1, pCh->BookmarkTimer.expires );
+
+	}
+	ip2trace (CHANN, ITRC_DRAIN, ITRC_RETURN, 1, pCh->BookmarkTimer.expires );
+	return;
+}
+
+//******************************************************************************
+// Function:   i2OutputFree(pCh)
+// Parameters: Pointer to a channel structure
+// Returns:    Space in output buffer
+//
+// Description:
+// Returns -1 if very gross error. Otherwise returns the amount of bytes still
+// free in the output buffer.
+//******************************************************************************
+static int
+i2OutputFree(i2ChanStrPtr pCh)
+{
+	int amountToMove;
+	unsigned long flags;
+
+	// Ensure channel structure seems real
+	if ( !i2Validate ( pCh ) ) {
+		return -1;
+	}
+	READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
+	amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1;
+	READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
+
+	if (amountToMove < 0) {
+		amountToMove += OBUF_SIZE;
+	}
+	// If this is negative, we will discover later
+	amountToMove -= sizeof(i2DataHeader);
+
+	return (amountToMove < 0) ? 0 : amountToMove;
+}
+static void
+
+ip2_owake( PTTY tp)
+{
+	i2ChanStrPtr  pCh;
+
+	if (tp == NULL) return;
+
+	pCh = tp->driver_data;
+
+	ip2trace (CHANN, ITRC_SICMD, 10, 2, tp->flags,
+			(1 << TTY_DO_WRITE_WAKEUP) );
+
+	wake_up_interruptible ( &tp->write_wait );
+	if ( ( tp->flags & (1 << TTY_DO_WRITE_WAKEUP) ) 
+	  && tp->ldisc.write_wakeup )
+	{
+		(tp->ldisc.write_wakeup) ( tp );
+
+		ip2trace (CHANN, ITRC_SICMD, 11, 0 );
+
+	}
+}
+
+static inline void
+set_baud_params(i2eBordStrPtr pB) 
+{
+	int i,j;
+	i2ChanStrPtr  *pCh;
+
+	pCh = (i2ChanStrPtr *) pB->i2eChannelPtr;
+
+	for (i = 0; i < ABS_MAX_BOXES; i++) {
+		if (pB->channelBtypes.bid_value[i]) {
+			if (BID_HAS_654(pB->channelBtypes.bid_value[i])) {
+				for (j = 0; j < ABS_BIGGEST_BOX; j++) {
+					if (pCh[i*16+j] == NULL)
+						break;
+					(pCh[i*16+j])->BaudBase    = 921600;	// MAX for ST654
+					(pCh[i*16+j])->BaudDivisor = 96;
+				}
+			} else {	// has cirrus cd1400
+				for (j = 0; j < ABS_BIGGEST_BOX; j++) {
+					if (pCh[i*16+j] == NULL)
+						break;
+					(pCh[i*16+j])->BaudBase    = 115200;	// MAX for CD1400
+					(pCh[i*16+j])->BaudDivisor = 12;
+				}
+			}
+		}
+	}
+}
+
+//******************************************************************************
+// Function:   i2StripFifo(pB)
+// Parameters: Pointer to a board structure
+// Returns:    ?
+//
+// Description:
+// Strips all the available data from the incoming FIFO, identifies the type of
+// packet, and either buffers the data or does what needs to be done.
+//
+// Note there is no overflow checking here: if the board sends more data than it
+// ought to, we will not detect it here, but blindly overflow...
+//******************************************************************************
+
+// A buffer for reading in blocks for unknown channels
+static unsigned char junkBuffer[IBUF_SIZE];
+
+// A buffer to read in a status packet. Because of the size of the count field
+// for these things, the maximum packet size must be less than MAX_CMD_PACK_SIZE
+static unsigned char cmdBuffer[MAX_CMD_PACK_SIZE + 4];
+
+// This table changes the bit order from MSR order given by STAT_MODEM packet to
+// status bits used in our library.
+static char xlatDss[16] = {
+0      | 0     | 0      | 0      ,
+0      | 0     | 0      | I2_CTS ,
+0      | 0     | I2_DSR | 0      ,
+0      | 0     | I2_DSR | I2_CTS ,
+0      | I2_RI | 0      | 0      ,
+0      | I2_RI | 0      | I2_CTS ,
+0      | I2_RI | I2_DSR | 0      ,
+0      | I2_RI | I2_DSR | I2_CTS ,
+I2_DCD | 0     | 0      | 0      ,
+I2_DCD | 0     | 0      | I2_CTS ,
+I2_DCD | 0     | I2_DSR | 0      ,
+I2_DCD | 0     | I2_DSR | I2_CTS ,
+I2_DCD | I2_RI | 0      | 0      ,
+I2_DCD | I2_RI | 0      | I2_CTS ,
+I2_DCD | I2_RI | I2_DSR | 0      ,
+I2_DCD | I2_RI | I2_DSR | I2_CTS };
+
+static inline void
+i2StripFifo(i2eBordStrPtr pB)
+{
+	i2ChanStrPtr pCh;
+	int channel;
+	int count;
+	unsigned short stuffIndex;
+	int amountToRead;
+	unsigned char *pc, *pcLimit;
+	unsigned char uc;
+	unsigned char dss_change;
+	unsigned long bflags,cflags;
+
+//	ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_ENTER, 0 );
+
+	while (HAS_INPUT(pB)) {
+//		ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 2, 0 );
+
+		// Process packet from fifo a one atomic unit
+		WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock,bflags);
+   
+		// The first word (or two bytes) will have channel number and type of
+		// packet, possibly other information
+		pB->i2eLeadoffWord[0] = iiReadWord(pB);
+
+		switch(PTYPE_OF(pB->i2eLeadoffWord))
+		{
+		case PTYPE_DATA:
+			pB->got_input = 1;
+
+//			ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 3, 0 );
+
+			channel = CHANNEL_OF(pB->i2eLeadoffWord); /* Store channel */
+			count = iiReadWord(pB);          /* Count is in the next word */
+
+// NEW: Check the count for sanity! Should the hardware fail, our death
+// is more pleasant. While an oversize channel is acceptable (just more
+// than the driver supports), an over-length count clearly means we are
+// sick!
+			if ( ((unsigned int)count) > IBUF_SIZE ) {
+				pB->i2eFatal = 2;
+				WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
+				return;     /* Bail out ASAP */
+			}
+			// Channel is illegally big ?
+			if ((channel >= pB->i2eChannelCnt) ||
+				(NULL==(pCh = ((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])))
+			{
+				iiReadBuf(pB, junkBuffer, count);
+				WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
+				break;         /* From switch: ready for next packet */
+			}
+
+			// Channel should be valid, then
+
+			// If this is a hot-key, merely post its receipt for now. These are
+			// always supposed to be 1-byte packets, so we won't even check the
+			// count. Also we will post an acknowledgement to the board so that
+			// more data can be forthcoming. Note that we are not trying to use
+			// these sequences in this driver, merely to robustly ignore them.
+			if(ID_OF(pB->i2eLeadoffWord) == ID_HOT_KEY)
+			{
+				pCh->hotKeyIn = iiReadWord(pB) & 0xff;
+				WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
+				i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_HOTACK);
+				break;   /* From the switch: ready for next packet */
+			}
+
+			// Normal data! We crudely assume there is room for the data in our
+			// buffer because the board wouldn't have exceeded his credit limit.
+			WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,cflags);
+													// We have 2 locks now
+			stuffIndex = pCh->Ibuf_stuff;
+			amountToRead = IBUF_SIZE - stuffIndex;
+			if (amountToRead > count)
+				amountToRead = count;
+
+			// stuffIndex would have been already adjusted so there would 
+			// always be room for at least one, and count is always at least
+			// one.
+
+			iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead);
+			pCh->icount.rx += amountToRead;
+
+			// Update the stuffIndex by the amount of data moved. Note we could
+			// never ask for more data than would just fit. However, we might
+			// have read in one more byte than we wanted because the read
+			// rounds up to even bytes. If this byte is on the end of the
+			// packet, and is padding, we ignore it. If the byte is part of
+			// the actual data, we need to move it.
+
+			stuffIndex += amountToRead;
+
+			if (stuffIndex >= IBUF_SIZE) {
+				if ((amountToRead & 1) && (count > amountToRead)) {
+					pCh->Ibuf[0] = pCh->Ibuf[IBUF_SIZE];
+					amountToRead++;
+					stuffIndex = 1;
+				} else {
+					stuffIndex = 0;
+				}
+			}
+
+			// If there is anything left over, read it as well
+			if (count > amountToRead) {
+				amountToRead = count - amountToRead;
+				iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead);
+				pCh->icount.rx += amountToRead;
+				stuffIndex += amountToRead;
+			}
+
+			// Update stuff index
+			pCh->Ibuf_stuff = stuffIndex;
+			WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,cflags);
+			WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
+
+#ifdef USE_IQ
+			schedule_work(&pCh->tqueue_input);
+#else
+			do_input(pCh);
+#endif
+
+			// Note we do not need to maintain any flow-control credits at this
+			// time:  if we were to increment .asof and decrement .room, there
+			// would be no net effect. Instead, when we strip data, we will
+			// increment .asof and leave .room unchanged.
+
+			break;   // From switch: ready for next packet
+
+		case PTYPE_STATUS:
+			ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 4, 0 );
+      
+			count = CMD_COUNT_OF(pB->i2eLeadoffWord);
+
+			iiReadBuf(pB, cmdBuffer, count);
+			// We can release early with buffer grab
+			WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
+
+			pc = cmdBuffer;
+			pcLimit = &(cmdBuffer[count]);
+
+			while (pc < pcLimit) {
+				channel = *pc++;
+
+				ip2trace (channel, ITRC_SFIFO, 7, 2, channel, *pc );
+
+				/* check for valid channel */
+				if (channel < pB->i2eChannelCnt
+					 && 
+					 (pCh = (((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])) != NULL
+					)
+				{
+					dss_change = 0;
+
+					switch (uc = *pc++)
+					{
+					/* Breaks and modem signals are easy: just update status */
+					case STAT_CTS_UP:
+						if ( !(pCh->dataSetIn & I2_CTS) )
+						{
+							pCh->dataSetIn |= I2_DCTS;
+							pCh->icount.cts++;
+							dss_change = 1;
+						}
+						pCh->dataSetIn |= I2_CTS;
+						break;
+
+					case STAT_CTS_DN:
+						if ( pCh->dataSetIn & I2_CTS )
+						{
+							pCh->dataSetIn |= I2_DCTS;
+							pCh->icount.cts++;
+							dss_change = 1;
+						}
+						pCh->dataSetIn &= ~I2_CTS;
+						break;
+
+					case STAT_DCD_UP:
+						ip2trace (channel, ITRC_MODEM, 1, 1, pCh->dataSetIn );
+
+						if ( !(pCh->dataSetIn & I2_DCD) )
+						{
+							ip2trace (CHANN, ITRC_MODEM, 2, 0 );
+							pCh->dataSetIn |= I2_DDCD;
+							pCh->icount.dcd++;
+							dss_change = 1;
+						}
+						pCh->dataSetIn |= I2_DCD;
+
+						ip2trace (channel, ITRC_MODEM, 3, 1, pCh->dataSetIn );
+						break;
+
+					case STAT_DCD_DN:
+						ip2trace (channel, ITRC_MODEM, 4, 1, pCh->dataSetIn );
+						if ( pCh->dataSetIn & I2_DCD )
+						{
+							ip2trace (channel, ITRC_MODEM, 5, 0 );
+							pCh->dataSetIn |= I2_DDCD;
+							pCh->icount.dcd++;
+							dss_change = 1;
+						}
+						pCh->dataSetIn &= ~I2_DCD;
+
+						ip2trace (channel, ITRC_MODEM, 6, 1, pCh->dataSetIn );
+						break;
+
+					case STAT_DSR_UP:
+						if ( !(pCh->dataSetIn & I2_DSR) )
+						{
+							pCh->dataSetIn |= I2_DDSR;
+							pCh->icount.dsr++;
+							dss_change = 1;
+						}
+						pCh->dataSetIn |= I2_DSR;
+						break;
+
+					case STAT_DSR_DN:
+						if ( pCh->dataSetIn & I2_DSR )
+						{
+							pCh->dataSetIn |= I2_DDSR;
+							pCh->icount.dsr++;
+							dss_change = 1;
+						}
+						pCh->dataSetIn &= ~I2_DSR;
+						break;
+
+					case STAT_RI_UP:
+						if ( !(pCh->dataSetIn & I2_RI) )
+						{
+							pCh->dataSetIn |= I2_DRI;
+							pCh->icount.rng++;
+							dss_change = 1;
+						}
+						pCh->dataSetIn |= I2_RI ;
+						break;
+
+					case STAT_RI_DN:
+						// to be compat with serial.c
+						//if ( pCh->dataSetIn & I2_RI )
+						//{
+						//	pCh->dataSetIn |= I2_DRI;
+						//	pCh->icount.rng++; 
+						//	dss_change = 1;
+						//}
+						pCh->dataSetIn &= ~I2_RI ;
+						break;
+
+					case STAT_BRK_DET:
+						pCh->dataSetIn |= I2_BRK;
+						pCh->icount.brk++;
+						dss_change = 1;
+						break;
+
+					// Bookmarks? one less request we're waiting for
+					case STAT_BMARK:
+						pCh->bookMarks--;
+						if (pCh->bookMarks <= 0 ) {
+							pCh->bookMarks = 0;
+							wake_up_interruptible( &pCh->pBookmarkWait );
+
+						ip2trace (channel, ITRC_DRAIN, 20, 1, pCh->BookmarkTimer.expires );
+						}
+						break;
+
+					// Flow control packets? Update the new credits, and if
+					// someone was waiting for output, queue him up again.
+					case STAT_FLOW:
+						pCh->outfl.room =
+							((flowStatPtr)pc)->room -
+							(pCh->outfl.asof - ((flowStatPtr)pc)->asof);
+
+						ip2trace (channel, ITRC_STFLW, 1, 1, pCh->outfl.room );
+
+						if (pCh->channelNeeds & NEED_CREDIT)
+						{
+							ip2trace (channel, ITRC_STFLW, 2, 1, pCh->channelNeeds);
+
+							pCh->channelNeeds &= ~NEED_CREDIT;
+							i2QueueNeeds(pB, pCh, NEED_INLINE);
+							if ( pCh->pTTY )
+								ip2_owake(pCh->pTTY);
+						}
+
+						ip2trace (channel, ITRC_STFLW, 3, 1, pCh->channelNeeds);
+
+						pc += sizeof(flowStat);
+						break;
+
+					/* Special packets: */
+					/* Just copy the information into the channel structure */
+
+					case STAT_STATUS:
+
+						pCh->channelStatus = *((debugStatPtr)pc);
+						pc += sizeof(debugStat);
+						break;
+
+					case STAT_TXCNT:
+
+						pCh->channelTcount = *((cntStatPtr)pc);
+						pc += sizeof(cntStat);
+						break;
+
+					case STAT_RXCNT:
+
+						pCh->channelRcount = *((cntStatPtr)pc);
+						pc += sizeof(cntStat);
+						break;
+
+					case STAT_BOXIDS:
+						pB->channelBtypes = *((bidStatPtr)pc);
+						pc += sizeof(bidStat);
+						set_baud_params(pB);
+						break;
+
+					case STAT_HWFAIL:
+						i2QueueCommands (PTYPE_INLINE, pCh, 0, 1, CMD_HW_TEST);
+						pCh->channelFail = *((failStatPtr)pc);
+						pc += sizeof(failStat);
+						break;
+
+					/* No explicit match? then
+					 * Might be an error packet...
+					 */
+					default:
+						switch (uc & STAT_MOD_ERROR)
+						{
+						case STAT_ERROR:
+							if (uc & STAT_E_PARITY) {
+								pCh->dataSetIn |= I2_PAR;
+								pCh->icount.parity++;
+							}
+							if (uc & STAT_E_FRAMING){
+								pCh->dataSetIn |= I2_FRA;
+								pCh->icount.frame++;
+							}
+							if (uc & STAT_E_OVERRUN){
+								pCh->dataSetIn |= I2_OVR;
+								pCh->icount.overrun++;
+							}
+							break;
+
+						case STAT_MODEM:
+							// the answer to DSS_NOW request (not change)
+							pCh->dataSetIn = (pCh->dataSetIn
+								& ~(I2_RI | I2_CTS | I2_DCD | I2_DSR) )
+								| xlatDss[uc & 0xf];
+							wake_up_interruptible ( &pCh->dss_now_wait );
+						default:
+							break;
+						}
+					}  /* End of switch on status type */
+					if (dss_change) {
+#ifdef USE_IQ
+						schedule_work(&pCh->tqueue_status);
+#else
+						do_status(pCh);
+#endif
+					}
+				}
+				else  /* Or else, channel is invalid */
+				{
+					// Even though the channel is invalid, we must test the
+					// status to see how much additional data it has (to be
+					// skipped)
+					switch (*pc++)
+					{
+					case STAT_FLOW:
+						pc += 4;    /* Skip the data */
+						break;
+
+					default:
+						break;
+					}
+				}
+			}  // End of while (there is still some status packet left)
+			break;
+
+		default: // Neither packet? should be impossible
+			ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 5, 1,
+				PTYPE_OF(pB->i2eLeadoffWord) );
+
+			break;
+		}  // End of switch on type of packets
+	}	//while(board HAS_INPUT)
+
+	ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_RETURN, 0 );
+
+	// Send acknowledgement to the board even if there was no data!
+	pB->i2eOutMailWaiting |= MB_IN_STRIPPED;
+	return;
+}
+
+//******************************************************************************
+// Function:   i2Write2Fifo(pB,address,count)
+// Parameters: Pointer to a board structure, source address, byte count
+// Returns:    bytes written
+//
+// Description:
+//  Writes count bytes to board io address(implied) from source
+//  Adjusts count, leaves reserve for next time around bypass cmds
+//******************************************************************************
+static int
+i2Write2Fifo(i2eBordStrPtr pB, unsigned char *source, int count,int reserve)
+{
+	int rc = 0;
+	unsigned long flags;
+	WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
+	if (!pB->i2eWaitingForEmptyFifo) {
+		if (pB->i2eFifoRemains > (count+reserve)) {
+			pB->i2eFifoRemains -= count;
+			iiWriteBuf(pB, source, count);
+			pB->i2eOutMailWaiting |= MB_OUT_STUFFED;
+			rc =  count;
+		}
+	}
+	WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
+	return rc;
+}
+//******************************************************************************
+// Function:   i2StuffFifoBypass(pB)
+// Parameters: Pointer to a board structure
+// Returns:    Nothing
+//
+// Description:
+// Stuffs as many bypass commands into the fifo as possible. This is simpler
+// than stuffing data or inline commands to fifo, since we do not have
+// flow-control to deal with.
+//******************************************************************************
+static inline void
+i2StuffFifoBypass(i2eBordStrPtr pB)
+{
+	i2ChanStrPtr pCh;
+	unsigned char *pRemove;
+	unsigned short stripIndex;
+	unsigned short packetSize;
+	unsigned short paddedSize;
+	unsigned short notClogged = 1;
+	unsigned long flags;
+
+	int bailout = 1000;
+
+	// Continue processing so long as there are entries, or there is room in the
+	// fifo. Each entry represents a channel with something to do.
+	while ( --bailout && notClogged && 
+			(NULL != (pCh = i2DeQueueNeeds(pB,NEED_BYPASS))))
+	{
+		WRITE_LOCK_IRQSAVE(&pCh->Cbuf_spinlock,flags);
+		stripIndex = pCh->Cbuf_strip;
+
+		// as long as there are packets for this channel...
+
+		while (stripIndex != pCh->Cbuf_stuff) {
+			pRemove = &(pCh->Cbuf[stripIndex]);
+			packetSize = CMD_COUNT_OF(pRemove) + sizeof(i2CmdHeader);
+			paddedSize = ROUNDUP(packetSize);
+
+			if (paddedSize > 0) {
+				if ( 0 == i2Write2Fifo(pB, pRemove, paddedSize,0)) {
+					notClogged = 0;	/* fifo full */
+					i2QueueNeeds(pB, pCh, NEED_BYPASS);	// Put back on queue
+					break;   // Break from the channel
+				} 
+			}
+#ifdef DEBUG_FIFO
+WriteDBGBuf("BYPS", pRemove, paddedSize);
+#endif	/* DEBUG_FIFO */
+			pB->debugBypassCount++;
+
+			pRemove += packetSize;
+			stripIndex += packetSize;
+			if (stripIndex >= CBUF_SIZE) {
+				stripIndex = 0;
+				pRemove = pCh->Cbuf;
+			}
+		}
+		// Done with this channel. Move to next, removing this one from 
+		// the queue of channels if we cleaned it out (i.e., didn't get clogged.
+		pCh->Cbuf_strip = stripIndex;
+		WRITE_UNLOCK_IRQRESTORE(&pCh->Cbuf_spinlock,flags);
+	}  // Either clogged or finished all the work
+
+#ifdef IP2DEBUG_TRACE
+	if ( !bailout ) {
+		ip2trace (ITRC_NO_PORT, ITRC_ERROR, 1, 0 );
+	}
+#endif
+}
+
+//******************************************************************************
+// Function:   i2StuffFifoFlow(pB)
+// Parameters: Pointer to a board structure
+// Returns:    Nothing
+//
+// Description:
+// Stuffs as many flow control packets into the fifo as possible. This is easier
+// even than doing normal bypass commands, because there is always at most one
+// packet, already assembled, for each channel.
+//******************************************************************************
+static inline void
+i2StuffFifoFlow(i2eBordStrPtr pB)
+{
+	i2ChanStrPtr pCh;
+	unsigned short paddedSize		= ROUNDUP(sizeof(flowIn));
+
+	ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_ENTER, 2,
+		pB->i2eFifoRemains, paddedSize );
+
+	// Continue processing so long as there are entries, or there is room in the
+	// fifo. Each entry represents a channel with something to do.
+	while ( (NULL != (pCh = i2DeQueueNeeds(pB,NEED_FLOW)))) {
+		pB->debugFlowCount++;
+
+		// NO Chan LOCK needed ???
+		if ( 0 == i2Write2Fifo(pB,(unsigned char *)&(pCh->infl),paddedSize,0)) {
+			break;
+		}
+#ifdef DEBUG_FIFO
+		WriteDBGBuf("FLOW",(unsigned char *) &(pCh->infl), paddedSize);
+#endif /* DEBUG_FIFO */
+
+	}  // Either clogged or finished all the work
+
+	ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_RETURN, 0 );
+}
+
+//******************************************************************************
+// Function:   i2StuffFifoInline(pB)
+// Parameters: Pointer to a board structure
+// Returns:    Nothing
+//
+// Description:
+// Stuffs as much data and inline commands into the fifo as possible. This is
+// the most complex fifo-stuffing operation, since there if now the channel
+// flow-control issue to deal with.
+//******************************************************************************
+static inline void
+i2StuffFifoInline(i2eBordStrPtr pB)
+{
+	i2ChanStrPtr pCh;
+	unsigned char *pRemove;
+	unsigned short stripIndex;
+	unsigned short packetSize;
+	unsigned short paddedSize;
+	unsigned short notClogged = 1;
+	unsigned short flowsize;
+	unsigned long flags;
+
+	int bailout  = 1000;
+	int bailout2;
+
+	ip2trace (ITRC_NO_PORT, ITRC_SICMD, ITRC_ENTER, 3, pB->i2eFifoRemains, 
+			pB->i2Dbuf_strip, pB->i2Dbuf_stuff );
+
+	// Continue processing so long as there are entries, or there is room in the
+	// fifo. Each entry represents a channel with something to do.
+	while ( --bailout && notClogged && 
+			(NULL != (pCh = i2DeQueueNeeds(pB,NEED_INLINE))) )
+	{
+		WRITE_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
+		stripIndex = pCh->Obuf_strip;
+
+		ip2trace (CHANN, ITRC_SICMD, 3, 2, stripIndex, pCh->Obuf_stuff );
+
+		// as long as there are packets for this channel...
+		bailout2 = 1000;
+		while ( --bailout2 && stripIndex != pCh->Obuf_stuff) {
+			pRemove = &(pCh->Obuf[stripIndex]);
+
+			// Must determine whether this be a data or command packet to
+			// calculate correctly the header size and the amount of
+			// flow-control credit this type of packet will use.
+			if (PTYPE_OF(pRemove) == PTYPE_DATA) {
+				flowsize = DATA_COUNT_OF(pRemove);
+				packetSize = flowsize + sizeof(i2DataHeader);
+			} else {
+				flowsize = CMD_COUNT_OF(pRemove);
+				packetSize = flowsize + sizeof(i2CmdHeader);
+			}
+			flowsize = CREDIT_USAGE(flowsize);
+			paddedSize = ROUNDUP(packetSize);
+
+			ip2trace (CHANN, ITRC_SICMD, 4, 2, pB->i2eFifoRemains, paddedSize );
+
+			// If we don't have enough credits from the board to send the data,
+			// flag the channel that we are waiting for flow control credit, and
+			// break out. This will clean up this channel and remove us from the
+			// queue of hot things to do.
+
+				ip2trace (CHANN, ITRC_SICMD, 5, 2, pCh->outfl.room, flowsize );
+
+			if (pCh->outfl.room <= flowsize)	{
+				// Do Not have the credits to send this packet.
+				i2QueueNeeds(pB, pCh, NEED_CREDIT);
+				notClogged = 0;
+				break;   // So to do next channel
+			}
+			if ( (paddedSize > 0) 
+				&& ( 0 == i2Write2Fifo(pB, pRemove, paddedSize, 128))) {
+				// Do Not have room in fifo to send this packet.
+				notClogged = 0;
+				i2QueueNeeds(pB, pCh, NEED_INLINE);	
+				break;   // Break from the channel
+			}
+#ifdef DEBUG_FIFO
+WriteDBGBuf("DATA", pRemove, paddedSize);
+#endif /* DEBUG_FIFO */
+			pB->debugInlineCount++;
+
+			pCh->icount.tx += flowsize;
+			// Update current credits
+			pCh->outfl.room -= flowsize;
+			pCh->outfl.asof += flowsize;
+			if (PTYPE_OF(pRemove) == PTYPE_DATA) {
+				pCh->Obuf_char_count -= DATA_COUNT_OF(pRemove);
+			}
+			pRemove += packetSize;
+			stripIndex += packetSize;
+
+			ip2trace (CHANN, ITRC_SICMD, 6, 2, stripIndex, pCh->Obuf_strip);
+
+			if (stripIndex >= OBUF_SIZE) {
+				stripIndex = 0;
+				pRemove = pCh->Obuf;
+
+				ip2trace (CHANN, ITRC_SICMD, 7, 1, stripIndex );
+
+			}
+		}	/* while */
+		if ( !bailout2 ) {
+			ip2trace (CHANN, ITRC_ERROR, 3, 0 );
+		}
+		// Done with this channel. Move to next, removing this one from the
+		// queue of channels if we cleaned it out (i.e., didn't get clogged.
+		pCh->Obuf_strip = stripIndex;
+		WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
+		if ( notClogged )
+		{
+
+			ip2trace (CHANN, ITRC_SICMD, 8, 0 );
+
+			if ( pCh->pTTY ) {
+				ip2_owake(pCh->pTTY);
+			}
+		}
+	}  // Either clogged or finished all the work
+
+	if ( !bailout ) {
+		ip2trace (ITRC_NO_PORT, ITRC_ERROR, 4, 0 );
+	}
+
+	ip2trace (ITRC_NO_PORT, ITRC_SICMD, ITRC_RETURN, 1,pB->i2Dbuf_strip);
+}
+
+//******************************************************************************
+// Function:   serviceOutgoingFifo(pB)
+// Parameters: Pointer to a board structure
+// Returns:    Nothing
+//
+// Description:
+// Helper routine to put data in the outgoing fifo, if we aren't already waiting
+// for something to be there. If the fifo has only room for a very little data,
+// go head and hit the board with a mailbox hit immediately. Otherwise, it will
+// have to happen later in the interrupt processing. Since this routine may be
+// called both at interrupt and foreground time, we must turn off interrupts
+// during the entire process.
+//******************************************************************************
+static void
+serviceOutgoingFifo(i2eBordStrPtr pB)
+{
+	// If we aren't currently waiting for the board to empty our fifo, service
+	// everything that is pending, in priority order (especially, Bypass before
+	// Inline).
+	if ( ! pB->i2eWaitingForEmptyFifo )
+	{
+		i2StuffFifoFlow(pB);
+		i2StuffFifoBypass(pB);
+		i2StuffFifoInline(pB);
+
+		iiSendPendingMail(pB);
+	} 
+}
+
+//******************************************************************************
+// Function:   i2ServiceBoard(pB)
+// Parameters: Pointer to a board structure
+// Returns:    Nothing
+//
+// Description:
+// Normally this is called from interrupt level, but there is deliberately
+// nothing in here specific to being called from interrupt level. All the
+// hardware-specific, interrupt-specific things happen at the outer levels.
+//
+// For example, a timer interrupt could drive this routine for some sort of
+// polled operation. The only requirement is that the programmer deal with any
+// atomiticity/concurrency issues that result.
+//
+// This routine responds to the board's having sent mailbox information to the
+// host (which would normally cause an interrupt). This routine reads the
+// incoming mailbox. If there is no data in it, this board did not create the
+// interrupt and/or has nothing to be done to it. (Except, if we have been
+// waiting to write mailbox data to it, we may do so.
+//
+// Based on the value in the mailbox, we may take various actions.
+//
+// No checking here of pB validity: after all, it shouldn't have been called by
+// the handler unless pB were on the list.
+//******************************************************************************
+static inline int
+i2ServiceBoard ( i2eBordStrPtr pB )
+{
+	unsigned inmail;
+	unsigned long flags;
+
+
+	/* This should be atomic because of the way we are called... */
+	if (NO_MAIL_HERE == ( inmail = pB->i2eStartMail ) ) {
+		inmail = iiGetMail(pB);
+	}
+	pB->i2eStartMail = NO_MAIL_HERE;
+
+	ip2trace (ITRC_NO_PORT, ITRC_INTR, 2, 1, inmail );
+
+	if (inmail != NO_MAIL_HERE) {
+		// If the board has gone fatal, nothing to do but hit a bit that will
+		// alert foreground tasks to protest!
+		if ( inmail & MB_FATAL_ERROR ) {
+			pB->i2eFatal = 1;
+			goto exit_i2ServiceBoard;
+		}
+
+		/* Assuming no fatal condition, we proceed to do work */
+		if ( inmail & MB_IN_STUFFED ) {
+			pB->i2eFifoInInts++;
+			i2StripFifo(pB);     /* There might be incoming packets */
+		}
+
+		if (inmail & MB_OUT_STRIPPED) {
+			pB->i2eFifoOutInts++;
+			WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
+			pB->i2eFifoRemains = pB->i2eFifoSize;
+			pB->i2eWaitingForEmptyFifo = 0;
+			WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
+
+			ip2trace (ITRC_NO_PORT, ITRC_INTR, 30, 1, pB->i2eFifoRemains );
+
+		}
+		serviceOutgoingFifo(pB);
+	}
+
+	ip2trace (ITRC_NO_PORT, ITRC_INTR, 8, 0 );
+
+exit_i2ServiceBoard:
+
+	return 0;
+}
