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