PageRenderTime 82ms CodeModel.GetById 10ms app.highlight 59ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/char/ip2/i2lib.c

https://bitbucket.org/evzijst/gittest
C | 2219 lines | 1324 code | 338 blank | 557 comment | 236 complexity | a60aea5df7e3c384238c5cd0c46ed4aa MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   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//***********************
  72static void i2QueueNeeds(i2eBordStrPtr, i2ChanStrPtr, int);
  73static i2ChanStrPtr i2DeQueueNeeds(i2eBordStrPtr, int );
  74static void i2StripFifo(i2eBordStrPtr);
  75static void i2StuffFifoBypass(i2eBordStrPtr);
  76static void i2StuffFifoFlow(i2eBordStrPtr);
  77static void i2StuffFifoInline(i2eBordStrPtr);
  78static 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.
  83static void iiSendPendingMail(i2eBordStrPtr);
  84static void serviceOutgoingFifo(i2eBordStrPtr);
  85
  86// Functions defined in ip2.c as part of interrupt handling
  87static void do_input(void *);
  88static void do_status(void *);
  89
  90//***************
  91//* Debug  Data *
  92//***************
  93#ifdef DEBUG_FIFO
  94
  95unsigned char DBGBuf[0x4000];
  96unsigned short I = 0;
  97
  98static void
  99WriteDBGBuf(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
 115static void
 116fatality(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
 144static inline int
 145i2Validate ( 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//******************************************************************************
 162static inline void
 163iiSendPendingMail(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			pB->SendPendingRetry = 0;
 178		} else {
 179/*		The only time we hit this area is when "iiTrySendMail" has
 180		failed.  That only occurs when the outbound mailbox is
 181		still busy with the last message.  We take a short breather
 182		to let the board catch up with itself and then try again.
 183		16 Retries is the limit - then we got a borked board.
 184			/\/\|=mhw=|\/\/				*/
 185
 186			if( ++pB->SendPendingRetry < 16 ) {
 187
 188				init_timer( &(pB->SendPendingTimer) );
 189				pB->SendPendingTimer.expires  = jiffies + 1;
 190				pB->SendPendingTimer.function = (void*)(unsigned long)iiSendPendingMail;
 191				pB->SendPendingTimer.data     = (unsigned long)pB;
 192				add_timer( &(pB->SendPendingTimer) );
 193			} else {
 194				printk( KERN_ERR "IP2: iiSendPendingMail unable to queue outbound mail\n" );
 195			}
 196		}
 197	}
 198}
 199
 200//******************************************************************************
 201// Function:   i2InitChannels(pB, nChannels, pCh)
 202// Parameters: Pointer to Ellis Board structure
 203//             Number of channels to initialize
 204//             Pointer to first element in an array of channel structures
 205// Returns:    Success or failure
 206//
 207// Description:
 208//
 209// This function patches pointers, back-pointers, and initializes all the
 210// elements in the channel structure array.
 211//
 212// This should be run after the board structure is initialized, through having
 213// loaded the standard loadware (otherwise it complains).
 214//
 215// In any case, it must be done before any serious work begins initializing the
 216// irq's or sending commands...
 217//
 218//******************************************************************************
 219static int
 220i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh)
 221{
 222	int index, stuffIndex;
 223	i2ChanStrPtr *ppCh;
 224	
 225	if (pB->i2eValid != I2E_MAGIC) {
 226		COMPLETE(pB, I2EE_BADMAGIC);
 227	}
 228	if (pB->i2eState != II_STATE_STDLOADED) {
 229		COMPLETE(pB, I2EE_BADSTATE);
 230	}
 231
 232	LOCK_INIT(&pB->read_fifo_spinlock);
 233	LOCK_INIT(&pB->write_fifo_spinlock);
 234	LOCK_INIT(&pB->Dbuf_spinlock);
 235	LOCK_INIT(&pB->Bbuf_spinlock);
 236	LOCK_INIT(&pB->Fbuf_spinlock);
 237	
 238	// NO LOCK needed yet - this is init
 239
 240	pB->i2eChannelPtr = pCh;
 241	pB->i2eChannelCnt = nChannels;
 242
 243	pB->i2Fbuf_strip = pB->i2Fbuf_stuff = 0;
 244	pB->i2Dbuf_strip = pB->i2Dbuf_stuff = 0;
 245	pB->i2Bbuf_strip = pB->i2Bbuf_stuff = 0;
 246
 247	pB->SendPendingRetry = 0;
 248
 249	memset ( pCh, 0, sizeof (i2ChanStr) * nChannels );
 250
 251	for (index = stuffIndex = 0, ppCh = (i2ChanStrPtr *)(pB->i2Fbuf);
 252		  nChannels && index < ABS_MOST_PORTS;
 253		  index++)
 254	{
 255		if ( !(pB->i2eChannelMap[index >> 4] & (1 << (index & 0xf)) ) ) {
 256			continue;
 257		}
 258		LOCK_INIT(&pCh->Ibuf_spinlock);
 259		LOCK_INIT(&pCh->Obuf_spinlock);
 260		LOCK_INIT(&pCh->Cbuf_spinlock);
 261		LOCK_INIT(&pCh->Pbuf_spinlock);
 262		// NO LOCK needed yet - this is init
 263		// Set up validity flag according to support level
 264		if (pB->i2eGoodMap[index >> 4] & (1 << (index & 0xf)) ) {
 265			pCh->validity = CHANNEL_MAGIC | CHANNEL_SUPPORT;
 266		} else {
 267			pCh->validity = CHANNEL_MAGIC;
 268		}
 269		pCh->pMyBord = pB;      /* Back-pointer */
 270
 271		// Prepare an outgoing flow-control packet to send as soon as the chance
 272		// occurs.
 273		if ( pCh->validity & CHANNEL_SUPPORT ) {
 274			pCh->infl.hd.i2sChannel = index;
 275			pCh->infl.hd.i2sCount = 5;
 276			pCh->infl.hd.i2sType = PTYPE_BYPASS;
 277			pCh->infl.fcmd = 37;
 278			pCh->infl.asof = 0;
 279			pCh->infl.room = IBUF_SIZE - 1;
 280
 281			pCh->whenSendFlow = (IBUF_SIZE/5)*4; // when 80% full
 282
 283		// The following is similar to calling i2QueueNeeds, except that this
 284		// is done in longhand, since we are setting up initial conditions on
 285		// many channels at once.
 286			pCh->channelNeeds = NEED_FLOW;  // Since starting from scratch
 287			pCh->sinceLastFlow = 0;         // No bytes received since last flow
 288											// control packet was queued
 289			stuffIndex++;
 290			*ppCh++ = pCh;      // List this channel as needing
 291								// initial flow control packet sent
 292		}
 293
 294		// Don't allow anything to be sent until the status packets come in from
 295		// the board.
 296
 297		pCh->outfl.asof = 0;
 298		pCh->outfl.room = 0;
 299
 300		// Initialize all the ring buffers
 301
 302		pCh->Ibuf_stuff = pCh->Ibuf_strip = 0;
 303		pCh->Obuf_stuff = pCh->Obuf_strip = 0;
 304		pCh->Cbuf_stuff = pCh->Cbuf_strip = 0;
 305
 306		memset( &pCh->icount, 0, sizeof (struct async_icount) );
 307		pCh->hotKeyIn       = HOT_CLEAR;
 308		pCh->channelOptions = 0;
 309		pCh->bookMarks      = 0;
 310		init_waitqueue_head(&pCh->pBookmarkWait);
 311
 312		init_waitqueue_head(&pCh->open_wait);
 313		init_waitqueue_head(&pCh->close_wait);
 314		init_waitqueue_head(&pCh->delta_msr_wait);
 315
 316		// Set base and divisor so default custom rate is 9600
 317		pCh->BaudBase    = 921600;	// MAX for ST654, changed after we get
 318		pCh->BaudDivisor = 96;		// the boxids (UART types) later
 319
 320		pCh->dataSetIn   = 0;
 321		pCh->dataSetOut  = 0;
 322
 323		pCh->wopen       = 0;
 324		pCh->throttled   = 0;
 325
 326		pCh->speed       = CBR_9600;
 327
 328		pCh->flags    = 0;
 329
 330		pCh->ClosingDelay     = 5*HZ/10;
 331		pCh->ClosingWaitTime  = 30*HZ;
 332
 333		// Initialize task queue objects
 334		INIT_WORK(&pCh->tqueue_input, do_input, pCh);
 335		INIT_WORK(&pCh->tqueue_status, do_status, pCh);
 336
 337#ifdef IP2DEBUG_TRACE
 338		pCh->trace = ip2trace;
 339#endif
 340
 341		++pCh;
 342     	--nChannels;
 343	}
 344	// No need to check for wrap here; this is initialization.
 345	pB->i2Fbuf_stuff = stuffIndex;
 346	COMPLETE(pB, I2EE_GOOD);
 347
 348}
 349
 350//******************************************************************************
 351// Function:   i2DeQueueNeeds(pB, type)
 352// Parameters: Pointer to a board structure
 353//             type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW
 354// Returns:   
 355//             Pointer to a channel structure
 356//
 357// Description: Returns pointer struct of next channel that needs service of
 358//  the type specified. Otherwise returns a NULL reference.
 359//
 360//******************************************************************************
 361static i2ChanStrPtr 
 362i2DeQueueNeeds(i2eBordStrPtr pB, int type)
 363{
 364	unsigned short queueIndex;
 365	unsigned long flags;
 366
 367	i2ChanStrPtr pCh = NULL;
 368
 369	switch(type) {
 370
 371	case  NEED_INLINE:
 372
 373		WRITE_LOCK_IRQSAVE(&pB->Dbuf_spinlock,flags);
 374		if ( pB->i2Dbuf_stuff != pB->i2Dbuf_strip)
 375		{
 376			queueIndex = pB->i2Dbuf_strip;
 377			pCh = pB->i2Dbuf[queueIndex];
 378			queueIndex++;
 379			if (queueIndex >= CH_QUEUE_SIZE) {
 380				queueIndex = 0;
 381			}
 382			pB->i2Dbuf_strip = queueIndex;
 383			pCh->channelNeeds &= ~NEED_INLINE;
 384		}
 385		WRITE_UNLOCK_IRQRESTORE(&pB->Dbuf_spinlock,flags); 
 386		break;
 387
 388	case NEED_BYPASS:
 389
 390		WRITE_LOCK_IRQSAVE(&pB->Bbuf_spinlock,flags);
 391		if (pB->i2Bbuf_stuff != pB->i2Bbuf_strip)
 392		{
 393			queueIndex = pB->i2Bbuf_strip;
 394			pCh = pB->i2Bbuf[queueIndex];
 395			queueIndex++;
 396			if (queueIndex >= CH_QUEUE_SIZE) {
 397				queueIndex = 0;
 398			}
 399			pB->i2Bbuf_strip = queueIndex;
 400			pCh->channelNeeds &= ~NEED_BYPASS;
 401		}
 402		WRITE_UNLOCK_IRQRESTORE(&pB->Bbuf_spinlock,flags); 
 403		break;
 404	
 405	case NEED_FLOW:
 406
 407		WRITE_LOCK_IRQSAVE(&pB->Fbuf_spinlock,flags);
 408		if (pB->i2Fbuf_stuff != pB->i2Fbuf_strip)
 409		{
 410			queueIndex = pB->i2Fbuf_strip;
 411			pCh = pB->i2Fbuf[queueIndex];
 412			queueIndex++;
 413			if (queueIndex >= CH_QUEUE_SIZE) {
 414				queueIndex = 0;
 415			}
 416			pB->i2Fbuf_strip = queueIndex;
 417			pCh->channelNeeds &= ~NEED_FLOW;
 418		}
 419		WRITE_UNLOCK_IRQRESTORE(&pB->Fbuf_spinlock,flags); 
 420		break;
 421	default:
 422		printk(KERN_ERR "i2DeQueueNeeds called with bad type:%x\n",type);
 423		break;
 424	}
 425	return pCh;
 426}
 427
 428//******************************************************************************
 429// Function:   i2QueueNeeds(pB, pCh, type)
 430// Parameters: Pointer to a board structure
 431//             Pointer to a channel structure
 432//             type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW
 433// Returns:    Nothing
 434//
 435// Description:
 436// For each type of need selected, if the given channel is not already in the
 437// queue, adds it, and sets the flag indicating it is in the queue.
 438//******************************************************************************
 439static void
 440i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type)
 441{
 442	unsigned short queueIndex;
 443	unsigned long flags;
 444
 445	// We turn off all the interrupts during this brief process, since the
 446	// interrupt-level code might want to put things on the queue as well.
 447
 448	switch (type) {
 449
 450	case NEED_INLINE:
 451
 452		WRITE_LOCK_IRQSAVE(&pB->Dbuf_spinlock,flags);
 453		if ( !(pCh->channelNeeds & NEED_INLINE) )
 454		{
 455			pCh->channelNeeds |= NEED_INLINE;
 456			queueIndex = pB->i2Dbuf_stuff;
 457			pB->i2Dbuf[queueIndex++] = pCh;
 458			if (queueIndex >= CH_QUEUE_SIZE)
 459				queueIndex = 0;
 460			pB->i2Dbuf_stuff = queueIndex;
 461		}
 462		WRITE_UNLOCK_IRQRESTORE(&pB->Dbuf_spinlock,flags); 
 463		break;
 464
 465	case NEED_BYPASS:
 466
 467		WRITE_LOCK_IRQSAVE(&pB->Bbuf_spinlock,flags);
 468		if ((type & NEED_BYPASS) && !(pCh->channelNeeds & NEED_BYPASS))
 469		{
 470			pCh->channelNeeds |= NEED_BYPASS;
 471			queueIndex = pB->i2Bbuf_stuff;
 472			pB->i2Bbuf[queueIndex++] = pCh;
 473			if (queueIndex >= CH_QUEUE_SIZE)
 474				queueIndex = 0;
 475			pB->i2Bbuf_stuff = queueIndex;
 476		} 
 477		WRITE_UNLOCK_IRQRESTORE(&pB->Bbuf_spinlock,flags); 
 478		break;
 479
 480	case NEED_FLOW:
 481
 482		WRITE_LOCK_IRQSAVE(&pB->Fbuf_spinlock,flags);
 483		if ((type & NEED_FLOW) && !(pCh->channelNeeds & NEED_FLOW))
 484		{
 485			pCh->channelNeeds |= NEED_FLOW;
 486			queueIndex = pB->i2Fbuf_stuff;
 487			pB->i2Fbuf[queueIndex++] = pCh;
 488			if (queueIndex >= CH_QUEUE_SIZE)
 489				queueIndex = 0;
 490			pB->i2Fbuf_stuff = queueIndex;
 491		}
 492		WRITE_UNLOCK_IRQRESTORE(&pB->Fbuf_spinlock,flags); 
 493		break;
 494
 495	case NEED_CREDIT:
 496		pCh->channelNeeds |= NEED_CREDIT;
 497		break;
 498	default:
 499		printk(KERN_ERR "i2QueueNeeds called with bad type:%x\n",type);
 500		break;
 501	}
 502	return;
 503}
 504
 505//******************************************************************************
 506// Function:   i2QueueCommands(type, pCh, timeout, nCommands, pCs,...)
 507// Parameters: type - PTYPE_BYPASS or PTYPE_INLINE
 508//             pointer to the channel structure
 509//             maximum period to wait
 510//             number of commands (n)
 511//             n commands
 512// Returns:    Number of commands sent, or -1 for error
 513//
 514// get board lock before calling
 515//
 516// Description:
 517// Queues up some commands to be sent to a channel. To send possibly several
 518// bypass or inline commands to the given channel. The timeout parameter
 519// indicates how many HUNDREDTHS OF SECONDS to wait until there is room:
 520// 0 = return immediately if no room, -ive  = wait forever, +ive = number of
 521// 1/100 seconds to wait. Return values:
 522// -1 Some kind of nasty error: bad channel structure or invalid arguments.
 523//  0 No room to send all the commands
 524// (+)   Number of commands sent
 525//******************************************************************************
 526static int
 527i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands,
 528					 cmdSyntaxPtr pCs0,...)
 529{
 530	int totalsize = 0;
 531	int blocksize;
 532	int lastended;
 533	cmdSyntaxPtr *ppCs;
 534	cmdSyntaxPtr pCs;
 535	int count;
 536	int flag;
 537	i2eBordStrPtr pB;
 538
 539	unsigned short maxBlock;
 540	unsigned short maxBuff;
 541	short bufroom;
 542	unsigned short stuffIndex;
 543	unsigned char *pBuf;
 544	unsigned char *pInsert;
 545	unsigned char *pDest, *pSource;
 546	unsigned short channel;
 547	int cnt;
 548	unsigned long flags = 0;
 549	rwlock_t *lock_var_p = NULL;
 550
 551	// Make sure the channel exists, otherwise do nothing
 552	if ( !i2Validate ( pCh ) ) {
 553		return -1;
 554	}
 555
 556	ip2trace (CHANN, ITRC_QUEUE, ITRC_ENTER, 0 );
 557
 558	pB = pCh->pMyBord;
 559
 560	// Board must also exist, and THE INTERRUPT COMMAND ALREADY SENT
 561	if (pB->i2eValid != I2E_MAGIC || pB->i2eUsingIrq == IRQ_UNDEFINED) {
 562		return -2;
 563	}
 564	// If the board has gone fatal, return bad, and also hit the trap routine if
 565	// it exists.
 566	if (pB->i2eFatal) {
 567		if ( pB->i2eFatalTrap ) {
 568			(*(pB)->i2eFatalTrap)(pB);
 569		}
 570		return -3;
 571	}
 572	// Set up some variables, Which buffers are we using?  How big are they?
 573	switch(type)
 574	{
 575	case PTYPE_INLINE:
 576		flag = INL;
 577		maxBlock = MAX_OBUF_BLOCK;
 578		maxBuff = OBUF_SIZE;
 579		pBuf = pCh->Obuf;
 580		break;
 581	case PTYPE_BYPASS:
 582		flag = BYP;
 583		maxBlock = MAX_CBUF_BLOCK;
 584		maxBuff = CBUF_SIZE;
 585		pBuf = pCh->Cbuf;
 586		break;
 587	default:
 588		return -4;
 589	}
 590	// Determine the total size required for all the commands
 591	totalsize = blocksize = sizeof(i2CmdHeader);
 592	lastended = 0;
 593	ppCs = &pCs0;
 594	for ( count = nCommands; count; count--, ppCs++)
 595	{
 596		pCs = *ppCs;
 597		cnt = pCs->length;
 598		// Will a new block be needed for this one? 
 599		// Two possible reasons: too
 600		// big or previous command has to be at the end of a packet.
 601		if ((blocksize + cnt > maxBlock) || lastended) {
 602			blocksize = sizeof(i2CmdHeader);
 603			totalsize += sizeof(i2CmdHeader);
 604		}
 605		totalsize += cnt;
 606		blocksize += cnt;
 607
 608		// If this command had to end a block, then we will make sure to
 609		// account for it should there be any more blocks.
 610		lastended = pCs->flags & END;
 611	}
 612	for (;;) {
 613		// Make sure any pending flush commands go out before we add more data.
 614		if ( !( pCh->flush_flags && i2RetryFlushOutput( pCh ) ) ) {
 615			// How much room (this time through) ?
 616			switch(type) {
 617			case PTYPE_INLINE:
 618				lock_var_p = &pCh->Obuf_spinlock;
 619				WRITE_LOCK_IRQSAVE(lock_var_p,flags);
 620				stuffIndex = pCh->Obuf_stuff;
 621				bufroom = pCh->Obuf_strip - stuffIndex;
 622				break;
 623			case PTYPE_BYPASS:
 624				lock_var_p = &pCh->Cbuf_spinlock;
 625				WRITE_LOCK_IRQSAVE(lock_var_p,flags);
 626				stuffIndex = pCh->Cbuf_stuff;
 627				bufroom = pCh->Cbuf_strip - stuffIndex;
 628				break;
 629			default:
 630				return -5;
 631			}
 632			if (--bufroom < 0) {
 633				bufroom += maxBuff;
 634			}
 635
 636			ip2trace (CHANN, ITRC_QUEUE, 2, 1, bufroom );
 637
 638			// Check for overflow
 639			if (totalsize <= bufroom) {
 640				// Normal Expected path - We still hold LOCK
 641				break; /* from for()- Enough room: goto proceed */
 642			}
 643		}
 644
 645		ip2trace (CHANN, ITRC_QUEUE, 3, 1, totalsize );
 646
 647		// Prepare to wait for buffers to empty
 648		WRITE_UNLOCK_IRQRESTORE(lock_var_p,flags); 
 649		serviceOutgoingFifo(pB);	// Dump what we got
 650
 651		if (timeout == 0) {
 652			return 0;   // Tired of waiting
 653		}
 654		if (timeout > 0)
 655			timeout--;   // So negative values == forever
 656		
 657		if (!in_interrupt()) {
 658			current->state = TASK_INTERRUPTIBLE;
 659			schedule_timeout(1);	// short nap 
 660		} else {
 661			// we cannot sched/sleep in interrrupt silly
 662			return 0;   
 663		}
 664		if (signal_pending(current)) {
 665			return 0;   // Wake up! Time to die!!!
 666		}
 667
 668		ip2trace (CHANN, ITRC_QUEUE, 4, 0 );
 669
 670	}	// end of for(;;)
 671
 672	// At this point we have room and the lock - stick them in.
 673	channel = pCh->infl.hd.i2sChannel;
 674	pInsert = &pBuf[stuffIndex];     // Pointer to start of packet
 675	pDest = CMD_OF(pInsert);         // Pointer to start of command
 676
 677	// When we start counting, the block is the size of the header
 678	for (blocksize = sizeof(i2CmdHeader), count = nCommands,
 679			lastended = 0, ppCs = &pCs0;
 680		count;
 681		count--, ppCs++)
 682	{
 683		pCs = *ppCs;         // Points to command protocol structure
 684
 685		// If this is a bookmark request command, post the fact that a bookmark
 686		// request is pending. NOTE THIS TRICK ONLY WORKS BECAUSE CMD_BMARK_REQ
 687		// has no parameters!  The more general solution would be to reference
 688		// pCs->cmd[0].
 689		if (pCs == CMD_BMARK_REQ) {
 690			pCh->bookMarks++;
 691
 692			ip2trace (CHANN, ITRC_DRAIN, 30, 1, pCh->bookMarks );
 693
 694		}
 695		cnt = pCs->length;
 696
 697		// If this command would put us over the maximum block size or 
 698		// if the last command had to be at the end of a block, we end
 699		// the existing block here and start a new one.
 700		if ((blocksize + cnt > maxBlock) || lastended) {
 701
 702			ip2trace (CHANN, ITRC_QUEUE, 5, 0 );
 703
 704			PTYPE_OF(pInsert) = type;
 705			CHANNEL_OF(pInsert) = channel;
 706			// count here does not include the header
 707			CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader);
 708			stuffIndex += blocksize;
 709			if(stuffIndex >= maxBuff) {
 710				stuffIndex = 0;
 711				pInsert = pBuf;
 712			}
 713			pInsert = &pBuf[stuffIndex];  // Pointer to start of next pkt
 714			pDest = CMD_OF(pInsert);
 715			blocksize = sizeof(i2CmdHeader);
 716		}
 717		// Now we know there is room for this one in the current block
 718
 719		blocksize += cnt;       // Total bytes in this command
 720		pSource = pCs->cmd;     // Copy the command into the buffer
 721		while (cnt--) {
 722			*pDest++ = *pSource++;
 723		}
 724		// If this command had to end a block, then we will make sure to account
 725		// for it should there be any more blocks.
 726		lastended = pCs->flags & END;
 727	}	// end for
 728	// Clean up the final block by writing header, etc
 729
 730	PTYPE_OF(pInsert) = type;
 731	CHANNEL_OF(pInsert) = channel;
 732	// count here does not include the header
 733	CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader);
 734	stuffIndex += blocksize;
 735	if(stuffIndex >= maxBuff) {
 736		stuffIndex = 0;
 737		pInsert = pBuf;
 738	}
 739	// Updates the index, and post the need for service. When adding these to
 740	// the queue of channels, we turn off the interrupt while doing so,
 741	// because at interrupt level we might want to push a channel back to the
 742	// end of the queue.
 743	switch(type)
 744	{
 745	case PTYPE_INLINE:
 746		pCh->Obuf_stuff = stuffIndex;  // Store buffer pointer
 747		WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags); 
 748
 749		pB->debugInlineQueued++;
 750		// Add the channel pointer to list of channels needing service (first
 751		// come...), if it's not already there.
 752		i2QueueNeeds(pB, pCh, NEED_INLINE);
 753		break;
 754
 755	case PTYPE_BYPASS:
 756		pCh->Cbuf_stuff = stuffIndex;  // Store buffer pointer
 757		WRITE_UNLOCK_IRQRESTORE(&pCh->Cbuf_spinlock,flags); 
 758
 759		pB->debugBypassQueued++;
 760		// Add the channel pointer to list of channels needing service (first
 761		// come...), if it's not already there.
 762		i2QueueNeeds(pB, pCh, NEED_BYPASS);
 763		break;
 764	}
 765
 766	ip2trace (CHANN, ITRC_QUEUE, ITRC_RETURN, 1, nCommands );
 767
 768	return nCommands; // Good status: number of commands sent
 769}
 770
 771//******************************************************************************
 772// Function:   i2GetStatus(pCh,resetBits)
 773// Parameters: Pointer to a channel structure
 774//             Bit map of status bits to clear
 775// Returns:    Bit map of current status bits
 776//
 777// Description:
 778// Returns the state of data set signals, and whether a break has been received,
 779// (see i2lib.h for bit-mapped result). resetBits is a bit-map of any status
 780// bits to be cleared: I2_BRK, I2_PAR, I2_FRA, I2_OVR,... These are cleared
 781// AFTER the condition is passed. If pCh does not point to a valid channel,
 782// returns -1 (which would be impossible otherwise.
 783//******************************************************************************
 784static int
 785i2GetStatus(i2ChanStrPtr pCh, int resetBits)
 786{
 787	unsigned short status;
 788	i2eBordStrPtr pB;
 789
 790	ip2trace (CHANN, ITRC_STATUS, ITRC_ENTER, 2, pCh->dataSetIn, resetBits );
 791
 792	// Make sure the channel exists, otherwise do nothing */
 793	if ( !i2Validate ( pCh ) )
 794		return -1;
 795
 796	pB = pCh->pMyBord;
 797
 798	status = pCh->dataSetIn;
 799
 800	// Clear any specified error bits: but note that only actual error bits can
 801	// be cleared, regardless of the value passed.
 802	if (resetBits)
 803	{
 804		pCh->dataSetIn &= ~(resetBits & (I2_BRK | I2_PAR | I2_FRA | I2_OVR));
 805		pCh->dataSetIn &= ~(I2_DDCD | I2_DCTS | I2_DDSR | I2_DRI);
 806	}
 807
 808	ip2trace (CHANN, ITRC_STATUS, ITRC_RETURN, 1, pCh->dataSetIn );
 809
 810	return status;
 811}
 812
 813//******************************************************************************
 814// Function:   i2Input(pChpDest,count)
 815// Parameters: Pointer to a channel structure
 816//             Pointer to data buffer
 817//             Number of bytes to read
 818// Returns:    Number of bytes read, or -1 for error
 819//
 820// Description:
 821// Strips data from the input buffer and writes it to pDest. If there is a
 822// collosal blunder, (invalid structure pointers or the like), returns -1.
 823// Otherwise, returns the number of bytes read.
 824//******************************************************************************
 825static int
 826i2Input(i2ChanStrPtr pCh)
 827{
 828	int amountToMove;
 829	unsigned short stripIndex;
 830	int count;
 831	unsigned long flags = 0;
 832
 833	ip2trace (CHANN, ITRC_INPUT, ITRC_ENTER, 0);
 834
 835	// Ensure channel structure seems real
 836	if ( !i2Validate( pCh ) ) {
 837		count = -1;
 838		goto i2Input_exit;
 839	}
 840	WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
 841
 842	// initialize some accelerators and private copies
 843	stripIndex = pCh->Ibuf_strip;
 844
 845	count = pCh->Ibuf_stuff - stripIndex;
 846
 847	// If buffer is empty or requested data count was 0, (trivial case) return
 848	// without any further thought.
 849	if ( count == 0 ) {
 850		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
 851		goto i2Input_exit;
 852	}
 853	// Adjust for buffer wrap
 854	if ( count < 0 ) {
 855		count += IBUF_SIZE;
 856	}
 857	// Don't give more than can be taken by the line discipline
 858	amountToMove = pCh->pTTY->ldisc.receive_room( pCh->pTTY );
 859	if (count > amountToMove) {
 860		count = amountToMove;
 861	}
 862	// How much could we copy without a wrap?
 863	amountToMove = IBUF_SIZE - stripIndex;
 864
 865	if (amountToMove > count) {
 866		amountToMove = count;
 867	}
 868	// Move the first block
 869	pCh->pTTY->ldisc.receive_buf( pCh->pTTY, 
 870		 &(pCh->Ibuf[stripIndex]), NULL, amountToMove );
 871	// If we needed to wrap, do the second data move
 872	if (count > amountToMove) {
 873		pCh->pTTY->ldisc.receive_buf( pCh->pTTY, 
 874		 pCh->Ibuf, NULL, count - amountToMove );
 875	}
 876	// Bump and wrap the stripIndex all at once by the amount of data read. This
 877	// method is good regardless of whether the data was in one or two pieces.
 878	stripIndex += count;
 879	if (stripIndex >= IBUF_SIZE) {
 880		stripIndex -= IBUF_SIZE;
 881	}
 882	pCh->Ibuf_strip = stripIndex;
 883
 884	// Update our flow control information and possibly queue ourselves to send
 885	// it, depending on how much data has been stripped since the last time a
 886	// packet was sent.
 887	pCh->infl.asof += count;
 888
 889	if ((pCh->sinceLastFlow += count) >= pCh->whenSendFlow) {
 890		pCh->sinceLastFlow -= pCh->whenSendFlow;
 891		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
 892		i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW);
 893	} else {
 894		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
 895	}
 896
 897i2Input_exit:
 898
 899	ip2trace (CHANN, ITRC_INPUT, ITRC_RETURN, 1, count);
 900
 901	return count;
 902}
 903
 904//******************************************************************************
 905// Function:   i2InputFlush(pCh)
 906// Parameters: Pointer to a channel structure
 907// Returns:    Number of bytes stripped, or -1 for error
 908//
 909// Description:
 910// Strips any data from the input buffer. If there is a collosal blunder,
 911// (invalid structure pointers or the like), returns -1. Otherwise, returns the
 912// number of bytes stripped.
 913//******************************************************************************
 914static int
 915i2InputFlush(i2ChanStrPtr pCh)
 916{
 917	int count;
 918	unsigned long flags;
 919
 920	// Ensure channel structure seems real
 921	if ( !i2Validate ( pCh ) )
 922		return -1;
 923
 924	ip2trace (CHANN, ITRC_INPUT, 10, 0);
 925
 926	WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
 927	count = pCh->Ibuf_stuff - pCh->Ibuf_strip;
 928
 929	// Adjust for buffer wrap
 930	if (count < 0) {
 931		count += IBUF_SIZE;
 932	}
 933
 934	// Expedient way to zero out the buffer
 935	pCh->Ibuf_strip = pCh->Ibuf_stuff;
 936
 937
 938	// Update our flow control information and possibly queue ourselves to send
 939	// it, depending on how much data has been stripped since the last time a
 940	// packet was sent.
 941
 942	pCh->infl.asof += count;
 943
 944	if ( (pCh->sinceLastFlow += count) >= pCh->whenSendFlow )
 945	{
 946		pCh->sinceLastFlow -= pCh->whenSendFlow;
 947		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
 948		i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW);
 949	} else {
 950		WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
 951	}
 952
 953	ip2trace (CHANN, ITRC_INPUT, 19, 1, count);
 954
 955	return count;
 956}
 957
 958//******************************************************************************
 959// Function:   i2InputAvailable(pCh)
 960// Parameters: Pointer to a channel structure
 961// Returns:    Number of bytes available, or -1 for error
 962//
 963// Description:
 964// If there is a collosal blunder, (invalid structure pointers or the like),
 965// returns -1. Otherwise, returns the number of bytes stripped. Otherwise,
 966// returns the number of bytes available in the buffer.
 967//******************************************************************************
 968#if 0
 969static int
 970i2InputAvailable(i2ChanStrPtr pCh)
 971{
 972	int count;
 973
 974	// Ensure channel structure seems real
 975	if ( !i2Validate ( pCh ) ) return -1;
 976
 977
 978	// initialize some accelerators and private copies
 979	READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
 980	count = pCh->Ibuf_stuff - pCh->Ibuf_strip;
 981	READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
 982
 983	// Adjust for buffer wrap
 984	if (count < 0)
 985	{
 986		count += IBUF_SIZE;
 987	}
 988
 989	return count;
 990}
 991#endif 
 992
 993//******************************************************************************
 994// Function:   i2Output(pCh, pSource, count)
 995// Parameters: Pointer to channel structure
 996//             Pointer to source data
 997//             Number of bytes to send
 998// Returns:    Number of bytes sent, or -1 for error
 999//
