File: /usr/src/linux/drivers/char/ip2/i2lib.c

1     /*******************************************************************************
2     *
3     *   (c) 1999 by Computone Corporation
4     *
5     ********************************************************************************
6     *
7     *
8     *   PACKAGE:     Linux tty Device Driver for IntelliPort family of multiport
9     *                serial I/O controllers.
10     *
11     *   DESCRIPTION: High-level interface code for the device driver. Uses the
12     *                Extremely Low Level Interface Support (i2ellis.c). Provides an
13     *                interface to the standard loadware, to support drivers or
14     *                application code. (This is included source code, not a separate
15     *                compilation module.)
16     *
17     *******************************************************************************/
18     //------------------------------------------------------------------------------
19     // Note on Strategy:
20     // Once the board has been initialized, it will interrupt us when:
21     // 1) It has something in the fifo for us to read (incoming data, flow control
22     // packets, or whatever).
23     // 2) It has stripped whatever we have sent last time in the FIFO (and
24     // consequently is ready for more).
25     //
26     // Note also that the buffer sizes declared in i2lib.h are VERY SMALL. This
27     // worsens performance considerably, but is done so that a great many channels
28     // might use only a little memory.
29     //------------------------------------------------------------------------------
30     
31     //------------------------------------------------------------------------------
32     // Revision History:
33     //
34     // 0.00 -  4/16/91 --- First Draft
35     // 0.01 -  4/29/91 --- 1st beta release
36     // 0.02 -  6/14/91 --- Changes to allow small model compilation
37     // 0.03 -  6/17/91 MAG Break reporting protected from interrupts routines with
38     //                     in-line asm added for moving data to/from ring buffers,
39     //                     replacing a variety of methods used previously.
40     // 0.04 -  6/21/91 MAG Initial flow-control packets not queued until
41     //                     i2_enable_interrupts time. Former versions would enqueue
42     //                     them at i2_init_channel time, before we knew how many
43     //                     channels were supposed to exist!
44     // 0.05 - 10/12/91 MAG Major changes: works through the ellis.c routines now;
45     //                     supports new 16-bit protocol and expandable boards.
46     //      - 10/24/91 MAG Most changes in place and stable.
47     // 0.06 -  2/20/92 MAG Format of CMD_HOTACK corrected: the command takes no
48     //                     argument.
49     // 0.07 -- 3/11/92 MAG Support added to store special packet types at interrupt
50     //                     level (mostly responses to specific commands.)
51     // 0.08 -- 3/30/92 MAG Support added for STAT_MODEM packet
52     // 0.09 -- 6/24/93 MAG i2Link... needed to update number of boards BEFORE
53     //                     turning on the interrupt.
54     // 0.10 -- 6/25/93 MAG To avoid gruesome death from a bad board, we sanity check
55     //                     some incoming.
56     //
57     // 1.1  - 12/25/96 AKM Linux version.
58     //      - 10/09/98 DMC Revised Linux version.
59     //------------------------------------------------------------------------------
60     
61     //************
62     //* Includes *
63     //************
64     
65     #include <linux/sched.h>
66     #include "i2lib.h"
67     
68     
69     //***********************
70     //* Function Prototypes *
71     //***********************
72     static void i2QueueNeeds(i2eBordStrPtr, i2ChanStrPtr, int);
73     static i2ChanStrPtr i2DeQueueNeeds(i2eBordStrPtr, int );
74     static void i2StripFifo(i2eBordStrPtr);
75     static void i2StuffFifoBypass(i2eBordStrPtr);
76     static void i2StuffFifoFlow(i2eBordStrPtr);
77     static void i2StuffFifoInline(i2eBordStrPtr);
78     static int i2RetryFlushOutput(i2ChanStrPtr);
79     
80     // Not a documented part of the library routines (careful...) but the Diagnostic
81     // i2diag.c finds them useful to help the throughput in certain limited
82     // single-threaded operations.
83     static void iiSendPendingMail(i2eBordStrPtr);
84     static void serviceOutgoingFifo(i2eBordStrPtr);
85     
86     // Functions defined in ip2.c as part of interrupt handling
87     static void do_input(i2ChanStrPtr);
88     static void do_status(i2ChanStrPtr);
89     
90     //***************
91     //* Debug  Data *
92     //***************
93     #ifdef DEBUG_FIFO
94     
95     unsigned char DBGBuf[0x4000];
96     unsigned short I = 0;
97     
98     static void
99     WriteDBGBuf(char *s, unsigned char *src, unsigned short n ) 
100     {
101     	char *p = src;
102     
103     	// XXX: We need a spin lock here if we ever use this again
104     
105     	while (*s) {	// copy label
106     		DBGBuf[I] = *s++;
107     		I = I++ & 0x3fff;
108     	}
109     	while (n--) {	// copy data
110     		DBGBuf[I] = *p++;
111     		I = I++ & 0x3fff;
112     	}
113     }
114     
115     static void
116     fatality(i2eBordStrPtr pB )
117     {
118     	int i;
119     
120     	for (i=0;i<sizeof(DBGBuf);i++) {
121     		if ((i%16) == 0)
122     			printk("\n%4x:",i);
123     		printk("%02x ",DBGBuf[i]);
124     	}
125     	printk("\n");
126     	for (i=0;i<sizeof(DBGBuf);i++) {
127     		if ((i%16) == 0)
128     			printk("\n%4x:",i);
129     		if (DBGBuf[i] >= ' ' && DBGBuf[i] <= '~') {
130     			printk(" %c ",DBGBuf[i]);
131     		} else {
132     			printk(" . ");
133     		}
134     	}
135     	printk("\n");
136     	printk("Last index %x\n",I);
137     }
138     #endif /* DEBUG_FIFO */
139     
140     //********
141     //* Code *
142     //********
143     
144     inline int
145     i2Validate ( i2ChanStrPtr pCh )
146     {
147     	//ip2trace(pCh->port_index, ITRC_VERIFY,ITRC_ENTER,2,pCh->validity,
148     	//	(CHANNEL_MAGIC | CHANNEL_SUPPORT));
149     	return ((pCh->validity & (CHANNEL_MAGIC_BITS | CHANNEL_SUPPORT)) 
150     			  == (CHANNEL_MAGIC | CHANNEL_SUPPORT));
151     }
152     
153     //******************************************************************************
154     // Function:   iiSendPendingMail(pB)
155     // Parameters: Pointer to a board structure
156     // Returns:    Nothing
157     //
158     // Description:
159     // If any outgoing mail bits are set and there is outgoing mailbox is empty,
160     // send the mail and clear the bits.
161     //******************************************************************************
162     static inline void
163     iiSendPendingMail(i2eBordStrPtr pB)
164     {
165     	if (pB->i2eOutMailWaiting && (!pB->i2eWaitingForEmptyFifo) )
166     	{
167     		if (iiTrySendMail(pB, pB->i2eOutMailWaiting))
168     		{
169     			/* If we were already waiting for fifo to empty,
170     			 * or just sent MB_OUT_STUFFED, then we are
171     			 * still waiting for it to empty, until we should
172     			 * receive an MB_IN_STRIPPED from the board.
173     			 */
174     			pB->i2eWaitingForEmptyFifo |=
175     				(pB->i2eOutMailWaiting & MB_OUT_STUFFED);
176     			pB->i2eOutMailWaiting = 0;
177     		}
178     	}
179     }
180     
181     //******************************************************************************
182     // Function:   i2InitChannels(pB, nChannels, pCh)
183     // Parameters: Pointer to Ellis Board structure
184     //             Number of channels to initialize
185     //             Pointer to first element in an array of channel structures
186     // Returns:    Success or failure
187     //
188     // Description:
189     //
190     // This function patches pointers, back-pointers, and initializes all the
191     // elements in the channel structure array.
192     //
193     // This should be run after the board structure is initialized, through having
194     // loaded the standard loadware (otherwise it complains).
195     //
196     // In any case, it must be done before any serious work begins initializing the
197     // irq's or sending commands...
198     //
199     //******************************************************************************
200     static int
201     i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh)
202     {
203     	int index, stuffIndex;
204     	i2ChanStrPtr *ppCh;
205     	
206     	if (pB->i2eValid != I2E_MAGIC) {
207     		COMPLETE(pB, I2EE_BADMAGIC);
208     	}
209     	if (pB->i2eState != II_STATE_STDLOADED) {
210     		COMPLETE(pB, I2EE_BADSTATE);
211     	}
212     
213     	LOCK_INIT(&pB->read_fifo_spinlock);
214     	LOCK_INIT(&pB->write_fifo_spinlock);
215     	LOCK_INIT(&pB->Dbuf_spinlock);
216     	LOCK_INIT(&pB->Bbuf_spinlock);
217     	LOCK_INIT(&pB->Fbuf_spinlock);
218     	
219     	// NO LOCK needed yet - this is init
220     
221     	pB->i2eChannelPtr = pCh;
222     	pB->i2eChannelCnt = nChannels;
223     
224     	pB->i2Fbuf_strip = pB->i2Fbuf_stuff = 0;
225     	pB->i2Dbuf_strip = pB->i2Dbuf_stuff = 0;
226     	pB->i2Bbuf_strip = pB->i2Bbuf_stuff = 0;
227     
228     	memset ( pCh, 0, sizeof (i2ChanStr) * nChannels );
229     
230     	for (index = stuffIndex = 0, ppCh = (i2ChanStrPtr *)(pB->i2Fbuf);
231     		  nChannels && index < ABS_MOST_PORTS;
232     		  index++)
233     	{
234     		if ( !(pB->i2eChannelMap[index >> 4] & (1 << (index & 0xf)) ) ) {
235     			continue;
236     		}
237     		LOCK_INIT(&pCh->Ibuf_spinlock);
238     		LOCK_INIT(&pCh->Obuf_spinlock);
239     		LOCK_INIT(&pCh->Cbuf_spinlock);
240     		LOCK_INIT(&pCh->Pbuf_spinlock);
241     		// NO LOCK needed yet - this is init
242     		// Set up validity flag according to support level
243     		if (pB->i2eGoodMap[index >> 4] & (1 << (index & 0xf)) ) {
244     			pCh->validity = CHANNEL_MAGIC | CHANNEL_SUPPORT;
245     		} else {
246     			pCh->validity = CHANNEL_MAGIC;
247     		}
248     		pCh->pMyBord = pB;      /* Back-pointer */
249     
250     		// Prepare an outgoing flow-control packet to send as soon as the chance
251     		// occurs.
252     		if ( pCh->validity & CHANNEL_SUPPORT ) {
253     			pCh->infl.hd.i2sChannel = index;
254     			pCh->infl.hd.i2sCount = 5;
255     			pCh->infl.hd.i2sType = PTYPE_BYPASS;
256     			pCh->infl.fcmd = 37;
257     			pCh->infl.asof = 0;
258     			pCh->infl.room = IBUF_SIZE - 1;
259     
260     			pCh->whenSendFlow = (IBUF_SIZE/5)*4; // when 80% full
261     
262     		// The following is similar to calling i2QueueNeeds, except that this
263     		// is done in longhand, since we are setting up initial conditions on
264     		// many channels at once.
265     			pCh->channelNeeds = NEED_FLOW;  // Since starting from scratch
266     			pCh->sinceLastFlow = 0;         // No bytes received since last flow
267     											// control packet was queued
268     			stuffIndex++;
269     			*ppCh++ = pCh;      // List this channel as needing
270     								// initial flow control packet sent
271     		}
272     
273     		// Don't allow anything to be sent until the status packets come in from
274     		// the board.
275     
276     		pCh->outfl.asof = 0;
277     		pCh->outfl.room = 0;
278     
279     		// Initialize all the ring buffers
280     
281     		pCh->Ibuf_stuff = pCh->Ibuf_strip = 0;
282     		pCh->Obuf_stuff = pCh->Obuf_strip = 0;
283     		pCh->Cbuf_stuff = pCh->Cbuf_strip = 0;
284     
285     		memset( &pCh->icount, 0, sizeof (struct async_icount) );
286     		pCh->hotKeyIn       = HOT_CLEAR;
287     		pCh->channelOptions = 0;
288     		pCh->bookMarks      = 0;
289     		init_waitqueue_head(&pCh->pBookmarkWait);
290     
291     		init_waitqueue_head(&pCh->open_wait);
292     		init_waitqueue_head(&pCh->close_wait);
293     		init_waitqueue_head(&pCh->delta_msr_wait);
294     
295     		// Set base and divisor so default custom rate is 9600
296     		pCh->BaudBase    = 921600;	// MAX for ST654, changed after we get
297     		pCh->BaudDivisor = 96;		// the boxids (UART types) later
298     
299     		pCh->dataSetIn   = 0;
300     		pCh->dataSetOut  = 0;
301     
302     		pCh->wopen       = 0;
303     		pCh->throttled   = 0;
304     
305     		pCh->speed       = CBR_9600;
306     
307     		pCh->flags    = 0;
308     		pCh->session  = 0;
309     		pCh->pgrp     = 0;
310     
311     		pCh->ClosingDelay     = 5*HZ/10;
312     		pCh->ClosingWaitTime  = 30*HZ;
313     
314     #ifdef USE_IQ
315     		// Initialize task queue objects
316     		pCh->tqueue_input.routine = (void(*)(void*)) do_input;
317     		pCh->tqueue_input.data = pCh;
318     		pCh->tqueue_status.routine = (void(*)(void*)) do_status;
319     		pCh->tqueue_status.data = pCh;
320     #endif
321     
322     		pCh->trace = ip2trace;
323     
324     		++pCh;
325          	--nChannels;
326     	}
327     	// No need to check for wrap here; this is initialization.
328     	pB->i2Fbuf_stuff = stuffIndex;
329     	COMPLETE(pB, I2EE_GOOD);
330     
331     }
332     
333     //******************************************************************************
334     // Function:   i2DeQueueNeeds(pB, type)
335     // Parameters: Pointer to a board structure
336     //             type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW
337     // Returns:   
338     //             Pointer to a channel structure
339     //
340     // Description: Returns pointer struct of next channel that needs service of
341     //  the type specified. Otherwise returns a NULL reference.
342     //
343     //******************************************************************************
344     static i2ChanStrPtr 
345     i2DeQueueNeeds(i2eBordStrPtr pB, int type)
346     {
347     	unsigned short queueIndex;
348     	unsigned long flags;
349     
350     	i2ChanStrPtr pCh = NULL;
351     
352     	switch(type) {
353     
354     	case  NEED_INLINE:
355     
356     		WRITE_LOCK_IRQSAVE(&pB->Dbuf_spinlock,flags);
357     		if ( pB->i2Dbuf_stuff != pB->i2Dbuf_strip)
358     		{
359     			queueIndex = pB->i2Dbuf_strip;
360     			pCh = pB->i2Dbuf[queueIndex];
361     			queueIndex++;
362     			if (queueIndex >= CH_QUEUE_SIZE) {
363     				queueIndex = 0;
364     			}
365     			pB->i2Dbuf_strip = queueIndex;
366     			pCh->channelNeeds &= ~NEED_INLINE;
367     		}
368     		WRITE_UNLOCK_IRQRESTORE(&pB->Dbuf_spinlock,flags); 
369     		break;
370     
371     	case NEED_BYPASS:
372     
373     		WRITE_LOCK_IRQSAVE(&pB->Bbuf_spinlock,flags);
374     		if (pB->i2Bbuf_stuff != pB->i2Bbuf_strip)
375     		{
376     			queueIndex = pB->i2Bbuf_strip;
377     			pCh = pB->i2Bbuf[queueIndex];
378     			queueIndex++;
379     			if (queueIndex >= CH_QUEUE_SIZE) {
380     				queueIndex = 0;
381     			}
382     			pB->i2Bbuf_strip = queueIndex;
383     			pCh->channelNeeds &= ~NEED_BYPASS;
384     		}
385     		WRITE_UNLOCK_IRQRESTORE(&pB->Bbuf_spinlock,flags); 
386     		break;
387     	
388     	case NEED_FLOW:
389     
390     		WRITE_LOCK_IRQSAVE(&pB->Fbuf_spinlock,flags);
391     		if (pB->i2Fbuf_stuff != pB->i2Fbuf_strip)
392     		{
393     			queueIndex = pB->i2Fbuf_strip;
394     			pCh = pB->i2Fbuf[queueIndex];
395     			queueIndex++;
396     			if (queueIndex >= CH_QUEUE_SIZE) {
397     				queueIndex = 0;
398     			}
399     			pB->i2Fbuf_strip = queueIndex;
400     			pCh->channelNeeds &= ~NEED_FLOW;
401     		}
402     		WRITE_UNLOCK_IRQRESTORE(&pB->Fbuf_spinlock,flags); 
403     		break;
404     	default:
405     		printk(KERN_ERR "i2DeQueueNeeds called with bad type:%x\n",type);
406     		break;
407     	}
408     	return pCh;
409     }
410     
411     //******************************************************************************
412     // Function:   i2QueueNeeds(pB, pCh, type)
413     // Parameters: Pointer to a board structure
414     //             Pointer to a channel structure
415     //             type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW
416     // Returns:    Nothing
417     //
418     // Description:
419     // For each type of need selected, if the given channel is not already in the
420     // queue, adds it, and sets the flag indicating it is in the queue.
421     //******************************************************************************
422     static void
423     i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type)
424     {
425     	unsigned short queueIndex;
426     	unsigned long flags;
427     
428     	// We turn off all the interrupts during this brief process, since the
429     	// interrupt-level code might want to put things on the queue as well.
430     
431     	switch (type) {
432     
433     	case NEED_INLINE:
434     
435     		WRITE_LOCK_IRQSAVE(&pB->Dbuf_spinlock,flags);
436     		if ( !(pCh->channelNeeds & NEED_INLINE) )
437     		{
438     			pCh->channelNeeds |= NEED_INLINE;
439     			queueIndex = pB->i2Dbuf_stuff;
440     			pB->i2Dbuf[queueIndex++] = pCh;
441     			if (queueIndex >= CH_QUEUE_SIZE)
442     				queueIndex = 0;
443     			pB->i2Dbuf_stuff = queueIndex;
444     		}
445     		WRITE_UNLOCK_IRQRESTORE(&pB->Dbuf_spinlock,flags); 
446     		break;
447     
448     	case NEED_BYPASS:
449     
450     		WRITE_LOCK_IRQSAVE(&pB->Bbuf_spinlock,flags);
451     		if ((type & NEED_BYPASS) && !(pCh->channelNeeds & NEED_BYPASS))
452     		{
453     			pCh->channelNeeds |= NEED_BYPASS;
454     			queueIndex = pB->i2Bbuf_stuff;
455     			pB->i2Bbuf[queueIndex++] = pCh;
456     			if (queueIndex >= CH_QUEUE_SIZE)
457     				queueIndex = 0;
458     			pB->i2Bbuf_stuff = queueIndex;
459     		} 
460     		WRITE_UNLOCK_IRQRESTORE(&pB->Bbuf_spinlock,flags); 
461     		break;
462     
463     	case NEED_FLOW:
464     
465     		WRITE_LOCK_IRQSAVE(&pB->Fbuf_spinlock,flags);
466     		if ((type & NEED_FLOW) && !(pCh->channelNeeds & NEED_FLOW))
467     		{
468     			pCh->channelNeeds |= NEED_FLOW;
469     			queueIndex = pB->i2Fbuf_stuff;
470     			pB->i2Fbuf[queueIndex++] = pCh;
471     			if (queueIndex >= CH_QUEUE_SIZE)
472     				queueIndex = 0;
473     			pB->i2Fbuf_stuff = queueIndex;
474     		}
475     		WRITE_UNLOCK_IRQRESTORE(&pB->Fbuf_spinlock,flags); 
476     		break;
477     
478     	case NEED_CREDIT:
479     		pCh->channelNeeds |= NEED_CREDIT;
480     		break;
481     	default:
482     		printk(KERN_ERR "i2QueueNeeds called with bad type:%x\n",type);
483     		break;
484     	}
485     	return;
486     }
487     
488     //******************************************************************************
489     // Function:   i2QueueCommands(type, pCh, timeout, nCommands, pCs,...)
490     // Parameters: type - PTYPE_BYPASS or PTYPE_INLINE
491     //             pointer to the channel structure
492     //             maximum period to wait
493     //             number of commands (n)
494     //             n commands
495     // Returns:    Number of commands sent, or -1 for error
496     //
497     // get board lock before calling
498     //
499     // Description:
500     // Queues up some commands to be sent to a channel. To send possibly several
501     // bypass or inline commands to the given channel. The timeout parameter
502     // indicates how many HUNDREDTHS OF SECONDS to wait until there is room:
503     // 0 = return immediately if no room, -ive  = wait forever, +ive = number of
504     // 1/100 seconds to wait. Return values:
505     // -1 Some kind of nasty error: bad channel structure or invalid arguments.
506     //  0 No room to send all the commands
507     // (+)   Number of commands sent
508     //******************************************************************************
509     static int
510     i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands,
511     					 cmdSyntaxPtr pCs0,...)
512     {
513     	int totalsize = 0;
514     	int blocksize;
515     	int lastended;
516     	cmdSyntaxPtr *ppCs;
517     	cmdSyntaxPtr pCs;
518     	int count;
519     	int flag;
520     	i2eBordStrPtr pB;
521     
522     	unsigned short maxBlock;
523     	unsigned short maxBuff;
524     	short bufroom;
525     	unsigned short stuffIndex;
526     	unsigned char *pBuf;
527     	unsigned char *pInsert;
528     	unsigned char *pDest, *pSource;
529     	unsigned short channel;
530     	int cnt;
531     	unsigned long flags = 0;
532     	rwlock_t *lock_var_p = NULL;
533     
534     	// Make sure the channel exists, otherwise do nothing
535     	if ( !i2Validate ( pCh ) ) {
536     		return -1;
537     	}
538     #ifdef IP2DEBUG_TRACE
539     	ip2trace (CHANN, ITRC_QUEUE, ITRC_ENTER, 0 );
540     #endif
541     	pB = pCh->pMyBord;
542     
543     	// Board must also exist, and THE INTERRUPT COMMAND ALREADY SENT
544     	if (pB->i2eValid != I2E_MAGIC || pB->i2eUsingIrq == IRQ_UNDEFINED) {
545     		return -2;
546     	}
547     	// If the board has gone fatal, return bad, and also hit the trap routine if
548     	// it exists.
549     	if (pB->i2eFatal) {
550     		if ( pB->i2eFatalTrap ) {
551     			(*(pB)->i2eFatalTrap)(pB);
552     		}
553     		return -3;
554     	}
555     	// Set up some variables, Which buffers are we using?  How big are they?
556     	switch(type)
557     	{
558     	case PTYPE_INLINE:
559     		flag = INL;
560     		maxBlock = MAX_OBUF_BLOCK;
561     		maxBuff = OBUF_SIZE;
562     		pBuf = pCh->Obuf;
563     		break;
564     	case PTYPE_BYPASS:
565     		flag = BYP;
566     		maxBlock = MAX_CBUF_BLOCK;
567     		maxBuff = CBUF_SIZE;
568     		pBuf = pCh->Cbuf;
569     		break;
570     	default:
571     		return -4;
572     	}
573     	// Determine the total size required for all the commands
574     	totalsize = blocksize = sizeof(i2CmdHeader);
575     	lastended = 0;
576     	ppCs = &pCs0;
577     	for ( count = nCommands; count; count--, ppCs++)
578     	{
579     		pCs = *ppCs;
580     		cnt = pCs->length;
581     		// Will a new block be needed for this one? 
582     		// Two possible reasons: too
583     		// big or previous command has to be at the end of a packet.
584     		if ((blocksize + cnt > maxBlock) || lastended) {
585     			blocksize = sizeof(i2CmdHeader);
586     			totalsize += sizeof(i2CmdHeader);
587     		}
588     		totalsize += cnt;
589     		blocksize += cnt;
590     
591     		// If this command had to end a block, then we will make sure to
592     		// account for it should there be any more blocks.
593     		lastended = pCs->flags & END;
594     	}
595     	for (;;) {
596     		// Make sure any pending flush commands go out before we add more data.
597     		if ( !( pCh->flush_flags && i2RetryFlushOutput( pCh ) ) ) {
598     			// How much room (this time through) ?
599     			switch(type) {
600     			case PTYPE_INLINE:
601     				lock_var_p = &pCh->Obuf_spinlock;
602     				WRITE_LOCK_IRQSAVE(lock_var_p,flags);
603     				stuffIndex = pCh->Obuf_stuff;
604     				bufroom = pCh->Obuf_strip - stuffIndex;
605     				break;
606     			case PTYPE_BYPASS:
607     				lock_var_p = &pCh->Cbuf_spinlock;
608     				WRITE_LOCK_IRQSAVE(lock_var_p,flags);
609     				stuffIndex = pCh->Cbuf_stuff;
610     				bufroom = pCh->Cbuf_strip - stuffIndex;
611     				break;
612     			default:
613     				return -5;
614     			}
615     			if (--bufroom < 0) {
616     				bufroom += maxBuff;
617     			}
618     #ifdef IP2DEBUG_TRACE
619     			ip2trace (CHANN, ITRC_QUEUE, 2, 1, bufroom );
620     #endif
621     			// Check for overflow
622     			if (totalsize <= bufroom) {
623     				// Normal Expected path - We still hold LOCK
624     				break; /* from for()- Enough room: goto proceed */
625     			}
626     		}
627     
628     #ifdef IP2DEBUG_TRACE
629     		ip2trace (CHANN, ITRC_QUEUE, 3, 1, totalsize );
630     #endif
631     		// Prepare to wait for buffers to empty
632     		WRITE_UNLOCK_IRQRESTORE(lock_var_p,flags); 
633     		serviceOutgoingFifo(pB);	// Dump what we got
634     
635     		if (timeout == 0) {
636     			return 0;   // Tired of waiting
637     		}
638     		if (timeout > 0)
639     			timeout--;   // So negative values == forever
640     		
641     		if (!in_interrupt()) {
642     			current->state = TASK_INTERRUPTIBLE;
643     			schedule_timeout(1);	// short nap 
644     		} else {
645     			// we cannot sched/sleep in interrrupt silly
646     			return 0;   
647     		}
648     		if (signal_pending(current)) {
649     			return 0;   // Wake up! Time to die!!!
650     		}
651     
652     #ifdef IP2DEBUG_TRACE
653     	ip2trace (CHANN, ITRC_QUEUE, 4, 0 );
654     #endif
655     	}	// end of for(;;)
656     
657     	// At this point we have room and the lock - stick them in.
658     	channel = pCh->infl.hd.i2sChannel;
659     	pInsert = &pBuf[stuffIndex];     // Pointer to start of packet
660     	pDest = CMD_OF(pInsert);         // Pointer to start of command
661     
662     	// When we start counting, the block is the size of the header
663     	for (blocksize = sizeof(i2CmdHeader), count = nCommands,
664     			lastended = 0, ppCs = &pCs0;
665     		count;
666     		count--, ppCs++)
667     	{
668     		pCs = *ppCs;         // Points to command protocol structure
669     
670     		// If this is a bookmark request command, post the fact that a bookmark
671     		// request is pending. NOTE THIS TRICK ONLY WORKS BECAUSE CMD_BMARK_REQ
672     		// has no parameters!  The more general solution would be to reference
673     		// pCs->cmd[0].
674     		if (pCs == CMD_BMARK_REQ) {
675     			pCh->bookMarks++;
676     #ifdef IP2DEBUG_TRACE
677     			ip2trace (CHANN, ITRC_DRAIN, 30, 1, pCh->bookMarks );
678     #endif
679     		}
680     		cnt = pCs->length;
681     
682     		// If this command would put us over the maximum block size or 
683     		// if the last command had to be at the end of a block, we end
684     		// the existing block here and start a new one.
685     		if ((blocksize + cnt > maxBlock) || lastended) {
686     #ifdef IP2DEBUG_TRACE
687     			ip2trace (CHANN, ITRC_QUEUE, 5, 0 );
688     #endif
689     			PTYPE_OF(pInsert) = type;
690     			CHANNEL_OF(pInsert) = channel;
691     			// count here does not include the header
692     			CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader);
693     			stuffIndex += blocksize;
694     			if(stuffIndex >= maxBuff) {
695     				stuffIndex = 0;
696     				pInsert = pBuf;
697     			}
698     			pInsert = &pBuf[stuffIndex];  // Pointer to start of next pkt
699     			pDest = CMD_OF(pInsert);
700     			blocksize = sizeof(i2CmdHeader);
701     		}
702     		// Now we know there is room for this one in the current block
703     
704     		blocksize += cnt;       // Total bytes in this command
705     		pSource = pCs->cmd;     // Copy the command into the buffer
706     		while (cnt--) {
707     			*pDest++ = *pSource++;
708     		}
709     		// If this command had to end a block, then we will make sure to account
710     		// for it should there be any more blocks.
711     		lastended = pCs->flags & END;
712     	}	// end for
713     	// Clean up the final block by writing header, etc
714     
715     	PTYPE_OF(pInsert) = type;
716     	CHANNEL_OF(pInsert) = channel;
717     	// count here does not include the header
718     	CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader);
719     	stuffIndex += blocksize;
720     	if(stuffIndex >= maxBuff) {
721     		stuffIndex = 0;
722     		pInsert = pBuf;
723     	}
724     	// Updates the index, and post the need for service. When adding these to
725     	// the queue of channels, we turn off the interrupt while doing so,
726     	// because at interrupt level we might want to push a channel back to the
727     	// end of the queue.
728     	switch(type)
729     	{
730     	case PTYPE_INLINE:
731     		pCh->Obuf_stuff = stuffIndex;  // Store buffer pointer
732     		WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags); 
733     
734     		pB->debugInlineQueued++;
735     		// Add the channel pointer to list of channels needing service (first
736     		// come...), if it's not already there.
737     		i2QueueNeeds(pB, pCh, NEED_INLINE);
738     		break;
739     
740     	case PTYPE_BYPASS:
741     		pCh->Cbuf_stuff = stuffIndex;  // Store buffer pointer
742     		WRITE_UNLOCK_IRQRESTORE(&pCh->Cbuf_spinlock,flags); 
743     
744     		pB->debugBypassQueued++;
745     		// Add the channel pointer to list of channels needing service (first
746     		// come...), if it's not already there.
747     		i2QueueNeeds(pB, pCh, NEED_BYPASS);
748     		break;
749     	}
750     #ifdef IP2DEBUG_TRACE
751     	ip2trace (CHANN, ITRC_QUEUE, ITRC_RETURN, 1, nCommands );
752     #endif
753     	return nCommands; // Good status: number of commands sent
754     }
755     
756     //******************************************************************************
757     // Function:   i2GetStatus(pCh,resetBits)
758     // Parameters: Pointer to a channel structure
759     //             Bit map of status bits to clear
760     // Returns:    Bit map of current status bits
761     //
762     // Description:
763     // Returns the state of data set signals, and whether a break has been received,
764     // (see i2lib.h for bit-mapped result). resetBits is a bit-map of any status
765     // bits to be cleared: I2_BRK, I2_PAR, I2_FRA, I2_OVR,... These are cleared
766     // AFTER the condition is passed. If pCh does not point to a valid channel,
767     // returns -1 (which would be impossible otherwise.
768     //******************************************************************************
769     static int
770     i2GetStatus(i2ChanStrPtr pCh, int resetBits)
771     {
772     	unsigned short status;
773     	i2eBordStrPtr pB;
774     
775     #ifdef IP2DEBUG_TRACE
776     	ip2trace (CHANN, ITRC_STATUS, ITRC_ENTER, 2, pCh->dataSetIn, resetBits );
777     #endif
778     
779     	// Make sure the channel exists, otherwise do nothing */
780     	if ( !i2Validate ( pCh ) )
781     		return -1;
782     
783     	pB = pCh->pMyBord;
784     
785     	status = pCh->dataSetIn;
786     
787     	// Clear any specified error bits: but note that only actual error bits can
788     	// be cleared, regardless of the value passed.
789     	if (resetBits)
790     	{
791     		pCh->dataSetIn &= ~(resetBits & (I2_BRK | I2_PAR | I2_FRA | I2_OVR));
792     		pCh->dataSetIn &= ~(I2_DDCD | I2_DCTS | I2_DDSR | I2_DRI);
793     	}
794     
795     #ifdef IP2DEBUG_TRACE
796     	ip2trace (CHANN, ITRC_STATUS, ITRC_RETURN, 1, pCh->dataSetIn );
797     #endif
798     
799     	return status;
800     }
801     
802     //******************************************************************************
803     // Function:   i2Input(pChpDest,count)
804     // Parameters: Pointer to a channel structure
805     //             Pointer to data buffer
806     //             Number of bytes to read
807     // Returns:    Number of bytes read, or -1 for error
808     //
809     // Description:
810     // Strips data from the input buffer and writes it to pDest. If there is a
811     // collosal blunder, (invalid structure pointers or the like), returns -1.
812     // Otherwise, returns the number of bytes read.
813     //******************************************************************************
814     static int
815     i2Input(i2ChanStrPtr pCh)
816     {
817     	int amountToMove;
818     	unsigned short stripIndex;
819     	int count;
820     	unsigned long flags = 0;
821     
822     #ifdef IP2DEBUG_TRACE
823     	ip2trace (CHANN, ITRC_INPUT, ITRC_ENTER, 0);
824     #endif
825     
826     	// Ensure channel structure seems real
827     	if ( !i2Validate( pCh ) ) {
828     		count = -1;
829     		goto i2Input_exit;
830     	}
831     	WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
832     
833     	// initialize some accelerators and private copies
834     	stripIndex = pCh->Ibuf_strip;
835     
836     	count = pCh->Ibuf_stuff - stripIndex;
837     
838     	// If buffer is empty or requested data count was 0, (trivial case) return
839     	// without any further thought.
840     	if ( count == 0 ) {
841     		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
842     		goto i2Input_exit;
843     	}
844     	// Adjust for buffer wrap
845     	if ( count < 0 ) {
846     		count += IBUF_SIZE;
847     	}
848     	// Don't give more than can be taken by the line discipline
849     	amountToMove = pCh->pTTY->ldisc.receive_room( pCh->pTTY );
850     	if (count > amountToMove) {
851     		count = amountToMove;
852     	}
853     	// How much could we copy without a wrap?
854     	amountToMove = IBUF_SIZE - stripIndex;
855     
856     	if (amountToMove > count) {
857     		amountToMove = count;
858     	}
859     	// Move the first block
860     	pCh->pTTY->ldisc.receive_buf( pCh->pTTY, 
861     		 &(pCh->Ibuf[stripIndex]), NULL, amountToMove );
862     	// If we needed to wrap, do the second data move
863     	if (count > amountToMove) {
864     		pCh->pTTY->ldisc.receive_buf( pCh->pTTY, 
865     		 pCh->Ibuf, NULL, count - amountToMove );
866     	}
867     	// Bump and wrap the stripIndex all at once by the amount of data read. This
868     	// method is good regardless of whether the data was in one or two pieces.
869     	stripIndex += count;
870     	if (stripIndex >= IBUF_SIZE) {
871     		stripIndex -= IBUF_SIZE;
872     	}
873     	pCh->Ibuf_strip = stripIndex;
874     
875     	// Update our flow control information and possibly queue ourselves to send
876     	// it, depending on how much data has been stripped since the last time a
877     	// packet was sent.
878     	pCh->infl.asof += count;
879     
880     	if ((pCh->sinceLastFlow += count) >= pCh->whenSendFlow) {
881     		pCh->sinceLastFlow -= pCh->whenSendFlow;
882     		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
883     		i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW);
884     	} else {
885     		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
886     	}
887     
888     i2Input_exit:
889     
890     #ifdef IP2DEBUG_TRACE
891     	ip2trace (CHANN, ITRC_INPUT, ITRC_RETURN, 1, count);
892     #endif
893     	return count;
894     }
895     
896     //******************************************************************************
897     // Function:   i2InputFlush(pCh)
898     // Parameters: Pointer to a channel structure
899     // Returns:    Number of bytes stripped, or -1 for error
900     //
901     // Description:
902     // Strips any data from the input buffer. If there is a collosal blunder,
903     // (invalid structure pointers or the like), returns -1. Otherwise, returns the
904     // number of bytes stripped.
905     //******************************************************************************
906     static int
907     i2InputFlush(i2ChanStrPtr pCh)
908     {
909     	int count;
910     	unsigned long flags;
911     
912     	// Ensure channel structure seems real
913     	if ( !i2Validate ( pCh ) )
914     		return -1;
915     
916     #ifdef IP2DEBUG_TRACE
917     	ip2trace (CHANN, ITRC_INPUT, 10, 0);
918     #endif
919     
920     	WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
921     	count = pCh->Ibuf_stuff - pCh->Ibuf_strip;
922     
923     	// Adjust for buffer wrap
924     	if (count < 0) {
925     		count += IBUF_SIZE;
926     	}
927     
928     	// Expedient way to zero out the buffer
929     	pCh->Ibuf_strip = pCh->Ibuf_stuff;
930     
931     
932     	// Update our flow control information and possibly queue ourselves to send
933     	// it, depending on how much data has been stripped since the last time a
934     	// packet was sent.
935     
936     	pCh->infl.asof += count;
937     
938     	if ( (pCh->sinceLastFlow += count) >= pCh->whenSendFlow )
939     	{
940     		pCh->sinceLastFlow -= pCh->whenSendFlow;
941     		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
942     		i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW);
943     	} else {
944     		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
945     	}
946     #ifdef IP2DEBUG_TRACE
947     	ip2trace (CHANN, ITRC_INPUT, 19, 1, count);
948     #endif
949     	return count;
950     }
951     
952     //******************************************************************************
953     // Function:   i2InputAvailable(pCh)
954     // Parameters: Pointer to a channel structure
955     // Returns:    Number of bytes available, or -1 for error
956     //
957     // Description:
958     // If there is a collosal blunder, (invalid structure pointers or the like),
959     // returns -1. Otherwise, returns the number of bytes stripped. Otherwise,
960     // returns the number of bytes available in the buffer.
961     //******************************************************************************
962     #if 0
963     static int
964     i2InputAvailable(i2ChanStrPtr pCh)
965     {
966     	int count;
967     
968     	// Ensure channel structure seems real
969     	if ( !i2Validate ( pCh ) ) return -1;
970     
971     
972     	// initialize some accelerators and private copies
973     	READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
974     	count = pCh->Ibuf_stuff - pCh->Ibuf_strip;
975     	READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
976     
977     	// Adjust for buffer wrap
978     	if (count < 0)
979     	{
980     		count += IBUF_SIZE;
981     	}
982     
983     	return count;
984     }
985     #endif 
986     
987     //******************************************************************************
988     // Function:   i2Output(pCh, pSource, count)
989     // Parameters: Pointer to channel structure
990     //             Pointer to source data
991     //             Number of bytes to send
992     // Returns:    Number of bytes sent, or -1 for error
993     //
994     // Description:
995     // Queues the data at pSource to be sent as data packets to the board. If there
996     // is a collosal blunder, (invalid structure pointers or the like), returns -1.
997     // Otherwise, returns the number of bytes written. What if there is not enough
998     // room for all the data? If pCh->channelOptions & CO_NBLOCK_WRITE is set, then
999     // we transfer as many characters as we can now, then return. If this bit is
1000     // clear (default), routine will spin along until all the data is buffered.
1001     // Should this occur, the 1-ms delay routine is called while waiting to avoid
1002     // applications that one cannot break out of.
1003     //******************************************************************************
1004     static int
1005     i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user )
1006     {
1007     	i2eBordStrPtr pB;
1008     	unsigned char *pInsert;
1009     	int amountToMove;
1010     	int countOriginal = count;
1011     	unsigned short channel;
1012     	unsigned short stuffIndex;
1013     	unsigned long flags;
1014     	int rc = 0;
1015     
1016     	int bailout = 10;
1017     
1018     #ifdef IP2DEBUG_TRACE
1019     	ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, user );
1020     #endif
1021     
1022     	// Ensure channel structure seems real
1023     	if ( !i2Validate ( pCh ) ) 
1024     		return -1;
1025     
1026     	// initialize some accelerators and private copies
1027     	pB = pCh->pMyBord;
1028     	channel = pCh->infl.hd.i2sChannel;
1029     
1030     	// If the board has gone fatal, return bad, and also hit the trap routine if
1031     	// it exists.
1032     	if (pB->i2eFatal) {
1033     		if (pB->i2eFatalTrap) {
1034     			(*(pB)->i2eFatalTrap)(pB);
1035     		}
1036     		return -1;
1037     	}
1038     	// Proceed as though we would do everything
1039     	while ( count > 0 ) {
1040     
1041     		// How much room in output buffer is there?
1042     		READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
1043     		amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1;
1044     		READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
1045     		if (amountToMove < 0) {
1046     			amountToMove += OBUF_SIZE;
1047     		}
1048     		// Subtract off the headers size and see how much room there is for real
1049     		// data. If this is negative, we will discover later.
1050     		amountToMove -= sizeof (i2DataHeader);
1051     
1052     		// Don't move more (now) than can go in a single packet
1053     		if ( amountToMove > (int)(MAX_OBUF_BLOCK - sizeof(i2DataHeader)) ) {
1054     			amountToMove = MAX_OBUF_BLOCK - sizeof(i2DataHeader);
1055     		}
1056     		// Don't move more than the count we were given
1057     		if (amountToMove > count) {
1058     			amountToMove = count;
1059     		}
1060     		// Now we know how much we must move: NB because the ring buffers have
1061     		// an overflow area at the end, we needn't worry about wrapping in the
1062     		// middle of a packet.
1063     
1064     // Small WINDOW here with no LOCK but I can't call Flush with LOCK
1065     // We would be flushing (or ending flush) anyway
1066     
1067     #ifdef IP2DEBUG_TRACE
1068     			ip2trace (CHANN, ITRC_OUTPUT, 10, 1, amountToMove );
1069     #endif
1070     		if ( !(pCh->flush_flags && i2RetryFlushOutput(pCh) ) 
1071     				&& amountToMove > 0 )
1072     		{
1073     			WRITE_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
1074     			stuffIndex = pCh->Obuf_stuff;
1075           
1076     			// Had room to move some data: don't know whether the block size,
1077     			// buffer space, or what was the limiting factor...
1078     			pInsert = &(pCh->Obuf[stuffIndex]);
1079     
1080     			// Set up the header
1081     			CHANNEL_OF(pInsert)     = channel;
1082     			PTYPE_OF(pInsert)       = PTYPE_DATA;
1083     			TAG_OF(pInsert)         = 0;
1084     			ID_OF(pInsert)          = ID_ORDINARY_DATA;
1085     			DATA_COUNT_OF(pInsert)  = amountToMove;
1086     
1087     			// Move the data
1088     			if ( user ) {
1089     				COPY_FROM_USER(rc, (char*)(DATA_OF(pInsert)), pSource,
1090     						amountToMove );
1091     			} else {
1092     				memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove );
1093     			}
1094     			// Adjust pointers and indices
1095     			pSource					+= amountToMove;
1096     			pCh->Obuf_char_count	+= amountToMove;
1097     			stuffIndex 				+= amountToMove + sizeof(i2DataHeader);
1098     			count 					-= amountToMove;
1099     
1100     			if (stuffIndex >= OBUF_SIZE) {
1101     				stuffIndex = 0;
1102     			}
1103     			pCh->Obuf_stuff = stuffIndex;
1104     
1105     			WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
1106     
1107     #ifdef IP2DEBUG_TRACE
1108     			ip2trace (CHANN, ITRC_OUTPUT, 13, 1, stuffIndex );
1109     #endif
1110     
1111     		} else {
1112     
1113     			// Cannot move data
1114     			// becuz we need to stuff a flush 
1115     			// or amount to move is <= 0
1116     
1117     #ifdef IP2DEBUG_TRACE
1118     			ip2trace(CHANN, ITRC_OUTPUT, 14, 3,
1119     				amountToMove,  pB->i2eFifoRemains, pB->i2eWaitingForEmptyFifo );
1120     #endif
1121     			// Put this channel back on queue
1122     			// this ultimatly gets more data or wakes write output
1123     			i2QueueNeeds(pB, pCh, NEED_INLINE);
1124     
1125     			if ( pB->i2eWaitingForEmptyFifo ) {
1126     
1127     #ifdef IP2DEBUG_TRACE
1128     				ip2trace (CHANN, ITRC_OUTPUT, 16, 0 );
1129     #endif
1130     				// or schedule
1131     				if (!in_interrupt()) {
1132     
1133     #ifdef IP2DEBUG_TRACE
1134     	ip2trace (CHANN, ITRC_OUTPUT, 61, 0 );
1135     #endif
1136     					current->state = TASK_INTERRUPTIBLE;
1137     					schedule_timeout(2);
1138     					if (signal_pending(current)) {
1139     						break;
1140     					}
1141     					continue;
1142     				} else {
1143     #ifdef IP2DEBUG_TRACE
1144     	ip2trace (CHANN, ITRC_OUTPUT, 62, 0 );
1145     #endif
1146     					// let interrupt in = WAS restore_flags()
1147     					// We hold no lock nor is irq off anymore???
1148     					
1149     					break;
1150     				}
1151     				break;   // from while(count)
1152     			}
1153     			else if ( pB->i2eFifoRemains < 32 && !pB->i2eTxMailEmpty ( pB ) )
1154     			{
1155     #ifdef IP2DEBUG_TRACE
1156     				ip2trace (CHANN, ITRC_OUTPUT, 19, 2, pB->i2eFifoRemains,
1157     									pB->i2eTxMailEmpty );
1158     #endif
1159     				break;   // from while(count)
1160     			} else if ( pCh->channelNeeds & NEED_CREDIT ) {
1161     #ifdef IP2DEBUG_TRACE
1162     				ip2trace (CHANN, ITRC_OUTPUT, 22, 0 );
1163     #endif
1164     				break;   // from while(count)
1165     			} else if ( --bailout) {
1166     
1167     				// Try to throw more things (maybe not us) in the fifo if we're
1168     				// not already waiting for it.
1169     	
1170     #ifdef IP2DEBUG_TRACE
1171     				ip2trace (CHANN, ITRC_OUTPUT, 20, 0 );
1172     #endif
1173     				serviceOutgoingFifo(pB);
1174     				//break;  CONTINUE;
1175     			} else {
1176     #ifdef IP2DEBUG_TRACE
1177     				ip2trace (CHANN, ITRC_OUTPUT, 21, 3, pB->i2eFifoRemains,
1178     							pB->i2eOutMailWaiting, pB->i2eWaitingForEmptyFifo );
1179     #endif
1180     				break;   // from while(count)
1181     			}
1182     		}
1183     	} // End of while(count)
1184     
1185     	i2QueueNeeds(pB, pCh, NEED_INLINE);
1186     
1187     	// We drop through either when the count expires, or when there is some
1188     	// count left, but there was a non-blocking write.
1189     	if (countOriginal > count) {
1190     #ifdef IP2DEBUG_TRACE
1191     		ip2trace (CHANN, ITRC_OUTPUT, 17, 2, countOriginal, count );
1192     #endif
1193     		serviceOutgoingFifo( pB );
1194     	}
1195     #ifdef IP2DEBUG_TRACE
1196     	ip2trace (CHANN, ITRC_OUTPUT, ITRC_RETURN, 2, countOriginal, count );
1197     #endif
1198     
1199     	return countOriginal - count;
1200     }
1201     
1202     //******************************************************************************
1203     // Function:   i2FlushOutput(pCh)
1204     // Parameters: Pointer to a channel structure
1205     // Returns:    Nothing
1206     //
1207     // Description:
1208     // Sends bypass command to start flushing (waiting possibly forever until there
1209     // is room), then sends inline command to stop flushing output, (again waiting
1210     // possibly forever).
1211     //******************************************************************************
1212     static inline void
1213     i2FlushOutput(i2ChanStrPtr pCh)
1214     {
1215     
1216     #ifdef IP2DEBUG_TRACE
1217     	ip2trace (CHANN, ITRC_FLUSH, 1, 1, pCh->flush_flags );
1218     #endif
1219     
1220     	if (pCh->flush_flags)
1221     		return;
1222     
1223     	if ( 1 != i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) {
1224     		pCh->flush_flags = STARTFL_FLAG;		// Failed - flag for later
1225     #ifdef IP2DEBUG_TRACE
1226     		ip2trace (CHANN, ITRC_FLUSH, 2, 0 );
1227     #endif
1228     	} else if ( 1 != i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL) ) {
1229     		pCh->flush_flags = STOPFL_FLAG;		// Failed - flag for later
1230     #ifdef IP2DEBUG_TRACE
1231     		ip2trace (CHANN, ITRC_FLUSH, 3, 0 );
1232     #endif
1233     	}
1234     }
1235     
1236     static int 
1237     i2RetryFlushOutput(i2ChanStrPtr pCh)
1238     {
1239     	int old_flags = pCh->flush_flags;
1240     
1241     #ifdef IP2DEBUG_TRACE
1242     	ip2trace (CHANN, ITRC_FLUSH, 14, 1, old_flags );
1243     #endif
1244     
1245     	pCh->flush_flags = 0;	// Clear flag so we can avoid recursion
1246     									// and queue the commands
1247     
1248     	if ( old_flags & STARTFL_FLAG ) {
1249     		if ( 1 == i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) {
1250     			old_flags = STOPFL_FLAG;	//Success - send stop flush
1251     		} else {
1252     			old_flags = STARTFL_FLAG;	//Failure - Flag for retry later
1253     		}
1254     #ifdef IP2DEBUG_TRACE
1255     		ip2trace (CHANN, ITRC_FLUSH, 15, 1, old_flags );
1256     #endif
1257     	}
1258     	if ( old_flags & STOPFL_FLAG ) {
1259     		if ( 1 == i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL) > 0 ) {
1260     			old_flags = 0;	// Success - clear flags
1261     		}
1262     #ifdef IP2DEBUG_TRACE
1263     		ip2trace (CHANN, ITRC_FLUSH, 16, 1, old_flags );
1264     #endif
1265     	}
1266        pCh->flush_flags = old_flags;
1267     
1268     #ifdef IP2DEBUG_TRACE
1269     	ip2trace (CHANN, ITRC_FLUSH, 17, 1, old_flags );
1270     #endif
1271     	return old_flags;
1272     }
1273     
1274     //******************************************************************************
1275     // Function:   i2DrainOutput(pCh,timeout)
1276     // Parameters: Pointer to a channel structure
1277     //             Maximum period to wait
1278     // Returns:    ?
1279     //
1280     // Description:
1281     // Uses the bookmark request command to ask the board to send a bookmark back as
1282     // soon as all the data is completely sent.
1283     //******************************************************************************
1284     static void
1285     i2DrainWakeup(i2ChanStrPtr pCh)
1286     {
1287     #ifdef IP2DEBUG_TRACE
1288     	ip2trace (CHANN, ITRC_DRAIN, 10, 1, pCh->BookmarkTimer.expires );
1289     #endif
1290     	pCh->BookmarkTimer.expires = 0;
1291     	wake_up_interruptible( &pCh->pBookmarkWait );
1292     }
1293     
1294     static void
1295     i2DrainOutput(i2ChanStrPtr pCh, int timeout)
1296     {
1297     	i2eBordStrPtr pB;
1298     
1299     #ifdef IP2DEBUG_TRACE
1300     	ip2trace (CHANN, ITRC_DRAIN, ITRC_ENTER, 1, pCh->BookmarkTimer.expires);
1301     #endif
1302     	pB = pCh->pMyBord;
1303     	// If the board has gone fatal, return bad, 
1304     	// and also hit the trap routine if it exists.
1305     	if (pB->i2eFatal) {
1306     		if (pB->i2eFatalTrap) {
1307     			(*(pB)->i2eFatalTrap)(pB);
1308     		}
1309     		return;
1310     	}
1311     	if ((timeout > 0) && (pCh->BookmarkTimer.expires == 0 )) {
1312     		// One per customer (channel)
1313     		init_timer( &(pCh->BookmarkTimer) );
1314     		pCh->BookmarkTimer.expires  = jiffies + timeout;
1315     		pCh->BookmarkTimer.function = (void*)(unsigned long)i2DrainWakeup;
1316     		pCh->BookmarkTimer.data     = (unsigned long)pCh;
1317     
1318     #ifdef IP2DEBUG_TRACE
1319     		ip2trace (CHANN, ITRC_DRAIN, 1, 1, pCh->BookmarkTimer.expires );
1320     #endif
1321     
1322     		add_timer( &(pCh->BookmarkTimer) );
1323     	}
1324     	
1325     	i2QueueCommands( PTYPE_INLINE, pCh, -1, 1, CMD_BMARK_REQ );
1326     	serviceOutgoingFifo( pB );
1327     	
1328     	interruptible_sleep_on( &(pCh->pBookmarkWait) );
1329     
1330     	// if expires == 0 then timer poped, then do not need to del_timer
1331     	if ((timeout > 0) && pCh->BookmarkTimer.expires && 
1332     				(pCh->BookmarkTimer.expires > jiffies)) {
1333     		del_timer( &(pCh->BookmarkTimer) );
1334     		pCh->BookmarkTimer.expires = 0;
1335     #ifdef IP2DEBUG_TRACE
1336     		ip2trace (CHANN, ITRC_DRAIN, 3, 1, pCh->BookmarkTimer.expires );
1337     #endif
1338     
1339     	}
1340     #ifdef IP2DEBUG_TRACE
1341     	ip2trace (CHANN, ITRC_DRAIN, ITRC_RETURN, 1, pCh->BookmarkTimer.expires );
1342     #endif
1343     	return;
1344     }
1345     
1346     //******************************************************************************
1347     // Function:   i2OutputFree(pCh)
1348     // Parameters: Pointer to a channel structure
1349     // Returns:    Space in output buffer
1350     //
1351     // Description:
1352     // Returns -1 if very gross error. Otherwise returns the amount of bytes still
1353     // free in the output buffer.
1354     //******************************************************************************
1355     static int
1356     i2OutputFree(i2ChanStrPtr pCh)
1357     {
1358     	int amountToMove;
1359     	unsigned long flags;
1360     
1361     	// Ensure channel structure seems real
1362     	if ( !i2Validate ( pCh ) ) {
1363     		return -1;
1364     	}
1365     	READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
1366     	amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1;
1367     	READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
1368     
1369     	if (amountToMove < 0) {
1370     		amountToMove += OBUF_SIZE;
1371     	}
1372     	// If this is negative, we will discover later
1373     	amountToMove -= sizeof(i2DataHeader);
1374     
1375     	return (amountToMove < 0) ? 0 : amountToMove;
1376     }
1377     static void
1378     
1379     ip2_owake( PTTY tp)
1380     {
1381     	i2ChanStrPtr  pCh;
1382     
1383     	if (tp == NULL) return;
1384     
1385     	pCh = tp->driver_data;
1386     
1387     #ifdef IP2DEBUG_TRACE
1388     	ip2trace (CHANN, ITRC_SICMD, 10, 2, tp->flags, (1 << TTY_DO_WRITE_WAKEUP) );
1389     #endif
1390     	wake_up_interruptible ( &tp->write_wait );
1391     	if ( ( tp->flags & (1 << TTY_DO_WRITE_WAKEUP) ) 
1392     	  && tp->ldisc.write_wakeup )
1393     	{
1394     		(tp->ldisc.write_wakeup) ( tp );
1395     #ifdef IP2DEBUG_TRACE
1396     		ip2trace (CHANN, ITRC_SICMD, 11, 0 );
1397     #endif
1398     	}
1399     }
1400     
1401     static inline void
1402     set_baud_params(i2eBordStrPtr pB) 
1403     {
1404     	int i,j;
1405     	i2ChanStrPtr  *pCh;
1406     
1407     	pCh = (i2ChanStrPtr *) pB->i2eChannelPtr;
1408     
1409     	for (i = 0; i < ABS_MAX_BOXES; i++) {
1410     		if (pB->channelBtypes.bid_value[i]) {
1411     			if (BID_HAS_654(pB->channelBtypes.bid_value[i])) {
1412     				for (j = 0; j < ABS_BIGGEST_BOX; j++) {
1413     					if (pCh[i*16+j] == NULL)
1414     						break;
1415     					(pCh[i*16+j])->BaudBase    = 921600;	// MAX for ST654
1416     					(pCh[i*16+j])->BaudDivisor = 96;
1417     				}
1418     			} else {	// has cirrus cd1400
1419     				for (j = 0; j < ABS_BIGGEST_BOX; j++) {
1420     					if (pCh[i*16+j] == NULL)
1421     						break;
1422     					(pCh[i*16+j])->BaudBase    = 115200;	// MAX for CD1400
1423     					(pCh[i*16+j])->BaudDivisor = 12;
1424     				}
1425     			}
1426     		}
1427     	}
1428     }
1429     
1430     //******************************************************************************
1431     // Function:   i2StripFifo(pB)
1432     // Parameters: Pointer to a board structure
1433     // Returns:    ?
1434     //
1435     // Description:
1436     // Strips all the available data from the incoming FIFO, identifies the type of
1437     // packet, and either buffers the data or does what needs to be done.
1438     //
1439     // Note there is no overflow checking here: if the board sends more data than it
1440     // ought to, we will not detect it here, but blindly overflow...
1441     //******************************************************************************
1442     
1443     // A buffer for reading in blocks for unknown channels
1444     static unsigned char junkBuffer[IBUF_SIZE];
1445     
1446     // A buffer to read in a status packet. Because of the size of the count field
1447     // for these things, the maximum packet size must be less than MAX_CMD_PACK_SIZE
1448     static unsigned char cmdBuffer[MAX_CMD_PACK_SIZE + 4];
1449     
1450     // This table changes the bit order from MSR order given by STAT_MODEM packet to
1451     // status bits used in our library.
1452     static char xlatDss[16] = {
1453     0      | 0     | 0      | 0      ,
1454     0      | 0     | 0      | I2_CTS ,
1455     0      | 0     | I2_DSR | 0      ,
1456     0      | 0     | I2_DSR | I2_CTS ,
1457     0      | I2_RI | 0      | 0      ,
1458     0      | I2_RI | 0      | I2_CTS ,
1459     0      | I2_RI | I2_DSR | 0      ,
1460     0      | I2_RI | I2_DSR | I2_CTS ,
1461     I2_DCD | 0     | 0      | 0      ,
1462     I2_DCD | 0     | 0      | I2_CTS ,
1463     I2_DCD | 0     | I2_DSR | 0      ,
1464     I2_DCD | 0     | I2_DSR | I2_CTS ,
1465     I2_DCD | I2_RI | 0      | 0      ,
1466     I2_DCD | I2_RI | 0      | I2_CTS ,
1467     I2_DCD | I2_RI | I2_DSR | 0      ,
1468     I2_DCD | I2_RI | I2_DSR | I2_CTS };
1469     
1470     static inline void
1471     i2StripFifo(i2eBordStrPtr pB)
1472     {
1473     	i2ChanStrPtr pCh;
1474     	int channel;
1475     	int count;
1476     	unsigned short stuffIndex;
1477     	int amountToRead;
1478     	unsigned char *pc, *pcLimit;
1479     	unsigned char uc;
1480     	unsigned char dss_change;
1481     	unsigned long bflags,cflags;
1482     
1483     #ifdef IP2DEBUG_TRACE
1484     	//ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_ENTER, 0 );
1485     #endif
1486     
1487     	while (HAS_INPUT(pB)) {
1488     #ifdef IP2DEBUG_TRACE
1489     		//ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 2, 0 );
1490     #endif
1491     		// Process packet from fifo a one atomic unit
1492     		WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock,bflags);
1493        
1494     		// The first word (or two bytes) will have channel number and type of
1495     		// packet, possibly other information
1496     		pB->i2eLeadoffWord[0] = iiReadWord(pB);
1497     
1498     		switch(PTYPE_OF(pB->i2eLeadoffWord))
1499     		{
1500     		case PTYPE_DATA:
1501     			pB->got_input = 1;
1502     
1503     #ifdef IP2DEBUG_TRACE
1504     			//ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 3, 0 );
1505     #endif
1506     			channel = CHANNEL_OF(pB->i2eLeadoffWord); /* Store channel */
1507     			count = iiReadWord(pB);          /* Count is in the next word */
1508     
1509     // NEW: Check the count for sanity! Should the hardware fail, our death
1510     // is more pleasant. While an oversize channel is acceptable (just more
1511     // than the driver supports), an over-length count clearly means we are
1512     // sick!
1513     			if ( ((unsigned int)count) > IBUF_SIZE ) {
1514     				pB->i2eFatal = 2;
1515     				WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
1516     				return;     /* Bail out ASAP */
1517     			}
1518     			// Channel is illegally big ?
1519     			if ((channel >= pB->i2eChannelCnt) ||
1520     				(NULL==(pCh = ((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])))
1521     			{
1522     				iiReadBuf(pB, junkBuffer, count);
1523     				WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
1524     				break;         /* From switch: ready for next packet */
1525     			}
1526     
1527     			// Channel should be valid, then
1528     
1529     			// If this is a hot-key, merely post its receipt for now. These are
1530     			// always supposed to be 1-byte packets, so we won't even check the
1531     			// count. Also we will post an acknowledgement to the board so that
1532     			// more data can be forthcoming. Note that we are not trying to use
1533     			// these sequences in this driver, merely to robustly ignore them.
1534     			if(ID_OF(pB->i2eLeadoffWord) == ID_HOT_KEY)
1535     			{
1536     				pCh->hotKeyIn = iiReadWord(pB) & 0xff;
1537     				WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
1538     				i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_HOTACK);
1539     				break;   /* From the switch: ready for next packet */
1540     			}
1541     
1542     			// Normal data! We crudely assume there is room for the data in our
1543     			// buffer because the board wouldn't have exceeded his credit limit.
1544     			WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,cflags);
1545     													// We have 2 locks now
1546     			stuffIndex = pCh->Ibuf_stuff;
1547     			amountToRead = IBUF_SIZE - stuffIndex;
1548     			if (amountToRead > count)
1549     				amountToRead = count;
1550     
1551     			// stuffIndex would have been already adjusted so there would 
1552     			// always be room for at least one, and count is always at least
1553     			// one.
1554     
1555     			iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead);
1556     			pCh->icount.rx += amountToRead;
1557     
1558     			// Update the stuffIndex by the amount of data moved. Note we could
1559     			// never ask for more data than would just fit. However, we might
1560     			// have read in one more byte than we wanted because the read
1561     			// rounds up to even bytes. If this byte is on the end of the
1562     			// packet, and is padding, we ignore it. If the byte is part of
1563     			// the actual data, we need to move it.
1564     
1565     			stuffIndex += amountToRead;
1566     
1567     			if (stuffIndex >= IBUF_SIZE) {
1568     				if ((amountToRead & 1) && (count > amountToRead)) {
1569     					pCh->Ibuf[0] = pCh->Ibuf[IBUF_SIZE];
1570     					amountToRead++;
1571     					stuffIndex = 1;
1572     				} else {
1573     					stuffIndex = 0;
1574     				}
1575     			}
1576     
1577     			// If there is anything left over, read it as well
1578     			if (count > amountToRead) {
1579     				amountToRead = count - amountToRead;
1580     				iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead);
1581     				pCh->icount.rx += amountToRead;
1582     				stuffIndex += amountToRead;
1583     			}
1584     
1585     			// Update stuff index
1586     			pCh->Ibuf_stuff = stuffIndex;
1587     			WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,cflags);
1588     			WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
1589     
1590     #ifdef USE_IQ
1591     			queue_task(&pCh->tqueue_input, &tq_immediate);
1592     			mark_bh(IMMEDIATE_BH);
1593     #else
1594     			do_input(pCh);
1595     #endif
1596     
1597     			// Note we do not need to maintain any flow-control credits at this
1598     			// time:  if we were to increment .asof and decrement .room, there
1599     			// would be no net effect. Instead, when we strip data, we will
1600     			// increment .asof and leave .room unchanged.
1601     
1602     			break;   // From switch: ready for next packet
1603     
1604     		case PTYPE_STATUS:
1605     #ifdef IP2DEBUG_TRACE
1606     			ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 4, 0 );
1607     #endif
1608           
1609     			count = CMD_COUNT_OF(pB->i2eLeadoffWord);
1610     
1611     			iiReadBuf(pB, cmdBuffer, count);
1612     			// We can release early with buffer grab
1613     			WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
1614     
1615     			pc = cmdBuffer;
1616     			pcLimit = &(cmdBuffer[count]);
1617     
1618     			while (pc < pcLimit) {
1619     				channel = *pc++;
1620     #ifdef IP2DEBUG_TRACE
1621     				ip2trace (channel, ITRC_SFIFO, 7, 2, channel, *pc );
1622     #endif
1623     				/* check for valid channel */
1624     				if (channel < pB->i2eChannelCnt
1625     					 && 
1626     					 (pCh = (((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])) != NULL
1627     					)
1628     				{
1629     					dss_change = 0;
1630     
1631     					switch (uc = *pc++)
1632     					{
1633     					/* Breaks and modem signals are easy: just update status */
1634     					case STAT_CTS_UP:
1635     						if ( !(pCh->dataSetIn & I2_CTS) )
1636     						{
1637     							pCh->dataSetIn |= I2_DCTS;
1638     							pCh->icount.cts++;
1639     							dss_change = 1;
1640     						}
1641     						pCh->dataSetIn |= I2_CTS;
1642     						break;
1643     
1644     					case STAT_CTS_DN:
1645     						if ( pCh->dataSetIn & I2_CTS )
1646     						{
1647     							pCh->dataSetIn |= I2_DCTS;
1648     							pCh->icount.cts++;
1649     							dss_change = 1;
1650     						}
1651     						pCh->dataSetIn &= ~I2_CTS;
1652     						break;
1653     
1654     					case STAT_DCD_UP:
1655     #ifdef IP2DEBUG_TRACE
1656     						ip2trace (channel, ITRC_MODEM, 1, 1, pCh->dataSetIn );
1657     #endif
1658     						if ( !(pCh->dataSetIn & I2_DCD) )
1659     						{
1660     #ifdef IP2DEBUG_TRACE
1661     							ip2trace (CHANN, ITRC_MODEM, 2, 0 );
1662     #endif
1663     							pCh->dataSetIn |= I2_DDCD;
1664     							pCh->icount.dcd++;
1665     							dss_change = 1;
1666     						}
1667     						pCh->dataSetIn |= I2_DCD;
1668     #ifdef IP2DEBUG_TRACE
1669     						ip2trace (channel, ITRC_MODEM, 3, 1, pCh->dataSetIn );
1670     #endif
1671     						break;
1672     
1673     					case STAT_DCD_DN:
1674     #ifdef IP2DEBUG_TRACE
1675     						ip2trace (channel, ITRC_MODEM, 4, 1, pCh->dataSetIn );
1676     #endif
1677     						if ( pCh->dataSetIn & I2_DCD )
1678     						{
1679     #ifdef IP2DEBUG_TRACE
1680     							ip2trace (channel, ITRC_MODEM, 5, 0 );
1681     #endif
1682     							pCh->dataSetIn |= I2_DDCD;
1683     							pCh->icount.dcd++;
1684     							dss_change = 1;
1685     						}
1686     						pCh->dataSetIn &= ~I2_DCD;
1687     #ifdef IP2DEBUG_TRACE
1688     						ip2trace (channel, ITRC_MODEM, 6, 1, pCh->dataSetIn );
1689     #endif
1690     						break;
1691     
1692     					case STAT_DSR_UP:
1693     						if ( !(pCh->dataSetIn & I2_DSR) )
1694     						{
1695     							pCh->dataSetIn |= I2_DDSR;
1696     							pCh->icount.dsr++;
1697     							dss_change = 1;
1698     						}
1699     						pCh->dataSetIn |= I2_DSR;
1700     						break;
1701     
1702     					case STAT_DSR_DN:
1703     						if ( pCh->dataSetIn & I2_DSR )
1704     						{
1705     							pCh->dataSetIn |= I2_DDSR;
1706     							pCh->icount.dsr++;
1707     							dss_change = 1;
1708     						}
1709     						pCh->dataSetIn &= ~I2_DSR;
1710     						break;
1711     
1712     					case STAT_RI_UP:
1713     						if ( !(pCh->dataSetIn & I2_RI) )
1714     						{
1715     							pCh->dataSetIn |= I2_DRI;
1716     							pCh->icount.rng++;
1717     							dss_change = 1;
1718     						}
1719     						pCh->dataSetIn |= I2_RI ;
1720     						break;
1721     
1722     					case STAT_RI_DN:
1723     						// to be compat with serial.c
1724     						//if ( pCh->dataSetIn & I2_RI )
1725     						//{
1726     						//	pCh->dataSetIn |= I2_DRI;
1727     						//	pCh->icount.rng++; 
1728     						//	dss_change = 1;
1729     						//}
1730     						pCh->dataSetIn &= ~I2_RI ;
1731     						break;
1732     
1733     					case STAT_BRK_DET:
1734     						pCh->dataSetIn |= I2_BRK;
1735     						pCh->icount.brk++;
1736     						dss_change = 1;
1737     						break;
1738     
1739     					// Bookmarks? one less request we're waiting for
1740     					case STAT_BMARK:
1741     						pCh->bookMarks--;
1742     						if (pCh->bookMarks <= 0 ) {
1743     							pCh->bookMarks = 0;
1744     							wake_up_interruptible( &pCh->pBookmarkWait );
1745     #ifdef IP2DEBUG_TRACE
1746     						ip2trace (channel, ITRC_DRAIN, 20, 1, pCh->BookmarkTimer.expires );
1747     #endif
1748     						}
1749     						break;
1750     
1751     					// Flow control packets? Update the new credits, and if
1752     					// someone was waiting for output, queue him up again.
1753     					case STAT_FLOW:
1754     						pCh->outfl.room =
1755     							((flowStatPtr)pc)->room -
1756     							(pCh->outfl.asof - ((flowStatPtr)pc)->asof);
1757     #ifdef IP2DEBUG_TRACE
1758     						ip2trace (channel, ITRC_STFLW, 1, 1, pCh->outfl.room );
1759     #endif
1760     						if (pCh->channelNeeds & NEED_CREDIT)
1761     						{
1762     #ifdef IP2DEBUG_TRACE
1763     						ip2trace (channel, ITRC_STFLW, 2, 1, pCh->channelNeeds);
1764     #endif
1765     							pCh->channelNeeds &= ~NEED_CREDIT;
1766     							i2QueueNeeds(pB, pCh, NEED_INLINE);
1767     							if ( pCh->pTTY )
1768     								ip2_owake(pCh->pTTY);
1769     						}
1770     #ifdef IP2DEBUG_TRACE
1771     						ip2trace (channel, ITRC_STFLW, 3, 1, pCh->channelNeeds);
1772     #endif
1773     						pc += sizeof(flowStat);
1774     						break;
1775     
1776     					/* Special packets: */
1777     					/* Just copy the information into the channel structure */
1778     
1779     					case STAT_STATUS:
1780     
1781     						pCh->channelStatus = *((debugStatPtr)pc);
1782     						pc += sizeof(debugStat);
1783     						break;
1784     
1785     					case STAT_TXCNT:
1786     
1787     						pCh->channelTcount = *((cntStatPtr)pc);
1788     						pc += sizeof(cntStat);
1789     						break;
1790     
1791     					case STAT_RXCNT:
1792     
1793     						pCh->channelRcount = *((cntStatPtr)pc);
1794     						pc += sizeof(cntStat);
1795     						break;
1796     
1797     					case STAT_BOXIDS:
1798     						pB->channelBtypes = *((bidStatPtr)pc);
1799     						pc += sizeof(bidStat);
1800     						set_baud_params(pB);
1801     						break;
1802     
1803     					case STAT_HWFAIL:
1804     						i2QueueCommands (PTYPE_INLINE, pCh, 0, 1, CMD_HW_TEST);
1805     						pCh->channelFail = *((failStatPtr)pc);
1806     						pc += sizeof(failStat);
1807     						break;
1808     
1809     					/* No explicit match? then
1810     					 * Might be an error packet...
1811     					 */
1812     					default:
1813     						switch (uc & STAT_MOD_ERROR)
1814     						{
1815     						case STAT_ERROR:
1816     							if (uc & STAT_E_PARITY) {
1817     								pCh->dataSetIn |= I2_PAR;
1818     								pCh->icount.parity++;
1819     							}
1820     							if (uc & STAT_E_FRAMING){
1821     								pCh->dataSetIn |= I2_FRA;
1822     								pCh->icount.frame++;
1823     							}
1824     							if (uc & STAT_E_OVERRUN){
1825     								pCh->dataSetIn |= I2_OVR;
1826     								pCh->icount.overrun++;
1827     							}
1828     							break;
1829     
1830     						case STAT_MODEM:
1831     							// the answer to DSS_NOW request (not change)
1832     							pCh->dataSetIn = (pCh->dataSetIn
1833     								& ~(I2_RI | I2_CTS | I2_DCD | I2_DSR) )
1834     								| xlatDss[uc & 0xf];
1835     							wake_up_interruptible ( &pCh->dss_now_wait );
1836     						default:
1837     							break;
1838     						}
1839     					}  /* End of switch on status type */
1840     					if (dss_change) {
1841     #ifdef USE_IQ
1842     						queue_task(&pCh->tqueue_status, &tq_immediate);
1843     						mark_bh(IMMEDIATE_BH);
1844     #else
1845     						do_status(pCh);
1846     #endif
1847     					}
1848     				}
1849     				else  /* Or else, channel is invalid */
1850     				{
1851     					// Even though the channel is invalid, we must test the
1852     					// status to see how much additional data it has (to be
1853     					// skipped)
1854     					switch (*pc++)
1855     					{
1856     					case STAT_FLOW:
1857     						pc += 4;    /* Skip the data */
1858     						break;
1859     
1860     					default:
1861     						break;
1862     					}
1863     				}
1864     			}  // End of while (there is still some status packet left)
1865     			break;
1866     
1867     		default: // Neither packet? should be impossible
1868     #ifdef IP2DEBUG_TRACE
1869     			ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 5, 1,
1870     				PTYPE_OF(pB->i2eLeadoffWord) );
1871     #endif
1872     			break;
1873     		}  // End of switch on type of packets
1874     	}	//while(board HAS_INPUT)
1875     #ifdef IP2DEBUG_TRACE
1876     	ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_RETURN, 0 );
1877     #endif
1878     	// Send acknowledgement to the board even if there was no data!
1879     	pB->i2eOutMailWaiting |= MB_IN_STRIPPED;
1880     	return;
1881     }
1882     
1883     //******************************************************************************
1884     // Function:   i2Write2Fifo(pB,address,count)
1885     // Parameters: Pointer to a board structure, source address, byte count
1886     // Returns:    bytes written
1887     //
1888     // Description:
1889     //  Writes count bytes to board io address(implied) from source
1890     //  Adjusts count, leaves reserve for next time around bypass cmds
1891     //******************************************************************************
1892     static int
1893     i2Write2Fifo(i2eBordStrPtr pB, unsigned char *source, int count,int reserve)
1894     {
1895     	int rc = 0;
1896     	unsigned long flags;
1897     	WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
1898     	if (!pB->i2eWaitingForEmptyFifo) {
1899     		if (pB->i2eFifoRemains > (count+reserve)) {
1900     			pB->i2eFifoRemains -= count;
1901     			iiWriteBuf(pB, source, count);
1902     			pB->i2eOutMailWaiting |= MB_OUT_STUFFED;
1903     			rc =  count;
1904     		}
1905     	}
1906     	WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
1907     	return rc;
1908     }
1909     //******************************************************************************
1910     // Function:   i2StuffFifoBypass(pB)
1911     // Parameters: Pointer to a board structure
1912     // Returns:    Nothing
1913     //
1914     // Description:
1915     // Stuffs as many bypass commands into the fifo as possible. This is simpler
1916     // than stuffing data or inline commands to fifo, since we do not have
1917     // flow-control to deal with.
1918     //******************************************************************************
1919     static inline void
1920     i2StuffFifoBypass(i2eBordStrPtr pB)
1921     {
1922     	i2ChanStrPtr pCh;
1923     	unsigned char *pRemove;
1924     	unsigned short stripIndex;
1925     	unsigned short packetSize;
1926     	unsigned short paddedSize;
1927     	unsigned short notClogged = 1;
1928     	unsigned long flags;
1929     
1930     	int bailout = 1000;
1931     
1932     	// Continue processing so long as there are entries, or there is room in the
1933     	// fifo. Each entry represents a channel with something to do.
1934     	while ( --bailout && notClogged && 
1935     			(NULL != (pCh = i2DeQueueNeeds(pB,NEED_BYPASS))))
1936     	{
1937     		WRITE_LOCK_IRQSAVE(&pCh->Cbuf_spinlock,flags);
1938     		stripIndex = pCh->Cbuf_strip;
1939     
1940     		// as long as there are packets for this channel...
1941     
1942     		while (stripIndex != pCh->Cbuf_stuff) {
1943     			pRemove = &(pCh->Cbuf[stripIndex]);
1944     			packetSize = CMD_COUNT_OF(pRemove) + sizeof(i2CmdHeader);
1945     			paddedSize = ROUNDUP(packetSize);
1946     
1947     			if (paddedSize > 0) {
1948     				if ( 0 == i2Write2Fifo(pB, pRemove, paddedSize,0)) {
1949     					notClogged = 0;	/* fifo full */
1950     					i2QueueNeeds(pB, pCh, NEED_BYPASS);	// Put back on queue
1951     					break;   // Break from the channel
1952     				} 
1953     			}
1954     #ifdef DEBUG_FIFO
1955     WriteDBGBuf("BYPS", pRemove, paddedSize);
1956     #endif	/* DEBUG_FIFO */
1957     			pB->debugBypassCount++;
1958     
1959     			pRemove += packetSize;
1960     			stripIndex += packetSize;
1961     			if (stripIndex >= CBUF_SIZE) {
1962     				stripIndex = 0;
1963     				pRemove = pCh->Cbuf;
1964     			}
1965     		}
1966     		// Done with this channel. Move to next, removing this one from 
1967     		// the queue of channels if we cleaned it out (i.e., didn't get clogged.
1968     		pCh->Cbuf_strip = stripIndex;
1969     		WRITE_UNLOCK_IRQRESTORE(&pCh->Cbuf_spinlock,flags);
1970     	}  // Either clogged or finished all the work
1971     
1972     #ifdef IP2DEBUG_TRACE
1973     	if ( !bailout ) {
1974     		ip2trace (ITRC_NO_PORT, ITRC_ERROR, 1, 0 );
1975     	}
1976     #endif
1977     }
1978     
1979     //******************************************************************************
1980     // Function:   i2StuffFifoFlow(pB)
1981     // Parameters: Pointer to a board structure
1982     // Returns:    Nothing
1983     //
1984     // Description:
1985     // Stuffs as many flow control packets into the fifo as possible. This is easier
1986     // even than doing normal bypass commands, because there is always at most one
1987     // packet, already assembled, for each channel.
1988     //******************************************************************************
1989     static inline void
1990     i2StuffFifoFlow(i2eBordStrPtr pB)
1991     {
1992     	i2ChanStrPtr pCh;
1993     	unsigned short paddedSize		= ROUNDUP(sizeof(flowIn));
1994     
1995     #ifdef IP2DEBUG_TRACE
1996     ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_ENTER, 2, pB->i2eFifoRemains, paddedSize );
1997     #endif
1998     
1999     	// Continue processing so long as there are entries, or there is room in the
2000     	// fifo. Each entry represents a channel with something to do.
2001     	while ( (NULL != (pCh = i2DeQueueNeeds(pB,NEED_FLOW)))) {
2002     		pB->debugFlowCount++;
2003     
2004     		// NO Chan LOCK needed ???
2005     		if ( 0 == i2Write2Fifo(pB,(unsigned char *)&(pCh->infl),paddedSize,0)) {
2006     			break;
2007     		}
2008     #ifdef DEBUG_FIFO
2009     WriteDBGBuf("FLOW",(unsigned char *) &(pCh->infl), paddedSize);
2010     #endif /* DEBUG_FIFO */
2011     
2012     	}  // Either clogged or finished all the work
2013     
2014     #ifdef IP2DEBUG_TRACE
2015     	ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_RETURN, 0 );
2016     #endif
2017     }
2018     
2019     //******************************************************************************
2020     // Function:   i2StuffFifoInline(pB)
2021     // Parameters: Pointer to a board structure
2022     // Returns:    Nothing
2023     //
2024     // Description:
2025     // Stuffs as much data and inline commands into the fifo as possible. This is
2026     // the most complex fifo-stuffing operation, since there if now the channel
2027     // flow-control issue to deal with.
2028     //******************************************************************************
2029     static inline void
2030     i2StuffFifoInline(i2eBordStrPtr pB)
2031     {
2032     	i2ChanStrPtr pCh;
2033     	unsigned char *pRemove;
2034     	unsigned short stripIndex;
2035     	unsigned short packetSize;
2036     	unsigned short paddedSize;
2037     	unsigned short notClogged = 1;
2038     	unsigned short flowsize;
2039     	unsigned long flags;
2040     
2041     	int bailout  = 1000;
2042     	int bailout2;
2043     
2044     #ifdef IP2DEBUG_TRACE
2045     	ip2trace (ITRC_NO_PORT, ITRC_SICMD, ITRC_ENTER, 3, pB->i2eFifoRemains, 
2046     			pB->i2Dbuf_strip, pB->i2Dbuf_stuff );
2047     #endif
2048     
2049     	// Continue processing so long as there are entries, or there is room in the
2050     	// fifo. Each entry represents a channel with something to do.
2051     	while ( --bailout && notClogged && 
2052     			(NULL != (pCh = i2DeQueueNeeds(pB,NEED_INLINE))) )
2053     	{
2054     		WRITE_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
2055     		stripIndex = pCh->Obuf_strip;
2056     
2057     #ifdef IP2DEBUG_TRACE
2058     		ip2trace (CHANN, ITRC_SICMD, 3, 2, stripIndex, pCh->Obuf_stuff );
2059     #endif 
2060     		// as long as there are packets for this channel...
2061     		bailout2 = 1000;
2062     		while ( --bailout2 && stripIndex != pCh->Obuf_stuff) {
2063     			pRemove = &(pCh->Obuf[stripIndex]);
2064     
2065     			// Must determine whether this be a data or command packet to
2066     			// calculate correctly the header size and the amount of
2067     			// flow-control credit this type of packet will use.
2068     			if (PTYPE_OF(pRemove) == PTYPE_DATA) {
2069     				flowsize = DATA_COUNT_OF(pRemove);
2070     				packetSize = flowsize + sizeof(i2DataHeader);
2071     			} else {
2072     				flowsize = CMD_COUNT_OF(pRemove);
2073     				packetSize = flowsize + sizeof(i2CmdHeader);
2074     			}
2075     			flowsize = CREDIT_USAGE(flowsize);
2076     			paddedSize = ROUNDUP(packetSize);
2077     
2078     #ifdef IP2DEBUG_TRACE
2079     			ip2trace (CHANN, ITRC_SICMD, 4, 2, pB->i2eFifoRemains, paddedSize );
2080     #endif 
2081     			// If we don't have enough credits from the board to send the data,
2082     			// flag the channel that we are waiting for flow control credit, and
2083     			// break out. This will clean up this channel and remove us from the
2084     			// queue of hot things to do.
2085     #ifdef IP2DEBUG_TRACE
2086     				ip2trace (CHANN, ITRC_SICMD, 5, 2, pCh->outfl.room, flowsize );
2087     #endif 
2088     			if (pCh->outfl.room <= flowsize)	{
2089     				// Do Not have the credits to send this packet.
2090     				i2QueueNeeds(pB, pCh, NEED_CREDIT);
2091     				notClogged = 0;
2092     				break;   // So to do next channel
2093     			}
2094     			if ( (paddedSize > 0) 
2095     				&& ( 0 == i2Write2Fifo(pB, pRemove, paddedSize, 128))) {
2096     				// Do Not have room in fifo to send this packet.
2097     				notClogged = 0;
2098     				i2QueueNeeds(pB, pCh, NEED_INLINE);	
2099     				break;   // Break from the channel
2100     			}
2101     #ifdef DEBUG_FIFO
2102     WriteDBGBuf("DATA", pRemove, paddedSize);
2103     #endif /* DEBUG_FIFO */
2104     			pB->debugInlineCount++;
2105     
2106     			pCh->icount.tx += flowsize;
2107     			// Update current credits
2108     			pCh->outfl.room -= flowsize;
2109     			pCh->outfl.asof += flowsize;
2110     			if (PTYPE_OF(pRemove) == PTYPE_DATA) {
2111     				pCh->Obuf_char_count -= DATA_COUNT_OF(pRemove);
2112     			}
2113     			pRemove += packetSize;
2114     			stripIndex += packetSize;
2115     #ifdef IP2DEBUG_TRACE
2116     			ip2trace (CHANN, ITRC_SICMD, 6, 2, stripIndex, pCh->Obuf_strip);
2117     #endif 
2118     			if (stripIndex >= OBUF_SIZE) {
2119     				stripIndex = 0;
2120     				pRemove = pCh->Obuf;
2121     #ifdef IP2DEBUG_TRACE
2122     				ip2trace (CHANN, ITRC_SICMD, 7, 1, stripIndex );
2123     #endif 
2124     			}
2125     		}	/* while */
2126     		if ( !bailout2 ) {
2127     			ip2trace (CHANN, ITRC_ERROR, 3, 0 );
2128     		}
2129     		// Done with this channel. Move to next, removing this one from the
2130     		// queue of channels if we cleaned it out (i.e., didn't get clogged.
2131     		pCh->Obuf_strip = stripIndex;
2132     		WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
2133     		if ( notClogged )
2134     		{
2135     #ifdef IP2DEBUG_TRACE
2136     			ip2trace (CHANN, ITRC_SICMD, 8, 0 );
2137     #endif
2138     			if ( pCh->pTTY ) {
2139     				ip2_owake(pCh->pTTY);
2140     			}
2141     		}
2142     	}  // Either clogged or finished all the work
2143     #ifdef IP2DEBUG_TRACE
2144     	if ( !bailout ) {
2145     		ip2trace (ITRC_NO_PORT, ITRC_ERROR, 4, 0 );
2146     	}
2147     #endif
2148     
2149     #ifdef IP2DEBUG_TRACE
2150     	ip2trace (ITRC_NO_PORT, ITRC_SICMD, ITRC_RETURN, 1,pB->i2Dbuf_strip);
2151     #endif
2152     }
2153     
2154     //******************************************************************************
2155     // Function:   serviceOutgoingFifo(pB)
2156     // Parameters: Pointer to a board structure
2157     // Returns:    Nothing
2158     //
2159     // Description:
2160     // Helper routine to put data in the outgoing fifo, if we aren't already waiting
2161     // for something to be there. If the fifo has only room for a very little data,
2162     // go head and hit the board with a mailbox hit immediately. Otherwise, it will
2163     // have to happen later in the interrupt processing. Since this routine may be
2164     // called both at interrupt and foreground time, we must turn off interrupts
2165     // during the entire process.
2166     //******************************************************************************
2167     static void
2168     serviceOutgoingFifo(i2eBordStrPtr pB)
2169     {
2170     	// If we aren't currently waiting for the board to empty our fifo, service
2171     	// everything that is pending, in priority order (especially, Bypass before
2172     	// Inline).
2173     	if ( ! pB->i2eWaitingForEmptyFifo )
2174     	{
2175     		i2StuffFifoFlow(pB);
2176     		i2StuffFifoBypass(pB);
2177     		i2StuffFifoInline(pB);
2178     
2179     		iiSendPendingMail(pB);
2180     	} 
2181     }
2182     
2183     //******************************************************************************
2184     // Function:   i2ServiceBoard(pB)
2185     // Parameters: Pointer to a board structure
2186     // Returns:    Nothing
2187     //
2188     // Description:
2189     // Normally this is called from interrupt level, but there is deliberately
2190     // nothing in here specific to being called from interrupt level. All the
2191     // hardware-specific, interrupt-specific things happen at the outer levels.
2192     //
2193     // For example, a timer interrupt could drive this routine for some sort of
2194     // polled operation. The only requirement is that the programmer deal with any
2195     // atomiticity/concurrency issues that result.
2196     //
2197     // This routine responds to the board's having sent mailbox information to the
2198     // host (which would normally cause an interrupt). This routine reads the
2199     // incoming mailbox. If there is no data in it, this board did not create the
2200     // interrupt and/or has nothing to be done to it. (Except, if we have been
2201     // waiting to write mailbox data to it, we may do so.
2202     //
2203     // Based on the value in the mailbox, we may take various actions.
2204     //
2205     // No checking here of pB validity: after all, it shouldn't have been called by
2206     // the handler unless pB were on the list.
2207     //******************************************************************************
2208     static inline int
2209     i2ServiceBoard ( i2eBordStrPtr pB )
2210     {
2211     	unsigned inmail;
2212     	unsigned long flags;
2213     
2214     
2215     	inmail = iiGetMail(pB);
2216     
2217     #ifdef IP2DEBUG_TRACE
2218     	ip2trace (ITRC_NO_PORT, ITRC_INTR, 2, 1, inmail );
2219     #endif
2220     
2221     	if (inmail != NO_MAIL_HERE) {
2222     		// If the board has gone fatal, nothing to do but hit a bit that will
2223     		// alert foreground tasks to protest!
2224     		if ( inmail & MB_FATAL_ERROR ) {
2225     			pB->i2eFatal = 1;
2226     			goto exit_i2ServiceBoard;
2227     		}
2228     
2229     		/* Assuming no fatal condition, we proceed to do work */
2230     		if ( inmail & MB_IN_STUFFED ) {
2231     			pB->i2eFifoInInts++;
2232     			i2StripFifo(pB);     /* There might be incoming packets */
2233     		}
2234     
2235     		if (inmail & MB_OUT_STRIPPED) {
2236     			pB->i2eFifoOutInts++;
2237     			WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
2238     			pB->i2eFifoRemains = pB->i2eFifoSize;
2239     			pB->i2eWaitingForEmptyFifo = 0;
2240     			WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
2241     #ifdef IP2DEBUG_TRACE
2242     		ip2trace (ITRC_NO_PORT, ITRC_INTR, 30, 1, pB->i2eFifoRemains );
2243     #endif
2244     		}
2245     		serviceOutgoingFifo(pB);
2246     	}
2247     
2248     #ifdef IP2DEBUG_TRACE
2249     	ip2trace (ITRC_NO_PORT, ITRC_INTR, 8, 0 );
2250     #endif
2251     
2252     exit_i2ServiceBoard:
2253     
2254     	return 0;
2255     }
2256