
/*
 *
 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"
#if defined(DIVA_ISTREAM) /* { */
#include "pc.h"
#include "pr_pc.h"
#include "di_defs.h"
#include "divasync.h"
#include "di.h"
#if !defined USE_EXTENDED_DEBUGS
#include "dimaint.h"
#else
#define dprintf
#endif
#include "dfifo.h"
int diva_istream_write(void *context,
		       int   Id,
		       void *data,
		       int length,
		       int final,
		       byte usr1,
		       byte usr2);
int diva_istream_read(void *context,
		      int Id,
		      void *data,
		      int max_length,
		      int *final,
		      byte *usr1,
		      byte *usr2);
/* -------------------------------------------------------------------
   Does provide iStream interface to the client
   ------------------------------------------------------------------- */
void diva_xdi_provide_istream_info(ADAPTER *a,
				   diva_xdi_stream_interface_t *pi) {
	pi->provided_service = 0;
}
/* ------------------------------------------------------------------
   Does write the data from caller's buffer to the card's
   stream interface.
   If synchronous service was requested, then function
   does return amount of data written to stream.
   'final' does indicate that piece of data to be written is
   final part of frame (necessary only by structured datatransfer)
   return  0 if zero lengh packet was written
   return -1 if stream is full
   ------------------------------------------------------------------ */
int diva_istream_write(void *context,
		       int Id,
		       void *data,
		       int length,
		       int final,
		       byte usr1,
		       byte usr2) {
	ADAPTER *a = (ADAPTER *)context;
	int written = 0, to_write = -1;
	char tmp[4];
	byte *data_ptr = (byte *)data;
	for (;;) {
		a->ram_in_dw(a,
#ifdef PLATFORM_GT_32BIT
			      ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]),
#else
			      (void *)(a->tx_stream[Id] + a->tx_pos[Id]),
#endif
			      (dword *)&tmp[0],
			      1);
		if (tmp[0] & DIVA_DFIFO_READY) { /* No free blocks more */
			if (to_write < 0)
				return (-1); /* was not able to write       */
			break;     /* only part of message was written */
		}
		to_write = min(length, DIVA_DFIFO_DATA_SZ);
		if (to_write) {
			a->ram_out_buffer(a,
#ifdef PLATFORM_GT_32BIT
					   ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id] + 4),
#else
					   (void *)(a->tx_stream[Id] + a->tx_pos[Id] + 4),
#endif
					   data_ptr,
					   (word)to_write);
			length  -= to_write;
			written  += to_write;
			data_ptr += to_write;
		}
		tmp[1] = (char)to_write;
		tmp[0] = (tmp[0] & DIVA_DFIFO_WRAP) |
			DIVA_DFIFO_READY |
			((!length && final) ? DIVA_DFIFO_LAST : 0);
		if (tmp[0] & DIVA_DFIFO_LAST) {
			tmp[2] = usr1;
			tmp[3] = usr2;
		}
		a->ram_out_dw(a,
#ifdef PLATFORM_GT_32BIT
			       ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]),
#else
			       (void *)(a->tx_stream[Id] + a->tx_pos[Id]),
#endif
			       (dword *)&tmp[0],
			       1);
		if (tmp[0] & DIVA_DFIFO_WRAP) {
			a->tx_pos[Id]  = 0;
		} else {
			a->tx_pos[Id] += DIVA_DFIFO_STEP;
		}
		if (!length) {
			break;
		}
	}
	return (written);
}
/* -------------------------------------------------------------------
   In case of SYNCRONOUS service:
   Does write data from stream in caller's buffer.
   Does return amount of data written to buffer
   Final flag is set on return if last part of structured frame
   was received
   return 0  if zero packet was received
   return -1 if stream is empty
   return -2 if read buffer does not profide sufficient space
   to accommodate entire segment
   max_length should be at least 68 bytes
   ------------------------------------------------------------------- */
int diva_istream_read(void *context,
		      int Id,
		      void *data,
		      int max_length,
		      int *final,
		      byte *usr1,
		      byte *usr2) {
	ADAPTER *a = (ADAPTER *)context;
	int read = 0, to_read = -1;
	char tmp[4];
	byte *data_ptr = (byte *)data;
	*final = 0;
	for (;;) {
		a->ram_in_dw(a,
#ifdef PLATFORM_GT_32BIT
			      ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]),
#else
			      (void *)(a->rx_stream[Id] + a->rx_pos[Id]),
#endif
			      (dword *)&tmp[0],
			      1);
		if (tmp[1] > max_length) {
			if (to_read < 0)
				return (-2); /* was not able to read */
			break;
		}
		if (!(tmp[0] & DIVA_DFIFO_READY)) {
			if (to_read < 0)
				return (-1); /* was not able to read */
			break;
		}
		to_read = min(max_length, (int)tmp[1]);
		if (to_read) {
			a->ram_in_buffer(a,
#ifdef PLATFORM_GT_32BIT
					 ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id] + 4),
#else
					 (void *)(a->rx_stream[Id] + a->rx_pos[Id] + 4),
#endif
					 data_ptr,
					 (word)to_read);
			max_length -= to_read;
			read     += to_read;
			data_ptr  += to_read;
		}
		if (tmp[0] & DIVA_DFIFO_LAST) {
			*final = 1;
		}
		tmp[0] &= DIVA_DFIFO_WRAP;
		a->ram_out_dw(a,
#ifdef PLATFORM_GT_32BIT
			      ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]),
#else
			      (void *)(a->rx_stream[Id] + a->rx_pos[Id]),
#endif
			      (dword *)&tmp[0],
			      1);
		if (tmp[0] & DIVA_DFIFO_WRAP) {
			a->rx_pos[Id]  = 0;
		} else {
			a->rx_pos[Id] += DIVA_DFIFO_STEP;
		}
		if (*final) {
			if (usr1)
				*usr1 = tmp[2];
			if (usr2)
				*usr2 = tmp[3];
			break;
		}
	}
	return (read);
}
/* ---------------------------------------------------------------------
   Does check if one of streams had caused interrupt and does
   wake up corresponding application
   --------------------------------------------------------------------- */
void pr_stream(ADAPTER *a) {
}
#endif /* } */
