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