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