
/*
 *
  Copyright (c) Eicon Networks, 2002.
 *
  This source file is supplied for the use with
  Eicon Networks range of DIVA Server Adapters.
 *
  Eicon File Revision :    2.1
 *
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2, or (at your option)
  any later version.
 *
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU General Public License for more details.
 *
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */
#include "platform.h"
#include "pc.h"
#include "pr_pc.h"
#include "di_defs.h"
#include "di.h"
#if !defined USE_EXTENDED_DEBUGS
  #include "dimaint.h"
#else
  #define dprintf
#endif
#include "io.h"
#include "dfifo.h"
#define PR_RAM  ((struct pr_ram *)0)
#define RAM ((struct dual *)0)
/*------------------------------------------------------------------*/
/* local function prototypes                                        */
/*------------------------------------------------------------------*/
void pr_out(ADAPTER * a);
byte pr_dpc(ADAPTER * a);
static byte pr_ready(ADAPTER * a);
static byte isdn_rc(ADAPTER *, byte, byte, byte, word, dword, dword);
static byte isdn_ind(ADAPTER *, byte, byte, byte, PBUFFER *, byte, word);
/* -----------------------------------------------------------------
    Functions used for the extended XDI Debug
    macros
    global convergence counter (used by all adapters)
    Look by the implementation part of the functions
    about the parameters.
    If you change the dubugging parameters, then you should update
    the aididbg.doc in the IDI doc's.
   ----------------------------------------------------------------- */
#if defined(XDI_USE_XLOG)
#define XDI_A_NR(_x_) ((byte)(((ISDN_ADAPTER *)(_x_->io))->ANum))
static void xdi_xlog (byte *msg, word code, int length);
static byte xdi_xlog_sec = 0;
#else
#define XDI_A_NR(_x_) ((byte)0)
#endif
static void xdi_xlog_rc_event (byte Adapter,
                               byte Id, byte Ch, byte Rc, byte cb, byte type);
static void xdi_xlog_request (byte Adapter, byte Id,
                              byte Ch, byte Req, byte type);
static void xdi_xlog_ind (byte Adapter,
                          byte Id,
                          byte Ch,
                          byte Ind,
                          byte rnr_valid,
                          byte rnr,
                          byte type);
