|
|
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.5 (Berkeley) 4/4/90 ! 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: ! 17: #include "../vaxmba/mtreg.h" ! 18: #include "../vaxmba/mbareg.h" ! 19: ! 20: #include "saio.h" ! 21: #include "savax.h" ! 22: ! 23: short mttypes[] = ! 24: { MBDT_TU78, 0 }; ! 25: ! 26: #define MASKREG(reg) ((reg)&0xffff) ! 27: ! 28: mtopen(io) ! 29: register struct iob *io; ! 30: { ! 31: register struct mtdevice *mtaddr; ! 32: register int i, skip; ! 33: ! 34: if (mbainit(io->i_adapt) == 0) ! 35: return (EADAPT); ! 36: mtaddr = (struct mtdevice *)mbadrv(io->i_adapt, io->i_ctlr); ! 37: for (i = 0;; i++) { ! 38: if (!mttypes[i]) { ! 39: printf("mt: not a tape\n"); ! 40: return (ENXIO); ! 41: } ! 42: if (mttypes[i] == (mtaddr->mtdt&MBDT_TYPE)) ! 43: break; ! 44: } ! 45: mtaddr->mtid = MTID_CLR; ! 46: DELAY(250); ! 47: while ((mtaddr->mtid & MTID_RDY) == 0); ! 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: for (skip = io->i_part; skip--;) { ! 55: io->i_cc = -1; ! 56: mtstrategy(io, MT_SFORWF); ! 57: } ! 58: return (0); ! 59: } ! 60: ! 61: mtclose(io) ! 62: register struct iob *io; ! 63: { ! 64: mtstrategy(io, MT_REW); ! 65: } ! 66: ! 67: mtstrategy(io, func) ! 68: register struct iob *io; ! 69: int func; ! 70: { ! 71: register int errcnt, s, ic; ! 72: register struct mtdevice *mtaddr; ! 73: struct mba_regs *mba; ! 74: ! 75: errcnt = 0; ! 76: mtaddr = (struct mtdevice *)mbadrv(io->i_adapt, io->i_ctlr); ! 77: mba = mbamba(io->i_adapt); ! 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, io->i_ctlr, 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: goto retry; ! 135: } ! 136: if (errcnt) ! 137: printf("mt: recovered by retry\n"); ! 138: return (io->i_cc); /* NO PARTIAL RECORD READS!!! */ ! 139: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.