1: #
   2: 
   3: /*
   4:  * TM tape driver
   5:  */
   6: 
   7: #include "../h/param.h"
   8: #include "../h/buf.h"
   9: #include "../h/dir.h"
  10: #include "../h/conf.h"
  11: #include "../h/file.h"
  12: #include "../h/user.h"
  13: 
  14: struct device {
  15:     int tmer;
  16:     int tmcs;
  17:     int tmbc;
  18:     char    *tmba;
  19:     int tmdb;
  20:     int tmrd;
  21: };
  22: 
  23: struct  buf tmtab;
  24: struct  buf ctmbuf;
  25: struct  buf rtmbuf;
  26: 
  27: char    t_flags[8];
  28: char    t_openf[8];
  29: daddr_t t_blkno[8];
  30: daddr_t t_nxrec[8];
  31: 
  32: #define TMADDR ((struct device *)0172520)
  33: 
  34: #define GO  01
  35: #define RCOM    02
  36: #define WCOM    04
  37: #define WEOF    06
  38: #define NOP 0100
  39: #define SFORW   010
  40: #define SREV    012
  41: #define WIRG    014
  42: #define REW 016
  43: #define DENS    060000      /* 9-channel */
  44: #define IENABLE 0100
  45: #define CRDY    0200
  46: #define GAPSD   010000
  47: #define TUR 1
  48: #define HARD    0102200 /* ILC, EOT, NXM */
  49: #define RLE 0100
  50: #define EOF 0040000
  51: #define WL  04
  52: 
  53: #define SSEEK   1
  54: #define SIO 2
  55: #define SCOM    3
  56: 
  57: #define T_WRITTEN 1
  58: 
  59: tmopen(dev, flag)
  60: {
  61:     register unit, ds;
  62: 
  63:     unit = minor(dev) & 0177;
  64:     if (t_openf[unit]) {
  65:         u.u_error = ENXIO;
  66:         return;
  67:     }
  68:     t_blkno[unit] = 0;
  69:     t_nxrec[unit] = 65535;
  70:     t_flags[unit] = 0;
  71: 
  72:     tmtab.b_flags |= B_TAPE;
  73:     ds = tcommand(dev, NOP);
  74:     if ((ds&TUR)==0) {
  75:         printf("mt%d off line\n",unit);
  76:         u.u_error = ENXIO;
  77:     }
  78:     if (flag && ds&WL) {
  79:         printf("mt%d needs write ring\n",unit);
  80:         u.u_error = ENXIO;
  81:     }
  82:     if (u.u_error==0)
  83:         t_openf[unit]++;
  84: }
  85: 
  86: tmclose(dev, flag)
  87: dev_t dev;
  88: int flag;
  89: {
  90: 
  91:     if ( flag == FWRITE ||
  92:     ((flag&FWRITE) && (t_flags[minor(dev)&0177]&T_WRITTEN))) {
  93:         tcommand(dev, WEOF);
  94:         tcommand(dev, WEOF);
  95:         tcommand(dev, SREV);
  96:     }
  97:     if ((minor(dev)&0200) == 0)
  98:         tcommand(dev, REW);
  99:     t_openf[minor(dev)&077] = 0;
 100: }
 101: 
 102: tcommand(dev, com)
 103: {
 104:     register struct buf *bp;
 105: 
 106:     bp = &ctmbuf;
 107:     spl5();
 108:     while (bp->b_flags&B_BUSY) {
 109:         bp->b_flags |= B_WANTED;
 110:         sleep((caddr_t)bp, PRIBIO);
 111:     }
 112:     bp->b_flags = B_BUSY|B_READ;
 113:     spl0();
 114:     bp->b_dev = dev;
 115:     bp->b_resid = com;
 116:     bp->b_blkno = 0;
 117:     tmstrategy(bp);
 118:     iowait(bp);
 119:     if (bp->b_flags&B_WANTED)
 120:         wakeup((caddr_t)bp);
 121:     bp->b_flags = 0;
 122:     return(bp->b_resid);
 123: }
 124: 
 125: tmstrategy(bp)
 126: register struct buf *bp;
 127: {
 128:     register daddr_t *p;
 129: 
 130:     if(bp->b_flags&B_PHYS)
 131:         mapalloc(bp);
 132:     if (bp != &ctmbuf) {
 133:         p = &t_nxrec[minor(bp->b_dev)&0177];
 134:         if (*p <= bp->b_blkno) {
 135:             if (*p < bp->b_blkno) {
 136:                 bp->b_flags |= B_ERROR;
 137:                 iodone(bp);
 138:                 return;
 139:             }
 140:             if (bp->b_flags&B_READ) {
 141:                 clrbuf(bp);
 142:                 bp->b_resid = 0;
 143:                 iodone(bp);
 144:                 return;
 145:             }
 146:         }
 147:         if ((bp->b_flags&B_READ) == 0) {
 148:             t_flags[minor(bp->b_dev)&0177] |= T_WRITTEN;
 149:             *p = bp->b_blkno+1;
 150:         }
 151:     }
 152:     bp->av_forw = 0;
 153:     spl5();
 154:     if (tmtab.b_actf == NULL)
 155:         tmtab.b_actf = bp;
 156:     else
 157:         tmtab.b_actl->av_forw = bp;
 158:     tmtab.b_actl = bp;
 159:     if (tmtab.b_active == NULL)
 160:         tmstart();
 161:     spl0();
 162: }
 163: 
 164: tmstart()
 165: {
 166:     register struct buf *bp;
 167:     register int com;
 168:     int unit;
 169:     register daddr_t *blkno;
 170: 
 171:     loop:
 172:     if ((bp = tmtab.b_actf) == 0)
 173:         return;
 174:     unit = minor(bp->b_dev)&0177;
 175:     blkno = &t_blkno[unit];
 176:     if (t_openf[unit] < 0 || (TMADDR->tmcs & CRDY) == NULL) {
 177:         bp->b_flags |= B_ERROR;
 178:         goto next;
 179:     }
 180:     if (bp == &ctmbuf) {
 181:         if (bp->b_resid == NOP) {
 182:             bp->b_resid = TMADDR->tmer;
 183:             goto next;
 184:         }
 185:         tmtab.b_active = SCOM;
 186:         TMADDR->tmcs = DENS|bp->b_resid|GO| (unit<<8) | IENABLE;
 187:         return;
 188:     }
 189:     com = (unit<<8) | ((bp->b_xmem & 03) << 4) | IENABLE|DENS;
 190:     if (*blkno != bp->b_blkno) {
 191:         tmtab.b_active = SSEEK;
 192:         if (*blkno < bp->b_blkno) {
 193:             com |= SFORW|GO;
 194:             TMADDR->tmbc = *blkno - bp->b_blkno;
 195:         } else {
 196:             if (bp->b_blkno == 0)
 197:                 com |= REW|GO;
 198:             else {
 199:                 com |= SREV|GO;
 200:                 TMADDR->tmbc = bp->b_blkno - *blkno;
 201:             }
 202:         }
 203:         TMADDR->tmcs = com;
 204:         return;
 205:     }
 206:     tmtab.b_active = SIO;
 207:     TMADDR->tmbc = -bp->b_bcount;
 208:     TMADDR->tmba = bp->b_un.b_addr;
 209:     TMADDR->tmcs = com | ((bp->b_flags&B_READ)? RCOM|GO:
 210:         ((tmtab.b_errcnt)? WIRG|GO: WCOM|GO));
 211:     return;
 212: 
 213: next:
 214:     tmtab.b_actf = bp->av_forw;
 215:     iodone(bp);
 216:     goto loop;
 217: }
 218: 
 219: tmintr()
 220: {
 221:     register struct buf *bp;
 222:     register int unit;
 223:     int state;
 224: 
 225:     if ((bp = tmtab.b_actf) == NULL)
 226:         return;
 227:     unit = minor(bp->b_dev)&0177;
 228:     state = tmtab.b_active;
 229:     tmtab.b_active = 0;
 230:     if (TMADDR->tmcs < 0) {     /* error bit */
 231:         while(TMADDR->tmrd & GAPSD) ; /* wait for gap shutdown */
 232:         if (TMADDR->tmer&EOF) {
 233:             t_nxrec[unit] = bp->b_blkno;
 234:             state = SCOM;
 235:             TMADDR->tmbc = -bp->b_bcount;
 236:             goto out;
 237:         }
 238:         if ((TMADDR->tmer&HARD) == 0 && TMADDR->tmer&RLE) {
 239:             state = SIO;
 240:             goto out;
 241:         }
 242:         if ((TMADDR->tmer&(HARD|EOF)) == NULL && state==SIO) {
 243:             if (++tmtab.b_errcnt < 2) {
 244:                 t_blkno[unit]++;
 245:                 tmtab.b_active = 0;
 246:                 tmstart();
 247:                 return;
 248:             }
 249:         } else
 250:             if (t_openf[unit]>0 && bp!=&rtmbuf &&
 251:                 (TMADDR->tmer&EOF)==0 ) {
 252:                 t_openf[unit] = -1;
 253:                 deverror(bp, TMADDR->tmer, 0);
 254:             }
 255:         bp->b_flags |= B_ERROR;
 256:         state = SIO;
 257:     }
 258: out:
 259:     switch ( state ) {
 260:     case SIO:
 261:         t_blkno[unit] += (bp->b_bcount>>BSHIFT);
 262:     case SCOM:
 263:         tmtab.b_errcnt = 0;
 264:         tmtab.b_actf = bp->av_forw;
 265:         bp->b_resid = -TMADDR->tmbc;
 266:         iodone(bp);
 267:         break;
 268:     case SSEEK:
 269:         t_blkno[unit] = bp->b_blkno;
 270:         break;
 271:     default:
 272:         return;
 273:     }
 274:     tmstart();
 275: }
 276: 
 277: tmread(dev)
 278: {
 279:     tmphys(dev);
 280:     physio(tmstrategy, &rtmbuf, dev, B_READ);
 281: }
 282: 
 283: tmwrite(dev)
 284: {
 285:     tmphys(dev);
 286:     physio(tmstrategy, &rtmbuf, dev, B_WRITE);
 287: }
 288: 
 289: tmphys(dev)
 290: {
 291:     register unit;
 292:     daddr_t a;
 293: 
 294:     unit = minor(dev) & 0177;
 295:     if(unit < 8) {
 296:         a = u.u_offset >> 9;
 297:         t_blkno[unit] = a;
 298:         t_nxrec[unit] = a+1;
 299:     }
 300: }

