SRI-NOSC/ncpk/drivers/ill.c
#
#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;
}