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) 07/09/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 } 137