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