Coherent4.2.10/coh.386/fifo.c

/* $Header: /ker/coh.386/RCS/fifo.c,v 2.5 93/10/29 00:55:09 nigel Exp Locker: nigel $ */
/*
 * $Log:	fifo.c,v $
 * Revision 2.5  93/10/29  00:55:09  nigel
 * R98 (aka 4.2 Beta) prior to removing System Global memory
 * 
 * Revision 2.4  93/08/19  03:26:26  nigel
 * Nigel's r83 (Stylistic cleanup)
 * 
 * Revision 2.3  93/07/26  14:59:42  nigel
 * Nigel's R80
 * 
 * Revision 1.3  93/04/14  10:06:27  root
 * r75
 * 
 * Revision 1.2  92/01/06  11:59:11  hal
 * Compile with cc.mwc.
 */

#include <kernel/typed.h>


/*
 * Arguments are passed into the kernel through boot_gift.
 * If you start getting "Not enough room for all arguments." messages
 * at boot time, just increase the BG_LEN  to whatever you need.
 * This structure is EXACTLY BG_LEN bytes long.
 */

TYPED_SPACE(boot_gift, BG_LEN, T_FIFO_SIC);

/*
 * fifo_open()
 *
 * Open a typed space as a fifo.
 *
 * Takes a typed_space that is already allocated, and a mode.    The type of
 * the typed space must be a FIFO.  Only T_FIFO_SIC has been implemented
 * (static, in-core fifo).
 *
 * The mode indicates whether to open for reading or writing.
 *  mode == 0 means read only.
 *  mode == 1 means write only.
 *  Other values are illegal.
 *
 * Returns a pointer to an initialized FIFO structure.  FIFO structures are
 * allocated from a pre-allocated array.  Returns F_NULL if it can't open
 * the fifo.
 */
FIFO *
fifo_open(fifo_space, mode)
typed_space *fifo_space;
int mode;
{
	/* ff_table is a table of FIFO structures which can be allocated on
	 * demand.  It is functionally similiar to the file descriptor table
	 * in the kernel.
	 */
	static FIFO ff_table[NFIFOS];
	static int inited = 0;	/* Has ff_table been initialized?  */

	int i;		/* A handy counter.  */
	FIFO *the_fifo;	/* The fifo we are going to allocate.  */

	/* Initialize ff_table the first time we get called.  */
	if (! inited) {
		for (i = 0; i < NFIFOS; ++i) {
			ff_table[i].f_space = F_NULL;
			ff_table[i].f_flags = 0;
		}
		inited = 1;
	}

	/* Check the type of the space we were passed.  */
	switch (fifo_space->ts_type) {

	case T_FIFO:	/* Overly general type, assuming SIC.  */
		fifo_space->ts_type = T_FIFO_SIC;
		break;

	case T_FIFO_SIC:	/* Static In-core Fifo.  */
		break;

	case T_FIFO_DIC:	/* Dynamic In-core Fifo (can grow).  */
		return F_NULL;	/* Unimplemented.  */

	case T_FIFO_SP:	/* Static Permanent Fifo (fixed size file). */
		return F_NULL;	/* Unimplemented.  */

	case T_FIFO_DP:	/* Dynamic Permanent Fifo (ordinary file).  */
		return F_NULL;	/* Unimplemented.  */

	default:
		return F_NULL;	/* Illegal type encountered.  */
	}

	/* ASSERTION: fifo_space is a valid and implemented FIFO.  */

	/* Find the first free FIFO structure.  */

	/* This should be re-implemented using a malloc-based scheme.
	 * At the moment, the tertiary boot libraries do not include a
	 * malloc.
	 */
	for (i = 0 ; i < NFIFOS && ff_table[i].f_flags != 0 ; i ++)
		/* DO NOTHING */ ;

	if (NFIFOS == i)
		return F_NULL;	/* No more free fifo structs.  */

	the_fifo = ff_table + i;

	/* ASSERTION: the_fifo points at a FIFO we can take.  */

	/* Initialize the FIFO struct.  */
	the_fifo->f_space = fifo_space;
	the_fifo->f_offset = fifo_space->ts_data;

	/* Initilize the flags.  */
	switch(mode) {
	case 0:	/* read */
		the_fifo->f_flags |= F_READ;
		break;
	case 1:	/* write */
		the_fifo->f_flags |= F_WRITE;
		break;
	default:
		return F_NULL;	/* Illegal mode flag.  */
	}
		
	return the_fifo;
}

/*
 * fifo_close()
 *
 * Finish with using a typed space as a fifo.
 * Free up FIFO structure associated with a typed space.
 * Returns 0 if ffp was not open, 1 otherwise.
 */
int
fifo_close(ffp)
FIFO *ffp;
{
	if (0 == ffp->f_flags)
		return 0;	/* This ffp is not open.  */

	ffp->f_space = F_NULL;
	ffp->f_offset = 0;
	ffp->f_flags = 0;

	return 1;
}


/*
 * fifo_read()
 *
 * Read a typed space from a fifo.
 * Return a pointer to the next typed space in the fifo ffp.  Returns
 * NULL on end of fifo.
 *
 * This read assumes that ffp->f_space has type T_FIFO_SIC.
 */

typed_space *
fifo_read(ffp)
register FIFO *ffp;
{
	typed_space *retval;

	/* Read MUST be set.  */
	if (F_READ != F_READ & ffp->f_flags ) {
		printf(" fifo_read: READ not set ");
		return 0;  /* This ffp is not open for reading.  */
	}

	/* From here to the end of fifo_read is really fifo_read_sic().  */


	/* Space of size 0 marks EOFIFO.  */
	if (ffp->f_offset->ts_size == 0) {
		printf(" fifo_read: space of size 0 ");
		retval = 0;
	} else {
		/* Return the next space.  */
		retval = ffp->f_offset;
		/* Advance to the next space.  */
		(char *) ffp->f_offset += ffp->f_offset->ts_size;
	}

	return retval;
}