RL02 Driver for Stand Alone System (4.1BSD)
Perry Kivolowitz
perry at sbcs.UUCP
Wed Sep 21 13:11:05 AEST 1983
kernel verision and rlreg.h also sent to net.sources
this file goes in /sys/stand
--------------------------------------------------------------------------
/* Stand alone rl02 driver Lory Molesky (lory at sbcs) */
/* (philabs!sbcs!lory) */
/* Hacked from stand alone rk.c and multiuser rl.c */
#include "../h/param.h"
#include "../h/rlreg.h"
#include "../h/inode.h"
#include "../h/pte.h"
#include "../h/ubareg.h"
#include "saio.h"
#include "savax.h"
u_short rlstd[] = { 0174400 };
short rl_off[] = { 0, 361, 0, -1, -1, -1, -1, -1 };
/* RL02 drive structure */
struct RL02 {
short nbpt; /* Number of 512 byte blocks/track */
short ntrak;
short nbpc; /* Number of 512 byte blocks/cylinder */
short ncyl;
short btrak; /* Number of bytes/track */
} rl02 = {
20, 2, 40, 512, 20*512
};
rlopen(io)
register struct iob *io;
{
register struct rldevice *rladdr = (struct rldevice *)ubamem(io->i_unit, rlstd[0]);
if (rl_off[io->i_boff] == -1 ||
io->i_boff < 0 || io->i_boff > 7)
_stop("rl bad unit");
io->i_boff = rl_off[io->i_boff] * NRLSECT*NRLTRKS;
rladdr->rlda.getstat = RL_RESET;
rlwait(rladdr);
}
rlstrategy(io, func)
register struct iob *io;
{
register struct rldevice *rladdr = (struct rldevice *)ubamem(io->i_unit, rlstd[0]);
int com,ctr,diff,temp_mp;
daddr_t bn;
short dn, cn, sn, tn;
short dn_curr, cn_curr, hd_curr, hd, cc_curr, sn_curr, word_count;
int ubinfo, errcnt = 0;
retry:
ubinfo = ubasetup(io, 1);
bn = io->i_bn << 1;
dn = io->i_unit;
/* validate drive status */
do {
rladdr->rlda.getstat = RL_RESET;
rladdr->rlcs = (dn <<8) | RL_GETSTAT; /* Get status*/
rlwait(rladdr);
} while( (rladdr->rlmp.getstat&RLMP_STATUS) != RLMP_STATOK && ++ctr<8 );
cc_curr = io->i_cc; /* current word count */
search:
/* Determine disk position */
hd = (bn / NRLSECT) & 1;
cn = bn/(NRLSECT*NRLTRKS);
sn = bn%NRLSECT;
rladdr->rlcs = (dn << 8) | RL_RHDR;
rlwait(rladdr);
/* mpr has 0-5 sector add. 6 head select. 7-15 Cylinder Address */
temp_mp = rladdr->rlmp.readhdr;
cn_curr = (temp_mp >> 7) & 0777;
hd_curr = (temp_mp >> 6) & 01;
diff = cn_curr - cn;
if ((diff != 0) || (hd_curr != hd)) {
/* Do a seek */
if (diff < 0)
rladdr->rlda.seek = -diff << 7 | RLDA_HGH | hd << 4;
else
rladdr->rlda.seek = diff << 7 | RLDA_LOW | hd << 4;
rladdr->rlcs = (dn << 8) | RL_SEEK;
rlwait(rladdr);
}
onesec:
word_count = (cc_curr < 256) ? cc_curr : 256;
rladdr->rlmp.rw = -(word_count >> 1);
rladdr->rlda.rw = (cn << 7) | (hd << 6) | sn;
rladdr->rlba = ubinfo;
com = (dn << 8) ;
if (func == READ)
com |= RL_READ;
else
com |= RL_WRITE;
rladdr->rlcs = com;
rlwait(rladdr);
cc_curr -= NRLBPSC;
bn +=1;
ubinfo += NRLBPSC;
if ((cc_curr <= 0) || (cn >= NRLCYLN)) goto leave;
goto search;
leave:
ubafree(io, ubinfo);
return (io->i_cc);
}
rlwait(rladdr)
register struct rldevice *rladdr;
{
while ((rladdr->rlcs & RL_CRDY) == 0)
;
}
More information about the Comp.sources.unix
mailing list