
/*
 *
 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), (word)(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 information */
					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                                              */
/*------------------------------------------------------------------*/
static 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                                               */
/*------------------------------------------------------------------*/
static 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, (word)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, (word)(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   - application 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
}
