SRI-NOSC/ncpk/drivers/ill.c

Compare this file to the similar file:
Show the results in this format:

#
#include "param.h"
#include "user.h"
#include "buf.h"
#include "net_net.h"
#include "net_netbuf.h"
#include "net_ill.h"
#include "net_imp.h"
#include "file.h"
#include "net_ncp.h"
#include "net_contab.h"



/*name:
	imp_init
function:
	to initialize the imp interface hardware

algorithm:
	reset the imp interface
	start strobing the host master ready bit
	enable interrupts

parameters:
	none

returns:
	nothing

globals:
	lbolt
	HMR_interval=
	IMPADDR-> status regs

calls:
	set_HMR
	sleep	(sys)

called by:
	impopen	(impio.c)

history:
	initial coding 10/5/75 S. F. Holmgren
	Recoded for modularity 15Feb77 JSK

*/

imp_init()
{
	int i;
	extern lbolt;
	

	IMPADDR->omaint =| omreset;
	/* reset any input extended memory bits */
	IMPADDR->imaint = IMPADDR->omaint = 0;
	HMR_interval = 60;
	set_HMR ();	/* start strobing host master ready */
	while( IMPADDR->imaint&imimprdy == 0)
		sleep (&lbolt, 0);	/* until imp says is up */

	/* enable interrupts */
	IMPADDR->istat = isintenb;
	IMPADDR->ostat = osintenb;


}
/*name:
	imp_output

function:
	Takes buffers( see buf.h ) linked into the impotab active
	queue and applies them to the imp interface.

algorithm:
	check to see if the queue is empty if so return
	set the active bit
	enable output interrupts and the endmsg bit( imp interface manual)
	calculate then end address and perform the mod 2 function
	on the calculated address( again see imp interface manual)
	load the start output address register
	load the end output address register which is also an implied
	go

parameters:
	none

returns:
	nothing

globals:
	impotab.d_active
	IMPADDR-> output regs
	(buffer)

calls:
	printf		(sys)

called by:
	impstrat	(impio.c)
	imp_odone	(impio.c)

history:
	initial coding 1/7/75 by S. F. Holmgren

*/

#ifdef IMPPRTDEBUG
int imp_o_debug;
# endif

imp_output()
{
	register struct buf *bp;
	register char *endaddr;
	register char *addr;

	
	if((bp = impotab.d_actf) == 0)
		return;			/* return nothing to do */

	impotab.d_active++;		/* something to do set myself active */

	/* set or reset disable endmsg according to user wishes */
	IMPADDR->ostat = osintenb | (bp->b_blkno ? osdiseom : 0) ;

	endaddr = bp->b_addr + bp->b_wcount;	/* generate second address */
	/*
	 * imp interface expects address of last word to be transferred.
	 * if low order bit is on, only 1 byte of last word is sent. Blech !
	 * NOTE: bp->b_wcount is really a byte count
	 */
	endaddr = endaddr&01 ? endaddr : endaddr-2;

	IMPADDR->spo = bp->b_addr;	/* load start addr */
	IMPADDR->epo = endaddr;		/* load endaddr and go */

#ifdef	IMPPRTDEBUG
	if (imp_o_debug) {
		printf ("IMP: ");	/* print first 24 bytes in olctal */
		addr = bp->b_addr;
		endaddr = bp->b_addr + bp->b_wcount-1;
		if (endaddr > addr+24)
			endaddr = addr+24;
		for (;addr<endaddr;addr++)
			printf ("%o ", *addr & 0377);
		printf ("\n");
	}
#endif
	
}



/*name:
	impread

function:
	to apply an input area to the input side of the imp interface

algorithm:
	inhibit interrupts
	calculate transfer parameters and save in globals
	load interface with saved parameters
	load end input register with address+size passed

parameters:
	addr - start address in which to store imp input data
	size - available number of bytes in which to store said data

returns:
	nothing

globals:
	impi_adr=
	impi_wcnt=

calls:
	spl_imp

called by:
	flushimp	(impio.c)
	ihbget		(impio.c)
	impopen		(impio.c)
	hh		(impio.c)
	ih		(impio.c)

history:
	initial coding 1/7/75 by S. F. Holmgren

*/

impread( addr,size )		/* start a read from imp into data area */
{
	spl_imp ();			/* not to be interrupted, please */
	impi_adr = addr;
	impi_wcnt = size>>1;
	IMPADDR->spi = addr;
	IMPADDR->epi = addr + size;
	

}