Defined functions

tcommand defined in line 102; used 5 times
tmclose defined in line 86; never used
tmintr defined in line 219; never used
tmopen defined in line 59; never used
tmphys defined in line 289; used 2 times
tmread defined in line 277; never used
tmstart defined in line 164; used 3 times
tmstrategy defined in line 125; used 3 times
tmwrite defined in line 283; never used

Defined variables

ctmbuf defined in line 24; used 3 times
rtmbuf defined in line 25; used 3 times
t_blkno defined in line 29; used 6 times
t_flags defined in line 27; used 3 times
t_nxrec defined in line 30; used 4 times
t_openf defined in line 28; used 6 times
tmtab defined in line 23; used 19 times

Defined struct's

device defined in line 14; never used

Defined macros

CRDY defined in line 45; used 1 times
DENS defined in line 43; used 2 times
EOF defined in line 50; used 3 times
GAPSD defined in line 46; used 1 times
GO defined in line 34; used 7 times
HARD defined in line 48; used 2 times
IENABLE defined in line 44; used 2 times
NOP defined in line 38; used 2 times
RCOM defined in line 35; used 1 times
REW defined in line 42; used 2 times
RLE defined in line 49; used 1 times
SCOM defined in line 55; used 2 times
SFORW defined in line 39; used 1 times
SIO defined in line 54; used 4 times
SREV defined in line 40; used 2 times
SSEEK defined in line 53; used 1 times
TMADDR defined in line 32; used 19 times
TUR defined in line 47; used 1 times
  • in line 74
T_WRITTEN defined in line 57; used 2 times
WCOM defined in line 36; used 1 times
WEOF defined in line 37; used 2 times
WIRG defined in line 41; used 1 times
WL defined in line 51; used 1 times
  • in line 78
Last modified: 1979-05-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1092
Valid CSS Valid XHTML 1.0 Strict