1: /*
   2:  * TJU16 tape 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/file.h"
  11: #include "../h/user.h"
  12: 
  13: struct  device
  14: {
  15:     int htcs1;
  16:     int htwc;
  17:     caddr_t htba;
  18:     int htfc;
  19:     int htcs2;
  20:     int htds;
  21:     int hter;
  22:     int htas;
  23:     int htck;
  24:     int htdb;
  25:     int htmr;
  26:     int htdt;
  27:     int htsn;
  28:     int httc;
  29:     int htbae;  /* 11/70 bus extension */
  30:     int htcs3;
  31: };
  32: 
  33: struct  buf httab;
  34: struct  buf rhtbuf;
  35: struct  buf chtbuf;
  36: 
  37: #define NUNIT   1
  38: #define INF 1000000
  39: 
  40: char    h_flags[NUNIT];
  41: char    h_openf[NUNIT];
  42: daddr_t h_blkno[NUNIT];
  43: daddr_t h_nxrec[NUNIT];
  44: 
  45: #define HTADDR  ((struct device *)0172440)
  46: 
  47: #define GO  01
  48: #define WCOM    060
  49: #define RCOM    070
  50: #define NOP 0
  51: #define WEOF    026
  52: #define SFORW   030
  53: #define SREV    032
  54: #define ERASE   024
  55: #define REW 06
  56: #define DCLR    010
  57: #define P800    01300       /* 800 + pdp11 mode */
  58: #define P1600   02300       /* 1600 + pdp11 mode */
  59: #define IENABLE 0100
  60: #define RDY 0200
  61: #define TM  04
  62: #define DRY 0200
  63: #define EOT 02000
  64: #define CS  02000
  65: #define COR 0100000
  66: #define PES 040
  67: #define WRL 04000
  68: #define MOL 010000
  69: #define ERR 040000
  70: #define FCE 01000
  71: #define TRE 040000
  72: #define HARD    064023  /* UNS|OPI|NEF|FMT|RMR|ILR|ILF */
  73: 
  74: #define CLR 040 /* controller clear (in cs2) */
  75: 
  76: #define NED 010000
  77: 
  78: #define SIO 1
  79: #define SSFOR   2
  80: #define SSREV   3
  81: #define SRETRY  4
  82: #define SCOM    5
  83: #define SOK 6
  84: 
  85: #define H_WRITTEN 1
  86: htopen(dev, flag)
  87: {
  88:     register unit, ds;
  89: 
  90:     httab.b_flags |= B_TAPE;
  91:     unit = minor(dev) & 077;
  92:     if (unit >= NUNIT || h_openf[unit]) {
  93:         u.u_error = ENXIO;
  94:         return;
  95:     }
  96:     h_blkno[unit] = 0;
  97:     h_nxrec[unit] = INF;
  98:     h_flags[unit] = 0;
  99:     ds = hcommand(dev, NOP);
 100:     if ((ds&MOL)==0 || (flag && (ds&WRL)))
 101:         u.u_error = ENXIO;
 102:     if (u.u_error==0)
 103:         h_openf[unit]++;
 104: }
 105: 
 106: htclose(dev, flag)
 107: {
 108:     register int unit;
 109: 
 110:     unit = minor(dev) & 077;
 111:     if (flag == FWRITE || ((flag&FWRITE) && (h_flags[unit]&H_WRITTEN))) {
 112:         hcommand(dev, WEOF);
 113:         hcommand(dev, WEOF);
 114:         hcommand(dev, SREV);
 115:     }
 116:     if ((minor(dev)&0200) == 0)
 117:         hcommand(dev, REW);
 118:     h_openf[unit] = 0;
 119: }
 120: 
 121: hcommand(dev, com)
 122: {
 123:     register struct buf *bp;
 124: 
 125:     bp = &chtbuf;
 126:     spl5();
 127:     while(bp->b_flags&B_BUSY) {
 128:         bp->b_flags |= B_WANTED;
 129:         sleep((caddr_t)bp, PRIBIO);
 130:     }
 131:     spl0();
 132:     bp->b_dev = dev;
 133:     bp->b_resid = com;
 134:     bp->b_blkno = 0;
 135:     bp->b_flags = B_BUSY|B_READ;
 136:     htstrategy(bp);
 137:     iowait(bp);
 138:     if(bp->b_flags&B_WANTED)
 139:         wakeup((caddr_t)bp);
 140:     bp->b_flags = 0;
 141:     return(bp->b_resid);
 142: }
 143: 
 144: htstrategy(bp)
 145: register struct buf *bp;
 146: {
 147:     register daddr_t *p;
 148: 
 149:     if(bp != &chtbuf) {
 150:         p = &h_nxrec[minor(bp->b_dev)&077];
 151:         if(bp->b_blkno > *p) {
 152:             bp->b_flags |= B_ERROR;
 153:             bp->b_error = ENXIO;
 154:             iodone(bp);
 155:             return;
 156:         }
 157:         if(bp->b_blkno == *p && bp->b_flags&B_READ) {
 158:             clrbuf(bp);
 159:             bp->b_resid = bp->b_bcount;
 160:             iodone(bp);
 161:             return;
 162:         }
 163:         if ((bp->b_flags&B_READ)==0) {
 164:             *p = bp->b_blkno + 1;
 165:             h_flags[minor(bp->b_dev)&077] |= H_WRITTEN;
 166:         }
 167:     }
 168:     bp->av_forw = NULL;
 169:     spl5();
 170:     if (httab.b_actf == NULL)
 171:         httab.b_actf = bp;
 172:     else
 173:         httab.b_actl->av_forw = bp;
 174:     httab.b_actl = bp;
 175:     if (httab.b_active==0)
 176:         htstart();
 177:     spl0();
 178: }
 179: 
 180: htstart()
 181: {
 182:     register struct buf *bp;
 183:     register unit, den;
 184:     daddr_t blkno;
 185: 
 186:     loop:
 187:     if ((bp = httab.b_actf) == NULL)
 188:         return;
 189:     unit = minor(bp->b_dev) & 0177;
 190:     HTADDR->htcs2 = ((unit>>3)&07);
 191:     den = P1600 | (unit&07);
 192:     if(unit > 077)
 193:         den = P800 | (unit&07);
 194:     if((HTADDR->httc&03777) != den)
 195:         HTADDR->httc = den;
 196:     if (HTADDR->htcs2 & NED || (HTADDR->htds&MOL)==0)
 197:         goto abort;
 198:     unit &= 077;
 199:     blkno = h_blkno[unit];
 200:     if (bp == &chtbuf) {
 201:         if (bp->b_resid==NOP) {
 202:             bp->b_resid = HTADDR->htds;
 203:             goto next;
 204:         }
 205:         httab.b_active = SCOM;
 206:         HTADDR->htfc = 0;
 207:         HTADDR->htcs1 = bp->b_resid|IENABLE|GO;
 208:         return;
 209:     }
 210:     if (h_openf[unit] < 0 || bp->b_blkno > h_nxrec[unit])
 211:         goto abort;
 212:     if (blkno == bp->b_blkno) {
 213:         httab.b_active = SIO;
 214:         HTADDR->htba = bp->b_un.b_addr;
 215:         if(cputype == 70)
 216:             HTADDR->htbae = bp->b_xmem;
 217:         HTADDR->htfc = -bp->b_bcount;
 218:         HTADDR->htwc = -(bp->b_bcount>>1);
 219:         den = ((bp->b_xmem&3) << 8) | IENABLE | GO;
 220:         if(bp->b_flags & B_READ)
 221:             den |= RCOM;
 222:         else {
 223:             if(HTADDR->htds & EOT) {
 224:                 bp->b_resid = bp->b_bcount;
 225:                 goto next;
 226:             }
 227:             den |= WCOM;
 228:         }
 229:         HTADDR->htcs1 = den;
 230:     } else {
 231:         if (blkno < bp->b_blkno) {
 232:             httab.b_active = SSFOR;
 233:             HTADDR->htfc = blkno - bp->b_blkno;
 234:             HTADDR->htcs1 = SFORW|IENABLE|GO;
 235:         } else {
 236:             httab.b_active = SSREV;
 237:             HTADDR->htfc = bp->b_blkno - blkno;
 238:             HTADDR->htcs1 = SREV|IENABLE|GO;
 239:         }
 240:     }
 241:     return;
 242: 
 243:     abort:
 244:     bp->b_flags |= B_ERROR;
 245: 
 246:     next:
 247:     httab.b_actf = bp->av_forw;
 248:     iodone(bp);
 249:     goto loop;
 250: }
 251: 
 252: htintr()
 253: {
 254:     register struct buf *bp;
 255:     register int unit, state;
 256:     int err;
 257: 
 258:     if ((bp = httab.b_actf)==NULL)
 259:         return;
 260:     unit = minor(bp->b_dev) & 077;
 261:     state = httab.b_active;
 262:     httab.b_active = 0;
 263:     if (HTADDR->htcs1&TRE) {
 264:         err = HTADDR->hter;
 265:         if (HTADDR->htcs2&077400 || (err&HARD))
 266:             state = 0;
 267:         if (bp == &rhtbuf)
 268:             err &= ~FCE;
 269:         if ((bp->b_flags&B_READ) && (HTADDR->htds&PES))
 270:             err &= ~(CS|COR);
 271:         if((HTADDR->htds&MOL) == 0) {
 272:             if(h_openf[unit])
 273:                 h_openf[unit] = -1;
 274:         }
 275:         else if(HTADDR->htds&TM) {
 276:             HTADDR->htwc = -(bp->b_bcount>>1);
 277:             h_nxrec[unit] = bp->b_blkno;
 278:             state = SOK;
 279:         }
 280:         else if(state && err == 0)
 281:             state = SOK;
 282:         if(httab.b_errcnt > 4)
 283:             deverror(bp, HTADDR->hter, HTADDR->htcs2);
 284:         htinit();
 285:         if (state==SIO && ++httab.b_errcnt < 10) {
 286:             httab.b_active = SRETRY;
 287:             h_blkno[unit]++;
 288:             HTADDR->htfc = -1;
 289:             HTADDR->htcs1 = SREV|IENABLE|GO;
 290:             return;
 291:         }
 292:         if (state!=SOK) {
 293:             bp->b_flags |= B_ERROR;
 294:             state = SIO;
 295:         }
 296:     } else if (HTADDR->htcs1 < 0) { /* SC */
 297:         if(HTADDR->htds & ERR)
 298:             htinit();
 299:     }
 300:     switch(state) {
 301:     case SIO:
 302:     case SOK:
 303:         h_blkno[unit]++;
 304: 
 305:     case SCOM:
 306:         httab.b_errcnt = 0;
 307:         httab.b_actf = bp->av_forw;
 308:         iodone(bp);
 309:         bp->b_resid = (-HTADDR->htwc)<<1;
 310:         break;
 311: 
 312:     case SRETRY:
 313:         if((bp->b_flags&B_READ)==0) {
 314:             httab.b_active = SSFOR;
 315:             HTADDR->htcs1 = ERASE|IENABLE|GO;
 316:             return;
 317:         }
 318: 
 319:     case SSFOR:
 320:     case SSREV:
 321:         if(HTADDR->htds & TM) {
 322:             if(state == SSREV) {
 323:                 h_nxrec[unit] = bp->b_blkno - HTADDR->htfc;
 324:                 h_blkno[unit] = h_nxrec[unit];
 325:             } else {
 326:                 h_nxrec[unit] = bp->b_blkno + HTADDR->htfc - 1;
 327:                 h_blkno[unit] = h_nxrec[unit]+1;
 328:             }
 329:         } else
 330:             h_blkno[unit] = bp->b_blkno;
 331:         break;
 332: 
 333:     default:
 334:         return;
 335:     }
 336:     htstart();
 337: }
 338: 
 339: htinit()
 340: {
 341:     register ocs2;
 342:     register omttc;
 343: 
 344:     omttc = HTADDR->httc & 03777;   /* preserve old slave select, dens, format */
 345:     ocs2 = HTADDR->htcs2 & 07;  /* preserve old unit */
 346: 
 347:     HTADDR->htcs2 = CLR;
 348:     HTADDR->htcs2 = ocs2;
 349:     HTADDR->httc = omttc;
 350:     HTADDR->htcs1 = DCLR|GO;
 351: }
 352: 
 353: htread(dev)
 354: {
 355:     htphys(dev);
 356:     physio(htstrategy, &rhtbuf, dev, B_READ);
 357: }
 358: 
 359: htwrite(dev)
 360: {
 361:     htphys(dev);
 362:     physio(htstrategy, &rhtbuf, dev, B_WRITE);
 363: }
 364: 
 365: htphys(dev)
 366: {
 367:     register unit;
 368:     daddr_t a;
 369: 
 370:     unit = minor(dev) & 077;
 371:     if(unit < NUNIT) {
 372:         a = u.u_offset >> 9;
 373:         h_blkno[unit] = a;
 374:         h_nxrec[unit] = a+1;
 375:     }
 376: }

