2.11BSD/sys/OTHERS/rf11/rf.c
/*
* SCCS id @(#)rf.c 2.2 (2.11BSD GTE) 1/2/93
*/
#include "rf.h"
#if NRF > 0
#include "param.h"
#include "systm.h"
#include "buf.h"
#include "conf.h"
#include "user.h"
#include "rfreg.h"
#define NRFBLK 1024
struct rfdevice *RFADDR = (struct rfdevice *)0177460;
struct buf rftab;
rfattach(addr, unit)
struct rfdevice *addr;
{
if (unit != 0)
return(0);
RFADDR = addr;
return(1);
}
rfstrategy(bp)
register struct buf *bp;
{
if (RFADDR == (struct rfdevice *) NULL) {
bp->b_error = ENXIO;
goto errexit;
}
if (bp->b_blkno >= NRFBLK * (minor(bp->b_dev) + 1)) {
bp->b_error = EINVAL;
errexit:
bp->b_flags |= B_ERROR;
iodone(bp);
return;
}
mapalloc(bp);
bp->av_forw = (struct buf *) NULL;
(void) _spl5();
if (rftab.b_actf == NULL)
rftab.b_actf = bp;
else
rftab.b_actl->av_forw = bp;
rftab.b_actl = bp;
if (rftab.b_active == NULL)
rfstart();
(void) _spl0();
}
rfstart()
{
register struct rfdevice *rfaddr = RFADDR;
register struct buf *bp;
register com;
if ((bp = rftab.b_actf) == (struct buf *) NULL)
return;
rftab.b_active++;
rfaddr->rfdar = (short) (bp->b_blkno << 8) & 0177777;
rfaddr->rfdae = (short) (bp->b_blkno >> 8) & 037;
rfaddr->rfcma = bp->b_un.b_addr;
rfaddr->rfwc = - (bp->b_bcount >> 1);
com = (bp->b_xmem & 3) << 4;
if (bp->b_flags & B_READ)
com |= RF_RCOM | RF_IENABLE | RF_GO;
else
com |= RF_WCOM | RF_IENABLE | RF_GO;
rfaddr->rfdcs = com;
#ifdef RF_DKN
dk_busy |= 1 << RF_DKN;
dk_numb[RF_DKN]++;
dk_wds[RF_DKN] += (bp->b_bcount) >> 6;
#endif
}
rfintr()
{
register struct rfdevice *rfaddr = RFADDR;
register struct buf *bp;
if (rftab.b_active == (struct buf *) NULL)
return;
#ifdef RF_DKN
dk_busy &= ~ (1 << RF_DKN);
#endif
bp = rftab.b_actf;
rftab.b_active = (struct buf *) NULL;
if (rfaddr->rfdcs & RF_ERR) {
while ((rfaddr->rfdcs & RF_RDY) == 0)
;
if (rfaddr->rfdcs & RF_WLO)
/*
* Give up on write locked devices
* immediately.
*/
printf("rf%d: write locked\n", minor(bp->b_dev));
else
{
#ifdef UCB_DEVERR
harderr(bp, "rf");
printf("cs=%b dae=%b\n", rfaddr->rfdcs,
RF_BITS, rfaddr->rfdae, RFDAE_BITS);
#else
deverror(bp, rfaddr->rfdcs, rfaddr->rfdae);
#endif
rfaddr->rfdcs = RF_CTLCLR;
if (++rftab.b_errcnt <= 10) {
rfstart();
return;
}
}
bp->b_flags |= B_ERROR;
}
rftab.b_errcnt = 0;
rftab.b_actf = bp->av_forw;
bp->b_resid = -(rfaddr->rfwc << 1);
iodone(bp);
rfstart();
}
#endif NRF