1: #
   2: /*
   3:  */
   4: 
   5: /*
   6:  * RP04 disk driver
   7:  *
   8:  * This driver has been tested on a working RP04 for a few hours.
   9:  * It does not attempt ECC error correction and is probably
  10:  * deficient in general in the case of errors and when packs
  11:  * are dismounted.
  12:  */
  13: 
  14: #include "../param.h"
  15: #include "../buf.h"
  16: #include "../conf.h"
  17: #include "../user.h"
  18: 
  19: struct {
  20:     int hpcs1;  /* Control and Status register 1 */
  21:     int hpwc;   /* Word count register */
  22:     int hpba;   /* UNIBUS address register */
  23:     int hpda;   /* Desired address register */
  24:     int hpcs2;  /* Control and Status register 2*/
  25:     int hpds;   /* Drive Status */
  26:     int hper1;  /* Error register 1 */
  27:     int hpas;   /* Attention Summary */
  28:     int hpla;   /* Look ahead */
  29:     int hpdb;   /* Data buffer */
  30:     int hpmr;   /* Maintenance register */
  31:     int hpdt;   /* Drive type */
  32:     int hpsn;   /* Serial number */
  33:     int hpof;   /* Offset register */
  34:     int hpca;   /* Desired Cylinder address register*/
  35:     int hpcc;   /* Current Cylinder */
  36:     int hper2;  /* Error register 2 */
  37:     int hper3;  /* Error register 3 */
  38:     int hppos;  /* Burst error bit position */
  39:     int hppat;  /* Burst error bit pattern */
  40:     int hpbae;  /* 11/70 bus extension */
  41: };
  42: 
  43: #define HPADDR  0176700
  44: #define NHP 8
  45: 
  46: struct {
  47:     char    *nblocks;
  48:     int cyloff;
  49: } hp_sizes[] {
  50:     9614,   0,      /* cyl 0 thru 23 */
  51:                 /* cyl 24 thru 43 available */
  52:     -1, 44,     /* cyl 44 thru 200 */
  53:     -1, 201,        /* cyl 201 thru 357 */
  54:     20900,  358,        /* cyl 358 thru 407 */
  55:                 /* cyl 408 thru 410 blank */
  56:     40600,  0,
  57:     40600,  100,
  58:     40600,  200,
  59:     40600,  300,
  60: };
  61: 
  62: 
  63: struct  devtab  hptab;
  64: struct  buf hpbuf;
  65: 
  66: char    hp_openf;
  67: 
  68:             /* Drive Commands */
  69: #define GO  01
  70: #define PRESET  020
  71: #define RECAL   06
  72: #define RCLR    010
  73: #define OFFSET  014
  74: 
  75: #define READY   0200    /* hpds - drive ready */
  76: #define PIP 020000  /* hpds - Positioning Operation in Progress */
  77: #define ERR 040000  /* hpcs1 - composite error */
  78: 
  79: #define DU  040000  /* hper1 - Drive Unsafe	*/
  80: #define DTE 010000  /* hper1 - Drive Timing Error	*/
  81: #define OPI 020000  /* hper1 - Operation Incomplete	*/
  82:         /* Error Correction Code errors */
  83: #define DCK 0100000 /* hper1 - Data Check error */
  84: #define ECH 0100    /* hper1 - ECC hard error */
  85: 
  86: #define CLR 040 /* hpcs2 - Controller Clear */
  87: 
  88: #define FMT22   010000  /* hpof - 16 bit /word format */
  89: /*
  90:  * Use av_back to save track+sector,
  91:  * b_resid for cylinder.
  92:  */
  93: 
  94: #define trksec  av_back
  95: #define cylin   b_resid
  96: 
  97: hpopen()
  98: {
  99: 
 100:     if(!hp_openf){
 101:         hp_openf++;
 102:         HPADDR->hpcs2 = CLR;
 103:         HPADDR->hpcs1 = RCLR|GO;
 104:         HPADDR->hpcs1 = PRESET|GO;
 105:         HPADDR->hpof = FMT22;
 106:     }
 107: }
 108: 
 109: hpstrategy(abp)
 110: struct buf *abp;
 111: {
 112:     register struct buf *bp;
 113:     register char *p1, *p2;
 114: 
 115:     bp = abp;
 116:     p1 = &hp_sizes[bp->b_dev.d_minor&07];
 117:     if (bp->b_dev.d_minor >= (NHP<<3) ||
 118:         bp->b_blkno >= p1->nblocks) {
 119:         bp->b_flags =| B_ERROR;
 120:         iodone(bp);
 121:         return;
 122:     }
 123:     bp->av_forw = 0;
 124:     bp->cylin = p1->cyloff;
 125:     p1 = bp->b_blkno;
 126:     p2 = lrem(p1, 22);
 127:     p1 = ldiv(p1, 22);
 128:     bp->trksec = (p1%19)<<8 | p2;
 129:     bp->cylin =+ p1/19;
 130:     spl5();
 131:     if ((p1 = hptab.d_actf)==0)
 132:         hptab.d_actf = bp;
 133:     else {
 134:         for (; p2 = p1->av_forw; p1 = p2) {
 135:             if (p1->cylin <= bp->cylin
 136:              && bp->cylin <  p2->cylin
 137:              || p1->cylin >= bp->cylin
 138:              && bp->cylin >  p2->cylin)
 139:                 break;
 140:         }
 141:         bp->av_forw = p2;
 142:         p1->av_forw = bp;
 143:     }
 144:     if (hptab.d_active==0)
 145:         hpstart();
 146:     spl0();
 147: }
 148: 
 149: hpstart()
 150: {
 151:     register struct buf *bp;
 152: 
 153:     if ((bp = hptab.d_actf) == 0)
 154:         return;
 155:     hptab.d_active++;
 156:     HPADDR->hpcs2 = bp->b_dev.d_minor >> 3;
 157:     HPADDR->hpca = bp->cylin;
 158:     rhstart(bp, &HPADDR->hpda, bp->trksec, &HPADDR->hpbae);
 159: }
 160: 
 161: hpintr()
 162: {
 163:     register struct buf *bp;
 164:     register int ctr;
 165: 
 166:     if (hptab.d_active == 0)
 167:         return;
 168:     bp = hptab.d_actf;
 169:     hptab.d_active = 0;
 170:     if (HPADDR->hpcs1 & ERR) {      /* error bit */
 171:         deverror(bp, HPADDR->hpcs2, 0);
 172:         if(HPADDR->hper1 & (DU|DTE|OPI)) {
 173:             HPADDR->hpcs2 = CLR;
 174:             HPADDR->hpcs1 = RECAL|GO;
 175:             ctr = 0;
 176:             while ((HPADDR->hpds&PIP) && --ctr);
 177:         }
 178:         HPADDR->hpcs1 = RCLR|GO;
 179:         if (++hptab.d_errcnt <= 10) {
 180:             hpstart();
 181:             return;
 182:         }
 183:         bp->b_flags =| B_ERROR;
 184:     }
 185:     hptab.d_errcnt = 0;
 186:     hptab.d_actf = bp->av_forw;
 187:     bp->b_resid = HPADDR->hpwc;
 188:     iodone(bp);
 189:     hpstart();
 190: }
 191: 
 192: hpread(dev)
 193: {
 194: 
 195:     if(hpphys(dev))
 196:     physio(hpstrategy, &hpbuf, dev, B_READ);
 197: }
 198: 
 199: hpwrite(dev)
 200: {
 201: 
 202:     if(hpphys(dev))
 203:     physio(hpstrategy, &hpbuf, dev, B_WRITE);
 204: }
 205: 
 206: hpphys(dev)
 207: {
 208:     register c;
 209: 
 210:     c = lshift(u.u_offset, -9);
 211:     c =+ ldiv(u.u_count+511, 512);
 212:     if(c > hp_sizes[dev.d_minor & 07].nblocks) {
 213:         u.u_error = ENXIO;
 214:         return(0);
 215:     }
 216:     return(1);
 217: }

