home *** CD-ROM | disk | FTP | other *** search
- /*
- * RL disk driver
- */
-
- #define DK_N 2
- #include "../h/param.h"
- #include "../h/buf.h"
- #include "../h/dir.h"
- #include "../h/user.h"
- #include "../h/systm.h"
-
- #define NRLBLK 10240
- #define RLCYLSZ 10240
- #define RLSECSZ 256
-
- #define RESET 013
- #define STAT 03
- #define GETSTAT 04
- #define WCOM 012
- #define RCOM 014
- #define SEEK 06
- #define SEEKHI 5
- #define SEEKLO 1
- #define RDHDR 010
- #define IENABLE 0100
- #define CRDY 0200
- #define OPI 02000
- #define CRCERR 04000
- #define TIMOUT 010000
- #define NXM 020000
- #define DE 040000
-
- struct device
- {
- int rlcs, rlba, rlda, rlmp;
- };
-
- #define RLADDR ((struct device *)0174400)
- #define RL_CNT 1
- struct buf rrlbuf;
- struct buf rltab;
-
- struct
- {
- int cn[4]; /* location of heads for each drive */
- int dn; /* drive number */
- int com; /* read or write command word */
- int chn; /* cylinder and head number */
- unsigned int bleft; /* bytes left to be transferred */
- unsigned int bpart; /* number of bytes transferred */
- int sn; /* sector number */
- union {
- int w[2];
- long l;
- } addr; /* address of memory for transfer */
-
- } rl = {-1,-1,-1,-1};
-
- rlstrategy(bp)
- register struct buf *bp;
- {
- if(bp->b_blkno >= NRLBLK) {
- if(bp->b_blkno == NRLBLK && bp->b_flags&B_READ)
- bp->b_resid = bp->b_bcount;
- else {
- bp->b_flags |= B_ERROR;
- bp->b_error = ENXIO;
- }
- iodone(bp);
- return;
- }
- bp->av_forw = NULL;
- spl5();
- if(rltab.b_actf == NULL)
- rltab.b_actf = bp;
- else
- rltab.b_actl->av_forw = bp;
- rltab.b_actl = bp;
- if(rltab.b_active == NULL)
- rlstart();
- spl0();
- }
-
- rlstart()
- {
-
- register struct buf *bp;
-
- if ((bp = rltab.b_actf) == NULL)
- return;
- rltab.b_active++;
- rl.dn = minor(bp->b_dev);
- rl.chn = bp->b_blkno/20;
- rl.sn = (bp->b_blkno%20) << 1;
- rl.bleft = bp->b_bcount;
- rl.addr.w[0] = bp->b_xmem & 3;
- rl.addr.w[1] = (int)bp->b_un.b_addr;
- rl.com = (rl.dn << 8) | IENABLE;
- if (bp->b_flags & B_READ)
- rl.com |= RCOM;
- else
- rl.com |= WCOM;
- rlio();
- }
-
- rlintr()
- {
- register struct buf *bp;
- register struct device *rp;
- register int status;
-
- rp = RLADDR;
- if (rltab.b_active == NULL) {
- /*
- logstray(rp);
- */
- return;
- }
- bp = rltab.b_actf;
- dk_busy &= ~(1<<DK_N);
- if (rp->rlcs < 0) { /* error bit */
- if (rp->rlcs & 036000) {
- if(rltab.b_errcnt > 2)
- deverror(bp, rp->rlcs, rp->rlda);
- }
- if (rp->rlcs & 040000) {
- rp->rlda = STAT;
- rp->rlcs = (rl.dn << 8) | GETSTAT;
- while ((rp->rlcs & CRDY) == 0)
- ;
- status = rp->rlmp;
- if(rltab.b_errcnt > 2)
- deverror(bp, status, rp->rlda);
- rp->rlda = RESET;
- rp->rlcs = (rl.dn << 8) | GETSTAT;
- while ((rp->rlcs & CRDY) == 0)
- ;
- if(status & 01000) {
- rlstart();
- return;
- }
- }
- if (++rltab.b_errcnt <= 10) {
- rl.cn[rl.dn] = -1;
- rlstart();
- return;
- }
- else {
- bp->b_flags |= B_ERROR;
- rl.bpart = rl.bleft;
- }
- }
-
- if ((rl.bleft -= rl.bpart) > 0) {
- rl.addr.l += rl.bpart;
- rl.sn=0;
- rl.chn++;
- rlio();
- return;
- }
- rltab.b_active = NULL;
- rltab.b_errcnt = 0;
- rltab.b_actf = bp->av_forw;
- bp->b_resid = 0;
- iodone(bp);
- rlstart();
- }
-
- rlio()
- {
-
- register struct device *rp;
- register dif;
- register int head;
-
- rp = RLADDR;
- dk_busy |= 1<<DK_N;
- dk_numb[DK_N] += 1;
- head = rl.bpart>>6;
- dk_wds[DK_N] += head;
- if (rl.cn[rl.dn] < 0) {
- rp->rlcs = (rl.dn << 8) | RDHDR;
- while ((rp->rlcs&CRDY) == 0)
- ;
- rl.cn[rl.dn] = (rp->rlmp&077700) >> 6;
- }
- dif =(rl.cn[rl.dn] >> 1) - (rl.chn >>1);
- head = (rl.chn & 1) << 4;
- if (dif < 0)
- rp->rlda = (-dif <<7) | SEEKHI | head;
- else
- rp->rlda = (dif << 7) | SEEKLO | head;
- rp->rlcs = (rl.dn << 8) | SEEK;
- rl.cn[rl.dn] = rl.chn;
- if (rl.bleft < (rl.bpart = RLCYLSZ - (rl.sn * RLSECSZ)))
- rl.bpart = rl.bleft;
- while ((rp->rlcs&CRDY) == 0)
- ;
- rp->rlda = (rl.chn << 6) | rl.sn;
- rp->rlba = rl.addr.w[1];
- rp->rlmp = -(rl.bpart >> 1);
- rp->rlcs = rl.com | rl.addr.w[0] << 4;
- }
-
- rlread(dev)
- {
-
- physio(rlstrategy, &rrlbuf, dev, B_READ);
- }
-
- rlwrite(dev)
- {
-
- physio(rlstrategy, &rrlbuf, dev, B_WRITE);
- }
-