xref: /original-bsd/sys/vax/stand/ut.c (revision f0fd5f8a)
1 /*	ut.c	4.5	82/12/17	*/
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 
19 u_short	utstd[] = { 0172440 };		/* non-standard */
20 
21 utopen(io)
22 	register struct iob *io;
23 {
24 	register skip;
25 
26 	utstrategy(io, UT_REW);
27 	skip = io->i_boff;
28 	while (skip--) {
29 		io->i_cc = 0;
30 		utstrategy(io, UT_SFORW);
31 	}
32 }
33 
34 utclose(io)
35 	register struct iob *io;
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;
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 		return(0);
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 	return (func == READ ?
102 		io->i_cc - ((-addr->utfc) & 0xffff) : -addr->utwc << 1);
103 }
104 
105 utquiet(addr)
106 	register struct utdevice *addr;
107 {
108 	register u_short word;
109 
110 	utwait(addr);
111 	do
112 		word = addr->utds;
113 	while ((word&UTDS_DRY) == 0 && (word&UTDS_PIP));
114 }
115