/*------------------------------------------------------------------*/
/* output function                                                  */
/*------------------------------------------------------------------*/
void pr_out(ADAPTER * a)
{
  byte e_no;
  ENTITY  * this = NULL;
  BUFFERS  *X;
  word length;
  word i;
  word clength;
  REQ * ReqOut;
  byte more;
  byte ReadyCount;
  byte ReqCount;
  byte Id;
  dtrc(dprintf("pr_out"));
        /* while a request is pending ...                           */
  e_no = look_req(a);
  if(!e_no)
  {
    dtrc(dprintf("no_req"));
    return;
  }
  ReadyCount = pr_ready(a);
  if(!ReadyCount)
  {
    dtrc(dprintf("not_ready"));
    return;
  }
  ReqCount = 0;
  while(e_no && ReadyCount) {
    next_req(a);
    this = entity_ptr(a, e_no);
#ifdef USE_EXTENDED_DEBUGS
    if ( !this )
    {
      DBG_FTL(("XDI: [%02x] !A%d ==> NULL entity ptr - try to ignore",
               xdi_xlog_sec++, (int)((ISDN_ADAPTER *)a->io)->ANum))
      e_no = look_req(a) ;
      ReadyCount-- ;
      continue ;
    }
    {
      DBG_TRC((">A%d Id=0x%x Req=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, this->Id, this->Req))
    }
#else
    dbug(dprintf("out:Req=%x,Id=%x,Ch=%x",this->Req,this->Id,this->ReqCh));
#endif
        /* get address of next available request buffer             */
    ReqOut = (REQ *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextReq)];
#if defined(DIVA_ISTREAM)
    if (!(a->tx_stream[this->Id]   &&
        this->Req == N_DATA)) {
#endif
        /* now copy the data from the current data buffer into the  */
        /* adapters request buffer                                  */
    length = 0;
    i = this->XCurrent;
    X = PTR_X(a,this);
    while(i<this->XNum && length<270) {
      clength = MIN((word)(270-length),X[i].PLength-this->XOffset);
      a->ram_out_buffer(a,
                        &ReqOut->XBuffer.P[length],
                        PTR_P(a,this,&X[i].P[this->XOffset]),
                        clength);
      length +=clength;
      this->XOffset +=clength;
      if(this->XOffset==X[i].PLength) {
        this->XCurrent = (byte)++i;
        this->XOffset = 0;
      }
    }
#if defined(DIVA_ISTREAM)
   } else { /* Use CMA extension in order to transfer data to the card */
      i = this->XCurrent;
      X = PTR_X(a,this);
      while (i < this->XNum) {
        diva_istream_write (a,
                            this->Id,
                            PTR_P(a,this,&X[i].P[0]),
                            X[i].PLength,
                            ((i+1) == this->XNum),
                            0, 0);
        this->XCurrent = (byte)++i;
      }
      length = 0;
   }
#endif
    a->ram_outw(a, &ReqOut->XBuffer.length, length);
    a->ram_out(a, &ReqOut->ReqId, this->Id);
    a->ram_out(a, &ReqOut->ReqCh, this->ReqCh);
        /* if it's a specific request (no ASSIGN) ...                */
    if(this->Id &0x1f) {
        /* if buffers are left in the list of data buffers do       */
        /* do chaining (LL_MDATA, N_MDATA)                          */
      this->More++;
      if(i<this->XNum && this->MInd) {
        xdi_xlog_request (XDI_A_NR(a), this->Id, this->ReqCh, this->MInd,
                          a->IdTypeTable[this->No]);
        a->ram_out(a, &ReqOut->Req, this->MInd);
        more = TRUE;
      }
      else {
        xdi_xlog_request (XDI_A_NR(a), this->Id, this->ReqCh, this->Req,
                          a->IdTypeTable[this->No]);
        this->More |=XMOREF;
        a->ram_out(a, &ReqOut->Req, this->Req);
        more = FALSE;
        if (a->FlowControlIdTable[this->ReqCh] == this->Id)
          a->FlowControlSkipTable[this->ReqCh] = TRUE;
        /*
           Note that remove request was sent to the card
           */
        if (this->Req == REMOVE) {
          a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_REMOVE_PENDING;
        }
      }
        /* if we did chaining, this entity is put back into the     */
        /* request queue                                            */
      if(more) {
        req_queue(a,this->No);
      }
    }
        /* else it's a ASSIGN                                       */
    else {
        /* save the request code used for buffer chaining           */
      this->MInd = 0;
      if (this->Id==BLLC_ID) this->MInd = LL_MDATA;
      if (this->Id==NL_ID   ||
          this->Id==TASK_ID ||
          this->Id==MAN_ID
        ) this->MInd = N_MDATA;
        /* send the ASSIGN                                          */
      a->IdTypeTable[this->No] = this->Id;
      xdi_xlog_request (XDI_A_NR(a),this->Id,this->ReqCh,this->Req, this->Id);
      this->More |=XMOREF;
      a->ram_out(a, &ReqOut->Req, this->Req);
        /* save the reference of the ASSIGN                         */
      assign_queue(a, this->No, a->ram_inw(a, &ReqOut->Reference));
    }
    a->ram_outw(a, &PR_RAM->NextReq, a->ram_inw(a, &ReqOut->next));
    ReadyCount--;
    ReqCount++;
    e_no = look_req(a);
  }
        /* send the filled request buffers to the ISDN adapter      */
  a->ram_out(a, &PR_RAM->ReqInput,
             (byte)(a->ram_in(a, &PR_RAM->ReqInput) + ReqCount));
        /* if it is a 'unreturncoded' UREMOVE request, remove the  */
        /* Id from our table after sending the request             */
  if(this && (this->Req==UREMOVE) && this->Id) {
    Id = this->Id;
    e_no = a->IdTable[Id];
    free_entity(a, e_no);
    for (i = 0; i < 256; i++)
    {
      if (a->FlowControlIdTable[i] == Id)
        a->FlowControlIdTable[i] = 0;
    }
    a->IdTable[Id] = 0;
    this->Id = 0;
  }
}
static byte pr_ready(ADAPTER * a)
{
  byte ReadyCount;
  ReadyCount = (byte)(a->ram_in(a, &PR_RAM->ReqOutput) -
                      a->ram_in(a, &PR_RAM->ReqInput));
  if(!ReadyCount) {
    if(!a->ReadyInt) {
      a->ram_inc(a, &PR_RAM->ReadyInt);
      a->ReadyInt++;
    }
  }
  return ReadyCount;
}
/*------------------------------------------------------------------*/
/* isdn interrupt handler                                           */
/*------------------------------------------------------------------*/
byte pr_dpc(ADAPTER * a)
{
  byte Count;
  RC * RcIn;
  IND * IndIn;
  byte c;
  byte RNRId;
  byte Rc;
  byte Ind;
        /* if return codes are available ...                        */
  if((Count = a->ram_in(a, &PR_RAM->RcOutput)) != 0) {
    dtrc(dprintf("#Rc=%x",Count));
        /* get the buffer address of the first return code          */
    RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextRc)];
        /* for all return codes do ...                              */
    while(Count--) {
      if((Rc=a->ram_in(a, &RcIn->Rc)) != 0) {
        dword tmp[2];
        /*
          Get extended information, associated with return code
          */
        a->ram_in_buffer(a,
                         &RcIn->Reserved2[0],
                         (byte*)&tmp[0],
                         8);
        /* call return code handler, if it is not our return code   */
        /* the handler returns 2                                    */
        /* for all return codes we process, we clear the Rc field   */
        isdn_rc(a,
                Rc,
                a->ram_in(a, &RcIn->RcId),
                a->ram_in(a, &RcIn->RcCh),
                a->ram_inw(a, &RcIn->Reference),
                tmp[0],  /* type of extended informtion */
                tmp[1]); /* extended information        */
        a->ram_out(a, &RcIn->Rc, 0);
      }
        /* get buffer address of next return code                   */
      RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &RcIn->next)];
    }
        /* clear all return codes (no chaining!)                    */
    a->ram_out(a, &PR_RAM->RcOutput ,0);
        /* call output function                                     */
    pr_out(a);
  }
        /* clear RNR flag                                           */
  RNRId = 0;
        /* if indications are available ...                         */
  if((Count = a->ram_in(a, &PR_RAM->IndOutput)) != 0) {
    dtrc(dprintf("#Ind=%x",Count));
        /* get the buffer address of the first indication           */
    IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextInd)];
        /* for all indications do ...                               */
    while(Count--) {
        /* if the application marks an indication as RNR, all       */
        /* indications from the same Id delivered in this interrupt */
        /* are marked RNR                                           */
      if(RNRId && RNRId==a->ram_in(a, &IndIn->IndId)) {
        a->ram_out(a, &IndIn->Ind, 0);
        a->ram_out(a, &IndIn->RNR, TRUE);
      }
      else {
        Ind = a->ram_in(a, &IndIn->Ind);
        if(Ind) {
          RNRId = 0;
        /* call indication handler, a return value of 2 means chain */
        /* a return value of 1 means RNR                            */
        /* for all indications we process, we clear the Ind field   */
          c = isdn_ind(a,
                       Ind,
                       a->ram_in(a, &IndIn->IndId),
                       a->ram_in(a, &IndIn->IndCh),
                       &IndIn->RBuffer,
                       a->ram_in(a, &IndIn->MInd),
                       a->ram_inw(a, &IndIn->MLength));
          if(c==1) {
            dtrc(dprintf("RNR"));
            a->ram_out(a, &IndIn->Ind, 0);
            RNRId = a->ram_in(a, &IndIn->IndId);
            a->ram_out(a, &IndIn->RNR, TRUE);
          }
        }
      }
        /* get buffer address of next indication                    */
      IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &IndIn->next)];
    }
    a->ram_out(a, &PR_RAM->IndOutput, 0);
  }
  return FALSE;
}
byte scom_test_int(ADAPTER * a)
{
  return a->ram_in(a,(void *)0x3fe);
}
void scom_clear_int(ADAPTER * a)
{
  a->ram_out(a,(void *)0x3fe,0);
}
/*------------------------------------------------------------------*/
/* return code handler                                              */
/*------------------------------------------------------------------*/
byte isdn_rc(ADAPTER * a,
             byte Rc,
             byte Id,
             byte Ch,
             word Ref,
             dword extended_info_type,
             dword extended_info)
{
  ENTITY  * this;
  byte e_no;
  word i;
  int cancel_rc;
#ifdef USE_EXTENDED_DEBUGS
  {
    DBG_TRC(("<A%d Id=0x%x Rc=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Rc))
  }
#else
  dbug(dprintf("isdn_rc(Rc=%x,Id=%x,Ch=%x)",Rc,Id,Ch));
#endif
        /* check for ready interrupt                                */
  if(Rc==READY_INT) {
    xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 0, 0);
    if(a->ReadyInt) {
      a->ReadyInt--;
      return 0;
    }
    return 2;
  }
        /* if we know this Id ...                                   */
  e_no = a->IdTable[Id];
  if(e_no) {
    this = entity_ptr(a,e_no);
    xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 0, a->IdTypeTable[this->No]);
    this->RcCh = Ch;
        /* if it is a return code to a REMOVE request, remove the   */
        /* Id from our table                                        */
    if ((a->misc_flags_table[e_no] & DIVA_MISC_FLAGS_REMOVE_PENDING) &&
        (Rc==OK)) {
      if (a->IdTypeTable[e_no] == NL_ID) {
        if (a->RcExtensionSupported &&
            (extended_info_type != DIVA_RC_TYPE_REMOVE_COMPLETE)) {
        dtrc(dprintf("XDI: N-REMOVE, A(%02x) Id:%02x, ignore RC=OK",
                        XDI_A_NR(a),Id));
          return (0);
        }
        if (extended_info_type == DIVA_RC_TYPE_REMOVE_COMPLETE)
          a->RcExtensionSupported = TRUE;
      }
      a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_REMOVE_PENDING;
      a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_NO_RC_CANCELLING;
      free_entity(a, e_no);
      for (i = 0; i < 256; i++)
      {
        if (a->FlowControlIdTable[i] == Id)
          a->FlowControlIdTable[i] = 0;
      }
      a->IdTable[Id] = 0;
      this->Id = 0;
      /* ---------------------------------------------------------------
        If we send N_DISC or N_DISK_ACK after we have received OK_FC
        then the card will respond with OK_FC and later with RC==OK.
        If we send N_REMOVE in this state we will receive only RC==OK
        This will create the state in that the XDI is waiting for the
        additional RC and does not delivery the RC to the client. This
        code corrects the counter of outstanding RC's in this case.
      --------------------------------------------------------------- */
      if ((this->More & XMOREC) > 1) {
        this->More &= ~XMOREC;
        this->More |= 1;
        dtrc(dprintf("XDI: correct MORE on REMOVE A(%02x) Id:%02x",
                     XDI_A_NR(a),Id));
      }
    }
    if (Rc==OK_FC) {
      a->FlowControlIdTable[Ch] = Id;
      a->FlowControlSkipTable[Ch] = FALSE;
      this->Rc = Rc;
      this->More &= ~(XBUSY | XMOREC);
      this->complete=0xff;
      xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
      CALLBACK(a, this);
      return 0;
    }
    /*
      New protocol code sends return codes that comes from release
      of flow control condition marked with DIVA_RC_TYPE_OK_FC extended
      information element type.
      If like return code arrives then application is able to process
      all return codes self and XDI should not cances return codes.
      This return code does not decrement XMOREC partial return code
      counter due to fact that it was no request for this return code,
      also XMOREC was not incremented.
      */
    if (extended_info_type == DIVA_RC_TYPE_OK_FC) {
      a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_NO_RC_CANCELLING;
      this->Rc = Rc;
      this->complete=0xff;
      xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
      DBG_TRC(("XDI OK_FC A(%02x) Id:%02x Ch:%02x Rc:%02x",
      XDI_A_NR(a), Id, Ch, Rc))
      CALLBACK(a, this);
      return 0;
    }
    cancel_rc = !(a->misc_flags_table[e_no] & DIVA_MISC_FLAGS_NO_RC_CANCELLING);
    if (cancel_rc && (a->FlowControlIdTable[Ch] == Id))
    {
      a->FlowControlIdTable[Ch] = 0;
      if ((Rc != OK) || !a->FlowControlSkipTable[Ch])
      {
        this->Rc = Rc;
        if (Ch == this->ReqCh)
        {
          this->More &=~(XBUSY | XMOREC);
          this->complete=0xff;
        }
        xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
        CALLBACK(a, this);
      }
      return 0;
    }
    if (this->More &XMOREC)
      this->More--;
        /* call the application callback function                   */
    if (((!cancel_rc) || (this->More & XMOREF)) && !(this->More & XMOREC)) {
      this->Rc = Rc;
      this->More &=~XBUSY;
      this->complete=0xff;
      xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
      CALLBACK(a, this);
    }
    return 0;
  }
        /* if it's an ASSIGN return code check if it's a return     */
        /* code to an ASSIGN request from us                        */
  if((Rc &0xf0)==ASSIGN_RC) {
    e_no = get_assign(a, Ref);
    if(e_no) {
      this = entity_ptr(a,e_no);
      this->Id = Id;
      xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 2, a->IdTypeTable[this->No]);
        /* call the application callback function                   */
      this->Rc = Rc;
      this->More &=~XBUSY;
      this->complete=0xff;
#if defined(DIVA_ISTREAM) /* { */
      if ((Rc == ASSIGN_OK) && a->ram_offset &&
          (a->IdTypeTable[this->No] == NL_ID) &&
          ((extended_info_type == DIVA_RC_TYPE_RX_DMA) ||
          (extended_info_type == DIVA_RC_TYPE_CMA_PTR)) &&
          extended_info) {
        dword offset = (*(a->ram_offset)) (a);
        dword tmp[2];
        extended_info -= offset;
#ifdef PLATFORM_GT_32BIT
        a->ram_in_dw(a, (void*)ULongToPtr(extended_info), (dword*)&tmp[0], 2);
#else
        a->ram_in_dw(a, (void*)extended_info, (dword*)&tmp[0], 2);
#endif
        a->tx_stream[Id]  = tmp[0];
        a->rx_stream[Id]  = tmp[1];
        if (extended_info_type == DIVA_RC_TYPE_RX_DMA) {
          DBG_TRC(("Id=0x%x RxDMA=%08x:%08x",
                    Id, a->tx_stream[Id], a->rx_stream[Id]))
          a->misc_flags_table[this->No] |= DIVA_MISC_FLAGS_RX_DMA;
        } else {
          DBG_TRC(("Id=0x%x CMA=%08x:%08x",
                    Id, a->tx_stream[Id], a->rx_stream[Id]))
          a->misc_flags_table[this->No] &= ~DIVA_MISC_FLAGS_RX_DMA;
          a->rx_pos[Id]     = 0;
          a->rx_stream[Id] -= offset;
        }
        a->tx_pos[Id]     = 0;
        a->tx_stream[Id] -= offset;
      } else {
        a->tx_stream[Id] = 0;
        a->rx_stream[Id] = 0;
        a->misc_flags_table[this->No] &= ~DIVA_MISC_FLAGS_RX_DMA;
      }
#endif /* } */
      CALLBACK(a, this);
      if(Rc==ASSIGN_OK) {
        a->IdTable[Id] = e_no;
      }
      else
      {
        free_entity(a, e_no);
        for (i = 0; i < 256; i++)
        {
          if (a->FlowControlIdTable[i] == Id)
            a->FlowControlIdTable[i] = 0;
        }
        a->IdTable[Id] = 0;
        this->Id = 0;
      }
      return 1;
    }
  }
  return 2;
}
/*------------------------------------------------------------------*/
/* indication handler                                               */
/*------------------------------------------------------------------*/
byte isdn_ind(ADAPTER * a,
              byte Ind,
              byte Id,
              byte Ch,
              PBUFFER * RBuffer,
              byte MInd,
              word MLength)
{
  ENTITY  * this;
  word clength;
  word offset;
  BUFFERS  *R;
  byte* cma = NULL;
#ifdef USE_EXTENDED_DEBUGS
  {
    DBG_TRC(("<A%d Id=0x%x Ind=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Ind))
  }
#else
  dbug(dprintf("isdn_ind(Ind=%x,Id=%x,Ch=%x)",Ind,Id,Ch));
#endif
  if(a->IdTable[Id]) {
    this = entity_ptr(a,a->IdTable[Id]);
    this->IndCh = Ch;
    xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind,
                  0/* rnr_valid */, 0 /* rnr */, a->IdTypeTable[this->No]);
        /* if the Receive More flag is not yet set, this is the     */
        /* first buffer of the packet                               */
    if(this->RCurrent==0xff) {
        /* check for receive buffer chaining                        */
      if(Ind==this->MInd) {
        this->complete = 0;
        this->Ind = MInd;
      }
      else {
        this->complete = 1;
        this->Ind = Ind;
      }
        /* call the application callback function for the receive   */
        /* look ahead                                               */
      this->RLength = MLength;
#if defined(DIVA_ISTREAM)
      if ((a->rx_stream[this->Id] ||
           (a->misc_flags_table[this->No] & DIVA_MISC_FLAGS_RX_DMA)) &&
          ((Ind == N_DATA) ||
           (a->protocol_capabilities & PROTCAP_CMA_ALLPR))) {
        PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)a->io ;
        if (a->misc_flags_table[this->No] & DIVA_MISC_FLAGS_RX_DMA) {
#if defined(DIVA_IDI_RX_DMA)
          dword d;
          diva_get_dma_map_entry (\
                   (struct _diva_dma_map_entry*)IoAdapter->dma_map,
                   (int)a->rx_stream[this->Id], (void**)&cma, &d);
#else
          cma = &a->stream_buffer[0];
          cma[0] = cma[1] = cma[2] = cma[3] = 0;
#endif
          this->RLength = MLength = (word)*(dword*)cma;
          cma += 4;
        } else {
        int final = 0;
        cma = &a->stream_buffer[0];
        this->RLength = MLength = (word)diva_istream_read (a,
                                                     Id,
                                                     cma,
                                                     sizeof(a->stream_buffer),
                                                     &final, NULL, NULL);
        }
        IoAdapter->RBuffer.length = MIN(MLength, 270);
        if (IoAdapter->RBuffer.length != MLength) {
          this->complete = 0;
        } else {
          this->complete = 1;
        }
        memcpy (IoAdapter->RBuffer.P, cma, IoAdapter->RBuffer.length) ;
        this->RBuffer = (DBUFFER *)&IoAdapter->RBuffer ;
      }
#endif
      if (!cma) {
        a->ram_look_ahead(a, RBuffer, this);
      }
      this->RNum = 0;
      CALLBACK(a, this);
        /* map entity ptr, selector could be re-mapped by call to   */
        /* IDI from within callback                                 */
      this = entity_ptr(a,a->IdTable[Id]);
      xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind,
          1/* rnr_valid */, this->RNR/* rnr */, a->IdTypeTable[this->No]);
        /* check for RNR                                            */
      if(this->RNR==1) {
        this->RNR = 0;
        return 1;
      }
        /* if no buffers are provided by the application, the       */
        /* application want to copy the data itself including       */
        /* N_MDATA/LL_MDATA chaining                                */
      if(!this->RNR && !this->RNum) {
        xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind,
            2/* rnr_valid */, 0/* rnr */, a->IdTypeTable[this->No]);
        return 0;
      }
        /* if there is no RNR, set the More flag                    */
      this->RCurrent = 0;
      this->ROffset = 0;
    }
    if(this->RNR==2) {
      if(Ind!=this->MInd) {
        this->RCurrent = 0xff;
        this->RNR = 0;
      }
      return 0;
    }
        /* if we have received buffers from the application, copy   */
        /* the data into these buffers                              */
    offset = 0;
    R = PTR_R(a,this);
    do {
      if(this->ROffset==R[this->RCurrent].PLength) {
        this->ROffset = 0;
        this->RCurrent++;
      }
      if (cma) {
        clength = MIN(MLength, R[this->RCurrent].PLength-this->ROffset);
      } else {
        clength = MIN(a->ram_inw(a, &RBuffer->length)-offset,
                      R[this->RCurrent].PLength-this->ROffset);
      }
      if(R[this->RCurrent].P) {
        if (cma) {
          memcpy (PTR_P(a,this,&R[this->RCurrent].P[this->ROffset]),
                  &cma[offset],
                  clength);
        } else {
          a->ram_in_buffer(a,
                           &RBuffer->P[offset],
                           PTR_P(a,this,&R[this->RCurrent].P[this->ROffset]),
                           clength);
        }
      }
      offset +=clength;
      this->ROffset +=clength;
      if (cma) {
        if (offset >= MLength) {
          break;
        }
        continue;
      }
    } while(offset<(a->ram_inw(a, &RBuffer->length)));
        /* if it's the last buffer of the packet, call the          */
        /* application callback function for the receive complete   */
        /* call                                                     */
    if(Ind!=this->MInd) {
      R[this->RCurrent].PLength = this->ROffset;
      if(this->ROffset) this->RCurrent++;
      this->RNum = this->RCurrent;
      this->RCurrent = 0xff;
      this->Ind = Ind;
      this->complete = 2;
      xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind,
          3/* rnr_valid */, 0/* rnr */, a->IdTypeTable[this->No]);
      CALLBACK(a, this);
    }
    return 0;
  }
  return 2;
}
#if defined(XDI_USE_XLOG)
/* -----------------------------------------------------------
   This function works in the same way as xlog on the
   active board
   ----------------------------------------------------------- */
