|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986, 1988 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: * @(#)ut.c 7.5 (Berkeley) 7/9/88 ! 7: */ ! 8: ! 9: /* ! 10: * SI Model 9700 -- emulates TU45 on the UNIBUS ! 11: */ ! 12: ! 13: #include "param.h" ! 14: #include "inode.h" ! 15: #include "fs.h" ! 16: ! 17: #include "../vax/pte.h" ! 18: ! 19: #include "../vaxuba/ubareg.h" ! 20: #include "../vaxuba/utreg.h" ! 21: ! 22: #include "saio.h" ! 23: #include "savax.h" ! 24: ! 25: #define MASKREG(reg) ((reg)&0xffff) ! 26: ! 27: #define MAXCTLR 1 /* all addresses must be specified */ ! 28: u_short utstd[MAXCTLR] = { 0172440 }; /* non-standard */ ! 29: ! 30: utopen(io) ! 31: register struct iob *io; ! 32: { ! 33: register int skip; ! 34: ! 35: if ((u_int)io->i_adapt >= nuba) ! 36: return (EADAPT); ! 37: if ((u_int)io->i_ctlr >= MAXCTLR) ! 38: return (ECTLR); ! 39: if (badaddr((char *)ubamem(io->i_unit, utstd[io->i_ctlr]), sizeof(short))) ! 40: return (ENXIO); ! 41: utstrategy(io, UT_REW); ! 42: for (skip = io->i_part; skip--;) ! 43: utstrategy(io, UT_SFORWF); ! 44: return (0); ! 45: } ! 46: ! 47: utclose(io) ! 48: register struct iob *io; ! 49: { ! 50: utstrategy(io, UT_REW); ! 51: } ! 52: ! 53: #define UTWAIT(addr) { \ ! 54: do \ ! 55: word = addr->utcs1; \ ! 56: while((word&UT_RDY) == 0); \ ! 57: } ! 58: ! 59: utstrategy(io, func) ! 60: register struct iob *io; ! 61: { ! 62: register struct utdevice *addr; ! 63: register u_short word; ! 64: register int errcnt; ! 65: int info, resid; ! 66: u_short dens; ! 67: ! 68: addr = (struct utdevice *)ubamem(io->i_unit, utstd[io->i_ctlr]); ! 69: dens = io->i_unit | PDP11FMT | UT_PE; ! 70: errcnt = 0; ! 71: retry: ! 72: utquiet(addr); ! 73: addr->uttc = dens; ! 74: info = ubasetup(io, 1); ! 75: addr->utwc = -((io->i_cc+1) >> 1); ! 76: addr->utfc = -io->i_cc; ! 77: if (func == READ) { ! 78: addr->utba = info; ! 79: addr->utcs1 = UT_RCOM | ((info>>8) & 0x30) | UT_GO; ! 80: } else if (func == WRITE) { ! 81: addr->utba = info; ! 82: addr->utcs1 = UT_WCOM | ((info>>8) & 0x30) | UT_GO; ! 83: } else if (func == UT_SREV) { ! 84: addr->utcs1 = UT_SREV | UT_GO; ! 85: return (0); ! 86: } else ! 87: addr->utcs1 = func | UT_GO; ! 88: UTWAIT(addr); ! 89: ubafree(io, info); ! 90: word = addr->utds; ! 91: if (word&(UTDS_EOT|UTDS_TM)) { ! 92: addr->utcs1 = UT_CLEAR | UT_GO; ! 93: goto done; ! 94: } ! 95: if ((word&UTDS_ERR) || (addr->utcs1&UT_TRE)) { ! 96: printf("ut error: cs1=%b er=%b cs2=%b ds=%b", ! 97: addr->utcs1, UT_BITS, addr->uter, UTER_BITS, ! 98: addr->utcs2, UTCS2_BITS, word, UTDS_BITS); ! 99: if (errcnt++ == 10) { ! 100: printf("ut: unrecovered error\n"); ! 101: return (-1); ! 102: } ! 103: if (addr->utcs1&UT_TRE) ! 104: addr->utcs2 |= UTCS2_CLR; ! 105: addr->utcs1 = UT_CLEAR | UT_GO; ! 106: utstrategy(io, UT_SREV); ! 107: utquiet(addr); ! 108: if (func == WRITE) { ! 109: addr->utcs1 = UT_ERASE | UT_GO; ! 110: UTWAIT(addr); ! 111: } ! 112: goto retry; ! 113: } ! 114: if (errcnt) ! 115: printf("ut: recovered by retry\n"); ! 116: done: ! 117: if (func == READ) { ! 118: resid = 0; ! 119: if (io->i_cc > MASKREG(addr->utfc)) ! 120: resid = io->i_cc - MASKREG(addr->utfc); ! 121: } else ! 122: resid = MASKREG(-addr->utfc); ! 123: return (io->i_cc - resid); ! 124: } ! 125: ! 126: static ! 127: utquiet(addr) ! 128: register struct utdevice *addr; ! 129: { ! 130: register u_short word; ! 131: ! 132: UTWAIT(addr); ! 133: do ! 134: word = addr->utds; ! 135: while ((word&UTDS_DRY) == 0 && (word&UTDS_PIP)); ! 136: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.