1: /*
   2:  * RP04/RP06 disk driver
   3:  */
   4: 
   5: #include "../h/param.h"
   6: #include "../h/systm.h"
   7: #include "../h/buf.h"
   8: #include "../h/conf.h"
   9: #include "../h/dir.h"
  10: #include "../h/user.h"
  11: 
  12: #define DK_N    0
  13: 
  14: struct  device
  15: {
  16:     union {
  17:         int w;
  18:         char    c[2];
  19:     } hpcs1;        /* Control and Status register 1 */
  20:     int hpwc;       /* Word count register */
  21:     caddr_t hpba;       /* UNIBUS address register */
  22:     int hpda;       /* Desired address register */
  23:     union {
  24:         int w;
  25:         char    c[2];
  26:     } hpcs2;        /* Control and Status register 2*/
  27:     int hpds;       /* Drive Status */
  28:     int hper1;      /* Error register 1 */
  29:     int hpas;       /* Attention Summary */
  30:     int hpla;       /* Look ahead */
  31:     int hpdb;       /* Data buffer */
  32:     int hpmr;       /* Maintenance register */
  33:     int hpdt;       /* Drive type */
  34:     int hpsn;       /* Serial number */
  35:     int hpof;       /* Offset register */
  36:     int hpdc;       /* Desired Cylinder address register*/
  37:     int hpcc;       /* Current Cylinder */
  38:     int hper2;      /* Error register 2 */
  39:     int hper3;      /* Error register 3 */
  40:     int hpec1;      /* Burst error bit position */
  41:     int hpec2;      /* Burst error bit pattern */
  42:     int hpbae;      /* 11/70 bus extension */
  43:     int hpcs3;
  44: };
  45: 
  46: #define HPADDR  ((struct device *)0176700)
  47: #define NHP 2
  48: #define NSECT   22
  49: #define NTRAC   19
  50: #define SDIST   2
  51: #define RDIST   6
  52: 
  53: struct  size
  54: {
  55:     daddr_t nblocks;
  56:     int cyloff;
  57: } hp_sizes[8] =
  58: {
  59:     9614,   0,      /* cyl 0 thru 22 */
  60:     8778,   23,     /* cyl 23 thru 43 */
  61:     0,  0,
  62:     0,  0,
  63:     161348, 44,     /* cyl 44 thru 429 */
  64:     160930, 430,        /* cyl 430 thru 814 */
  65:     153406, 44,     /* cyl 44 thru 410 (rp04, rp05) */
  66:     322278, 44,     /* cyl 44 thru 814 (rp06) */
  67: };
  68: 
  69: #define P400    020
  70: #define M400    0220
  71: #define P800    040
  72: #define M800    0240
  73: #define P1200   060
  74: #define M1200   0260
  75: int hp_offset[16] =
  76: {
  77:     P400, M400, P400, M400,
  78:     P800, M800, P800, M800,
  79:     P1200, M1200, P1200, M1200,
  80:     0, 0, 0, 0,
  81: };
  82: 
  83: struct  buf hptab;
  84: struct  buf rhpbuf;
  85: struct  buf hputab[NHP];
  86: 
  87: #define GO  01
  88: #define PRESET  020
  89: #define RTC 016
  90: #define OFFSET  014
  91: #define SEARCH  030
  92: #define RECAL   06
  93: #define DCLR    010
  94: #define WCOM    060
  95: #define RCOM    070
  96: 
  97: #define IE  0100
  98: #define PIP 020000
  99: #define DRY 0200
 100: #define ERR 040000
 101: #define TRE 040000
 102: #define DCK 0100000
 103: #define WLE 04000
 104: #define ECH 0100
 105: #define VV  0100
 106: #define DPR 0400
 107: #define MOL 010000
 108: #define FMT22   010000
 109: 
 110: #define b_cylin b_resid
 111: 
 112: daddr_t dkblock();
 113: 
 114: hpstrategy(bp)
 115: register struct buf *bp;
 116: {
 117:     register struct buf *dp;
 118:     register unit;
 119:     long sz, bn;
 120: 
 121:     unit = minor(bp->b_dev) & 077;
 122:     sz = bp->b_bcount;
 123:     sz = (sz+511) >> 9;
 124:     if (unit >= (NHP<<3) ||
 125:         bp->b_blkno < 0 ||
 126:         (bn = dkblock(bp))+sz > hp_sizes[unit&07].nblocks) {
 127:         bp->b_flags |= B_ERROR;
 128:         iodone(bp);
 129:         return;
 130:     }
 131:     bp->b_cylin = bn/(NSECT*NTRAC) + hp_sizes[unit&07].cyloff;
 132:     unit = dkunit(bp);
 133:     dp = &hputab[unit];
 134:     spl5();
 135:     disksort(dp, bp);
 136:     if (dp->b_active == 0) {
 137:         hpustart(unit);
 138:         if(hptab.b_active == 0)
 139:             hpstart();
 140:     }
 141:     spl0();
 142: }
 143: 
 144: hpustart(unit)
 145: register unit;
 146: {
 147:     register struct buf *bp, *dp;
 148:     daddr_t bn;
 149:     int sn, cn, csn;
 150: 
 151:     HPADDR->hpcs2.w = unit;
 152:     HPADDR->hpcs1.c[0] = IE;
 153:     HPADDR->hpas = 1<<unit;
 154: 
 155:     if(unit >= NHP)
 156:         return;
 157:     dk_busy &= ~(1<<(unit+DK_N));
 158:     dp = &hputab[unit];
 159:     if((bp=dp->b_actf) == NULL)
 160:         return;
 161:     if((HPADDR->hpds & VV) == 0) {
 162:         HPADDR->hpcs1.c[0] = IE|PRESET|GO;
 163:         HPADDR->hpof = FMT22;
 164:     }
 165:     if(dp->b_active)
 166:         goto done;
 167:     dp->b_active++;
 168:     if ((HPADDR->hpds & (DPR|MOL)) != (DPR|MOL))
 169:         goto done;
 170: 
 171:     bn = dkblock(bp);
 172:     cn = bp->b_cylin;
 173:     sn = bn%(NSECT*NTRAC);
 174:     sn = (sn+NSECT-SDIST)%NSECT;
 175: 
 176:     if(HPADDR->hpcc != cn)
 177:         goto search;
 178:     csn = (HPADDR->hpla>>6) - sn + SDIST - 1;
 179:     if(csn < 0)
 180:         csn += NSECT;
 181:     if(csn > NSECT-RDIST)
 182:         goto done;
 183: 
 184: search:
 185:     HPADDR->hpdc = cn;
 186:     HPADDR->hpda = sn;
 187:     HPADDR->hpcs1.c[0] = IE|SEARCH|GO;
 188:     unit += DK_N;
 189:     dk_busy |= 1<<unit;
 190:     dk_numb[unit] += 1;
 191:     return;
 192: 
 193: done:
 194:     dp->b_forw = NULL;
 195:     if(hptab.b_actf == NULL)
 196:         hptab.b_actf = dp; else
 197:         hptab.b_actl->b_forw = dp;
 198:     hptab.b_actl = dp;
 199: }
 200: 
 201: hpstart()
 202: {
 203:     register struct buf *bp, *dp;
 204:     register unit;
 205:     daddr_t bn;
 206:     int dn, sn, tn, cn;
 207: 
 208: loop:
 209:     if ((dp = hptab.b_actf) == NULL)
 210:         return;
 211:     if ((bp = dp->b_actf) == NULL) {
 212:         hptab.b_actf = dp->b_forw;
 213:         goto loop;
 214:     }
 215:     hptab.b_active++;
 216:     unit = minor(bp->b_dev) & 077;
 217:     dn = dkunit(bp);
 218:     bn = dkblock(bp);
 219:     cn = bn/(NSECT*NTRAC) + hp_sizes[unit&07].cyloff;
 220:     sn = bn%(NSECT*NTRAC);
 221:     tn = sn/NSECT;
 222:     sn = sn%NSECT;
 223: 
 224:     HPADDR->hpcs2.w = dn;
 225:     if ((HPADDR->hpds & (DPR|MOL)) != (DPR|MOL)) {
 226:         hptab.b_active = 0;
 227:         hptab.b_errcnt = 0;
 228:         dp->b_actf = bp->av_forw;
 229:         bp->b_flags |= B_ERROR;
 230:         iodone(bp);
 231:         goto loop;
 232:     }
 233:     if(hptab.b_errcnt >= 16) {
 234:         HPADDR->hpof = hp_offset[hptab.b_errcnt & 017] | FMT22;
 235:         HPADDR->hpcs1.w = OFFSET|GO;
 236:         while(HPADDR->hpds & PIP)
 237:             ;
 238:     }
 239:     HPADDR->hpdc = cn;
 240:     HPADDR->hpda = (tn << 8) + sn;
 241:     HPADDR->hpba = bp->b_un.b_addr;
 242:     if(cputype == 70)
 243:         HPADDR->hpbae = bp->b_xmem;
 244:     HPADDR->hpwc = -(bp->b_bcount>>1);
 245:     unit = ((bp->b_xmem&3) << 8) | IE | GO;
 246:     if(bp->b_flags & B_READ)
 247:         unit |= RCOM; else
 248:         unit |= WCOM;
 249:     HPADDR->hpcs1.w = unit;
 250: 
 251:     dk_busy |= 1<<(DK_N+NHP);
 252:     dk_numb[DK_N+NHP] += 1;
 253:     unit = bp->b_bcount>>6;
 254:     dk_wds[DK_N+NHP] += unit;
 255: }
 256: 
 257: hpintr()
 258: {
 259:     register struct buf *bp, *dp;
 260:     register unit;
 261:     int as, i, j;
 262: 
 263:     as = HPADDR->hpas & 0377;
 264:     if(hptab.b_active) {
 265:         dk_busy &= ~(1<<(DK_N+NHP));
 266:         dp = hptab.b_actf;
 267:         bp = dp->b_actf;
 268:         unit = dkunit(bp);
 269:         HPADDR->hpcs2.c[0] = unit;
 270:         if (HPADDR->hpcs1.w & TRE) {        /* error bit */
 271:             while((HPADDR->hpds & DRY) == 0)
 272:                 ;
 273:             if(++hptab.b_errcnt > 28 || HPADDR->hper1&WLE)
 274:                 bp->b_flags |= B_ERROR; else
 275:                 hptab.b_active = 0;
 276:             if(hptab.b_errcnt > 27)
 277:                 deverror(bp, HPADDR->hpcs2.w, HPADDR->hper1);
 278:             if((bp->b_flags&B_PHYS) == 0 &&
 279:                (HPADDR->hper1 & (DCK|ECH)) == DCK) {
 280:                 i = HPADDR->hpec1 - 1;
 281:                 j = i&017;
 282:                 i >>= 4;
 283:                 if(i >= 0 && i <256) {
 284:                     bp->b_un.b_words[i] ^= HPADDR->hpec2 << j;
 285:                     bp->b_un.b_words[i+1] ^= HPADDR->hpec2 >> (16-j);
 286:                 }
 287:                 hptab.b_active++;
 288:                 printf("%D ", bp->b_blkno);
 289:                 prdev("ECC", bp->b_dev);
 290:             }
 291:             HPADDR->hpcs1.w = TRE|IE|DCLR|GO;
 292:             if((hptab.b_errcnt&07) == 4) {
 293:                 HPADDR->hpcs1.w = RECAL|IE|GO;
 294:                 while(HPADDR->hpds & PIP)
 295:                     ;
 296:             }
 297:         }
 298:         if(hptab.b_active) {
 299:             if(hptab.b_errcnt) {
 300:                 HPADDR->hpcs1.w = RTC|GO;
 301:                 while(HPADDR->hpds & PIP)
 302:                     ;
 303:             }
 304:             hptab.b_active = 0;
 305:             hptab.b_errcnt = 0;
 306:             hptab.b_actf = dp->b_forw;
 307:             dp->b_active = 0;
 308:             dp->b_errcnt = 0;
 309:             dp->b_actf = bp->av_forw;
 310:             bp->b_resid = -(HPADDR->hpwc<<1);
 311:             iodone(bp);
 312:             HPADDR->hpcs1.w = IE;
 313:             if(dp->b_actf)
 314:                 hpustart(unit);
 315:         }
 316:         as &= ~(1<<unit);
 317:     } else {
 318:         if(as == 0)
 319:             HPADDR->hpcs1.w = IE;
 320:         HPADDR->hpcs1.c[1] = TRE>>8;
 321:     }
 322:     for(unit=0; unit<NHP; unit++)
 323:         if(as & (1<<unit))
 324:             hpustart(unit);
 325:     hpstart();
 326: }
 327: 
 328: hpread(dev)
 329: {
 330: 
 331:     physio(hpstrategy, &rhpbuf, dev, B_READ);
 332: }
 333: 
 334: hpwrite(dev)
 335: {
 336: 
 337:     physio(hpstrategy, &rhpbuf, dev, B_WRITE);
 338: }

