|
|
1.1 ! root 1: /* mt.c 6.1 83/07/29 */ ! 2: ! 3: /* ! 4: * TM78/TU78 tape driver ! 5: * Made to work reliably by by Jeffrey R. Schwab (Purdue) ! 6: */ ! 7: #include "../machine/pte.h" ! 8: ! 9: #include "../h/param.h" ! 10: #include "../h/inode.h" ! 11: #include "../h/fs.h" ! 12: ! 13: #include "../vaxmba/mtreg.h" ! 14: #include "../vaxmba/mbareg.h" ! 15: ! 16: #include "saio.h" ! 17: #include "savax.h" ! 18: ! 19: short mttypes[] = ! 20: { MBDT_TU78, 0 }; ! 21: ! 22: #define MASKREG(reg) ((reg)&0xffff) ! 23: ! 24: mtopen(io) ! 25: register struct iob *io; ! 26: { ! 27: register int skip; ! 28: register struct mtdevice *mtaddr = ! 29: (struct mtdevice *)mbadrv(io->i_unit); ! 30: int i; ! 31: ! 32: for (i = 0; mttypes[i]; i++) ! 33: if (mttypes[i] == (mtaddr->mtdt&MBDT_TYPE)) ! 34: goto found; ! 35: _stop("not a tape\n"); ! 36: found: ! 37: mbainit(UNITTOMBA(io->i_unit)); ! 38: mtaddr->mtid = MTID_CLR; ! 39: DELAY(250); ! 40: while ((mtaddr->mtid & MTID_RDY) == 0) ! 41: ; ! 42: ! 43: /* clear any attention bits present on open */ ! 44: i = mtaddr->mtner; ! 45: mtaddr->mtas = mtaddr->mtas; ! 46: ! 47: mtstrategy(io, MT_REW); ! 48: skip = io->i_boff; ! 49: while (skip--) { ! 50: io->i_cc = -1; ! 51: mtstrategy(io, MT_SFORWF); ! 52: } ! 53: } ! 54: ! 55: mtclose(io) ! 56: register struct iob *io; ! 57: { ! 58: ! 59: mtstrategy(io, MT_REW); ! 60: } ! 61: ! 62: mtstrategy(io, func) ! 63: register struct iob *io; ! 64: int func; ! 65: { ! 66: register int errcnt, s, ic; ! 67: register struct mtdevice *mtaddr = ! 68: (struct mtdevice *)mbadrv(io->i_unit); ! 69: struct mba_regs *mba = mbamba(io->i_unit); ! 70: ! 71: errcnt = 0; ! 72: retry: ! 73: /* code to trap for attention up prior to start of command */ ! 74: if ((mtaddr->mtas & 0xffff) != 0) { ! 75: printf("mt unexpected attention er=%x - continuing\n", ! 76: MASKREG(mtaddr->mtner)); ! 77: mtaddr->mtas = mtaddr->mtas; ! 78: } ! 79: ! 80: if (func == READ || func == WRITE) { ! 81: mtaddr->mtca = 1<<2; /* 1 record */ ! 82: mtaddr->mtbc = io->i_cc; ! 83: mbastart(io, func); ! 84: /* wait for mba to go idle and read result status */ ! 85: while((mba->mba_sr & MBSR_DTBUSY) != 0) ! 86: ; ! 87: ic = mtaddr->mter & MTER_INTCODE; ! 88: } else { ! 89: mtaddr->mtncs[0] = (-io->i_cc << 8)|func|MT_GO; ! 90: rwait: ! 91: do ! 92: s = mtaddr->mtas&0xffff; ! 93: while (s == 0); ! 94: ic = mtaddr->mtner & MTER_INTCODE; ! 95: mtaddr->mtas = mtaddr->mtas; /* clear attention */ ! 96: } ! 97: switch (ic) { ! 98: case MTER_TM: ! 99: case MTER_EOT: ! 100: case MTER_LEOT: ! 101: return (0); ! 102: ! 103: case MTER_DONE: ! 104: /* make sure a record was read */ ! 105: if ((mtaddr->mtca & (1 << 2)) != 0) { ! 106: printf("mt record count not decremented - retrying\n"); ! 107: goto retry; ! 108: } ! 109: break; ! 110: ! 111: case MTER_RWDING: ! 112: goto rwait; ! 113: default: ! 114: printf("mt hard error: er=%x\n", ! 115: MASKREG(mtaddr->mter)); ! 116: mtaddr->mtid = MTID_CLR; ! 117: DELAY(250); ! 118: while ((mtaddr->mtid & MTID_RDY) == 0) ! 119: ; ! 120: return (-1); ! 121: ! 122: case MTER_RETRY: ! 123: printf("mt error: er=%x\n", MASKREG(mtaddr->mter)); ! 124: if (errcnt == 10) { ! 125: printf("mt: unrecovered error\n"); ! 126: return (-1); ! 127: } ! 128: errcnt++; ! 129: goto retry; ! 130: } ! 131: if (errcnt) ! 132: printf("mt: recovered by retry\n"); ! 133: return (io->i_cc); /* NO PARTIAL RECORD READS!!! */ ! 134: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.