1: /*
   2:  * ML11 solid state disk driver.
   3:  *
   4:  * This driver was written by Fred Canter and distributed on the
   5:  * DEC v7m UNIX tape.  It has been modified for 2BSD and has been
   6:  * included with the permission of the DEC UNIX Engineering Group.
   7:  *
   8:  * This driver does not support mixed drive types,
   9:  * it requires that the ML11 be on a separate
  10:  * RH11 or RH70 controller and that there be only
  11:  * ML11 drives on that controller.
  12:  */
  13: 
  14: /*
  15:  *	SCCS id	@(#)ml.c	2.1 (Berkeley)	8/5/83
  16:  */
  17: 
  18: #include "ml.h"
  19: #if NML > 0
  20: #include "param.h"
  21: #include <sys/systm.h>
  22: #include <sys/buf.h>
  23: #include <sys/conf.h>
  24: #include <sys/dir.h>
  25: #include <sys/user.h>
  26: #include <sys/seg.h>
  27: #include <sys/mlreg.h>
  28: 
  29: bool_t  ml_alive;
  30: extern  struct  mldevice *MLADDR;
  31: 
  32: /*
  33:  * Ml_sizes[] contains the size of each ML11
  34:  * unit in blocks.  The size is set dynamicaly
  35:  * by reading the number of arrays from the ML maintenance
  36:  * register.  The array type bit the the ML maintenacne
  37:  * register is used to adjust the number of blocks per array
  38:  * from 512 (16k chips) to 2048 (64k chips).
  39:  */
  40: short   ml_sizes[NML];
  41: 
  42: struct  buf mltab;
  43: struct  buf rmlbuf;
  44: 
  45: void
  46: mlprobe()
  47: {
  48:     register unit;
  49: 
  50:     if (fioword (MLADDR) != -1) {
  51:         ml_alive++;
  52:         for (unit = 0; unit < NML; unit++) {
  53:             MLADDR->mlcs2.c[0] = unit;
  54: 
  55:             /*
  56: 			 * Find the size of the ML11 unit by reading
  57: 			 * the number of array modules from the ML
  58: 			 * maintenance register.  There are 512
  59: 			 * blocks per array unless the array type
  60: 			 * bit is set, in which case there are 2048
  61: 			 * blocks per array.
  62: 			 */
  63:             ml_sizes[unit] = (MLADDR->mlmr >> 2) & 037000;
  64:             if (MLADDR->mlmr & 02000)
  65:                 ml_sizes[unit] <<= 2;
  66:         }
  67: #if PDP11 == 70 || PDP11 == GENERIC
  68:         if (fioword (&(MLADDR->mlbae)) != -1)
  69:             mltab.b_flags |= B_RH70;
  70: #endif
  71:     }
  72: }
  73: 
  74: 
  75: mlstrategy(bp)
  76: register struct buf *bp;
  77: {
  78:     register struct buf *dp;
  79:     register unit;
  80:     int tr;
  81:     long sz, bn;
  82: 
  83:     unit = minor(bp->b_dev) & 07;
  84:     if (!ml_alive || unit >= NML)
  85:         goto bad;
  86: #ifdef  UNIBUS_MAP
  87:     if ((bp->b_flags & B_PHYS) && ((mltab.b_flags & B_RH70) == 0))
  88:         mapalloc(bp);
  89: #endif
  90: 
  91:     (void) _spl5();
  92:     if ((MLADDR->mldt & 0377) != ML11)
  93:         goto bad;
  94:     MLADDR->mlcs2.c[0] = unit;
  95: 
  96:     /*
  97: 	 * Check the ML11 transfer rate.
  98: 	 * 2mb is too fast for any pdp11.
  99: 	 * 1mb allowed on pdp11/70 only.
 100: 	 * .5mb & .25mb ok on any processor.
 101: 	 */
 102:     tr = MLADDR->mlmr & 01400;
 103:     if ((tr == MLMR_2MB) || ((tr == MLMR_1MB)
 104:         && ((mltab.b_flags & B_RH70) == 0))) {
 105:         printf("\nML11 xfer rate error\n");
 106:         goto bad;
 107:     }
 108:     sz = bp->b_bcount;
 109:     sz = (sz + 511) >> 9;
 110:     if (bp->b_blkno < 0 || (bp->b_blkno + sz) > ml_sizes[unit]) {
 111:         goto bad;
 112:     }
 113: 
 114:     bp->av_forw = NULL;
 115:     dp = &mltab;
 116:     if (dp->b_actf == NULL)
 117:         dp->b_actf = bp;
 118:     else
 119:         dp->b_actl->av_forw = bp;
 120:     dp->b_actl = bp;
 121:     if (dp->b_active == NULL)
 122:         mlstart();
 123:     return;
 124: 
 125: bad:
 126:     u.u_error = ENXIO;
 127:     bp->b_flags |= B_ERROR;
 128:     iodone(bp);
 129: }
 130: 
 131: mlstart()
 132: {
 133:     register struct buf *bp;
 134:     register unit, com;
 135: 
 136:     if ((bp = mltab.b_actf) == NULL)
 137:         return;
 138:     mltab.b_active++;
 139:     unit = minor(bp->b_dev) & 07;
 140:     (void) _spl5();
 141:     MLADDR->mlcs2.w = unit;
 142:     if ((MLADDR->mlds & MLDS_VV) == 0)
 143:         MLADDR->mlcs1.w = ML_PRESET | ML_GO;
 144:     if ((MLADDR->mlds & (MLDS_DPR | MLDS_MOL)) != (MLDS_DPR | MLDS_MOL)) {
 145:         mltab.b_active = 0;
 146:         mltab.b_errcnt = 0;
 147:         bp->b_actf = bp->av_forw;
 148:         bp->b_flags |= B_ERROR;
 149:         iodone(bp);
 150:         (void) _spl0();
 151:         return;
 152:     }
 153:     MLADDR->mlda = bp->b_blkno;
 154:     MLADDR->mlba = bp->b_un.b_addr;
 155: #if PDP11 == 70 || PDP11 == GENERIC
 156:     if (mltab.b_flags & B_RH70)
 157:         MLADDR->mlbae = bp->b_xmem;
 158: #endif
 159:     MLADDR->mlwc = -(bp->b_bcount >> 1);
 160:     com = ((bp->b_xmem & 3) << 8) | ML_IE | ML_GO;
 161:     if (bp->b_flags & B_READ)
 162:         com |= ML_RCOM;
 163:     else
 164:         com |= ML_WCOM;
 165:     MLADDR->mlcs1.w = com;
 166: #ifdef  ML_DKN
 167:     dk_busy |= 1 << (ML_DKN + NML);
 168:     dk_numb[ML_DKN + NML] += 1;
 169:     dk_wds[ML_DKN + NML] += bp->b_bcount >> 6;
 170: #endif	ML_DKN
 171:     (void) _spl0();
 172: }
 173: 
 174: mlintr()
 175: {
 176:     register struct buf *bp;
 177:     register unit;
 178:     int as;
 179:     int ctr;
 180: 
 181:     if (mltab.b_active == NULL)
 182:         return;
 183:     as = MLADDR->mlas & 0377;
 184:     bp = mltab.b_actf;
 185:     unit = minor(bp->b_dev) & 7;
 186: #ifdef  ML_DKN
 187:     dk_busy &= ~(1 << (ML_DKN + NML));
 188: #endif
 189:     as &= ~(1<<unit);
 190:     MLADDR->mlas = as;
 191:     MLADDR->mlcs2.c[0] = unit;
 192:     if (MLADDR->mlcs1.w & ML_TRE) {     /* error bit */
 193:         ctr = 0;
 194:         while (((MLADDR->mlds & MLDS_DRY) == 0) && --ctr)
 195:             ;
 196:         if (mltab.b_errcnt == 0)
 197: #ifdef  UCB_DEVERR
 198:             harderr (bp, "ml");
 199:             printf ("cs2=%b er=%b\n", MLADDR->mlcs2.w,
 200:                 MLCS2_BITS, MLADDR->mler, MLER_BITS);
 201: #else
 202:             deverror(bp, MLADDR->mlcs2.w, MLADDR->mler);
 203: #endif	UCB_DEVERR
 204:         MLADDR->mlcs1.w = ML_DCLR | ML_GO;
 205:         if (++mltab.b_errcnt <= 10) {
 206:             mlstart();
 207:             return;
 208:         }
 209:         bp->b_flags |= B_ERROR;
 210:     }
 211:     mltab.b_errcnt = 0;
 212:     mltab.b_actf = bp->av_forw;
 213:     bp->b_resid = 0;
 214:     iodone(bp);
 215:     mlstart();
 216: }
 217: 
 218: mlread(dev)
 219: dev_t   dev;
 220: {
 221:     physio(mlstrategy, &rmlbuf, dev, B_READ);
 222: }
 223: 
 224: mlwrite(dev)
 225: dev_t   dev;
 226: {
 227:     physio(mlstrategy, &rmlbuf, dev, B_WRITE);
 228: }
 229: #endif	NML

Defined functions

mlintr defined in line 174; never used
mlprobe defined in line 45; never used
mlread defined in line 218; never used
mlstart defined in line 131; used 3 times
mlstrategy defined in line 75; used 2 times
mlwrite defined in line 224; never used

Defined variables

ml_alive defined in line 29; used 2 times
ml_sizes defined in line 40; used 3 times
mltab defined in line 42; used 15 times
rmlbuf defined in line 43; used 2 times
Last modified: 1983-08-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1140
Valid CSS Valid XHTML 1.0 Strict