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;
}