static void xdi_xlog (byte *msg, word code, int length) {
  xdi_dbg_xlog ("\x00\x02", msg, code, length);
}
#endif
/* -----------------------------------------------------------
    This function writes the information about the Return Code
    processing in the trace buffer. Trace ID is 221.
    INPUT:
        Adapter - system unicue adapter number (0 ... 255)
        Id      - Id of the entity that had sent this return code
        Ch      - Channel of the entity that had sent this return code
        Rc      - return code value
        cb:       (0...2)
                  switch (cb) {
                   case 0: printf ("DELIVERY"); break;
                   case 1: printf ("CALLBACK"); break;
                   case 2: printf ("ASSIGN"); break;
                  }
                  DELIVERY - have entered isdn_rc with this RC
                  CALLBACK - about to make callback to the application
                             for this RC
                  ASSIGN   - about to make callback for RC that is result
                             of ASSIGN request. It is no DELIVERY message
                             before of this message
        type   - the Id that was sent by the ASSIGN of this entity.
                 This should be global Id like NL_ID, DSIG_ID, MAN_ID.
                 An unknown Id will cause "?-" in the front of the request.
                 In this case the log.c is to be extended.
   ----------------------------------------------------------- */
static void xdi_xlog_rc_event (byte Adapter,
                               byte Id, byte Ch, byte Rc, byte cb, byte type) {
#if defined(XDI_USE_XLOG)
  word LogInfo[4];
  PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
  PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
  PUT_WORD(&LogInfo[2], ((word)Rc | (word)(type << 8)));
  PUT_WORD(&LogInfo[3], cb);
  xdi_xlog ((byte*)&LogInfo[0], 221, sizeof(LogInfo));
#endif
}
/* ------------------------------------------------------------------------
    This function writes the information about the request processing
    in the trace buffer. Trace ID is 220.
    INPUT:
        Adapter - system unicue adapter number (0 ... 255)
        Id      - Id of the entity that had sent this request
        Ch      - Channel of the entity that had sent this request
        Req     - Code of the request
        type    - the Id that was sent by the ASSIGN of this entity.
                  This should be global Id like NL_ID, DSIG_ID, MAN_ID.
                  An unknown Id will cause "?-" in the front of the request.
                  In this case the log.c is to be extended.
   ------------------------------------------------------------------------ */
