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