1000// Description:
1001// Queues the data at pSource to be sent as data packets to the board. If there
1002// is a collosal blunder, (invalid structure pointers or the like), returns -1.
1003// Otherwise, returns the number of bytes written. What if there is not enough
1004// room for all the data? If pCh->channelOptions & CO_NBLOCK_WRITE is set, then
1005// we transfer as many characters as we can now, then return. If this bit is
1006// clear (default), routine will spin along until all the data is buffered.
1007// Should this occur, the 1-ms delay routine is called while waiting to avoid
1008// applications that one cannot break out of.
1009//******************************************************************************
1010static int
1011i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user )
1012{
1013	i2eBordStrPtr pB;
1014	unsigned char *pInsert;
1015	int amountToMove;
1016	int countOriginal = count;
1017	unsigned short channel;
1018	unsigned short stuffIndex;
1019	unsigned long flags;
1020	int rc = 0;
1021
1022	int bailout = 10;
1023
1024	ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, user );
1025
1026	// Ensure channel structure seems real
1027	if ( !i2Validate ( pCh ) ) 
1028		return -1;
1029
1030	// initialize some accelerators and private copies
1031	pB = pCh->pMyBord;
1032	channel = pCh->infl.hd.i2sChannel;
1033
1034	// If the board has gone fatal, return bad, and also hit the trap routine if
1035	// it exists.
1036	if (pB->i2eFatal) {
1037		if (pB->i2eFatalTrap) {
1038			(*(pB)->i2eFatalTrap)(pB);
1039		}
1040		return -1;
1041	}
1042	// Proceed as though we would do everything
1043	while ( count > 0 ) {
1044
1045		// How much room in output buffer is there?
1046		READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
1047		amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1;
1048		READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
1049		if (amountToMove < 0) {
1050			amountToMove += OBUF_SIZE;
1051		}
1052		// Subtract off the headers size and see how much room there is for real
1053		// data. If this is negative, we will discover later.
1054		amountToMove -= sizeof (i2DataHeader);
1055
1056		// Don't move more (now) than can go in a single packet
1057		if ( amountToMove > (int)(MAX_OBUF_BLOCK - sizeof(i2DataHeader)) ) {
1058			amountToMove = MAX_OBUF_BLOCK - sizeof(i2DataHeader);
1059		}
1060		// Don't move more than the count we were given
1061		if (amountToMove > count) {
1062			amountToMove = count;
1063		}
1064		// Now we know how much we must move: NB because the ring buffers have
1065		// an overflow area at the end, we needn't worry about wrapping in the
1066		// middle of a packet.
1067
1068// Small WINDOW here with no LOCK but I can't call Flush with LOCK
1069// We would be flushing (or ending flush) anyway
1070
1071		ip2trace (CHANN, ITRC_OUTPUT, 10, 1, amountToMove );
1072
1073		if ( !(pCh->flush_flags && i2RetryFlushOutput(pCh) ) 
1074				&& amountToMove > 0 )
1075		{
1076			WRITE_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
1077			stuffIndex = pCh->Obuf_stuff;
1078      
1079			// Had room to move some data: don't know whether the block size,
1080			// buffer space, or what was the limiting factor...
1081			pInsert = &(pCh->Obuf[stuffIndex]);
1082
1083			// Set up the header
1084			CHANNEL_OF(pInsert)     = channel;
1085			PTYPE_OF(pInsert)       = PTYPE_DATA;
1086			TAG_OF(pInsert)         = 0;
1087			ID_OF(pInsert)          = ID_ORDINARY_DATA;
1088			DATA_COUNT_OF(pInsert)  = amountToMove;
1089
1090			// Move the data
1091			if ( user ) {
1092				rc = copy_from_user((char*)(DATA_OF(pInsert)), pSource,
1093						amountToMove );
1094			} else {
1095				memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove );
1096			}
1097			// Adjust pointers and indices
1098			pSource					+= amountToMove;
1099			pCh->Obuf_char_count	+= amountToMove;
1100			stuffIndex 				+= amountToMove + sizeof(i2DataHeader);
1101			count 					-= amountToMove;
1102
1103			if (stuffIndex >= OBUF_SIZE) {
1104				stuffIndex = 0;
1105			}
1106			pCh->Obuf_stuff = stuffIndex;
1107
1108			WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
1109
1110			ip2trace (CHANN, ITRC_OUTPUT, 13, 1, stuffIndex );
1111
1112		} else {
1113
1114			// Cannot move data
1115			// becuz we need to stuff a flush 
1116			// or amount to move is <= 0
1117
1118			ip2trace(CHANN, ITRC_OUTPUT, 14, 3,
1119				amountToMove,  pB->i2eFifoRemains,
1120				pB->i2eWaitingForEmptyFifo );
1121
1122			// Put this channel back on queue
1123			// this ultimatly gets more data or wakes write output
1124			i2QueueNeeds(pB, pCh, NEED_INLINE);
1125
1126			if ( pB->i2eWaitingForEmptyFifo ) {
1127
1128				ip2trace (CHANN, ITRC_OUTPUT, 16, 0 );
1129
1130				// or schedule
1131				if (!in_interrupt()) {
1132
1133					ip2trace (CHANN, ITRC_OUTPUT, 61, 0 );
1134
1135					current->state = TASK_INTERRUPTIBLE;
1136					schedule_timeout(2);
1137					if (signal_pending(current)) {
1138						break;
1139					}
1140					continue;
1141				} else {
1142
1143					ip2trace (CHANN, ITRC_OUTPUT, 62, 0 );
1144
1145					// let interrupt in = WAS restore_flags()
1146					// We hold no lock nor is irq off anymore???
1147					
1148					break;
1149				}
1150				break;   // from while(count)
1151			}
1152			else if ( pB->i2eFifoRemains < 32 && !pB->i2eTxMailEmpty ( pB ) )
1153			{
1154				ip2trace (CHANN, ITRC_OUTPUT, 19, 2,
1155					pB->i2eFifoRemains,
1156					pB->i2eTxMailEmpty );
1157
1158				break;   // from while(count)
1159			} else if ( pCh->channelNeeds & NEED_CREDIT ) {
1160
1161				ip2trace (CHANN, ITRC_OUTPUT, 22, 0 );
1162
1163				break;   // from while(count)
1164			} else if ( --bailout) {
1165
1166				// Try to throw more things (maybe not us) in the fifo if we're
1167				// not already waiting for it.
1168	
1169				ip2trace (CHANN, ITRC_OUTPUT, 20, 0 );
1170
1171				serviceOutgoingFifo(pB);
1172				//break;  CONTINUE;
1173			} else {
1174				ip2trace (CHANN, ITRC_OUTPUT, 21, 3,
1175					pB->i2eFifoRemains,
1176					pB->i2eOutMailWaiting,
1177					pB->i2eWaitingForEmptyFifo );
1178
1179				break;   // from while(count)
1180			}
1181		}
1182	} // End of while(count)
1183
1184	i2QueueNeeds(pB, pCh, NEED_INLINE);
1185
1186	// We drop through either when the count expires, or when there is some
1187	// count left, but there was a non-blocking write.
1188	if (countOriginal > count) {
1189
1190		ip2trace (CHANN, ITRC_OUTPUT, 17, 2, countOriginal, count );
1191
1192		serviceOutgoingFifo( pB );
1193	}
1194
1195	ip2trace (CHANN, ITRC_OUTPUT, ITRC_RETURN, 2, countOriginal, count );
1196
1197	return countOriginal - count;
1198}
1199
1200//******************************************************************************
1201// Function:   i2FlushOutput(pCh)
1202// Parameters: Pointer to a channel structure
1203// Returns:    Nothing
1204//
1205// Description:
1206// Sends bypass command to start flushing (waiting possibly forever until there
1207// is room), then sends inline command to stop flushing output, (again waiting
1208// possibly forever).
1209//******************************************************************************
1210static inline void
1211i2FlushOutput(i2ChanStrPtr pCh)
1212{
1213
1214	ip2trace (CHANN, ITRC_FLUSH, 1, 1, pCh->flush_flags );
1215
1216	if (pCh->flush_flags)
1217		return;
1218
1219	if ( 1 != i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) {
1220		pCh->flush_flags = STARTFL_FLAG;		// Failed - flag for later
1221
1222		ip2trace (CHANN, ITRC_FLUSH, 2, 0 );
1223
1224	} else if ( 1 != i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL) ) {
1225		pCh->flush_flags = STOPFL_FLAG;		// Failed - flag for later
1226
1227		ip2trace (CHANN, ITRC_FLUSH, 3, 0 );
1228	}
1229}
1230
1231static int 
1232i2RetryFlushOutput(i2ChanStrPtr pCh)
1233{
1234	int old_flags = pCh->flush_flags;
1235
1236	ip2trace (CHANN, ITRC_FLUSH, 14, 1, old_flags );
1237
1238	pCh->flush_flags = 0;	// Clear flag so we can avoid recursion
1239									// and queue the commands
1240
1241	if ( old_flags & STARTFL_FLAG ) {
1242		if ( 1 == i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) {
1243			old_flags = STOPFL_FLAG;	//Success - send stop flush
1244		} else {
1245			old_flags = STARTFL_FLAG;	//Failure - Flag for retry later
1246		}
1247
1248		ip2trace (CHANN, ITRC_FLUSH, 15, 1, old_flags );
1249
1250	}
1251	if ( old_flags & STOPFL_FLAG ) {
1252		if (1 == i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL)) {
1253			old_flags = 0;	// Success - clear flags
1254		}
1255
1256		ip2trace (CHANN, ITRC_FLUSH, 16, 1, old_flags );
1257	}
1258	pCh->flush_flags = old_flags;
1259
1260	ip2trace (CHANN, ITRC_FLUSH, 17, 1, old_flags );
1261
1262	return old_flags;
1263}
1264
1265//******************************************************************************
1266// Function:   i2DrainOutput(pCh,timeout)
1267// Parameters: Pointer to a channel structure
1268//             Maximum period to wait
1269// Returns:    ?
1270//
1271// Description:
1272// Uses the bookmark request command to ask the board to send a bookmark back as
1273// soon as all the data is completely sent.
1274//******************************************************************************
1275static void
1276i2DrainWakeup(i2ChanStrPtr pCh)
1277{
1278	ip2trace (CHANN, ITRC_DRAIN, 10, 1, pCh->BookmarkTimer.expires );
1279
1280	pCh->BookmarkTimer.expires = 0;
1281	wake_up_interruptible( &pCh->pBookmarkWait );
1282}
1283
1284static void
1285i2DrainOutput(i2ChanStrPtr pCh, int timeout)
1286{
1287	wait_queue_t wait;
1288	i2eBordStrPtr pB;
1289
1290	ip2trace (CHANN, ITRC_DRAIN, ITRC_ENTER, 1, pCh->BookmarkTimer.expires);
1291
1292	pB = pCh->pMyBord;
1293	// If the board has gone fatal, return bad, 
1294	// and also hit the trap routine if it exists.
1295	if (pB->i2eFatal) {
1296		if (pB->i2eFatalTrap) {
1297			(*(pB)->i2eFatalTrap)(pB);
1298		}
1299		return;
1300	}
1301	if ((timeout > 0) && (pCh->BookmarkTimer.expires == 0 )) {
1302		// One per customer (channel)
1303		init_timer( &(pCh->BookmarkTimer) );
1304		pCh->BookmarkTimer.expires  = jiffies + timeout;
1305		pCh->BookmarkTimer.function = (void*)(unsigned long)i2DrainWakeup;
1306		pCh->BookmarkTimer.data     = (unsigned long)pCh;
1307
1308		ip2trace (CHANN, ITRC_DRAIN, 1, 1, pCh->BookmarkTimer.expires );
1309
1310		add_timer( &(pCh->BookmarkTimer) );
1311	}
1312	
1313	i2QueueCommands( PTYPE_INLINE, pCh, -1, 1, CMD_BMARK_REQ );
1314
1315	init_waitqueue_entry(&wait, current);
1316	add_wait_queue(&(pCh->pBookmarkWait), &wait);
1317	set_current_state( TASK_INTERRUPTIBLE );
1318
1319	serviceOutgoingFifo( pB );
1320	
1321	schedule();	// Now we take our interruptible sleep on
1322
1323	// Clean up the queue
1324	set_current_state( TASK_RUNNING );
1325	remove_wait_queue(&(pCh->pBookmarkWait), &wait);
1326
1327	// if expires == 0 then timer poped, then do not need to del_timer
1328	if ((timeout > 0) && pCh->BookmarkTimer.expires && 
1329	                     time_before(jiffies, pCh->BookmarkTimer.expires)) {
1330		del_timer( &(pCh->BookmarkTimer) );
1331		pCh->BookmarkTimer.expires = 0;
1332
1333		ip2trace (CHANN, ITRC_DRAIN, 3, 1, pCh->BookmarkTimer.expires );
1334
1335	}
1336	ip2trace (CHANN, ITRC_DRAIN, ITRC_RETURN, 1, pCh->BookmarkTimer.expires );
1337	return;
1338}
1339
1340//******************************************************************************
1341// Function:   i2OutputFree(pCh)
1342// Parameters: Pointer to a channel structure
1343// Returns:    Space in output buffer
1344//
1345// Description:
1346// Returns -1 if very gross error. Otherwise returns the amount of bytes still
1347// free in the output buffer.
1348//******************************************************************************
1349static int
1350i2OutputFree(i2ChanStrPtr pCh)
1351{
1352	int amountToMove;
1353	unsigned long flags;
1354
1355	// Ensure channel structure seems real
1356	if ( !i2Validate ( pCh ) ) {
1357		return -1;
1358	}
1359	READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
1360	amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1;
1361	READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
1362
1363	if (amountToMove < 0) {
1364		amountToMove += OBUF_SIZE;
1365	}
1366	// If this is negative, we will discover later
1367	amountToMove -= sizeof(i2DataHeader);
1368
1369	return (amountToMove < 0) ? 0 : amountToMove;
1370}
1371static void
1372
1373ip2_owake( PTTY tp)
1374{
1375	i2ChanStrPtr  pCh;
1376
1377	if (tp == NULL) return;
1378
1379	pCh = tp->driver_data;
1380
1381	ip2trace (CHANN, ITRC_SICMD, 10, 2, tp->flags,
1382			(1 << TTY_DO_WRITE_WAKEUP) );
1383
1384	wake_up_interruptible ( &tp->write_wait );
1385	if ( ( tp->flags & (1 << TTY_DO_WRITE_WAKEUP) ) 
1386	  && tp->ldisc.write_wakeup )
1387	{
1388		(tp->ldisc.write_wakeup) ( tp );
1389
1390		ip2trace (CHANN, ITRC_SICMD, 11, 0 );
1391
1392	}
1393}
1394
1395static inline void
1396set_baud_params(i2eBordStrPtr pB) 
1397{
1398	int i,j;
1399	i2ChanStrPtr  *pCh;
1400
1401	pCh = (i2ChanStrPtr *) pB->i2eChannelPtr;
1402
1403	for (i = 0; i < ABS_MAX_BOXES; i++) {
1404		if (pB->channelBtypes.bid_value[i]) {
1405			if (BID_HAS_654(pB->channelBtypes.bid_value[i])) {
1406				for (j = 0; j < ABS_BIGGEST_BOX; j++) {
1407					if (pCh[i*16+j] == NULL)
1408						break;
1409					(pCh[i*16+j])->BaudBase    = 921600;	// MAX for ST654
1410					(pCh[i*16+j])->BaudDivisor = 96;
1411				}
1412			} else {	// has cirrus cd1400
1413				for (j = 0; j < ABS_BIGGEST_BOX; j++) {
1414					if (pCh[i*16+j] == NULL)
1415						break;
1416					(pCh[i*16+j])->BaudBase    = 115200;	// MAX for CD1400
1417					(pCh[i*16+j])->BaudDivisor = 12;
1418				}
1419			}
1420		}
1421	}
1422}
1423
1424//******************************************************************************
1425// Function:   i2StripFifo(pB)
1426// Parameters: Pointer to a board structure
1427// Returns:    ?
1428//
1429// Description:
1430// Strips all the available data from the incoming FIFO, identifies the type of
1431// packet, and either buffers the data or does what needs to be done.
1432//
1433// Note there is no overflow checking here: if the board sends more data than it
1434// ought to, we will not detect it here, but blindly overflow...
1435//******************************************************************************
1436
1437// A buffer for reading in blocks for unknown channels
1438static unsigned char junkBuffer[IBUF_SIZE];
1439
1440// A buffer to read in a status packet. Because of the size of the count field
1441// for these things, the maximum packet size must be less than MAX_CMD_PACK_SIZE
1442static unsigned char cmdBuffer[MAX_CMD_PACK_SIZE + 4];
1443
1444// This table changes the bit order from MSR order given by STAT_MODEM packet to
1445// status bits used in our library.
1446static char xlatDss[16] = {
14470      | 0     | 0      | 0      ,
14480      | 0     | 0      | I2_CTS ,
14490      | 0     | I2_DSR | 0      ,
14500      | 0     | I2_DSR | I2_CTS ,
14510      | I2_RI | 0      | 0      ,
14520      | I2_RI | 0      | I2_CTS ,
14530      | I2_RI | I2_DSR | 0      ,
14540      | I2_RI | I2_DSR | I2_CTS ,
1455I2_DCD | 0     | 0      | 0      ,
1456I2_DCD | 0     | 0      | I2_CTS ,
1457I2_DCD | 0     | I2_DSR | 0      ,
1458I2_DCD | 0     | I2_DSR | I2_CTS ,
1459I2_DCD | I2_RI | 0      | 0      ,
1460I2_DCD | I2_RI | 0      | I2_CTS ,
1461I2_DCD | I2_RI | I2_DSR | 0      ,
1462I2_DCD | I2_RI | I2_DSR | I2_CTS };
1463
1464static inline void
1465i2StripFifo(i2eBordStrPtr pB)
1466{
1467	i2ChanStrPtr pCh;
1468	int channel;
1469	int count;
1470	unsigned short stuffIndex;
1471	int amountToRead;
1472	unsigned char *pc, *pcLimit;
1473	unsigned char uc;
1474	unsigned char dss_change;
1475	unsigned long bflags,cflags;
1476
1477//	ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_ENTER, 0 );
1478
1479	while (HAS_INPUT(pB)) {
1480//		ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 2, 0 );
1481
1482		// Process packet from fifo a one atomic unit
1483		WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock,bflags);
1484   
1485		// The first word (or two bytes) will have channel number and type of
1486		// packet, possibly other information
1487		pB->i2eLeadoffWord[0] = iiReadWord(pB);
1488
1489		switch(PTYPE_OF(pB->i2eLeadoffWord))
1490		{
1491		case PTYPE_DATA:
1492			pB->got_input = 1;
1493
1494//			ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 3, 0 );
1495
1496			channel = CHANNEL_OF(pB->i2eLeadoffWord); /* Store channel */
1497			count = iiReadWord(pB);          /* Count is in the next word */
1498
1499// NEW: Check the count for sanity! Should the hardware fail, our death
1500// is more pleasant. While an oversize channel is acceptable (just more
1501// than the driver supports), an over-length count clearly means we are
1502// sick!
1503			if ( ((unsigned int)count) > IBUF_SIZE ) {
1504				pB->i2eFatal = 2;
1505				WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
1506				return;     /* Bail out ASAP */
1507			}
1508			// Channel is illegally big ?
1509			if ((channel >= pB->i2eChannelCnt) ||
1510				(NULL==(pCh = ((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])))
1511			{
1512				iiReadBuf(pB, junkBuffer, count);
1513				WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
1514				break;         /* From switch: ready for next packet */
1515			}
1516
1517			// Channel should be valid, then
1518
1519			// If this is a hot-key, merely post its receipt for now. These are
1520			// always supposed to be 1-byte packets, so we won't even check the
1521			// count. Also we will post an acknowledgement to the board so that
1522			// more data can be forthcoming. Note that we are not trying to use
1523			// these sequences in this driver, merely to robustly ignore them.
1524			if(ID_OF(pB->i2eLeadoffWord) == ID_HOT_KEY)
1525			{
1526				pCh->hotKeyIn = iiReadWord(pB) & 0xff;
1527				WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
1528				i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_HOTACK);
1529				break;   /* From the switch: ready for next packet */
1530			}
1531
1532			// Normal data! We crudely assume there is room for the data in our
1533			// buffer because the board wouldn't have exceeded his credit limit.
1534			WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,cflags);
1535													// We have 2 locks now
1536			stuffIndex = pCh->Ibuf_stuff;
1537			amountToRead = IBUF_SIZE - stuffIndex;
1538			if (amountToRead > count)
1539				amountToRead = count;
1540
1541			// stuffIndex would have been already adjusted so there would 
1542			// always be room for at least one, and count is always at least
1543			// one.
1544
1545			iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead);
1546			pCh->icount.rx += amountToRead;
1547
1548			// Update the stuffIndex by the amount of data moved. Note we could
1549			// never ask for more data than would just fit. However, we might
1550			// have read in one more byte than we wanted because the read
1551			// rounds up to even bytes. If this byte is on the end of the
1552			// packet, and is padding, we ignore it. If the byte is part of
1553			// the actual data, we need to move it.
1554
1555			stuffIndex += amountToRead;
1556
1557			if (stuffIndex >= IBUF_SIZE) {
1558				if ((amountToRead & 1) && (count > amountToRead)) {
1559					pCh->Ibuf[0] = pCh->Ibuf[IBUF_SIZE];
1560					amountToRead++;
1561					stuffIndex = 1;
1562				} else {
1563					stuffIndex = 0;
1564				}
1565			}
1566
1567			// If there is anything left over, read it as well
1568			if (count > amountToRead) {
1569				amountToRead = count - amountToRead;
1570				iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead);
1571				pCh->icount.rx += amountToRead;
1572				stuffIndex += amountToRead;
1573			}
1574
1575			// Update stuff index
1576			pCh->Ibuf_stuff = stuffIndex;
1577			WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,cflags);
1578			WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
1579
1580#ifdef USE_IQ
1581			schedule_work(&pCh->tqueue_input);
1582#else
1583			do_input(pCh);
1584#endif
1585
1586			// Note we do not need to maintain any flow-control credits at this
1587			// time:  if we were to increment .asof and decrement .room, there
1588			// would be no net effect. Instead, when we strip data, we will
1589			// increment .asof and leave .room unchanged.
1590
1591			break;   // From switch: ready for next packet
1592
1593		case PTYPE_STATUS:
1594			ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 4, 0 );
1595      
1596			count = CMD_COUNT_OF(pB->i2eLeadoffWord);
1597
1598			iiReadBuf(pB, cmdBuffer, count);
1599			// We can release early with buffer grab
1600			WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
1601
1602			pc = cmdBuffer;
1603			pcLimit = &(cmdBuffer[count]);
1604
1605			while (pc < pcLimit) {
1606				channel = *pc++;
1607
1608				ip2trace (channel, ITRC_SFIFO, 7, 2, channel, *pc );
1609
1610				/* check for valid channel */
1611				if (channel < pB->i2eChannelCnt
1612					 && 
1613					 (pCh = (((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])) != NULL
1614					)
1615				{
1616					dss_change = 0;
1617
1618					switch (uc = *pc++)
1619					{
1620					/* Breaks and modem signals are easy: just update status */
1621					case STAT_CTS_UP:
1622						if ( !(pCh->dataSetIn & I2_CTS) )
1623						{
1624							pCh->dataSetIn |= I2_DCTS;
1625							pCh->icount.cts++;
1626							dss_change = 1;
1627						}
1628						pCh->dataSetIn |= I2_CTS;
1629						break;
1630
1631					case STAT_CTS_DN:
1632						if ( pCh->dataSetIn & I2_CTS )
1633						{
1634							pCh->dataSetIn |= I2_DCTS;
1635							pCh->icount.cts++;
1636							dss_change = 1;
1637						}
1638						pCh->dataSetIn &= ~I2_CTS;
1639						break;
1640
1641					case STAT_DCD_UP:
1642						ip2trace (channel, ITRC_MODEM, 1, 1, pCh->dataSetIn );
1643
1644						if ( !(pCh->dataSetIn & I2_DCD) )
1645						{
1646							ip2trace (CHANN, ITRC_MODEM, 2, 0 );
1647							pCh->dataSetIn |= I2_DDCD;
1648							pCh->icount.dcd++;
1649							dss_change = 1;
1650						}
1651						pCh->dataSetIn |= I2_DCD;
1652
1653						ip2trace (channel, ITRC_MODEM, 3, 1, pCh->dataSetIn );
1654						break;
1655
1656					case STAT_DCD_DN:
1657						ip2trace (channel, ITRC_MODEM, 4, 1, pCh->dataSetIn );
1658						if ( pCh->dataSetIn & I2_DCD )
1659						{
1660							ip2trace (channel, ITRC_MODEM, 5, 0 );
1661							pCh->dataSetIn |= I2_DDCD;
1662							pCh->icount.dcd++;
1663							dss_change = 1;
1664						}
1665						pCh->dataSetIn &= ~I2_DCD;
1666
1667						ip2trace (channel, ITRC_MODEM, 6, 1, pCh->dataSetIn );
1668						break;
1669

Large files files are truncated, but you can click here to view the full file