/*name:
	ill_oint

function:
	This is the imp output interrupt.

algorithm:
	Check for unexpected interrupts from the imp
	Check for errors
	call impodone

parameters:
	none

returns:
	nothing

globals:
	impotab.d_active
	IMPADDR->ostat

calls:
	imp_odone	(impio.c)
	printf		(sys)

called by:
	hardware interrupt

history:
	initial coding 1/7/75 by S. F. Holmgren
	recoded 15Feb77 for modularity JSK

*/

ill_oint()
{
	char errbits;

	if (impotab.d_active == 0) /* ignore unexpected interrupts */
		return;

	errbits = 0;
	if( IMPADDR->ostat & ostimout )	/* timeout errror */
	{
		errbits++;
		printf ("IMP: Timeout\n");
	}
	imp_odone (errbits);
}
/*
name:
	imp_iint

function:
	Wakes up the input process

algorithm:
	calulate device dependant values of msglen end of msg and errors
	wakes up input process

parameters:

	none


returns:
	nothing

globals:
	imp_stat.error=
	imp_stat.inpendmsg=
	imp_stat.inpwcnt=

calls:
	wakeup		to start input handling process running

called by:
	hardware interrupt

history:
	coded by Steve Holmgren 04/28/75
	Recoded for modularity 15Feb77 JSK


*/

ill_iint()
{
	imp_stat.error = IMPADDR->istat & iserr; /* currently not filled in */
	imp_stat.inpendmsg = IMPADDR->istat & isendmsg;
	/* delvelop remainder word count, ala dec interface */
	imp_stat.inpwcnt = (IMPADDR->istat & isbufful) ?
		0 : ((IMPADDR->spi - impi_adr) >>1) - impi_wcnt;
	wakeup( &imp );
}
/*name:

/*name:
	set_HMR

function:
	To repeatedly tickle the host master ready bit of the imp interface

algorithm:
	if someone hasnt set HMR_interval to zero ( should i go away?? )
		set the host master ready bit
		setup timeout so that i am called again
	else
		wakeup the guy who reset HMR_interval

parameters:
	none

returns:
	nothing

globals:
	HMR_interval
	IMPADDR->omaint=	(host master ready)

calls:
	timeout(sys)

called by:
	imp_init
	timeout(sys)

history:
	initial coding 1/7/75 by S. F. Holmgren

*/

set_HMR()
{

	if( HMR_interval )
	{
		IMPADDR->omaint =| omhstrdy;
		timeout( &set_HMR,0,HMR_interval);	/* restart */
	}else{
		wakeup (&HMR_interval);
	}
}

/*
	spl_imp

function:
	centralize priority setting of imp because of variations
	in interface configurations

algorithm:
	call correct kernel procedure

parameters:
	none

returns:
	nothing

globals:
	none

calls:
	spl?

called by:
	anyone who fiddles with things that get changed by imp interrupts :

spl_imp	acc.c	impread
	
	contab.c entconta
	ill.c	impread
	
	impio.c	impopen
		impstrat
	kerbuf.c bytesout    
		catmsg
		freeb
		freebuf
		freekb
		getbuf
		getkb
		linkbuf
	ncpio.c	ncpclose
		ncpread	{      
		wf_setup
	nopcls.c netopen
	nrdwr.c	netread
		netsleep
		netwrite
		sendallo


history:
	Added 1 Feb 77 for compatibility with other imp-drivers,
		by JC McMillan

*/

spl_imp()
{
	spl4();	/* just high enuf to disalbe interrupts from imp iface */
}
/*name:
	imp_reset

function:
	reset interface

algorithm:
	reset host_master ready. Reset all other bits. Wait
	on HMR_interval insures that host_master_ready does not
	get reset by the clock routine

parameters:
	none

returns:
	nothing

globals:
	HMR_interval=
	IMPADDR->omant=

calls:
	printf	(sys)
	sleep	(sys)

called by:
	imp_dwn		(impio.c)
	impopen		(impio.c)

history:
	initial coding 08 Jan 77 by JSK

*/

imp_reset()
{
	printf("\nIMP:Reset\n");

	spl6 ();
	HMR_interval = 0;
	sleep (&HMR_interval);
	IMPADDR->omaint =| omreset;
}