Research V7 development
authorDennis Ritchie <dmr@research.uucp>
Sun, 13 May 1979 22:22:09 +0000 (17:22 -0500)
committerDennis Ritchie <dmr@research.uucp>
Sun, 13 May 1979 22:22:09 +0000 (17:22 -0500)
Work on file usr/sys/dev/rl.c

Synthesized-from: v7

usr/sys/dev/rl.c [new file with mode: 0644]

diff --git a/usr/sys/dev/rl.c b/usr/sys/dev/rl.c
new file mode 100644 (file)
index 0000000..86fd81e
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ *  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);
+}