1: /*
   2:  *	SCCS id	@(#)rl.c	2.1 (Berkeley)	11/20/83
   3:  */
   4: 
   5: /*
   6:  *  RL01/RL02 disk driver
   7:  */
   8: 
   9: #include "rl.h"
  10: #if NRL > 0
  11: #include "param.h"
  12: #include <sys/buf.h>
  13: #include <sys/dir.h>
  14: #include <sys/user.h>
  15: #include <sys/systm.h>
  16: #include <sys/conf.h>
  17: #include <sys/rlreg.h>
  18: 
  19: #define RL01_NBLKS  10240   /* Number of UNIX blocks for an RL01 drive */
  20: #define RL02_NBLKS  20480   /* Number of UNIX blocks for an RL02 drive */
  21: #define RL_CYLSZ    10240   /* bytes per cylinder */
  22: #define RL_SECSZ    256 /* bytes per sector */
  23: 
  24: #define rlwait(r)   while (((r)->rlcs & RL_CRDY) == 0)
  25: 
  26: struct  rldevice *RLADDR;
  27: 
  28: struct  buf rrlbuf;
  29: struct  buf rltab;
  30: 
  31: struct  rl_softc {
  32:     short   cn[4];      /* location of heads for each drive */
  33:     short   type[4];    /* parameter dependent on drive type (RL01/2) */
  34:     short   dn;     /* drive number */
  35:     short   com;        /* read or write command word */
  36:     short   chn;        /* cylinder and head number */
  37:     u_short bleft;      /* bytes left to be transferred */
  38:     u_short bpart;      /* number of bytes transferred */
  39:     short   sn;     /* sector number */
  40:     union   {
  41:         short   w[2];
  42:         long    l;
  43:     } rl_un;        /* address of memory for transfer */
  44: 
  45: } rl = {-1,-1,-1,-1, -1,-1,-1,-1}; /* initialize cn[] and type[] */
  46: 
  47: rlattach(addr, unit)
  48: struct rldevice *addr;
  49: {
  50:     if (unit != 0)
  51:         return(0);
  52:     RLADDR = addr;
  53:     return(1);
  54: }
  55: 
  56: rlstrategy(bp)
  57: register struct buf *bp;
  58: {
  59:     register struct rldevice *rp;
  60:     int s, nblocks, drive, ctr;
  61: 
  62:     if ((rp = RLADDR) == (struct rldevice *) NULL) {
  63:         bp->b_error = ENXIO;
  64:         goto bad;
  65:     }
  66: 
  67:     /*
  68: 	 * We must determine what type of drive we are talking to in order
  69: 	 * to determine how many blocks are on the device.  The rl.type[]
  70: 	 * array has been initialized with -1's so that we may test first
  71: 	 * contact with a particular drive and do this determination only once.
  72: 	 *
  73: 	 * For some unknown reason the RL02 (seems to be
  74: 	 * only drive 1) does not return a valid drive status
  75: 	 * the first time that a GET STATUS request is issued
  76: 	 * for the drive, in fact it can take up to three or more
  77: 	 * GET STATUS requests to obtain the correct status.
  78: 	 * In order to overcome this "HACK" the driver has been
  79: 	 * modified to issue a GET STATUS request, validate the
  80: 	 * drive status returned, and then use it to determine the
  81: 	 * drive type. If a valid status is not returned after eight
  82: 	 * attempts, then an error message is printed.
  83: 	 */
  84:     if (rl.type[minor(bp->b_dev)] < 0) {
  85:         drive = minor(bp->b_dev);
  86:         ctr = 0;
  87:         do { /* get status and reset when first touching this drive */
  88:             rp->rlda = RLDA_RESET | RLDA_GS;
  89:             rp->rlcs = (drive << 8) | RL_GETSTATUS; /* set up csr */
  90:             rlwait(rp);
  91:         } while (((rp->rlmp & 0177477) != 035) && (++ctr < 8));
  92:         if (ctr >= 8) {
  93:             printf("rl%d:  can't get status\n", drive);
  94:             rl.type[drive] = RL02_NBLKS;    /* assume RL02 */
  95:         } else if (rp->rlmp & RLMP_DTYP) {
  96:             rl.type[drive] = RL02_NBLKS;    /* drive is RL02 */
  97: #ifdef  DISTRIBUTION_BINARY
  98:             /*
  99: 			 * HACK-- for the 2.9 distribution binary,
 100: 			 * patch the swplo value if swapping on an RL02.
 101: 			 */
 102:             if ((bdevsw[major(swapdev)].d_strategy == rlstrategy)
 103:                 && (drive == minor(swapdev)) && (swplo == (8000-1)))
 104:                 swplo = (daddr_t) (17000 - 1);
 105: #endif
 106:         } else
 107:             rl.type[drive] = RL01_NBLKS;    /* drive RL01 */
 108:     }
 109:     /* determine nblocks based upon which drive this is */
 110:     nblocks = rl.type[minor(bp->b_dev)];
 111:     if(bp->b_blkno >= nblocks) {
 112:         if((bp->b_blkno == nblocks) && (bp->b_flags & B_READ))
 113:             bp->b_resid = bp->b_bcount;
 114:         else
 115:             {
 116:             bp->b_error = ENXIO;
 117: bad:
 118:             bp->b_flags |= B_ERROR;
 119:         }
 120:         iodone(bp);
 121:         return;
 122:     }
 123: #ifdef UNIBUS_MAP
 124:     mapalloc(bp);
 125: #endif
 126: 
 127:     bp->av_forw = NULL;
 128:     s = spl5();
 129:     if(rltab.b_actf == NULL)
 130:         rltab.b_actf = bp;
 131:     else
 132:         rltab.b_actl->av_forw = bp;
 133:     rltab.b_actl = bp;
 134:     if(rltab.b_active == NULL)
 135:         rlstart();
 136:     splx(s);
 137: }
 138: 
 139: rlstart()
 140: {
 141:     register struct rl_softc *rlp = &rl;
 142:     register struct buf *bp;
 143: 
 144:     if ((bp = rltab.b_actf) == NULL)
 145:         return;
 146:     rltab.b_active++;
 147:     rlp->dn = minor(bp->b_dev);
 148:     rlp->chn = bp->b_blkno / 20;
 149:     rlp->sn = (bp->b_blkno % 20) << 1;
 150:     rlp->bleft = bp->b_bcount;
 151:     rlp->rl_un.w[0] = bp->b_xmem & 3;
 152:     rlp->rl_un.w[1] = (int) bp->b_un.b_addr;
 153:     rlp->com = (rlp->dn << 8) | RL_IE;
 154:     if (bp->b_flags & B_READ)
 155:         rlp->com |= RL_RCOM;
 156:     else
 157:         rlp->com |= RL_WCOM;
 158:     rlio();
 159: }
 160: 
 161: rlintr()
 162: {
 163:     register struct buf *bp;
 164:     register struct rldevice *rladdr = RLADDR;
 165:     register status;
 166: 
 167:     if (rltab.b_active == NULL)
 168:         return;
 169:     bp = rltab.b_actf;
 170: #ifdef  RL_DKN
 171:     dk_busy &= ~(1 << RL_DKN);
 172: #endif	RL_DKN
 173:     if (rladdr->rlcs & RL_CERR) {
 174:         if (rladdr->rlcs & RL_HARDERR) {
 175:             if(rltab.b_errcnt > 2) {
 176: #ifdef  UCB_DEVERR
 177:                 harderr(bp, "rl");
 178:                 printf("cs=%b da=%b\n", rladdr->rlcs, RL_BITS,
 179:                     rladdr->rlda, RLDA_BITS);
 180: #else
 181:                 deverror(bp, rladdr->rlcs, rladdr->rlda);
 182: #endif	UCB_DEVERR
 183:             }
 184:         }
 185:         if (rladdr->rlcs & RL_DRE) {
 186:             rladdr->rlda = RLDA_GS;
 187:             rladdr->rlcs = (rl.dn <<  8) | RL_GETSTATUS;
 188:             rlwait(rladdr);
 189:             status = rladdr->rlmp;
 190:             if(rltab.b_errcnt > 2) {
 191: #ifdef  UCB_DEVERR
 192:                 harderr(bp, "rl");
 193:                 printf("mp=%b da=%b\n", status, RLMP_BITS,
 194:                     rladdr->rlda, RLDA_BITS);
 195: #else
 196:                 deverror(bp, status, rladdr->rlda);
 197: #endif
 198:             }
 199:             rladdr->rlda = RLDA_RESET | RLDA_GS;
 200:             rladdr->rlcs = (rl.dn << 8) | RL_GETSTATUS;
 201:             rlwait(rladdr);
 202:             if(status & RLMP_VCHK) {
 203:                 rlstart();
 204:                 return;
 205:             }
 206:         }
 207:         if (++rltab.b_errcnt <= 10) {
 208:             rl.cn[rl.dn] = -1;
 209:             rlstart();
 210:             return;
 211:         }
 212:         else
 213:             {
 214:             bp->b_flags |= B_ERROR;
 215:             rl.bpart = rl.bleft;
 216:         }
 217:     }
 218: 
 219:     if ((rl.bleft -= rl.bpart) > 0) {
 220:         rl.rl_un.l += rl.bpart;
 221:         rl.sn=0;
 222:         rl.chn++;
 223:         rlio();
 224:         return;
 225:     }
 226:     bp->b_resid = 0;
 227:     rltab.b_active = NULL;
 228:     rltab.b_errcnt = 0;
 229:     rltab.b_actf = bp->av_forw;
 230:     iodone(bp);
 231:     rlstart();
 232: }
 233: 
 234: rlio()
 235: {
 236: 
 237:     register struct rldevice *rladdr = RLADDR;
 238:     register dif;
 239:     register head;
 240: 
 241: #ifdef  RL_DKN
 242:     dk_busy |= 1 << RL_DKN;
 243:     dk_numb[RL_DKN]++;
 244:     head = rl.bpart >> 6;
 245:     dk_wds[RL_DKN] += head;
 246: #endif	RL_DKN
 247: 
 248:     /*
 249: 	 * When the device is first touched, find where the heads are and
 250: 	 * what type of drive it is.
 251: 	 * rl.cn[] is initialized as -1 and this indicates that we have not
 252: 	 * touched this drive before.
 253: 	 */
 254:     if (rl.cn[rl.dn] < 0) {
 255:         /* find where the heads are */
 256:         rladdr->rlcs = (rl.dn << 8) | RL_RHDR;
 257:         rlwait(rladdr);
 258:         rl.cn[rl.dn] = ((rladdr->rlmp) >> 6) & 01777;
 259:     }
 260:     dif =(rl.cn[rl.dn] >> 1) - (rl.chn >> 1);
 261:     head = (rl.chn & 1) << 4;
 262:     if (dif < 0)
 263:         rladdr->rlda = (-dif << 7) | RLDA_SEEKHI | head;
 264:     else
 265:         rladdr->rlda = (dif << 7) | RLDA_SEEKLO | head;
 266:     rladdr->rlcs = (rl.dn << 8) | RL_SEEK;
 267:     rl.cn[rl.dn] = rl.chn;
 268:     if (rl.bleft < (rl.bpart = RL_CYLSZ - (rl.sn * RL_SECSZ)))
 269:         rl.bpart = rl.bleft;
 270:     rlwait(rladdr);
 271:     rladdr->rlda = (rl.chn << 6) | rl.sn;
 272:     rladdr->rlba = rl.rl_un.w[1];
 273:     rladdr->rlmp = -(rl.bpart >> 1);
 274:     rladdr->rlcs = rl.com | rl.rl_un.w[0] << 4;
 275: }
 276: 
 277: rlread(dev)
 278: dev_t   dev;
 279: {
 280:     physio(rlstrategy, &rrlbuf, dev, B_READ);
 281: }
 282: 
 283: rlwrite(dev)
 284: dev_t   dev;
 285: {
 286:     physio(rlstrategy, &rrlbuf, dev, B_WRITE);
 287: }
 288: #endif	NRL

Defined functions

rlattach defined in line 47; never used
rlintr defined in line 161; used 4 times
rlio defined in line 234; used 2 times
rlread defined in line 277; never used
rlstart defined in line 139; used 4 times
rlstrategy defined in line 56; used 3 times
rlwrite defined in line 283; never used

Defined variables

RLADDR defined in line 26; used 4 times
rl defined in line 45; used 43 times
rltab defined in line 29; used 17 times
rrlbuf defined in line 28; used 2 times

Defined struct's

rl_softc defined in line 31; used 2 times
  • in line 141(2)

Defined macros

RL01_NBLKS defined in line 19; used 1 times
RL02_NBLKS defined in line 20; used 2 times
RL_CYLSZ defined in line 21; used 1 times
RL_SECSZ defined in line 22; used 1 times
rlwait defined in line 24; used 5 times
Last modified: 1983-11-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1127
Valid CSS Valid XHTML 1.0 Strict