|
|
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.3 (Berkeley) 2/22/88 ! 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 "param.h" ! 16: #include "inode.h" ! 17: #include "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 struct mtdevice *mtaddr; ! 34: register int i, skip; ! 35: ! 36: if (mbainit(io->i_adapt) == 0) ! 37: return (EADAPT); ! 38: mtaddr = (struct mtdevice *)mbadrv(io->i_adapt, io->i_ctlr); ! 39: for (i = 0;; i++) { ! 40: if (!mttypes[i]) { ! 41: printf("mt: not a tape\n"); ! 42: return (ENXIO); ! 43: } ! 44: if (mttypes[i] == (mtaddr->mtdt&MBDT_TYPE)) ! 45: break; ! 46: } ! 47: mtaddr->mtid = MTID_CLR; ! 48: DELAY(250); ! 49: while ((mtaddr->mtid & MTID_RDY) == 0); ! 50: ! 51: /* clear any attention bits present on open */ ! 52: i = mtaddr->mtner; ! 53: mtaddr->mtas = mtaddr->mtas; ! 54: ! 55: mtstrategy(io, MT_REW); ! 56: for (skip = io->i_part; skip--;) { ! 57: io->i_cc = -1; ! 58: mtstrategy(io, MT_SFORWF); ! 59: } ! 60: return (0); ! 61: } ! 62: ! 63: mtclose(io) ! 64: register struct iob *io; ! 65: { ! 66: mtstrategy(io, MT_REW); ! 67: } ! 68: ! 69: mtstrategy(io, func) ! 70: register struct iob *io; ! 71: int func; ! 72: { ! 73: register int errcnt, s, ic; ! 74: register struct mtdevice *mtaddr; ! 75: struct mba_regs *mba; ! 76: ! 77: errcnt = 0; ! 78: mtaddr = (struct mtdevice *)mbadrv(io->i_adapt, io->i_ctlr); ! 79: mba = mbamba(io->i_adapt); ! 80: retry: ! 81: /* code to trap for attention up prior to start of command */ ! 82: if ((mtaddr->mtas & 0xffff) != 0) { ! 83: printf("mt unexpected attention er=%x - continuing\n", ! 84: MASKREG(mtaddr->mtner)); ! 85: mtaddr->mtas = mtaddr->mtas; ! 86: } ! 87: ! 88: if (func == READ || func == WRITE) { ! 89: mtaddr->mtca = 1<<2; /* 1 record */ ! 90: mtaddr->mtbc = io->i_cc; ! 91: mbastart(io, io->i_ctlr, func); ! 92: /* wait for mba to go idle and read result status */ ! 93: while((mba->mba_sr & MBSR_DTBUSY) != 0) ! 94: ; ! 95: ic = mtaddr->mter & MTER_INTCODE; ! 96: } else { ! 97: mtaddr->mtncs[0] = (-io->i_cc << 8)|func|MT_GO; ! 98: rwait: ! 99: do ! 100: s = mtaddr->mtas&0xffff; ! 101: while (s == 0); ! 102: ic = mtaddr->mtner & MTER_INTCODE; ! 103: mtaddr->mtas = mtaddr->mtas; /* clear attention */ ! 104: } ! 105: switch (ic) { ! 106: case MTER_TM: ! 107: case MTER_EOT: ! 108: case MTER_LEOT: ! 109: return (0); ! 110: ! 111: case MTER_DONE: ! 112: /* make sure a record was read */ ! 113: if ((mtaddr->mtca & (1 << 2)) != 0) { ! 114: printf("mt record count not decremented - retrying\n"); ! 115: goto retry; ! 116: } ! 117: break; ! 118: ! 119: case MTER_RWDING: ! 120: goto rwait; ! 121: default: ! 122: printf("mt hard error: er=%x\n", ! 123: MASKREG(mtaddr->mter)); ! 124: mtaddr->mtid = MTID_CLR; ! 125: DELAY(250); ! 126: while ((mtaddr->mtid & MTID_RDY) == 0) ! 127: ; ! 128: return (-1); ! 129: ! 130: case MTER_RETRY: ! 131: printf("mt error: er=%x\n", MASKREG(mtaddr->mter)); ! 132: if (errcnt++ == 10) { ! 133: printf("mt: unrecovered error\n"); ! 134: return (-1); ! 135: } ! 136: goto retry; ! 137: } ! 138: if (errcnt) ! 139: printf("mt: recovered by retry\n"); ! 140: return (io->i_cc); /* NO PARTIAL RECORD READS!!! */ ! 141: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.