Defined functions

hpintr defined in line 257; never used
hpread defined in line 328; never used
hpstart defined in line 201; used 2 times
hpstrategy defined in line 114; used 2 times
hpustart defined in line 144; used 3 times
hpwrite defined in line 334; never used

Defined variables

hp_offset defined in line 75; used 1 times
hp_sizes defined in line 57; used 3 times
hptab defined in line 83; used 24 times
hputab defined in line 85; used 2 times
rhpbuf defined in line 84; used 2 times

Defined struct's

device defined in line 14; never used
size defined in line 53; never used

Defined macros

DCK defined in line 102; used 2 times
  • in line 279(2)
DCLR defined in line 93; used 1 times
DK_N defined in line 12; used 6 times
DPR defined in line 106; used 4 times
DRY defined in line 99; used 1 times
ECH defined in line 104; used 1 times
ERR defined in line 100; never used
FMT22 defined in line 108; used 2 times
GO defined in line 87; used 7 times
HPADDR defined in line 46; used 43 times
IE defined in line 97; used 8 times
M1200 defined in line 74; used 2 times
  • in line 79(2)
M400 defined in line 70; used 2 times
  • in line 77(2)
M800 defined in line 72; used 2 times
  • in line 78(2)
MOL defined in line 107; used 4 times
NHP defined in line 47; used 8 times
NSECT defined in line 48; used 10 times
NTRAC defined in line 49; used 4 times
OFFSET defined in line 90; used 1 times
P1200 defined in line 73; used 2 times
  • in line 79(2)
P400 defined in line 69; used 2 times
  • in line 77(2)
P800 defined in line 71; used 2 times
  • in line 78(2)
PIP defined in line 98; used 3 times
PRESET defined in line 88; used 1 times
RCOM defined in line 95; used 1 times
RDIST defined in line 51; used 1 times
RECAL defined in line 92; used 1 times
RTC defined in line 89; used 1 times
SDIST defined in line 50; used 2 times
SEARCH defined in line 91; used 1 times
TRE defined in line 101; used 3 times
VV defined in line 105; used 1 times
WCOM defined in line 94; used 1 times
WLE defined in line 103; used 1 times
b_cylin defined in line 110; used 2 times
Last modified: 1979-05-12
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1473
Valid CSS Valid XHTML 1.0 Strict