static void xdi_xlog_request (byte Adapter, byte Id,
                              byte Ch, byte Req, byte type) {
#if defined(XDI_USE_XLOG)
  word LogInfo[3];
  PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
  PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
  PUT_WORD(&LogInfo[2], ((word)Req | (word)(type << 8)));
  xdi_xlog ((byte*)&LogInfo[0], 220, sizeof(LogInfo));
#endif
}
/* ------------------------------------------------------------------------
    This function writes the information about the indication processing
    in the trace buffer. Trace ID is 222.
    INPUT:
        Adapter - system unicue adapter number (0 ... 255)
        Id      - Id of the entity that had sent this indication
        Ch      - Channel of the entity that had sent this indication
        Ind     - Code of the indication
        rnr_valid: (0 .. 3) supported
          switch (rnr_valid) {
            case 0: printf ("DELIVERY"); break;
            case 1: printf ("RNR=%d", rnr);
            case 2: printf ("RNum=0");
            case 3: printf ("COMPLETE");
          }
          DELIVERY - indication entered isdn_rc function
          RNR=...  - application had returned RNR=... after the
                     look ahead callback
          RNum=0   - aplication had not returned any buffer to copy
                     this indication and will copy it self
          COMPLETE - XDI had copied the data to the buffers provided
                     bu the application and is about to issue the
                     final callback
        rnr:  Look case 1 of the rnr_valid
        type: the Id that was sent by the ASSIGN of this entity. This should
              be global Id like NL_ID, DSIG_ID, MAN_ID. An unknown Id will
              cause "?-" in the front of the request. In this case the
              log.c is to be extended.
   ------------------------------------------------------------------------ */
static void xdi_xlog_ind (byte Adapter,
                          byte Id,
                          byte Ch,
                          byte Ind,
                          byte rnr_valid,
                          byte rnr,
                          byte type) {
#if defined(XDI_USE_XLOG)
  word LogInfo[4];
  PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
  PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
  PUT_WORD(&LogInfo[2], ((word)Ind | (word)(type << 8)));
  PUT_WORD(&LogInfo[3], ((word)rnr | (word)(rnr_valid << 8)));
  xdi_xlog ((byte*)&LogInfo[0], 222, sizeof(LogInfo));
#endif
}
