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