xref: /csrg-svn/sys/vax/stand/ut.c (revision 23250)
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