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