Showing error 1051

User: Jiri Slaby
Error type: Leaving function in locked state
Error type description: Some lock is not unlocked on all paths of a function, so it is leaked
File location: drivers/char/ip2/i2lib.c
Line in file: 770
Project: Linux Kernel
Project version: 2.6.28
Tools: Undetermined 1
Entered: 2012-03-04 17:07:06 UTC


Source:

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