Defined functions

hpintr defined in line 161; never used
hpopen defined in line 97; never used
hpphys defined in line 206; used 2 times
hpread defined in line 192; never used
hpstart defined in line 149; used 3 times
hpstrategy defined in line 109; used 2 times
hpwrite defined in line 199; never used

Defined variables

hp_openf defined in line 66; used 2 times
hpbuf defined in line 64; used 2 times
hptab defined in line 63; used 11 times

Defined macros

CLR defined in line 86; used 2 times
DCK defined in line 83; never used
DTE defined in line 80; used 1 times
DU defined in line 79; used 1 times
ECH defined in line 84; never used
ERR defined in line 77; used 1 times
FMT22 defined in line 88; used 1 times
GO defined in line 69; used 4 times
HPADDR defined in line 43; used 16 times
NHP defined in line 44; used 1 times
OFFSET defined in line 73; never used
OPI defined in line 81; used 1 times
PIP defined in line 76; used 1 times
PRESET defined in line 70; used 1 times
RCLR defined in line 72; used 2 times
READY defined in line 75; never used
RECAL defined in line 71; used 1 times
cylin defined in line 95; used 11 times
trksec defined in line 94; used 2 times
Last modified: 1975-07-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1109
Valid CSS Valid XHTML 1.0 Strict