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