Defined functions

hcommand defined in line 121; used 5 times
htclose defined in line 106; used 3 times
htinit defined in line 339; used 2 times
htintr defined in line 252; used 2 times
htopen defined in line 86; used 3 times
htphys defined in line 365; used 2 times
htread defined in line 353; used 2 times
htstart defined in line 180; used 2 times
htstrategy defined in line 144; used 5 times
htwrite defined in line 359; used 2 times

Defined variables

chtbuf defined in line 35; used 3 times
h_blkno defined in line 42; used 8 times
h_flags defined in line 40; used 3 times
h_nxrec defined in line 43; used 9 times
h_openf defined in line 41; used 6 times
httab defined in line 33; used 21 times
rhtbuf defined in line 34; used 3 times

Defined struct's

device defined in line 13; never used

Defined macros

CLR defined in line 74; used 1 times
COR defined in line 65; used 1 times
CS defined in line 64; used 1 times
DCLR defined in line 56; used 1 times
DRY defined in line 62; never used
EOT defined in line 63; used 1 times
ERASE defined in line 54; used 1 times
ERR defined in line 69; used 1 times
FCE defined in line 70; used 1 times
GO defined in line 47; used 7 times
HARD defined in line 72; used 1 times
HTADDR defined in line 45; used 42 times
H_WRITTEN defined in line 85; used 2 times
IENABLE defined in line 59; used 6 times
INF defined in line 38; used 1 times
  • in line 97
MOL defined in line 68; used 3 times
NED defined in line 76; used 1 times
NOP defined in line 50; used 2 times
NUNIT defined in line 37; used 6 times
P1600 defined in line 58; used 1 times
P800 defined in line 57; used 1 times
PES defined in line 66; used 1 times
RCOM defined in line 49; used 1 times
RDY defined in line 60; never used
REW defined in line 55; used 1 times
SCOM defined in line 82; used 1 times
SFORW defined in line 52; used 1 times
SIO defined in line 78; used 3 times
SOK defined in line 83; used 3 times
SRETRY defined in line 81; used 1 times
SREV defined in line 53; used 3 times
SSFOR defined in line 79; used 2 times
SSREV defined in line 80; used 2 times
TM defined in line 61; used 2 times
TRE defined in line 71; used 1 times
WCOM defined in line 48; used 1 times
WEOF defined in line 51; used 2 times
WRL defined in line 67; used 1 times
Last modified: 1979-05-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1513
Valid CSS Valid XHTML 1.0 Strict